โมดูล 4/5 · สัปดาห์ 10–12 · 27 ชม.

บินอัตโนมัติใน SITL และภาคสนาม

UAT 304 การวางแผนภารกิจและการบินอัตโนมัติของระบบอากาศยานไร้คนขับ

เวลาเรียนประมาณ 90 นาทีร่าง รอตรวจปรับปรุงล่าสุด 28 กันยายน 2569

บทเรียน

เมื่อเรียนจบโมดูลนี้ ผู้เรียนจะสามารถ

  1. ฝึกภารกิจอัตโนมัติจากเครื่องจำลองสู่ภาคสนามตามลำดับขั้น
  2. เทียบเวลาบินแต่ละช่วงกับแผน และหาสาเหตุของช่วงที่ต่างมาก
  3. อธิบายการทำงานของ failsafe แต่ละชนิดใน ArduPilot และตั้งค่าตามภารกิจ
  4. ทดสอบการตอบสนองต่อเหตุผิดปกติใน SITL ก่อนบินจริง

ความรู้พื้นฐานที่ควรมี: UAT 304 โมดูล 1–3 · UAT 206 โมดูล 5 (ทดลองควบคุมใน SITL)

ทำไมต้องรู้

ภารกิจอัตโนมัติที่ผ่านใน SITL ไม่ได้รับประกันว่าจะผ่านในภาคสนาม ลม สัญญาณ GNSS และลิงก์จริงต่างจากเครื่องจำลอง หน่วยความรู้เรื่องแผนฝึกจากรีโมตสู่ภารกิจจำลองของคลังความรู้โดรนให้ฝึกทีละขั้นพร้อมเกณฑ์สังเกตและไฟล์บันทึก และหน่วยความรู้เรื่องเส้นทางทักษะการบินเชื่อมจาก simulator สู่ภาคสนามพร้อม checklist ก่อนและหลังบิน โมดูลนี้เน้นสองเรื่อง คือ ตรวจว่าภารกิจเป็นไปตามแผน และ ทดสอบว่าระบบตอบสนองต่อเหตุผิดปกติอย่างที่ตั้งใจ

ลำดับการฝึก

  1. SITL กับภารกิจเดียวกับที่จะบินจริง ทดสอบทุก failsafe
  2. บินจริงในพื้นที่โล่ง ความสูงและระยะน้อยกว่าแผน นักบินพร้อมรับช่วงควบคุมเอง
  3. บินภารกิจจริงเต็มรูปแบบ พร้อมผู้สังเกต
  4. ทบทวน log ทุกเที่ยวก่อนบินเที่ยวถัดไป

เทียบเวลาบินกับแผน

ตัวอย่างที่ 1 ช่วงใดใช้เวลานานผิดปกติ

เที่ยวบินที่ 1 จากโมดูล 3 บินที่ 8 m/s หยุดถ่ายภาพจุดละ 60 วินาที เวลาจริงอ่านจากเวลาที่ถึงแต่ละ waypoint ใน log (ค่าจำลอง) ทีมถือว่าช่วงที่ช้ากว่าแผนเกิน 20% ต้องหาสาเหตุ

import math

pts = {"H": (0, 0), "P1": (420, 150), "P2": (900, -200), "P10": (1100, -900)}
legs = [("H", "P1"), ("P1", "P2"), ("P2", "P10"), ("P10", "H")]
actual_s = [118, 138, 170, 245]                  # วินาทีจาก log ต่อช่วง รวมเวลาหยุดที่จุดปลาย
SPEED, HOLD = 8.0, 60
for (a, b), act in zip(legs, actual_s):
    d = math.dist(pts[a], pts[b])
    plan = d / SPEED + (HOLD if b != "H" else 0)
    diff = (act - plan) / plan
    flag = "  <- investigate" if diff > 0.20 else ""
    print(f"{a:>3}->{b:<3} {d:5.0f} m  plan {plan:5.1f} s  actual {act:3d} s  {diff:+.0%}{flag}")
  H->P1    446 m  plan 115.7 s  actual 118 s  +2%
 P1->P2    594 m  plan 134.3 s  actual 138 s  +3%
 P2->P10   728 m  plan 151.0 s  actual 170 s  +13%
P10->H    1421 m  plan 177.7 s  actual 245 s  +38%  <- investigate

ช่วงสุดท้ายที่บินกลับจาก P10 มาจุดขึ้นบินช้ากว่าแผนมาก ขณะที่ช่วงอื่นใกล้แผน สาเหตุที่เป็นไปได้คือบินสวนลม หรือโหมด RTL ใช้ความเร็วต่างจากความเร็วภารกิจ ต้องดูทิศลมและความเร็วใน log ก่อนสรุป ข้อมูลนี้ช่วยให้วางแผนพลังงานของเที่ยวถัดไปแม่นขึ้น

