Butterfly_Effect( )

地面と別れる方法

Eigenで力学してみる(1)

C++向けの行列計算ライブラリEigenを使って姿勢運動を扱う話.
初回はウォーミングアップということで,Quaternionクラスの使い方の練習をする.

はじめに

僕はC++をメインで使い、行列計算ライブラリとしてEigenを使っている.C++の高速性とMatlab的な行列演算を両立するためだ.Eigenには姿勢演算に便利なQuaternion(4元数)機能があるのだけど,これの使い方を解説してる記事は少ない.Quaternion(厳密にはそのオイラーパラメータ)によるキネマティクス処理は強力なので,ポイントを解説しておく.

Quaternionの時間発展を追う

Quaternionを使うとベクトルの回転操作が容易だ.ただし,

  1. 座標系を固定し,ベクトルを回転させる
  2. ベクトルを固定し,座標系を回転させる

のどちらを計算しているのか意識することがとても重要.ここでは前者を行っている.

#include "Eigen/Dense"
#include "Eigen/Geometry"
#include <iostream>

using namespace std;
using namespace Eigen;

int main(){
    Quaterniond q;
    Vector3d vec;
    Matrix3d DCM;
    
    // z軸の単位ベクトル
    Vector3d Z = Vector3d::UnitZ();
    cout << "Z = " << Z.transpose() << endl;
    
    // x軸周りに+π/4回転させるクォータニオンを生成
    q = AngleAxisd(M_PI/4, Vector3d::UnitX());
    cout << "q = " << q.coeffs().transpose() << endl;
    
    // ベクトルZをクォータニオンによって回転させる
    vec = q * Z;
    cout << "vec = " << vec.transpose() << endl;
    
    // クォータニオンからDCMを生成する
    DCM = q.toRotationMatrix();
    cout << "DCM = " << endl << DCM << endl;
    
    // クォータニオンを作用させることと,DCMを作用させることは等価
    vec = DCM * Z;
    cout << "vec = " << vec.transpose() << endl;

    return EXIT_SUCCESS;
}

なお,ベクトルを固定して座標系を回転させる場合は,共役クォータニオンを作用させればいい.

//vec = q * Z;    <-------この行を修正する
vec = q.conjugate() * Z;

ただし,クォータニオンが規格化されていることが前提となる.クォータニオンの規格化は次のように行う.

q.normalize();