在繼續討論ROS後續的光達應用之前,我們要先面對四元數這個東西。 在ROS中,有一個在控制機器人時很重要的訊息:odometry。中文翻作里程計,他指出了機器人當下的方向姿態以及移動的六軸速度。 六軸速度很好想像--他就是三軸的速度+三軸的角速度。而他的方向姿態使用的就是本次的主角:四元數。 如果有在使用3D繪圖軟體的人可能會知道,在電腦中記錄一個物體的方向是利用所謂歐拉角的方式。歐拉角是很容易可以想像的方式--也就是物體針對各軸的旋轉角: ![](https://hackmd.io/_uploads/BJl0c4e62.png) (圖片摘自維基百科) 這種表示方式很直觀,但存在一點問題--這種表示方式會因為選擇的軸的順序不同而有不同表示數值,即使表示的旋轉完全一樣。 發生的成因主要是因為座標系本身隨著機器人的旋轉而跟著旋轉,使得有些狀態下旋轉過後新的座標軸和舊的座標軸重合了: * 先對 X 軸旋轉==>直接旋轉 * 接著對 Y 軸旋轉 90 度,因為旋轉 的關係,改變了 X 與 Z 軸,而使得其軸對調,也就是說現在 Z 軸與一開始的 X 軸對齊 * 再對 Z 軸旋轉,因為步驟2的關係,Z 軸的軸向被改成和一開始的 X 軸對齊,所以現在對 Z 軸旋轉,與一開始對 X 軸旋轉所造成的影響是相同的 這個狀況被稱作萬象鎖問題,從很多3D建圖軟體可以看到這個現象: ![](https://hackmd.io/_uploads/BJp1oVep2.png) 圖中上下的教阿為同一姿態,但右邊調整出的旋轉角卻不同。另一個觀點是,我的Z旋轉被拿去和X旋轉整合了。 這使得在旋轉過程中,很可能會損失某一軸的旋轉特性。因此必須找到另外一個表示法,而且他最好計算簡單一點。 於是就是主角登場的時候了。 四元數這個概念由愛爾蘭數學家威廉·盧雲·哈密頓在1843年創立,主要由複數所構成: >w + xi + yj + zk,其中i, j, k為虛數i 實際使用上,為了計算上的方便w通常會當作0,僅使用虛部部分。一個原因是這樣比較容易想像xyz三軸的概念,另外一個則是我們原本就是拿來定義三維旋轉,因此是在四維空間的一個子集裡面運算,當然會有一軸清零(雖然運算過程中偶爾還是會有跑到四維空間的現象)。 知道了四元數是複數座標軸後,就可以討論一些性質: #### 四元數不會出現萬象鎖問題 在前面討論歐拉角的時候提到過。 #### 儲存空間較小 使用矩陣儲存旋轉的時候需要使用到3x3的矩陣,相較之下四元數只需要一半不到 #### 旋轉過程中的內插值平滑 這個製作動畫的時候偶爾會發生,當你想從-30度轉到30度的時候,實際上是有兩種方式可以轉的:-30>0>30;-30>-180>-330 這時候,就得看到底有沒有限制短軸優先的規則。一些不如預期的內差就是這樣誕生的。 當然,四元數不是只有優點。實際上就是因為他是個虛數座標,因此光基本運算規則就足以勸退一堆人。 但在電腦計算上由於高效以及不太容易發生預期外的錯誤,因此還是相對容易被採用的。這也是為什麼雖然他長得真的很不友善,但機器人回授還是會選擇四元數的原因。 另外四元數的數學和旋轉運算證明其實相當有趣,有興趣的話可以自行參考: <a href="https://www.qiujiawei.com/understanding-quaternions/#5">Understanding Quaternions 中文翻譯《理解四元數》</a> 若擔心翻譯不到位或是有簡體恐慌症的,請參考原文 <a href="https://www.3dgep.com/understanding-quaternions/">Understanding Quaternions</a>