iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
自我挑戰組

盯!視覺追蹤機器人 | ROS2打造追蹤機器人系列 第 11 篇

Day 11|邊走邊看!整合 TurtleBot3 的轉向與前進控制

  • 分享至 

  • xImage
  •  

前一天,我整理了 TurtleBot3 前進時需要判斷的條件:目標要接近畫面中央,而且在影像中的大小還沒有達到停止門檻。接下來,就要把這些條件和前面建立的轉向控制放在一起。

如果機器人正在往前走,紅色方塊卻移到畫面旁邊,甚至直接離開視野,它就需要根據新的辨識結果調整動作。

所以今天的目標是:整合轉向、前進與停止的判斷,讓 TurtleBot3 根據每一幀影像更新移動指令。

轉向與前進,分別負責什麼?

前面使用 error_x 判斷紅色方塊相對於畫面中心的位置,再透過 P 控制計算旋轉速度。昨天則加入目標大小的判斷,用來決定是否需要繼續靠近。

這兩個控制量各自負責的事情,可以整理成:

控制項目 作用 判斷依據
angular.z 控制左右轉向 目標與畫面中心的水平誤差 error_x
linear.x 控制前進速度 目標是否接近中央,以及外接框面積 box_area

簡單來說,angular.z 負責「往哪邊看」,linear.x 負責「要不要靠近」。最後再把兩個數值放進同一個 Twist 訊息,發布到 /cmd_vel。

先對準目標,再決定要不要前進

看到紅色方塊後,還不能直接讓機器人往前走。如果目標已經偏到畫面邊緣,這時繼續前進,就可能朝著沒有對準目標的方向移動。

因此,我先沿用 Day 10 的條件:目標超出死區時先轉向,回到中央的容許範圍後,再根據大小決定是否前進。

畫面中的情況 機器人的動作
找到目標,但水平誤差超出死區 停止前進,調整轉向
目標在死區內,面積小於停止門檻 不轉向,以設定速度前進
目標在死區內,面積達到停止門檻 停止前進與轉向
沒有找到目標 停止前進與轉向

依照這個版本的條件,機器人會在轉向與前進之間切換。先讓動作的判斷順序清楚,之後再研究小幅轉向時持續前進的方式。

整合 linear.x 與 angular.z

接著把 Day 9 的死區、P 控制與最大角速度限制,和 Day 10 的前進條件放進同一段流程。

以下是放在影像回呼函式中的控制片段,假設程式已經取得辨識結果,並建立好 Twist 所需的匯入與 /cmd_vel 的 Publisher。target_found 代表這一幀是否找到目標;找到時,才會使用對應的 error_x 和 box_area。

面積門檻沿用前一天的名稱 AREA_THRESHOLD,其餘參數也需要先設定,再依照模擬畫面調整。

twist = Twist()

if not target_found:
    # 找不到目標,停止前進與轉向
    twist.linear.x = 0.0
    twist.angular.z = 0.0
else:
    # 先根據水平誤差決定轉向速度
    if abs(error_x) <= DEAD_ZONE:
        angular_z = 0.0
    else:
        angular_z = -KP_ANGULAR * error_x
        angular_z = max(
            -MAX_ANGULAR_SPEED,
            min(MAX_ANGULAR_SPEED, angular_z)
        )

    twist.angular.z = angular_z

    # 方向對準,而且尚未達到面積門檻,才往前走
    if abs(error_x) <= DEAD_ZONE and box_area < AREA_THRESHOLD:
        twist.linear.x = FORWARD_SPEED
    else:
        twist.linear.x = 0.0

# 每次完成判斷後,都發布這一幀對應的速度指令
self.cmd_vel_pub.publish(twist)

這段程式先確認有沒有找到目標,再處理轉向與前進。即使目標的面積已經達到門檻,只要它還偏離中央,機器人仍然可以原地轉向,讓目標回到畫面中間。

另外,最後的 publish() 要放在整個判斷之外,讓前進、轉向和停止的結果都能送出去。否則程式雖然算出了新的速度,機器人卻不一定有收到對應的指令。

這裡的 box_area 仍然只是 Bounding Box(外接框)在影像中的面積,用來判斷是否停止靠近,還不能直接換算成實際距離。

目標消失時,為什麼要主動停止?

假設前一幀紅色方塊還在中央,機器人正在前進,下一幀方塊卻離開畫面。如果這時只是跳過控制程式,沒有發布新的速度指令,機器人就可能暫時繼續執行上一個動作。

所以只要這一幀找不到目標,就把兩個速度都設成 0:

twist.linear.x = 0.0
twist.angular.z = 0.0

接著透過前面統一的 publish(),把停止指令送出去。找不到目標,也是一種需要處理的辨識結果。

這裡處理的是「收到影像,但沒有辨識到方塊」的情況。如果相機影像直接中斷,回呼函式可能不會再執行,就需要另外加入影像逾時的檢查。

至於失去目標後要不要旋轉搜尋,可以等基本流程穩定後,再繼續研究。

從追蹤走向跟拍,還要觀察什麼?

前一天提到,移動跟拍除了跟得上目標,也要考慮畫面是否平順。把控制整合後,接下來就能觀察轉向、前進與停止之間的切換,會不會讓機器人的動作太突然。

例如目標的水平誤差一直在死區邊界附近變動,機器人就可能反覆切換轉向與前進;目標面積在停止門檻附近變化時,也可能出現走一下、停一下的情況。

目前先確認每個條件都能對應到預期的動作,再根據實際表現調整。等到基本追蹤流程穩定後,才繼續研究怎麼讓移動更自然,讓相機拍到的畫面也比較舒服。

實際測試要觀察什麼?

接下來在 Gazebo 中,我會先讓紅色方塊位於畫面中央,確認面積小於門檻時,TurtleBot3 是否會前進;再讓目標偏向兩側,觀察機器人是否會停止前進,先調整方向。

當方塊在畫面中逐漸變大、達到停止門檻時,要確認前進速度是否歸零。最後再讓目標離開視野,檢查前進與轉向是否都會停止。

除了觀察機器人的動作,也可以一起查看 error_x、box_area 和發布的速度,確認目前是哪個條件觸發了動作。這樣遇到走走停停的情況時,才比較容易判斷要調整的是死區、面積門檻,還是速度設定。

今天的流程

  1. 回顧 linear.x 與 angular.z 各自負責的動作。
  2. 設定目標偏離中央時先轉向,對準後再判斷是否前進。
  3. 將轉向與前進條件整合到同一個 Twist 訊息。
  4. 加入目標消失時的停止判斷,並統一發布速度指令。
  5. 整理在 Gazebo 中需要觀察的情況,準備確認控制效果。

這次先把轉向、前進與停止整合成一套控制邏輯,讓 TurtleBot3 能根據每一幀的辨識結果,決定下一步該怎麼動。接下來再透過 Gazebo 測試,確認實際動作是否符合預期。

ㄣ

NEXT

下一篇會進一步觀察連續追蹤時的表現,特別是目標持續移動、方向改變,以及前進與停止切換的情況。再從這些觀察中,找出目前控制方式需要調整的地方。


上一篇
Day 10|追!讓 TurtleBot3 知道什麼時候前進
下一篇
Day 12|觀察 TurtleBot3 的連續追蹤
系列文
盯!視覺追蹤機器人 | ROS2打造追蹤機器人 共 12 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言