SLAM และ sensor fusion
UAT 366 ระบบอากาศยานไร้คนขับอัตโนมัติภายในอาคารและระบบอากาศยานไร้คนขับหลายลำ
บทเรียน
เมื่อเรียนจบโมดูลนี้ ผู้เรียนจะสามารถ
- อธิบายขั้นทำนายและขั้นปรับแก้ของ Kalman filter แบบสองสถานะ (ตำแหน่งและความเร็ว)
- หลอมรวม IMU กับตำแหน่งจาก UWB และอ่านความแปรปรวนที่ลดลงเมื่อได้ค่าวัด
- อธิบาย SLAM แบบกราฟและการปิดวง (loop closure)
- กระจายความคลาดเมื่อปิดวงเพื่อแก้เส้นทางทั้งเส้น
ทำไมต้องรู้
IMU ให้ข้อมูลถี่มากแต่คลาดสะสมเร็ว UWB ให้ตำแหน่งที่ไม่คลาดสะสมแต่มีสัญญาณรบกวนและช้ากว่า Kalman filter (Kalman, 1960) หลอมรวมข้อดีของทั้งสองแหล่ง UAT 322 สอน Kalman หนึ่งสถานะไปแล้ว โมดูลนี้ใช้สองสถานะ คือตำแหน่งกับความเร็ว เพื่อให้เห็นว่าค่าวัดตำแหน่งช่วยประมาณความเร็วที่ไม่ได้วัดตรงได้อย่างไร และเมื่อไม่มี UWB เลย SLAM กับการปิดวงช่วยแก้ความคลาดสะสม
Kalman filter สองสถานะ
สถานะคือ ตำแหน่งกับความเร็วในแนวทางเดิน ขั้น ทำนาย ใช้ความเร่งจาก IMU ทุก 0.1 s ความไม่แน่นอน เพิ่มขึ้นทุกครั้ง ขั้น ปรับแก้ ใช้ตำแหน่งจาก UWB เมื่อได้ค่าวัด ความไม่แน่นอนลดลง ตำราของ Thrun และคณะ (2005) และ Groves (2013) อธิบายสมการเต็มรูปแบบ
ตัวอย่างที่ 1 หลอมรวม IMU กับ UWB
โดรนบินตามทางเดินด้วยความเร็วจริง 1.0 m/s เริ่มที่ความเร็วประมาณ 0 (ไม่รู้) UWB วัดตำแหน่งทุก 0.5 s ส่วนเบี่ยงเบนมาตรฐาน 0.10 m ความคลาดของค่าวัดใช้ชุดค่าตายตัวเพื่อให้ผลซ้ำได้
DT, SIGMA_A, SIGMA_Z = 0.1, 0.5, 0.10
uwb_noise = [0.08, -0.12, 0.05, 0.10, -0.06, -0.09] # m, ค่าตายตัวแทนสัญญาณรบกวน
x = [0.0, 0.0] # ตำแหน่ง ความเร็ว (ประมาณ)
P = [[0.5 ** 2, 0.0], [0.0, 1.0 ** 2]]
q = SIGMA_A ** 2
Q = [[q * DT ** 4 / 4, q * DT ** 3 / 2], [q * DT ** 3 / 2, q * DT ** 2]]
for step in range(1, 31):
x = [x[0] + DT * x[1], x[1]] # ทำนาย (IMU วัดความเร่ง 0)
P = [[P[0][0] + DT * (P[1][0] + P[0][1]) + DT * DT * P[1][1] + Q[0][0], P[0][1] + DT * P[1][1] + Q[0][1]],
[P[1][0] + DT * P[1][1] + Q[1][0], P[1][1] + Q[1][1]]]
if step % 5 == 0: # ปรับแก้ด้วย UWB
z = 1.0 * step * DT + uwb_noise[step // 5 - 1]
s = P[0][0] + SIGMA_Z ** 2
k = [P[0][0] / s, P[1][0] / s]
innov = z - x[0]
x = [x[0] + k[0] * innov, x[1] + k[1] * innov]
P = [[(1 - k[0]) * P[0][0], (1 - k[0]) * P[0][1]], [P[1][0] - k[1] * P[0][0], P[1][1] - k[1] * P[0][1]]]
print(f"t {step * DT:.1f} s: p {x[0]:.2f} (true {step * DT:.2f}), v {x[1]:.2f}, "
f"sigma_p {P[0][0] ** 0.5:.3f} m, sigma_v {P[1][1] ** 0.5:.3f} m/s")
t 0.5 s: p 0.57 (true 0.50), v 0.57, sigma_p 0.099 m, sigma_v 0.719 m/s
t 1.0 s: p 0.88 (true 1.00), v 0.61, sigma_p 0.097 m, sigma_v 0.262 m/s
t 1.5 s: p 1.48 (true 1.50), v 0.98, sigma_p 0.090 m, sigma_v 0.164 m/s
t 2.0 s: p 2.06 (true 2.00), v 1.07, sigma_p 0.085 m, sigma_v 0.141 m/s
t 2.5 s: p 2.49 (true 2.50), v 0.97, sigma_p 0.082 m, sigma_v 0.137 m/s
t 3.0 s: p 2.93 (true 3.00), v 0.92, sigma_p 0.081 m, sigma_v 0.136 m/s
ความเร็วที่ไม่เคยวัดตรงถูกประมาณจากตำแหน่งที่วัดต่อเนื่อง และเข้าใกล้ 1.0 m/s ภายในไม่กี่วินาที ส่วนเบี่ยงเบนมาตรฐานของตำแหน่งลดลงจนต่ำกว่าความคลาดของ UWB เอง เพราะตัวกรองรวมข้อมูลหลายครั้งเข้าด้วยกัน
SLAM แบบกราฟและการปิดวง
SLAM (simultaneous localization and mapping) สร้างแผนที่และหาตำแหน่งตัวเองไปพร้อมกัน บทเรียนของ Grisetti และคณะ (2010) อธิบาย SLAM แบบกราฟ ที่เก็บตำแหน่งแต่ละช่วงเป็นจุดในกราฟ และความสัมพันธ์จาก odometry เป็นเส้นเชื่อม เมื่อโดรนกลับมาเห็นที่เดิม (loop closure) จะได้เส้นเชื่อมใหม่ที่บอกว่าจุดจบกับจุดเริ่มเป็นที่เดียวกัน ความคลาดสะสมตลอดวงจึงถูกกระจายไปทุกจุด ระบบอย่าง ORB-SLAM3 ทำเรื่องนี้กับภาพจำนวนมาก
ตัวอย่างที่ 2 กระจายความคลาดปิดวงตามระยะทาง
วิธีอย่างง่ายนี้กระจายความคลาดตามสัดส่วนระยะทางสะสม ระบบจริงแก้ด้วยการปรับกราฟทั้งหมดที่คิดน้ำหนักความไม่แน่นอนของแต่ละเส้นเชื่อม
import math
odom = [(0.0, 0.0), (20.3, 0.2), (20.6, 20.4), (0.8, 20.9), (1.2, 0.8)] # กลับที่เริ่มจริง
err = (odom[-1][0] - odom[0][0], odom[-1][1] - odom[0][1])
seg = [math.dist(a, b) for a, b in zip(odom, odom[1:])]
cum = [0.0]
for s in seg:
cum.append(cum[-1] + s)
total = cum[-1]
print(f"loop closure error ({err[0]:.1f}, {err[1]:.1f}) m over {total:.1f} m = {math.hypot(*err) / total:.1%}")
for (x, y), s in zip(odom, cum):
f = s / total
print(f"({x:5.1f}, {y:5.1f}) -> ({x - f * err[0]:5.2f}, {y - f * err[1]:5.2f})")
loop closure error (1.2, 0.8) m over 80.4 m = 1.8%
( 0.0, 0.0) -> ( 0.00, 0.00)
( 20.3, 0.2) -> (20.00, -0.00)
( 20.6, 20.4) -> (20.00, 20.00)
( 0.8, 20.9) -> (-0.10, 20.30)
( 1.2, 0.8) -> ( 0.00, 0.00)
ปฏิบัติการประจำโมดูล
ปฏิบัติการ: หลอมรวมข้อมูลและปิดวง
- บันทึก log ของ IMU และตำแหน่ง UWB ขณะบินตามแนวทางเดินในห้องปฏิบัติการ
- ใช้โค้ดตัวอย่างที่ 1 กับข้อมูลจริง ปรับ SIGMA_A และ SIGMA_Z แล้วสังเกตผลต่อความเร็วและความแปรปรวน
- เทียบกับผลของ EKF2 ใน log ของ PX4 อธิบายความต่าง
- บินเป็นวงกลับที่เริ่มด้วย VIO วัดความคลาดปิดวง แล้วใช้โค้ดตัวอย่างที่ 2 แก้เส้นทาง
- เทียบผลกับระบบ SLAM ที่แล็บมี (เช่น ORB-SLAM3) ด้วยวิธีประเมินเส้นทางจาก UAT 322
ข้อผิดพลาดที่พบบ่อย
ระวัง
- ตั้งความแปรปรวนของค่าวัดต่ำเกินจริง จนตัวกรองเชื่อ UWB มากไป
- ลืมเพิ่ม Q จนความแปรปรวนลดเหลือศูนย์และไม่รับค่าวัดใหม่
- ใช้เวลาของเซนเซอร์คนละนาฬิกา โดยไม่ซิงก์
- เชื่อการปิดวงที่จับคู่ผิดที่ ซึ่งทำให้แผนที่บิดทั้งแผ่น
- ประเมินเฉพาะผลที่ดูดีบนภาพ แทนตัวเลขความคลาด
สรุป
- Kalman filter สองสถานะทำนายด้วย IMU แล้วปรับแก้ด้วย UWB ความแปรปรวนเพิ่มเมื่อทำนายและลดเมื่อปรับแก้
- ค่าวัดตำแหน่งช่วยประมาณความเร็วที่ไม่ได้วัดตรง
- SLAM แบบกราฟเก็บตำแหน่งเป็นจุดและความสัมพันธ์เป็นเส้นเชื่อม
- การปิดวงให้ข้อมูลใหม่ที่กระจายความคลาดสะสมไปทั้งเส้นทาง
แบบฝึกตรวจความเข้าใจ
- ในขั้นทำนาย ความแปรปรวน P เพิ่มหรือลด เพราะอะไร
- ถ้า P[0][0] = 0.04 m² และความแปรปรวนค่าวัด 0.01 m² อัตราขยาย K ของตำแหน่งเท่าใด
- ความคลาดปิดวง (3, 4) m บนวงยาว 100 m คิดเป็นกี่เปอร์เซ็นต์
- จากข้อ 3 จุดที่ระยะสะสม 50 m ต้องเลื่อนเท่าใด
- loop closure ที่จับคู่ผิดที่ทำให้เกิดอะไร
เฉลย
- เพิ่ม เพราะการทำนายสะสมความไม่แน่นอนจาก Q และความเร็วที่ไม่แน่นอน
- ครึ่งหนึ่งของความคลาด คือ (1.5, 2) m
- แผนที่และเส้นทางบิดเพราะกราฟถูกบังคับให้เชื่อมจุดที่ไม่ใช่ที่เดียวกัน
สรุปสูตรสำคัญ
| ขั้นทำนาย | |
| ขั้นปรับแก้ | |
| กระจายความคลาดปิดวง |
แหล่งอ้างอิงหลัก
- Kalman, R. E. (1960). A new approach to linear filtering and prediction problems. Journal of Basic Engineering, 82(1), 35–45. link
- Thrun, S., Burgard, W., & Fox, D. (2005). Probabilistic robotics. MIT Press. link
- Groves, P. D. (2013). Principles of GNSS, inertial, and multisensor integrated navigation systems (2nd ed.). Artech House. link
- Grisetti, G., Kümmerle, R., Stachniss, C., & Burgard, W. (2010). A tutorial on graph-based SLAM. IEEE Intelligent Transportation Systems Magazine, 2(4), 31–43. link
- Cadena, C., Carlone, L., Carrillo, H., Latif, Y., Scaramuzza, D., Neira, J., Reid, I., & Leonard, J. J. (2016). Past, present, and future of simultaneous localization and mapping: Toward the robust-perception age. IEEE Transactions on Robotics, 32(6), 1309–1332. link
- Campos, C., Elvira, R., Gómez Rodríguez, J. J., Montiel, J. M. M., & Tardós, J. D. (2021). ORB-SLAM3: An accurate open-source library for visual, visual–inertial, and multimap SLAM. IEEE Transactions on Robotics, 37(6), 1874–1890. link
อ่านเพิ่มเติม
ศึกษาหน่วยความรู้ที่กำหนดล่วงหน้า ดูสื่อประกอบ และทำ quiz ประจำโมดูล
SLAM และการนำทางในพื้นที่ไม่มี GNSS
การประมาณสถานะด้วย Kalman filter/EKF
ในชั้นเรียน / ภาคสนาม
ปฏิบัติการเข้มข้นในแล็บและภาคสนาม บันทึกผลลงสมุดปฏิบัติการ
หลักฐานการเรียนรู้: สมุดปฏิบัติการที่อาจารย์ลงนาม