ロボットのGUIコントローラを作る(その2)
初稿: 2013/10/4, 最終更新:
2.ロボットの関節を動かす
次は、ロボットの関節を動かすことを目標にしていきます。
2.1 COLLADA形式のロボットモデル
ロボットのモデルファイルから、関節情報がどのように記述されているか見ていきましょう。kawada-hironx-parallelfingers.daeファイルはテキストで書かれたXMLファイルですので、ワードパッドで開くことが出来ます。
fig.3 colladaの中身
中身を知らずに見ていても何が書いてあるのか良くわかりませんので、"<node id="と書かれた行を見つけて追ってみてください。nodeタグ中のnameと書かれた中身を拾って図示していくと、次の図のようになり階層構造が、タグの入れ子で記述されていることが分かります。
また、各ノードの中身を見ていると、位置姿勢を表す<translate><rotate>や、幾何形状を現す<instance_geometry>などと書かれているタグがあることが分かります。このように、ロボットの関節は幾何形状と位置姿勢を持ったノードの階層的な構造で管理されています。
2.2 ノード情報をプログラムで表示してみる
理解するには手を動かしてみるのが早いので、早速プログラムを書いて読み込まれたノード情報を表示してみます。testApp.cppを編集してsearchPrintNodeという関数を足して呼び出すようにします。
loadModel関数の2個目の引数のtrueをfalseに変更している点に注意してください。これはモデルを最適化するかどうかのオプションです。
- void printAiMatrix4x4(aiMatrix4x4 m)
- void printNode(const aiNode* node)
- void searchPrintNode(const aiNode* node)
の3つの関数をtestApp::setup()の前にコピー&ペーストしてください。これはルートノードから子ノードを順にたどって、中身を表示していく関数です。
ビルドしなおして実行すると、標準出力に各ノードの情報がずらっと表示されます。その中の一部、首のパン関節を見てみます。
Name: HEAD_JOINT0_Link :ノードの名前
Parent: CHEST_JOINT0_Link :親ノードの名前
NumChildren: 1 :子ノードの数
Child: HEAD_JOINT1_Link :1番目の子ノードの名前
NumMeshes: 1 :メッシュの数
Transformation: :親ノードに対する位置姿勢(同次行列)
1, 0, 0, 0 :r11 r12 r13 x
0, 1, 0, 0 :r21 r22 r23 y
0, 0, 1, 0.5695 :r31 r32 r33 z
0, 0, 0, 1 : 0 0 0 1
Meshes[0]: 7 :1番目のメッシュのインデックス
2.3 首の関節を動かしてみる
今は関節を動かしてみたいのですから、Transformationを変えてやれば良いのだろうと勘が働きます。testApp::setup関数の中に足したsearchPrintNodeの下に次の一行を加えて、ビルド実行しなおしてください。
model.getAssimpScene()->mRootNode->FindNode("HEAD_JOINT0_Link")->mTransformation *= aiMatrix4x4().FromEulerAnglesXYZ(0,0,45*3.14/180.0);
この一行では、HEAD_JOINT0_Linkという名前のノードのmTransformationに、オイラー角(0,0,45度をラジアンにしたもの)を基に作った回転行列を掛けています。
fig.5 Panの回転
おお、首が回ってる。簡単ですね。