แผนภูมิแท่งคู่ของสี่ช่วงบิน แท่งสีเทาเวลาตามแผนและแท่งสีฟ้าเวลาจริง ช่วง P10 ไป H แท่งเวลาจริงเป็นสีชมพูสูงกว่าแผนชัดเจน
ภาพที่ 1 เวลาบินแต่ละช่วงเทียบแผน

Failsafe ใน ArduPilot

เอกสาร ArduPilot อธิบาย failsafe แต่ละชนิดแยกกัน:

  • วิทยุบังคับหาย FS_THR_ENABLE เช่น 1 = RTL (ลงจอดถ้าไม่มี GPS) 3 = ลงจอด ถ้าต้องการให้ภารกิจอัตโนมัติบินต่อ ใช้บิตที่ 0 ของ FS_OPTIONS (ตั้งแต่ Copter 4.0 ค่า 2 เดิมถูกยกเลิก)
  • ลิงก์ GCS หาย FS_GCS_ENABLE ทำงานเมื่อไม่ได้รับสัญญาณเกิน FS_GCS_TIMEOUT (ค่าเริ่มต้น 5 วินาที) และบิตที่ 1 ของ FS_OPTIONS ให้ภารกิจบินต่อได้
  • แบตเตอรี่ BATT_FS_LOW_ACT และ BATT_FS_CRT_ACT เช่น 2 = RTL 1 = ลงจอด ไม่ทำงานถ้าอยู่ในโหมด RTL หรือ Land อยู่แล้ว และรีเซ็ตไม่ได้จนกว่าจะรีบูต
  • EKF ทำงานเมื่อค่าความแปรปรวนของเข็มทิศ ตำแหน่ง หรือความเร็วสองในสามเกิน FS_EKF_THRESH (ค่าเริ่มต้น 0.8) นาน 1 วินาที ค่าเริ่มต้นของ FS_EKF_ACTION คือลงจอด

เอกสารไม่ได้ระบุลำดับความสำคัญเมื่อเกิดหลาย failsafe พร้อมกัน ทีมจึงต้องทดสอบใน SITL ด้วยรุ่นเฟิร์มแวร์ที่ใช้จริง ตัวอย่างต่อไปนี้เป็น แบบจำลองเพื่อการสอน ที่ใช้หลัก “การกระทำที่ปลอดภัยกว่าชนะ” เพื่อฝึกคิดล่วงหน้า ไม่ใช่การทำงานภายในของ ArduPilot

ตัวอย่างที่ 2 ไล่เหตุการณ์ตามค่าที่ตั้งไว้ (แบบจำลองสอน)

params = {"FS_GCS_CONTINUE_AUTO": True, "BATT_FS_LOW_ACT": "RTL", "BATT_FS_CRT_ACT": "LAND", "FS_EKF_ACTION": "LAND"}
events = [(300, "GCS link lost"), (420, "GCS link restored"), (540, "battery low"), (600, "EKF variance high")]
RANK = {"AUTO": 0, "RTL": 1, "LAND": 2}         # ยิ่งมากยิ่งอนุรักษ์นิยม (สมมติฐานของแบบจำลอง)

mode = "AUTO"
for t, ev in events:
    want = mode
    if ev == "GCS link lost":
        want = "AUTO" if params["FS_GCS_CONTINUE_AUTO"] else "RTL"
    elif ev == "battery low":
        want = params["BATT_FS_LOW_ACT"]
    elif ev == "EKF variance high":
        want = params["FS_EKF_ACTION"]
    new = want if RANK[want] >= RANK[mode] else mode
    print(f"t={t:>3}s {ev:<20} requested {want:<4} -> mode {new}")
    mode = new
t=300s GCS link lost        requested AUTO -> mode AUTO
t=420s GCS link restored    requested AUTO -> mode AUTO
t=540s battery low          requested RTL  -> mode RTL
t=600s EKF variance high    requested LAND -> mode LAND

ลิงก์ GCS ขาดช่วงสั้นไม่ทำให้ภารกิจหยุด เพราะตั้งให้บินต่อ แต่เมื่อแบตเตอรี่ต่ำ อากาศยานกลับจุดขึ้นบิน และเมื่อ EKF ผิดปกติระหว่างทางกลับ อากาศยานลงจอด ณ จุดนั้น ซึ่งอาจเป็นกลางพื้นที่น้ำท่วม ทีมต้องรู้ล่วงหน้าว่าผลแบบนี้เป็นไปได้ และเตรียมทีมเก็บอากาศยาน ก่อนงานจริงต้องทดสอบลำดับเหตุการณ์เดียวกันใน SITL ว่าได้ผลตรงกับที่คาด

แผนภาพสถานะสามกล่อง AUTO RTL และ LAND ลูกศรจาก AUTO ไป RTL เขียนว่าแบตเตอรี่ต่ำ ลูกศรจาก RTL ไป LAND เขียนว่า EKF ผิดปกติหรือแบตเตอรี่วิกฤต ลูกศรวนที่ AUTO เขียนว่าลิงก์ GCS หายเมื่อตั้งให้บินต่อ
ภาพที่ 2 สถานะของภารกิจตามเหตุผิดปกติ (แบบจำลองสอน)

