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

SLAM และ sensor fusion

UAT 366 ระบบอากาศยานไร้คนขับอัตโนมัติภายในอาคารและระบบอากาศยานไร้คนขับหลายลำ

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

บทเรียน

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

  1. อธิบายขั้นทำนายและขั้นปรับแก้ของ Kalman filter แบบสองสถานะ (ตำแหน่งและความเร็ว)
  2. หลอมรวม IMU กับตำแหน่งจาก UWB และอ่านความแปรปรวนที่ลดลงเมื่อได้ค่าวัด
  3. อธิบาย SLAM แบบกราฟและการปิดวง (loop closure)
  4. กระจายความคลาดเมื่อปิดวงเพื่อแก้เส้นทางทั้งเส้น

ความรู้พื้นฐานที่ควรมี: UAT 366 โมดูล 1 · UAT 322 โมดูล 2–3 (Kalman filter หนึ่งมิติและ SLAM)

ทำไมต้องรู้

IMU ให้ข้อมูลถี่มากแต่คลาดสะสมเร็ว UWB ให้ตำแหน่งที่ไม่คลาดสะสมแต่มีสัญญาณรบกวนและช้ากว่า Kalman filter (Kalman, 1960) หลอมรวมข้อดีของทั้งสองแหล่ง UAT 322 สอน Kalman หนึ่งสถานะไปแล้ว โมดูลนี้ใช้สองสถานะ คือตำแหน่งกับความเร็ว เพื่อให้เห็นว่าค่าวัดตำแหน่งช่วยประมาณความเร็วที่ไม่ได้วัดตรงได้อย่างไร และเมื่อไม่มี UWB เลย SLAM กับการปิดวงช่วยแก้ความคลาดสะสม

Kalman filter สองสถานะ

สถานะคือ ตำแหน่งกับความเร็วในแนวทางเดิน ขั้น ทำนาย ใช้ความเร่งจาก IMU ทุก 0.1 s ความไม่แน่นอน เพิ่มขึ้นทุกครั้ง ขั้น ปรับแก้ ใช้ตำแหน่งจาก UWB เมื่อได้ค่าวัด ความไม่แน่นอนลดลง ตำราของ Thrun และคณะ (2005) และ Groves (2013) อธิบายสมการเต็มรูปแบบ

สองกล่อง กล่องซ้ายขั้นทำนายพร้อมสมการ x เท่ากับ F x บวก B a และ P เท่ากับ F P F ทรานสโพสบวก Q กล่องขวาขั้นปรับแก้พร้อมสมการอัตราขยาย K และการปรับ x ลูกศรโค้งด้านบนเขียนว่า IMU ทุก 0.1 วินาที ลูกศรโค้งด้านล่างเขียนว่า UWB เมื่อมีค่าวัด
ภาพที่ 1 วงรอบทำนายและปรับแก้ของ Kalman filter

ตัวอย่างที่ 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 ทำเรื่องนี้กับภาพจำนวนมาก

เส้นทางสี่เหลี่ยม เส้นประสีชมพูคือ odometry ที่คลาดจนจุดจบไม่กลับมาที่จุดเริ่ม เส้นทึบสีเขียวคือเส้นทางหลังปิดวง ลูกศรสีม่วงจากจุดจบของ odometry ไปจุดเริ่ม ความคลาดปิดวง 1.2 และ 0.8 เมตร
ภาพที่ 2 เส้นทางก่อนและหลังปิดวง

ตัวอย่างที่ 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)

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

ปฏิบัติการ: หลอมรวมข้อมูลและปิดวง

  1. บันทึก log ของ IMU และตำแหน่ง UWB ขณะบินตามแนวทางเดินในห้องปฏิบัติการ
  2. ใช้โค้ดตัวอย่างที่ 1 กับข้อมูลจริง ปรับ SIGMA_A และ SIGMA_Z แล้วสังเกตผลต่อความเร็วและความแปรปรวน
  3. เทียบกับผลของ EKF2 ใน log ของ PX4 อธิบายความต่าง
  4. บินเป็นวงกลับที่เริ่มด้วย VIO วัดความคลาดปิดวง แล้วใช้โค้ดตัวอย่างที่ 2 แก้เส้นทาง
  5. เทียบผลกับระบบ SLAM ที่แล็บมี (เช่น ORB-SLAM3) ด้วยวิธีประเมินเส้นทางจาก UAT 322

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

ระวัง

  • ตั้งความแปรปรวนของค่าวัดต่ำเกินจริง จนตัวกรองเชื่อ UWB มากไป
  • ลืมเพิ่ม Q จนความแปรปรวนลดเหลือศูนย์และไม่รับค่าวัดใหม่
  • ใช้เวลาของเซนเซอร์คนละนาฬิกา โดยไม่ซิงก์
  • เชื่อการปิดวงที่จับคู่ผิดที่ ซึ่งทำให้แผนที่บิดทั้งแผ่น
  • ประเมินเฉพาะผลที่ดูดีบนภาพ แทนตัวเลขความคลาด

สรุป

  • Kalman filter สองสถานะทำนายด้วย IMU แล้วปรับแก้ด้วย UWB ความแปรปรวนเพิ่มเมื่อทำนายและลดเมื่อปรับแก้
  • ค่าวัดตำแหน่งช่วยประมาณความเร็วที่ไม่ได้วัดตรง
  • SLAM แบบกราฟเก็บตำแหน่งเป็นจุดและความสัมพันธ์เป็นเส้นเชื่อม
  • การปิดวงให้ข้อมูลใหม่ที่กระจายความคลาดสะสมไปทั้งเส้นทาง

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

  1. ในขั้นทำนาย ความแปรปรวน P เพิ่มหรือลด เพราะอะไร
  2. ถ้า P[0][0] = 0.04 m² และความแปรปรวนค่าวัด 0.01 m² อัตราขยาย K ของตำแหน่งเท่าใด
  3. ความคลาดปิดวง (3, 4) m บนวงยาว 100 m คิดเป็นกี่เปอร์เซ็นต์
  4. จากข้อ 3 จุดที่ระยะสะสม 50 m ต้องเลื่อนเท่าใด
  5. loop closure ที่จับคู่ผิดที่ทำให้เกิดอะไร
เฉลย
  1. เพิ่ม เพราะการทำนายสะสมความไม่แน่นอนจาก Q และความเร็วที่ไม่แน่นอน
  2. ครึ่งหนึ่งของความคลาด คือ (1.5, 2) m
  3. แผนที่และเส้นทางบิดเพราะกราฟถูกบังคับให้เชื่อมจุดที่ไม่ใช่ที่เดียวกัน

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

ขั้นทำนาย
ขั้นปรับแก้
กระจายความคลาดปิดวง

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

  1. Kalman, R. E. (1960). A new approach to linear filtering and prediction problems. Journal of Basic Engineering, 82(1), 35–45. link
  2. Thrun, S., Burgard, W., & Fox, D. (2005). Probabilistic robotics. MIT Press. link
  3. Groves, P. D. (2013). Principles of GNSS, inertial, and multisensor integrated navigation systems (2nd ed.). Artech House. link
  4. 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
  5. 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
  6. 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 ประจำโมดูล

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

ปฏิบัติการเข้มข้นในแล็บและภาคสนาม บันทึกผลลงสมุดปฏิบัติการ

หลักฐานการเรียนรู้: สมุดปฏิบัติการที่อาจารย์ลงนาม

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

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

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