要知道我們相對於起點的位置,最簡單的方式就是時刻知道自己朝什麼方向前進了多少--然後把這些數值加總起來。然而對人類來說,可以依靠羅盤等方式來累計,但對於機器人來說要怎麼做呢? 我們以最常見的雙輪驅動速差小車為例(包含許多常見平台以及我們的智慧機器人),一個比較簡單的方式是在馬達上加上編碼器,透過計算編碼器的數值來知道車子左右輪轉動的圈數,接著只需要知道輪幅就可以計算出移動的距離了。 計算看似美好,但存在一些缺點--比方說,輪子在光滑平面上利用速差轉彎時,容易有滑動的狀況。在這種情況發生後,里程計的數值就不能直接代表移動距離。 這時候我們就會嘗試加入IMU(Inertial measurement unit,慣性測量單元)來輔助。IMU量測的是三軸(XYZ)上的重力加速度以及三軸的角速度--很顯然的,加速度這種數值就是有變化的瞬間量測。因此IMU擅長的是短時間的變化,剛好可以跟前面的編碼器相輔相成,結合兩者的資料就可以得到相對準確的里程計。 而具體這些數值的計算是一個不短的數學過程,發送的ROS訊息格式要填的東西也很多。幸好,大部分的底盤供應商都會把這些東西打包完成,我們只需要使用廠商提供的package就可以了。 而里程計的訊息則會以nav_msgs/odometry的格式發送到odom這個頻道去。這個訊息的格式具體如下: ```python std_msgs/Header header string child_frame_id geometry_msgs/PoseWithCovariance pose geometry_msgs/TwistWithCovariance twist ``` 把底下兩個msg的格式再拆開: ```python std_msgs/Header header string child_frame_id #geometry_msgs/PoseWithCovariance pose #Point position float64 x float64 y float64 z #Quaternion orientation float64 x float64 y float64 z float64 w float64[36] covariance ############################### #geometry_msgs/TwistWithCovariance twist #Vector3 linear float64 x float64 y float64 z #Vector3 angular float64 x float64 y float64 z float64[36] covariance ``` ......恩,幸好通常供應商會幫忙弄好。 但我們還是要學會看懂資料內容,其中比較沒看過的恐怕會是pose中的Quaternion這個資料了--於是,下一篇我們就來科普一下Quaternion是什麼。