โมดูล 3/5 · สัปดาห์ 7–9 · 27 ชม.

หลบหลีกสิ่งกีดขวาง

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

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

บทเรียน

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

  1. อธิบาย potential field และปัญหาจุดต่ำสุดเฉพาะที่
  2. เลือกทิศบินด้วย vector field histogram (VFH) จากข้อมูลระยะของ LiDAR
  3. อธิบายการทำงานของ Collision Prevention ใน PX4 และพฤติกรรมเมื่อไม่มีข้อมูลระยะ
  4. เปรียบเทียบการหลบหลีกแบบตอบสนองกับการวางแผนเส้นทางล่วงหน้า และหลักของ velocity obstacle

ความรู้พื้นฐานที่ควรมี: UAT 366 โมดูล 1–2 · UAT 322 โมดูล 3 (occupancy grid, A* และระยะหยุด)

ทำไมต้องรู้

UAT 322 สอนการวางเส้นทางบนแผนที่ด้วย A* และการตรวจว่าหยุดทันหรือไม่ แต่ในคลังจริง มีกล่องวางขวางทางเดินหรือพาเลทยื่นออกมาที่ไม่อยู่บนแผนที่ โดรนต้อง ตอบสนอง ต่อสิ่งที่เซนเซอร์เห็นตอนนั้น วิธีตอบสนองคำนวณเร็วแต่มีจุดอ่อนที่ต้องรู้ ถ้าไม่รู้ โดรนอาจค้างกลางทางเดินหรือแกว่งไปมาระหว่างชั้นวาง

Potential field

Khatib (1986) เสนอ potential field ที่ให้เป้าหมายดึงหุ่นยนต์ และสิ่งกีดขวางผลักออก หุ่นยนต์เคลื่อนตามแรงลัพธ์ แนวคิดง่ายและคำนวณได้แบบเวลาจริง แต่ Koren และ Borenstein (1991) วิเคราะห์ข้อจำกัดที่ติดมากับวิธีนี้ ได้แก่ ติดจุดต่ำสุดเฉพาะที่ (local minimum) ที่แรงหักล้างกัน ผ่านช่องแคบระหว่างสิ่งกีดขวางไม่ได้ และแกว่งในทางแคบ

จุดเริ่มทางซ้าย เป้าหมายทางขวา เสาวงกลมอยู่ตรงกลางแนว เส้นทางสีชมพูจากจุดเริ่มหยุดก่อนถึงเสา ลูกศรสีเขียวดึงไปเป้าหมายและลูกศรสีชมพูผลักจากเสามีขนาดเท่ากัน ด้านล่างเขียนว่าแรงหักล้างกันคือติดจุดต่ำสุดเฉพาะที่
ภาพที่ 1 Potential field ติดจุดต่ำสุดเฉพาะที่

ตัวอย่างที่ 1 จำลอง potential field หน้าเสา

เสารัศมีอิทธิพล 2.5 m อยู่ที่ (5, 0) เป้าหมายที่ (10, 0) เทียบเริ่มตรงแนวกับเริ่มเยื้อง 0.5 m

import math

def fly(start, goal=(10, 0), obstacle=(5, 0), k_att=1.0, k_rep=5.0, rho0=2.5, step=0.05):
    x, y = start
    for i in range(2000):
        fx, fy = k_att * (goal[0] - x), k_att * (goal[1] - y)
        dx, dy = x - obstacle[0], y - obstacle[1]
        d = math.hypot(dx, dy)
        if d < rho0:
            m = k_rep * (1 / d - 1 / rho0) / d ** 2
            fx, fy = fx + m * dx / d, fy + m * dy / d
        f = math.hypot(fx, fy)
        if f < 1e-3:
            return f"stuck at ({x:.2f}, {y:.2f}) after {i} steps"
        x, y = x + step * fx / max(f, 1), y + step * fy / max(f, 1)
        if math.hypot(goal[0] - x, goal[1] - y) < 0.1:
            return f"reached goal after {i} steps"
    return "timeout"

print("start on the line:", fly((0, 0)))
print("start 0.5 m to the side:", fly((0, 0.5)))
start on the line: stuck at (4.17, 0.00) after 88 steps
start 0.5 m to the side: reached goal after 233 steps

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

