簡潔明瞭的搞清楚四元數和旋轉矩陣的關係及使用

1 混淆的哪裏?

關於四元數和旋轉矩陣,使用過程中很容易迷糊,很重要的原因是沒有區分好『座標系的旋轉』和『向量的旋轉』。

不想看詳細的說明過程可以直接看總結部分。

2 兩種旋轉

下面首先來區分這兩種旋轉。以一個飛機爲例,假設慣性系爲N(XYZ)系(下圖中的黑色座標系),B系(X’Y’Z’)與飛機固連(下圖中的藍色座標系)。t0時刻,飛機的B系與N系完全重合。
在這裏插入圖片描述
座標系的旋轉: N系的XYZ旋轉到B系的X’Y’Z’,對應的四元數爲q,V並沒隨着B系的轉動而轉動,如上圖所示。座標系旋轉後,有1個信息是我們想知道的:

  • V向量在B系中的座標是多少?(第一個問題)

向量的旋轉: R向量從初始位置旋轉到了R’的位置,對應的四元數爲q,如下圖所示。
在這裏插入圖片描述
向量旋轉後,同樣有1個信息是我們想知道的:

  • R’向量在N系中新的座標是多少?(第二個問題)

從上面可以看出,旋轉可以指座標系的旋轉,也可以指向量的旋轉,他們代表的含義是完全不同的,所以當談到旋轉時,一定要搞清楚這個前提條件:究竟是『誰』被旋轉了。

2.1 回答第一個問題

  • V向量在B系中的座標是多少?
    V向量在空間中的位置並沒有變,只是它在B系中有另一個座標表示方法。

V’ = q-1 * V * q

上式中,由於四元數quaternion並不能與vector直接運算,需要把V轉換爲純四元,即實部爲0的四元數。如果使用eigen來實現,有幾種的不同的方法,但是最終的結果都是一樣的。

// 場景一:N系中的向量Vn_in_N在B系表示
    float angle = 30 * (3.1415926 / 180.f);
    Vector3f Vn_in_N = { 0, 0, 1 };
    Quaternionf q(AngleAxisf(angle, Vector3f::UnitX()));

    // 方法1:
    Vector3f Vn_in_B = (q.conjugate() * Quaternionf(0, Vn_in_N.x(), Vn_in_N.y(), Vn_in_N.z()) * q).vec();
    cout << "Vn_in_B = " << Vn_in_B << endl;
    cout << endl;

    // 方法2:
    Vn_in_B = q.matrix().transpose() * Vn_in_N; // q.matrix()爲Cbn,b繫到n系的座標變換矩陣
    cout << "Vn_in_B = " << Vn_in_B << endl;
    cout << endl;

    // 方法3:Eigen中對 * 進行了運算符重載,本質上與方法2是相同的
    Vn_in_B = q.conjugate() * Vn_in_N;
    cout << "Vn_in_B = " << Vn_in_B << endl;
    cout << endl;

如果B系中有已知的向量V2’,那麼它在N系中的表示V2爲:
V2 = q * V2’ * q-1
使用eigen實現的代碼就不贅述了。

2.2 回答第二個問題

  • R向量被旋轉後,它在空間中的位置發生了變化,有一個新的座標R’
    R’ = q * R * q-1

有一點值得注意的是,很多場合把q轉換爲旋轉矩陣Cbn(b–>n),這裏的Cbn指的是把B系中已知的向量Vb在N系中的座標是多少Vn,即:
Vn = Cbn * Vb
在這裏插入圖片描述
上面代碼中的 q.matrix() 就是Cbn

3 總結

以下的結論務必記住。

如果一個向量 V 固定,座標系旋轉按照四元數 q 進行了旋轉,得到了一個新座標系,則該向量分別在新舊座標系中投影表達式間的關係可以表示爲:
V’ = q-1 * V * q

如果一個座標系固定, 一個向量 V按照四元數 q 相對該座標系進行了轉動,得到一個新的向量 V’,則新舊向量之間的關係爲:
V’ = q * V * q-1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章