Learning Objectives
- 用左右輪速度算出 v、ω,也能反過來算
- 說明差速機器人為什麼能原地轉、不能橫移
- 親手把速度積分成位置,預測機器人會走到哪裡
- 說明里程計的誤差為什麼會累積,以及機器人撞牆時它為什麼還在算
兩個輪子怎麼決定機器人的動作
掃地機器人只有兩個驅動輪,沒有方向盤,還是能轉彎,也能在原地掉頭。祕密是兩個輪子可以轉得不一樣快:右輪快一點,機器人就往左偏;兩輪反向,機器人就原地轉。這種結構叫差速驅動(differential drive)。
前幾課你下的指令都是 Twist:linear.x 是往前的速度 v,angular.z 是旋轉速度 ω。馬達聽不懂 v 和 ω,它只知道自己要轉多快,所以中間一定有人在換算。設兩輪距離是 L(公尺):
v =(右輪速度 + 左輪速度)÷ 2
ω =(右輪速度 − 左輪速度)÷ L
用數字試一次,L = 0.2:
| 左輪(m/s) | 右輪(m/s) | v(m/s) | ω(rad/s) | 機器人的動作 |
|---|---|---|---|---|
| 0.3 | 0.3 | 0.3 | 0 | 直走 |
| 0.2 | 0.3 | 0.25 | 0.5 | 往左畫弧,半徑 v ÷ ω = 0.5 公尺 |
| −0.1 | 0.1 | 0 | 1.0 | 原地往左轉 |
| 0 | 0.2 | 0.1 | 1.0 | 繞著不動的左輪轉 |
ω 是正的代表逆時針,也就是往左轉;這是 ROS 的慣例(REP-103,右手定則:z 軸朝上,大拇指朝上時四指彎的方向是正)。
反過來,導航程式算出 v 和 ω 之後,馬達驅動程式要這樣換回去:
左輪速度 = v − ω × L ÷ 2
右輪速度 = v + ω × L ÷ 2
為什麼兩輪距離越大,同樣的速度差轉得越慢?因為機器人是繞著一個點轉,輪子離中心越遠,轉同一個角度要走的路越長。
一步一步換算輪速與 v、ω
這兩個函數是上面兩組公式。注意第二個函數是第一個的反運算:把結果代回去應該得到原本的輪速。
不能橫移,以及里程計怎麼算
差速機器人不能橫移。 看公式:不管兩個輪子怎麼轉,都只有 v 和 ω 兩個量,沒有「往左平移」這個選項。輪子只能往前後滾,側向會被地面摩擦力擋住。這和汽車不能直接橫移一樣,要停進路邊車位得前後調整幾次。這種「能到達任何位置,但當下不能往任意方向走」的限制叫非完整約束(nonholonomic constraint)。路徑規劃必須考慮它:一條要機器人側移的路徑,這種底盤走不出來。
里程計(odometry) 回答「我走到哪裡了」。馬達軸上的編碼器(encoder)數輪子轉了幾圈,換算成輪速,再得到 v 和 ω。接下來是把速度一小段一小段加起來:
x = x + v × cos(θ) × dt
y = y + v × sin(θ) × dt
θ = θ + ω × dt
這三行就是積分:把 dt 這麼短的時間裡走的一小段路,依目前的朝向分解成 x、y,再累加起來。/odom 這個 topic 發布的就是這個結果,所以它一開始是 (0, 0):里程計是相對起點的,不知道自己在地圖的哪裡。
假設 v = 0.25、θ = 30°(cos = 0.866、sin = 0.5)、dt = 0.1,這一小段的位移是 x 多 0.02165、y 多 0.0125。下面的範例把 dt 故意設成 0.5 秒,你會看到積分結果和正確答案有明顯的差距;dt 越小越接近。
親手積分一個圓
v = 0.25、ω = 0.5 應該畫出半徑 0.5 公尺的圓。看每一步的 x、y、θ 怎麼變,最後和公式比較。
實作題:算出機器人走到哪裡
補上 wheels_to_twist 和 integrate。程式會依序跑三段:直走、原地轉、繞弧,每段結束印出 x、y、θ。寫完想一想:第二段結束時 x、y 應該和第一段一樣嗎?
看里程計也會錯
剛才的機器人回到了起點,因為里程計回報的速度是對的。真實世界沒這麼好:輪子會打滑、地板有高低、輪徑會因為磨損或胎壓改變。編碼器量到輪子轉了 100 圈,不代表機器人走了 100 圈的距離。
更麻煩的是累積:每一步都把前一步的結果拿來加,前面的誤差一直留在裡面,沒有東西把它拉回來。假設真實輪徑比程式設定的大 1%,走 10 公尺就差 10 公分,走 100 公尺差 1 公尺;朝向差 1° 的話,之後走的每一公尺都會往旁邊偏約 1.7 公分,而且越偏越多。
下一個練習打開里程計雜訊,紅色虛線是里程計以為自己走的路,藍線是真實的路。
這裡和真實的差異。 模擬世界的
noise.odom是加在里程計讀數上的(每 0.01 秒一個獨立的相對雜訊),機器人本身還是照指令走;真實機器人相反,讀數大致準確,是實際移動偏離了。從程式的角度看,結果一樣:/odom和真實位置越來越遠。這裡把雜訊設到 1.0(100%)才看得清楚,因為獨立的雜訊會互相抵消,平均起來比真實的系統性誤差(例如輪徑不準)溫和得多。
確認一下
兩輪距離 0.3 公尺,左輪 0.1 m/s,右輪 0.4 m/s。v 和 ω 是多少?
導航程式要求差速機器人往正左方平移 1 公尺,朝向不變。會發生什麼?
機器人的右輪實際比設定值大 1%,但程式不知道。它照著里程計走一條「直線」,真實的路徑會怎樣?
機器人被人用手抬起來,放到 2 公尺外。里程計會怎樣?
從安全的角度,哪個設計比較合理?
重點整理
- 差速驅動:v 是兩輪平均,ω 是兩輪差除以輪距。ω 為正是逆時針(往左)。
- 只有 v、ω 兩個量,所以能原地轉、不能橫移。路徑規劃要知道這件事。
- 里程計把速度積分成位置,一開始是 (0, 0),是相對起點的。
- 指令不等於實際:開迴路算時間,遇到馬達跑不到就錯。看
/odom比較好,但它也會錯。 - 里程計的誤差會累積,輪子打滑或撞牆時它照算不誤,所以要和其他感測器交叉確認,不一致就停下來。
- 這條軌道的物理是簡化的:沒有慣性、輪子不打滑(撞牆時里程計照算),
noise只加在讀數上。
下一課處理「怎麼準確走到目標」:不是用固定速度走到再急停,而是依照還差多少決定下多大的指令,也就是 PID 控制。