Vector field histogram

VFH ของ Borenstein และ Koren (1991) แปลงข้อมูลสิ่งกีดขวางรอบตัวเป็น ฮิสโทแกรมเชิงขั้ว ความหนาแน่นของสิ่งกีดขวางในแต่ละทิศ แล้วเลือก “หุบ” ที่ความหนาแน่นต่ำกว่าเกณฑ์ซึ่งใกล้ทิศเป้าหมายที่สุด วิธีนี้ไม่ติดจุดต่ำสุดแบบ potential field เพราะตัดสินจากภาพรวมรอบตัว

ฮิสโทแกรมเชิงขั้วรอบโดรน ช่องสีชมพูยาวด้านหน้าและเยื้องซ้ายขวาคือทิศที่ถูกกีดขวางใกล้กว่า 3 เมตร ช่องสีเขียวสั้นคือทิศว่าง ลูกศรเส้นประสีม่วงชี้ทิศเป้าหมาย 0 องศา ลูกศรสีฟ้าชี้ทิศที่เลือก 50 องศา
ภาพที่ 2 ฮิสโทแกรมเชิงขั้วของ VFH

ตัวอย่างที่ 2 เลือกทิศจากระยะ LiDAR

แบบง่ายของ VFH: 36 ช่อง ช่องละ 10° ถือว่าช่องที่มีสิ่งกีดขวางใกล้กว่า 3 m ถูกกีดขวาง แล้วเลือกช่องว่างที่ใกล้ทิศเป้าหมายที่สุด

ranges = [6.0] * 36                                   # m ต่อช่อง 10° เริ่มที่ 0° ตามเข็ม
for k in (34, 35, 0, 1, 2): ranges[k] = 1.2           # กล่องขวางด้านหน้า
for k in (3, 4): ranges[k] = 2.5
for k in (31, 32, 33): ranges[k] = 2.8
THRESH, GOAL_DEG = 3.0, 0

def angle_diff(a, b):
    return abs((a - b + 180) % 360 - 180)

blocked = [k * 10 for k, r in enumerate(ranges) if r < THRESH]
free = [k * 10 for k, r in enumerate(ranges) if r >= THRESH]
best = min(free, key=lambda a: angle_diff(a, GOAL_DEG))
print("blocked headings:", blocked)
print(f"chosen heading {best} deg ({angle_diff(best, GOAL_DEG)} deg from goal)")
blocked headings: [0, 10, 20, 30, 40, 310, 320, 330, 340, 350]
chosen heading 50 deg (50 deg from goal)

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

ระบบในตัวควบคุมการบิน

Collision Prevention ของ PX4 ใช้ข้อมูลจากเซนเซอร์วัดระยะบนตัวควบคุมการบิน หรือจากคอมพิวเตอร์บนลำผ่าน MAVLink แบ่งรอบตัวเป็น 72 ช่อง ใช้ได้ในโหมด Position ชะลอและหยุดก่อนชน โดยตั้งระยะด้วย CP_DIST และเวลาหน่วงด้วย CP_DELAY ถ้าข้อมูลระยะหยุดมา 0.5 s จะจำกัดการเคลื่อนที่ และถ้าหยุดมา 5 s จะเปลี่ยนเป็น HOLD ArduPilot มีระบบ Object Avoidance ที่คล้ายกัน ระบบเหล่านี้ป้องกันการชนแต่ไม่วางเส้นทางอ้อมให้

สำหรับสิ่งที่เคลื่อนที่ เช่น รถยกหรือโดรนลำอื่น แนวคิด velocity obstacle ของ Fiorini และ Shiller (1998) หาชุดความเร็วที่จะทำให้ชนในอนาคตหากทั้งสองคงความเร็วเดิม แล้วเลือกความเร็วนอกชุดนั้น (ต่อยอดในโมดูล 4)

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

