Failsafe และ geofence
UAT 305 เทคโนโลยีออโตไพลอตและระบบควบคุม
บทเรียน
เมื่อเรียนจบโมดูลนี้ ผู้เรียนจะสามารถ
- ตั้งค่า geofence แบบเพดาน วงกลม และรูปหลายเหลี่ยมทั้งแบบรวมและแบบกัน
- ตรวจว่าจุดใดอยู่ในหรือนอกรั้ว และใกล้ขอบเกินระยะเผื่อ ด้วยโปรแกรม
- ตรวจจาก log ว่า failsafe ของ GCS ทำงานตามเวลาที่ตั้งไว้หรือไม่
- ออกแบบการทดสอบ failsafe และ geofence ก่อนใช้งานจริง
ทำไมต้องรู้
UAT 312 คำนวณระยะเผื่อของ geofence และ UAT 304 ไล่เหตุการณ์ failsafe ในภารกิจแล้ว โมดูลนี้มองจากฝั่งออโตไพลอต: ตั้งค่าอย่างไร และพิสูจน์อย่างไรว่าทำงานจริง หน่วยความรู้เรื่องสถาปัตยกรรม PX4 และ ArduPilot ครอบคลุม failsafe และ geofence และปฏิบัติการหยุดและต่อลิงก์จำลองของคลังความรู้โดรนให้บันทึกพฤติกรรมเมื่อ telemetry ขาดหาย
ชนิดของ geofence ใน ArduPilot
FENCE_TYPE เป็นบิตมาสก์: 1 = เพดานความสูง 2 = วงกลมรอบจุดขึ้นบิน 4 = รั้วรูปหลายเหลี่ยมและวงกลมแบบรวมและแบบกัน 8 = ความสูงต่ำสุด ค่าเริ่มต้นของ Copter 4.6.3 คือ 7 FENCE_ACTION กำหนดสิ่งที่ทำเมื่อฝ่ารั้ว เช่น 1 = RTL หรือลงจอด (ค่าเริ่มต้น) 2 = ลงจอดเสมอ 4 = เบรกแล้วลงจอด และ FENCE_MARGIN คือระยะเผื่อจากขอบ (ค่าเริ่มต้น 2 m) เอกสารเรื่องรั้วแบบรวมและแบบกันอธิบายว่า รั้วแบบรวม (inclusion) คือพื้นที่ที่ต้องอยู่ข้างใน ส่วน รั้วแบบกัน (exclusion) คือพื้นที่ห้ามเข้า รูปหลายเหลี่ยมมีได้ถึง 70 จุด และอัปโหลดจาก GCS ผ่าน MAVLink2
ตัวอย่างที่ 1 ตรวจจุดกับรั้วรวมและรั้วกัน
รั้วแบบรวมเป็นสี่เหลี่ยม 400 × 300 m มีรั้วแบบกันรอบอาคารสูงข้างใน ใช้วิธีลากเส้นนับจุดตัด (ray casting) ตรวจว่าอยู่ข้างในหรือไม่ และหาระยะถึงขอบที่ใกล้ที่สุด
import math
INCLUSION = [(0, 0), (400, 0), (400, 300), (0, 300)] # m
EXCLUSION = [(250, 120), (320, 120), (320, 200), (250, 200)] # อาคารสูง
MARGIN = 2.0 # FENCE_MARGIN
def inside(p, poly):
x, y, c = p[0], p[1], False
for i in range(len(poly)):
(x1, y1), (x2, y2) = poly[i], poly[(i + 1) % len(poly)]
if (y1 > y) != (y2 > y) and x < x1 + (y - y1) * (x2 - x1) / (y2 - y1):
c = not c
return c
def dist_to_edge(p, poly):
best = math.inf
for i in range(len(poly)):
(ax, ay), (bx, by) = poly[i], poly[(i + 1) % len(poly)]
dx, dy = bx - ax, by - ay
t = max(0.0, min(1.0, ((p[0] - ax) * dx + (p[1] - ay) * dy) / (dx * dx + dy * dy)))
best = min(best, math.hypot(p[0] - (ax + t * dx), p[1] - (ay + t * dy)))
return best
for p in [(100, 100), (398.5, 150), (300, 150), (410, 50)]:
if not inside(p, INCLUSION):
verdict = "BREACH: outside inclusion fence"
elif inside(p, EXCLUSION):
verdict = "BREACH: inside exclusion zone"
elif min(dist_to_edge(p, INCLUSION), dist_to_edge(p, EXCLUSION)) < MARGIN:
verdict = "within margin of a fence edge"
else:
verdict = "ok"
print(f"{p}: {verdict}")
(100, 100): ok
(398.5, 150): within margin of a fence edge
(300, 150): BREACH: inside exclusion zone
(410, 50): BREACH: outside inclusion fence
จุดที่ห่างขอบเพียง 1.5 m ยังไม่ฝ่ารั้ว แต่อยู่ในระยะเผื่อ ซึ่ง ArduPilot ใช้ป้องกันไม่ให้ภารกิจหรือการบินแบบนำทางพาเข้าใกล้ขอบเกินไป การตรวจภารกิจกับรั้วด้วยโปรแกรมก่อนอัปโหลดช่วยจับจุดเส้นทางที่วางผิดได้ก่อนบิน
พิสูจน์ failsafe ของ GCS จาก log
GCS ส่งข้อความ HEARTBEAT มาที่อากาศยานเป็นระยะ ตามเอกสาร MAVLink ลิงก์วิทยุมักส่ง 1 Hz และถือว่าขาดการติดต่อเมื่อหายไปราวสี่ถึงห้าข้อความ แต่ MAVLink ไม่ได้กำหนดอัตราหรือเวลาตายตัว ArduPilot ใช้ FS_GCS_TIMEOUT (ค่าเริ่มต้น 5 วินาที ช่วง 2–120) ถ้าไม่ได้รับ heartbeat นานเกินค่านี้ failsafe ของ GCS จะทำงานตาม FS_GCS_ENABLE
ตัวอย่างที่ 2 failsafe ทำงานตรงเวลาหรือไม่
เวลาที่อากาศยานได้รับ heartbeat จาก GCS และเวลาที่ log บันทึกการเปลี่ยนโหมดเป็น RTL จากการทดสอบใน SITL (ข้อมูลจำลอง)
TIMEOUT = 5.0 # FS_GCS_TIMEOUT
TOLERANCE = 0.5 # s ความคลาดที่ทีมยอมรับ
heartbeats = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9.1, 10, 16.4, 17.4, 18.4] # s
mode_change_rtl = 15.2 # s จาก log
gaps = [(heartbeats[i], heartbeats[i + 1] - heartbeats[i]) for i in range(len(heartbeats) - 1)]
for start, gap in gaps:
if gap > TIMEOUT:
expected = start + TIMEOUT
diff = mode_change_rtl - expected
print(f"link lost after t={start}s for {gap:.1f}s -> failsafe expected at {expected:.1f}s")
print(f"logged RTL at {mode_change_rtl}s ({diff:+.1f}s) -> {'as configured' if abs(diff) <= TOLERANCE else 'CHECK SETTINGS'}")
print(f"largest gap without failsafe: {max(g for _, g in gaps if g <= TIMEOUT):.1f}s")
link lost after t=10s for 6.4s -> failsafe expected at 15.0s
logged RTL at 15.2s (+0.2s) -> as configured
largest gap without failsafe: 1.1s
failsafe ทำงานห่างจากเวลาที่คาดเพียงเล็กน้อย จึงถือว่าทำงานตามค่าที่ตั้ง ช่วงที่ heartbeat หายเกิน 1 วินาทีเล็กน้อยไม่ทำให้ failsafe ทำงาน ซึ่งเป็นพฤติกรรมที่ต้องการ ถ้าเวลาต่างจากที่คาดมาก ให้ตรวจว่าตั้ง FS_GCS_ENABLE ถูกหรือไม่ และ GCS ตัวอื่นยังส่ง heartbeat อยู่หรือไม่
แผนทดสอบ
ทดสอบ failsafe และ geofence ทุกชนิดใน SITL ก่อน แล้วจึงทดสอบจริงบางรายการในพื้นที่ปลอดภัย เช่น เพดานความสูงต่ำ ๆ และตัดลิงก์ GCS ขณะลอยตัว ทุกการทดสอบต้องมีเกณฑ์ผ่านที่วัดได้ เช่น เวลาทำงานคลาดไม่เกิน 0.5 วินาที และไม่ฝ่ารั้วเกิน 2 m และบันทึกผลพร้อมรุ่นเฟิร์มแวร์และไฟล์พารามิเตอร์
ปฏิบัติการประจำโมดูล
ปฏิบัติการ: ทดสอบ failsafe และ geofence ใน SITL
- วาดรั้วแบบรวมและแบบกันใน GCS อัปโหลดเข้า SITL และตั้ง
FENCE_TYPEกับFENCE_ACTION - ส่งออกจุดของรั้วและภารกิจ ตรวจด้วยตัวอย่างที่ 1
- บินเข้าหารั้วใน SITL สังเกตระยะที่หยุดและการกระทำ
- ตัดลิงก์ GCS ใน SITL เก็บเวลา heartbeat และการเปลี่ยนโหมดจาก log ตรวจด้วยตัวอย่างที่ 2
- เขียนรายงานผลทดสอบพร้อมรุ่นเฟิร์มแวร์และค่าพารามิเตอร์
ข้อผิดพลาดที่พบบ่อย
ระวัง
- เปิดรั้วแต่ตั้ง
FENCE_ACTIONเป็นรายงานอย่างเดียว - วาดรั้วแบบกันซ้อนกับจุดขึ้นบิน ทำให้ติดเครื่องไม่ได้หรือทำงานผิด
- ไม่ทดสอบ failsafe จริง เพราะเชื่อว่าตั้งค่าถูกแล้ว
- สับสนเวลาของ log กับเวลาที่ GCS แสดง
- เปลี่ยนค่าหน้างานโดยไม่ทดสอบซ้ำ
สรุป
FENCE_TYPEรวมเพดาน วงกลม รูปหลายเหลี่ยม และความสูงต่ำสุดFENCE_ACTIONกำหนดการกระทำ และFENCE_MARGINคือระยะเผื่อจากขอบ- รั้วแบบรวมคือพื้นที่ที่ต้องอยู่ รั้วแบบกันคือพื้นที่ห้ามเข้า ตรวจด้วยการนับจุดตัดและระยะถึงขอบได้
- failsafe ของ GCS ทำงานเมื่อ heartbeat หายเกิน
FS_GCS_TIMEOUT(ค่าเริ่มต้น 5 วินาที) ตรวจยืนยันได้จาก log - ทดสอบทุกชนิดใน SITL ด้วยเกณฑ์ผ่านที่วัดได้ ก่อนใช้งานจริง
แบบฝึกตรวจความเข้าใจ
FENCE_TYPE= 5 เปิดรั้วชนิดใด- จุด (5, 5) อยู่ในสี่เหลี่ยม (0,0)–(10,10) หรือไม่ และห่างขอบที่ใกล้ที่สุดเท่าใด
- heartbeat สุดท้ายที่ t = 20 s
FS_GCS_TIMEOUT= 5 s failsafe ควรทำงานเมื่อใด - รั้วแบบกันใช้ทำอะไร
- ทำไมต้องบันทึกรุ่นเฟิร์มแวร์พร้อมผลทดสอบ
เฉลย
- บิต 1 และ 4 คือเพดานความสูงและรูปหลายเหลี่ยมหรือวงกลม
- อยู่ข้างใน ห่างขอบ 5 m
- ราว t = 25 s
- กำหนดพื้นที่ห้ามเข้าภายในพื้นที่บิน เช่น รอบอาคารสูงหรือพื้นที่ชุมนุม
- ชื่อ ค่าเริ่มต้น และพฤติกรรมเปลี่ยนตามรุ่น ผลทดสอบจึงใช้ได้กับรุ่นที่ทดสอบเท่านั้น
สรุปสูตรสำคัญ
| ระยะจากจุดถึงส่วนของเส้นตรง |
แหล่งอ้างอิงหลัก
- ArduPilot Dev Team. Inclusion and exclusion fences. ArduPilot Copter documentation. link
- ArduPilot Dev Team. Parameter list (Copter stable V4.6.3). ArduPilot Copter documentation. link
- ArduPilot Dev Team. ArduPilot source code, tag Copter-4.6.3 [Computer software]. GitHub. link
- ArduPilot Dev Team. GCS failsafe. ArduPilot Copter documentation. link
- MAVLink Development Team. Heartbeat/connection protocol. MAVLink developer guide. link
อ่านเพิ่มเติม
ศึกษาหน่วยความรู้ที่กำหนดล่วงหน้า ดูสื่อประกอบ และทำ quiz ประจำโมดูล
ในชั้นเรียน / ภาคสนาม
ปฏิบัติการในห้องแล็บหรือภาคสนามตามใบงาน พร้อม checklist ความปลอดภัย
หลักฐานการเรียนรู้: ใบงานที่ผ่านการตรวจและผล quiz