2. วางเส้นทางและงบเวลา
ท่าบินรูปตัว T และการแบ่งเวลา 150 วินาทีให้แต่ละคำสั่ง ตามเอนจินของตัวจำลอง
ภารกิจ 150 วินาทีเหมือนเดินทางด้วยงบเงินจำกัด ถ้าไม่จดว่าแต่ละช่วงใช้เท่าไร ก็ไม่รู้ว่าเกินเมื่อไร โดรนของชมรมไม่มีเครื่องวัดระยะบิน มันบินตามเวลา ดังนั้น เวลาคือหน่วยเงินเดียวที่ต้องบริหาร
1. โดรนนับระยะด้วยเวลา
คำสั่ง fw(250) ไม่ได้บอกให้โดรนไป "250 ซม. แล้วหยุด" ใน protocol.cpp มันคือ
void Arduino::move_forward_cm(uint16_t distance_cm, uint8_t speed) {
set_direction(1, speed); // 1 = เดินหน้า
delay(ms_round(distance_cm * MS_PER_CM_FWD)); // รอตามเวลา
poshold(speed); // แล้วสั่งหยุดนิ่ง
}สั่งทิศ รอตามเวลา แล้วสั่งหยุด ค่าเวลาต่อซม. วัดมาจากโดรนจริงและเก็บไว้ใน config.hpp
| ทิศ | ms ต่อ 1 ซม. | 250 ซม. ใช้ |
|---|---|---|
เดินหน้า fw | 15.46 | 3.87 วินาที |
ถอย bw | 15.16 | 3.79 วินาที |
ซ้าย ml | 15.65 | 3.91 วินาที |
ขวา mr | 15.65 | 3.91 วินาที |
เรียกวิธีนี้ว่า dead-reckoning คือเดาตำแหน่งจากเวลาและความเร็ว แบตอ่อนลงหรือลมแรง ความเร็วเปลี่ยน ระยะก็เพี้ยน จึงต้องซ้อมในสนามจริงและจูนตัวเลข
delay ≈ 3865 ms ≈ 3.87 วินาที · ความเร็วเฉลี่ย ≈ 65 ซม./วินาที
2. ท่าตัว T
ภารกิจทิ้งสัมภาระต้องไปสองแท่นบน แล้วกลับ เส้นทางที่ประหยัดคือรูปตัว T
ทำไมถึงเป็นตัว T: จุด Takeoff อยู่ตรงกลางระหว่างแท่นสองแท่นบนพอดี ไปทางเหนือ 250 ซม. จะอยู่แนวเดียวกับแท่น จากนั้นซ้าย 250 ถึงแท่นหนึ่ง ข้ามไปขวาอีก 500 ถึงอีกแท่น ไม่ต้องเลี้ยวตัว (yaw) ซึ่งเสียเวลา (42 ms ต่อองศา ตามค่า YAW_MS_PER_DEG ใน config.hpp)
ระยะรวมของตัว T คือ 250 + 250 + 500 + 250 + 250 = 1,500 ซม. กินเวลาบินล้วนๆ ราว 23 วินาที
ท่านี้เป็นแบบที่ใช้ในโปรแกรม mission-t ของตัวจำลอง ส่วนโค้ดจริงของชมรม (KEY1_mode1 ใน Drone_Mission.ino) ใช้ตัวเลขต่างกันเล็กน้อย เช่น fw(256) และ mr(480) ที่ได้จากการจูนบนสนามจริง ตัวเลขในตัวจำลองเป็นค่ากลางที่ปรับทีหลังได้
3. งบเวลาแจกแจง
เอนจินใน src/flight/engine.ts ใช้ค่าคงที่เหล่านี้นับเวลา ผลลัพธ์ของ mission-warm (ตัว T ด้านบนอย่างเดียว) คือ 42.0 วินาที
| ขั้น | วิธีคิด | เวลา |
|---|---|---|
calibration() | ตั้งศูนย์ 3 วินาที | 3.0 วิ |
reload() | คนแข่งใส่บอล | 6.5 วิ |
takeOff() | ขึ้น 80 ซม. | 1.9 วิ |
sh(100) | ปรับความสูงเล็กน้อย | 0.1 วิ |
fw(250) | 250 × 15.46 | 3.9 วิ |
ml(250) | 250 × 15.65 | 3.9 วิ |
poshold() ×2 | หยุดนิ่ง 1.2 วิ ต่อครั้ง | 2.4 วิ |
drop() ×2 | ปล่อยชุด 20 ลูก 1.6 วิ ต่อครั้ง | 3.2 วิ |
mr(500) | 500 × 15.65 | 7.8 วิ |
ml(250) | 250 × 15.65 | 3.9 วิ |
bw(250) | 250 × 15.16 | 3.8 วิ |
autoLand() | ลงจากความสูง 100 ซม. | 1.6 วิ |
| รวม | ≈ 42.0 วิ |
เวลาในตัวจำลองต่างจากโดรนจริง
ตัวจำลองนับ fw(250) เป็น 3.87 วินาที แต่ใน DroneEasy.cpp ฟังก์ชัน fw() ทำ move_forward_cm แล้วต่อด้วย settle(400) ซึ่งรออีก 400 ms โดรนจริงจึงช้ากว่าเล็กน้อยทุกครั้งที่สั่งเคลื่อนที่ ตัวปล่อยบอลก็ต่างกัน ฟังก์ชันของจริงบล็อก 1.5 วินาทีต่อครั้ง (ดู ปล่อยสัมภาระ) ประมาณการหยาบๆ ของ mission-t บนโดรนจริงคือ 83.5 + 4 (10 คำสั่งเคลื่อนที่ × 0.4) + 7.2 (4 การปล่อย × 1.8 ที่ต่างกัน) ≈ 95 วินาที ตัวเลขนี้คำนวณเอา ยังไม่ได้จับเวลาจริง
4. เทคนิคเขียนแผน
- ลงตารางก่อนโค้ด เขียนทีละขั้น พร้อมเวลา แล้วบวก ถ้าเกิน 150 ตัดขั้นที่ได้คะแนนน้อยสุดก่อน
- ใช้ความสูงร่วมกัน สั่ง
sh()ให้น้อยที่สุด ขึ้นลงทุก 10 ซม. กินเวลา 12 ms/ซม. ตามเอนจิน - เส้นตรงสั้นๆ ก่อน ตัว T ใช้ระยะตรงเท่ากันทุกท่อน แก้ตัวเลขทีละท่อนได้ง่ายกว่าเส้นทางซับซ้อน
- เลี้ยวให้น้อย ถ้าเลี่ยง
yawได้ ให้เลี่ยง การหมุน 90° กินเวลา 90 × 42 ms + 220 ms ≈ 4 วินาที ตามเอนจิน - เผื่อ 10–20% ตัวจำลองไม่รู้เรื่องลมหรือแบต ถ้าแผนใช้ 140 วินาที ในสนามจริงมีโอกาสหมดเวลา
ลองทำ
- ตั้งค่า
mission-warmแล้วปรับfw(250)เป็นfw(300)ดูว่าเวลาเพิ่มกี่วินาที (คำตอบ: 50 × 15.46 ms ≈ 0.77 วินาที) - จดตารางงบเวลาของท่าที่คุณออกแบบเอง แล้วเทียบกับผลที่ตัวจำลองบอก
- คำนวณว่า ถ้าเพิ่ม
settle(400)หลังทุกคำสั่งเคลื่อนที่ จะเกิน 150 วินาทีหรือไม่
พังตรงไหนบ่อย
- นับเวลาจากตัวจำลองอย่างเดียว โดรนจริงช้ากว่าตามที่คำนวณข้างบน
- ระยะสะสมเพี้ยน ซ้ายขวาบนสนามไม่เท่ากัน เพราะ 15.65 ms/ซม. เป็นค่าเฉลี่ย จดค่าที่วัดจริงของโดรนตัวเอง
- ลืมเวลาบรรจุบอล
reload()ใช้ 6.5 วินาที ในตัวอย่าง - ลืม
poshold()ก่อนปล่อย โดรนยังไหลอยู่ บอลตกนอกแท่น - ตัดสินจากเวลาที่เหลือเท่านั้น เวลาเหลือไม่ได้แปลว่าคะแนนครบ ตรวจรายการคะแนนที่ตัวจำลองสรุปให้ด้วย