ปฏิบัติการ: หลบหลีกใน SITL และในห้องปฏิบัติการ

  1. ทดลองโค้ดตัวอย่างที่ 1 เปลี่ยนตำแหน่งเริ่ม ค่า k_rep และรัศมีอิทธิพล หาเงื่อนไขที่ติด
  2. บันทึกข้อมูลระยะ LiDAR ในทางเดินจำลอง ใช้โค้ดตัวอย่างที่ 2 เลือกทิศ แล้วเพิ่มเงื่อนไขความกว้างหุบ
  3. เปิด Collision Prevention ใน PX4 SITL ทดลองตั้ง CP_DIST สองค่า บินเข้าหากำแพงในโหมด Position
  4. จำลองการตัดข้อมูลระยะ ตรวจพฤติกรรมที่ 0.5 s และ 5 s
  5. ทดสอบจริงในห้องปฏิบัติการด้วยสิ่งกีดขวางนุ่ม ความเร็วต่ำ มีตาข่ายกันและผู้ควบคุมพร้อมรับช่วง

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

ระวัง

  • ไม่มีกลไกออกจากจุดต่ำสุดเฉพาะที่
  • เลือกช่องว่างที่แคบกว่าตัวโดรน
  • เชื่อว่าระบบในตัวควบคุมการบินจะวางเส้นทางอ้อมให้
  • ไม่ทดสอบกรณีเซนเซอร์หยุดส่งข้อมูล
  • ทดสอบครั้งแรกด้วยความเร็วสูงใกล้สิ่งกีดขวางแข็ง

สรุป

  • Potential field เรียบง่ายแต่ติดจุดต่ำสุด ผ่านช่องแคบไม่ได้ และแกว่ง
  • VFH ใช้ฮิสโทแกรมเชิงขั้วเลือกหุบว่างที่ใกล้เป้าหมาย
  • Collision Prevention ของ PX4 ชะลอและหยุดก่อนชน และเปลี่ยนเป็น HOLD เมื่อไม่มีข้อมูลระยะ 5 s
  • การหลบหลีกแบบตอบสนองต้องใช้ร่วมกับการวางเส้นทางและ velocity obstacle สำหรับสิ่งที่เคลื่อนที่

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

  1. จุดต่ำสุดเฉพาะที่ของ potential field เกิดจากอะไร
  2. VFH เลือกทิศบินอย่างไร
  3. ช่องว่างที่ใกล้เป้าหมายที่สุดอยู่ที่ 40° และ 320° เป้าหมายที่ 10° ควรเลือกทิศใด
  4. Collision Prevention ของ PX4 แบ่งรอบตัวเป็นกี่ช่อง
  5. ถ้าข้อมูลระยะหยุดมา 5 s PX4 ทำอะไร
เฉลย
  1. แรงดึงและแรงผลักมีขนาดเท่ากันและทิศตรงข้ามจนแรงลัพธ์เป็นศูนย์
  2. เลือกหุบที่ความหนาแน่นของสิ่งกีดขวางต่ำกว่าเกณฑ์และใกล้ทิศเป้าหมายที่สุด
  3. 40° เพราะห่างเป้าหมาย 30° ส่วน 320° ห่าง 50°
  4. 72 ช่อง
  5. เปลี่ยนเป็น HOLD

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

แรงดึงไปเป้าหมาย
แรงผลักจากสิ่งกีดขวาง (เมื่อ d < ρ₀)

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

  1. Khatib, O. (1986). Real-time obstacle avoidance for manipulators and mobile robots. The International Journal of Robotics Research, 5(1), 90–98. link
  2. Koren, Y., & Borenstein, J. (1991). Potential field methods and their inherent limitations for mobile robot navigation. In Proceedings of the 1991 IEEE International Conference on Robotics and Automation (pp. 1398–1404). IEEE. link
  3. Borenstein, J., & Koren, Y. (1991). The vector field histogram—Fast obstacle avoidance for mobile robots. IEEE Transactions on Robotics and Automation, 7(3), 278–288. link
  4. Fiorini, P., & Shiller, Z. (1998). Motion planning in dynamic environments using velocity obstacles. The International Journal of Robotics Research, 17(7), 760–772. link
  5. PX4 Autopilot. Collision prevention. PX4 user guide (main). link
  6. ArduPilot Dev Team. Object avoidance. ArduPilot Copter documentation. link
  7. Siegwart, R., Nourbakhsh, I. R., & Scaramuzza, D. (2011). Introduction to autonomous mobile robots (2nd ed.). MIT Press. link

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

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

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

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

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

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

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

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