ปฏิบัติการประจำโมดูล

ปฏิบัติการ: SITL สู่ภาคสนาม

  1. อัปโหลดภารกิจจากโมดูล 3 ใน SITL บันทึก log แล้วเทียบเวลาด้วยตัวอย่างที่ 1
  2. ทดสอบใน SITL: ตัดลิงก์ GCS ปิดวิทยุบังคับ ลดแรงดันแบตเตอรี่จำลอง และจำลอง GPS หาย บันทึกผลแต่ละกรณี
  3. เทียบผลกับแบบจำลองในตัวอย่างที่ 2 ถ้าต่างกัน ให้เชื่อผลของ SITL และแก้แบบจำลองของทีม
  4. บินจริงขั้นที่ 2 ตามลำดับการฝึก ภายใต้การกำกับของอาจารย์
  5. ทบทวน log ก่อนขยายสู่ภารกิจเต็ม

ข้อผิดพลาดที่พบบ่อย

ระวัง

  • กระโดดจาก SITL ไปภารกิจเต็มทันที
  • ไม่ทดสอบ failsafe ใน SITL ด้วยค่าที่จะใช้จริง
  • เดาลำดับของ failsafe แทนการทดสอบ
  • ใช้ความหมายของพารามิเตอร์จากเฟิร์มแวร์รุ่นเก่า
  • ไม่ดู log ก่อนบินเที่ยวถัดไป

สรุป

  • ฝึกตามลำดับจาก SITL สู่ภาคสนามแบบจำกัด แล้วจึงภารกิจเต็ม
  • เทียบเวลาแต่ละช่วงกับแผนเพื่อหาช่วงผิดปกติ และใช้ปรับแผนพลังงาน
  • failsafe ของ ArduPilot แยกตามชนิด แต่ละชนิดตั้งการกระทำได้ และเอกสารไม่ระบุลำดับเมื่อเกิดพร้อมกัน
  • ทดสอบลำดับเหตุการณ์ใน SITL ก่อนงานจริงเสมอ

แบบฝึกตรวจความเข้าใจ

  1. ช่วงบิน 800 m ที่ 8 m/s หยุด 60 วินาที ใช้เวลาตามแผนเท่าใด
  2. แผน 100 s จริง 130 s ส่วนต่างสัมพัทธ์เท่าใด
  3. ถ้าต้องการให้ภารกิจบินต่อเมื่อวิทยุบังคับหายใน Copter รุ่นปัจจุบัน ต้องตั้งอะไร
  4. failsafe แบตเตอรี่ทำงานหรือไม่ถ้าอากาศยานอยู่ในโหมด RTL แล้ว
  5. ทำไมต้องทดสอบลำดับ failsafe ใน SITL
เฉลย
  1. s
  2. บิตที่ 0 ของ FS_OPTIONS
  3. ไม่ทำงาน
  4. เอกสารไม่ระบุลำดับเมื่อเกิดหลายเหตุพร้อมกัน และผลขึ้นกับรุ่นเฟิร์มแวร์และค่าที่ตั้ง

สรุปสูตรสำคัญ

เวลาตามแผนของช่วงบิน
ส่วนต่างสัมพัทธ์

แหล่งอ้างอิงหลัก

  1. ArduPilot Dev Team. SITL simulator (software in the loop). link
  2. ArduPilot Dev Team. Radio failsafe. ArduPilot Copter documentation. link
  3. ArduPilot Dev Team. Battery failsafe. ArduPilot Copter documentation. link
  4. ArduPilot Dev Team. GCS failsafe. ArduPilot Copter documentation. link
  5. ArduPilot Dev Team. EKF failsafe. ArduPilot Copter documentation. link
  6. ArduPilot Dev Team. Parameter list (Copter stable V4.6.3). ArduPilot Copter documentation. link
  7. ArduPilot Dev Team. Onboard message log messages. ArduPilot Copter documentation. link

อ่านเพิ่มเติม

ศึกษาหน่วยความรู้ที่กำหนดล่วงหน้า ดูสื่อประกอบ และทำ quiz ประจำโมดูล

ในชั้นเรียน / ภาคสนาม

ปฏิบัติการในห้องแล็บหรือภาคสนามตามใบงาน พร้อม checklist ความปลอดภัย

หลักฐานการเรียนรู้: ใบงานที่ผ่านการตรวจและผล quiz

แบบทดสอบประจำโมดูล

แบบทดสอบนี้ใช้ตรวจความเข้าใจ (formative) ไม่ใช่การสอบเก็บคะแนน

โดเมนความรู้: การวางแผนภารกิจ การบิน และการจำลอง · การควบคุม ออโตไพลอต และการนำทาง · กฎหมาย ความปลอดภัย และความเสี่ยง