ทดลองควบคุมใน SITL
UAT 206 ระบบควบคุมและออโตไพลอตเบื้องต้น
บทเรียน
เมื่อเรียนจบโมดูลนี้ ผู้เรียนจะสามารถ
- ตั้งการทดลองควบคุมใน SITL ของ PX4 หรือ ArduPilot และเก็บ log
- คำนวณเวลาขึ้น overshoot และเวลาเข้าที่จากข้อมูลผลตอบสนองแบบขั้น
- เปรียบเทียบค่าจูนสองชุดอย่างเป็นระบบ
- วัดความคลาดการติดตามเส้นทางเมื่อมีลมจำลอง
ทำไมต้องรู้
การจูนบนโดรนจริงเสี่ยงตก และทำซ้ำเงื่อนไขเดิมได้ยาก SITL (software in the loop) รันซอฟต์แวร์ออโตไพลอตจริงบนคอมพิวเตอร์ต่อกับเครื่องจำลอง จึงทดลองเปลี่ยนค่าได้ปลอดภัยและเทียบผลได้ยุติธรรม หน่วยความรู้เรื่อง SITL ของคลังความรู้โดรนย้ำให้ทำชุดพื้นฐานให้ทำงานก่อน แล้วค่อยเพิ่มส่วนอื่นทีละอย่าง และเก็บรุ่นกับ log ทุกครั้ง
สถาปัตยกรรมการทดลอง
ออโตไพลอต SITL รับค่าเซนเซอร์จากเครื่องจำลองและส่งคำสั่งมอเตอร์กลับ GCS เชื่อมผ่าน MAVLink เพื่อสั่งและดูสถานะ ส่วน log นำไปวิเคราะห์ด้วย Flight Review ของ PX4 หรือ UAV Log Viewer ของ ArduPilot คู่มือ PX4 ใช้คำสั่ง make px4_sitl gz_x500 เปิดควอดคอปเตอร์ใน Gazebo และ ArduPilot มี SITL ในตัวที่ไม่ต้องใช้ Gazebo
วัดผลตอบสนองแบบขั้นจาก log
คู่มือจูนของ PX4 ให้ทดสอบด้วยการสั่งแบบขั้นขณะลอยตัว และหน้า Flight Review บอกว่าค่าประมาณควรตามค่าตั้งอย่างใกล้ชิด ถ้าไม่ตามแปลว่าต้องจูน การดูกราฟด้วยตาช่วยได้ แต่การคำนวณค่าวัดทำให้เทียบค่าจูนสองชุดได้ชัดเจน
ตัวอย่างที่ 1 เทียบค่าจูนสองชุดจาก log อัตราหมุน
log จำลองผลตอบสนองของอัตราหมุน roll ต่อคำสั่งแบบขั้น บันทึก 250 Hz ชุด A ปรับ P สูง ชุด B ลด P และเพิ่ม D
import math
def response(zeta, w0, rate_hz=250, t_end=2.0):
t = [k / rate_hz for k in range(int(t_end * rate_hz))]
wd = w0 * math.sqrt(1 - zeta ** 2)
y = [1 - math.exp(-zeta * w0 * s) * (math.cos(wd * s) + zeta / math.sqrt(1 - zeta ** 2) * math.sin(wd * s)) for s in t]
return t, y
def metrics(t, y, target=1.0):
t10 = next(a for a, b in zip(t, y) if b >= 0.1 * target)
t90 = next(a for a, b in zip(t, y) if b >= 0.9 * target)
over = max(y) / target - 1
ts = next(t[i] for i in range(len(y)) if all(abs(v - target) <= 0.02 * target for v in y[i:]))
return t90 - t10, over, ts
for name, zeta, w0 in (("set A (high P)", 0.45, 6.0), ("set B (lower P, more D)", 0.7, 5.0)):
tr, mp, ts = metrics(*response(zeta, w0))
print(f"{name:<24} rise {tr * 1000:4.0f} ms, overshoot {mp:5.1%}, settling {ts:.2f} s")
set A (high P) rise 256 ms, overshoot 20.5%, settling 1.39 s
set B (lower P, more D) rise 424 ms, overshoot 4.6%, settling 1.20 s
ชุด A ขึ้นเร็วกว่าแต่เกินเป้าราวหนึ่งในห้าและนิ่งช้า ชุด B ขึ้นช้ากว่าแต่เกินเพียงเล็กน้อยและนิ่งเร็วกว่า ตรงกับที่คู่มือ PX4 ต้องการ เวลาใช้กับ log จริงต้องตัดช่วงก่อนสั่งออก และใช้ค่าสุดท้ายจริงแทนค่า 1.0
ความคลาดการติดตามเมื่อมีลม
ปฏิบัติการ L02 ของคลังความรู้โดรนให้บินภารกิจเดิมโดยไม่มีลมและมีลม เปลี่ยนตัวแปรเดียว แล้วเทียบค่าคลาดบนแกนและหน่วยเดียวกัน ค่าที่นิยมรายงานคือ RMS และค่าสูงสุด
ตัวอย่างที่ 2 ค่าคลาดการติดตามเส้นทาง
ค่าคลาดด้านข้างของเส้นทางตรง 60 s บันทึก 10 Hz (ข้อมูลสมมติ)
import math
t = [k / 10 for k in range(600)]
calm = [0.15 * math.sin(0.8 * s) for s in t] # m ไม่มีลม
windy = [0.8 * (1 - math.exp(-s / 5)) + 0.3 * math.sin(0.5 * s) for s in t] # m ลมด้านข้าง
def summary(err):
rms = math.sqrt(sum(e * e for e in err) / len(err))
return rms, max(abs(e) for e in err), sum(err) / len(err)
for name, err in (("calm", calm), ("crosswind", windy)):
rms, peak, bias = summary(err)
print(f"{name:<10} RMS {rms:.2f} m, max {peak:.2f} m, mean offset {bias:+.2f} m")
calm RMS 0.11 m, max 0.15 m, mean offset +0.01 m
crosswind RMS 0.78 m, max 1.10 m, mean offset +0.74 m
ลมด้านข้างทำให้ค่าคลาดมีส่วนเฉลี่ยที่เอียงไปด้านหนึ่ง แปลว่าลูปความเร็วยังแก้สิ่งรบกวนคงที่ไม่ทัน ถ้าเพิ่ม I ของลูปความเร็วแล้วค่าเฉลี่ยลดลง แสดงว่าตรงจุด หลังจูนด้วยมือแล้ว อาจเทียบกับผล Autotune ของ PX4 หรือ AutoTune ของ ArduPilot ซึ่งคู่มือแนะนำให้ทำรอบจุดลอยนิ่ง
ปฏิบัติการประจำโมดูล
ปฏิบัติการ: จูนและทดสอบใน SITL
- เปิด SITL ตามคู่มือ PX4 (Gazebo) หรือ ArduPilot บันทึกรุ่นเฟิร์มแวร์ รุ่นเครื่องจำลอง และไฟล์พารามิเตอร์
- สั่ง roll แบบขั้นขณะลอยตัว เปิด log ใน Flight Review หรือ UAV Log Viewer แล้วส่งออกข้อมูลอัตราหมุน
- ใช้ฟังก์ชัน
metricsจากตัวอย่างที่ 1 กับข้อมูลจริงของค่าจูนสองชุด - บินภารกิจเส้นตรงแบบไม่มีลมและมีลมตามปฏิบัติการ L02 คำนวณค่าคลาดด้วยตัวอย่างที่ 2
- เขียนรายงานสั้นที่เทียบค่าจูน แนบกราฟ ไฟล์พารามิเตอร์ และข้อจำกัดของผลจากการจำลอง
ข้อผิดพลาดที่พบบ่อย
ระวัง
- เปลี่ยนหลายค่าพร้อมกัน ในการทดลองครั้งเดียว
- ไม่บันทึกรุ่นซอฟต์แวร์และไฟล์พารามิเตอร์
- คิดว่าค่าที่ดีใน SITL ใช้กับโดรนจริงได้ทันที
- ดูกราฟด้วยตาอย่างเดียว ไม่คำนวณค่าวัด
- เทียบผลต่างช่วงเวลาหรือต่างหน่วย
สรุป
- SITL ใช้ซอฟต์แวร์ออโตไพลอตจริงกับเครื่องจำลอง ทดลองได้ปลอดภัยและทำซ้ำได้
- วัด , และ จาก log เพื่อเทียบค่าจูนอย่างเป็นตัวเลข
- รายงานค่าคลาดการติดตามทั้ง RMS ค่าสูงสุด และค่าเฉลี่ย
- ผลจาก SITL ต้องยืนยันด้วยการบินจริงอย่างระมัดระวังก่อนใช้งาน
แบบฝึกตรวจความเข้าใจ
- SITL ต่างจากการบินในเกมจำลองทั่วไปอย่างไร
- ค่า 10% ขึ้นที่ 0.05 s และ 90% ที่ 0.17 s เวลาขึ้นเท่าใด
- ค่าสูงสุดของผลตอบสนอง 1.25 ต่อค่าสุดท้าย 1.0 overshoot เท่าใด
- ค่าคลาด 0.3, −0.4 และ 0 m มี RMS เท่าใด
- ค่าคลาดเฉลี่ยไม่เป็นศูนย์เมื่อมีลมด้านข้างบอกอะไร
เฉลย
- SITL รันซอฟต์แวร์ออโตไพลอตตัวจริงที่ใช้บนโดรน
- s
- 25%
- m
- ตัวควบคุมยังแก้สิ่งรบกวนคงที่ไม่หมด อาจต้องเพิ่ม I ของลูปความเร็ว
สรุปสูตรสำคัญ
| ค่าคลาดการติดตามแบบ RMS |
แหล่งอ้างอิงหลัก
- PX4 Autopilot. Gazebo simulation. PX4 user guide (main). link
- ArduPilot Dev Team. SITL simulator (software in the loop). link
- PX4 Autopilot. Log analysis using Flight Review. PX4 guide (main). link
- ArduPilot Dev Team. UAV Log Viewer. ArduPilot Copter documentation. link
- PX4 Autopilot. Multicopter PID tuning guide. PX4 guide (main). link
- PX4 Autopilot. Multicopter auto-tuning. PX4 guide (main). link
- ArduPilot Dev Team. AutoTune. ArduPilot Copter documentation. link
- Åström, K. J., & Murray, R. M. (2021). Feedback systems: An introduction for scientists and engineers (2nd ed.). Princeton University Press. link
อ่านเพิ่มเติม
ศึกษาหน่วยความรู้ที่กำหนดล่วงหน้า ดูสื่อประกอบ และทำ quiz ประจำโมดูล
ในชั้นเรียน / ภาคสนาม
ปฏิบัติการในห้องแล็บหรือภาคสนามตามใบงาน พร้อม checklist ความปลอดภัย
หลักฐานการเรียนรู้: ใบงานที่ผ่านการตรวจและผล quiz