ロボットシミュレーションの構成
デモプログラムを改造して自分のシミュレーションをつくろう!
前回は、ODEを使った開発環境の構築までを解説しました。しかし、ODEで簡単にロボットシミュレーションを構築できるといえども、プログラムをゼロから作ろうとすると非常に時間がかかります。そのため、すでに動くことが保証されているデモプログラムをもとに、それを改造していくことをお勧めします。
本連載では「demo_buggy.cpp」を基本プログラムとして、プログラム構成を理解し、新たなロボットシミュレーションの作成につなげていきます。何を隠そう、私の作ったODEロボットシミュレーションはすべて「demo_buggy.cpp」を改造して作られたものなのです。
図1-1は、デモプログラム「demo_buggy.cpp」を用いてシミュレーション空間に構築したデモバギーを示しています。ちなみにこのデモバギーはボックス型物体1個と円柱型物体3個で構成されているように見えますが、ODEの動力学計算において円柱型物体は存在しないため、円柱型に見える物体は、計算上はボール型物体であり、3次元描画のみ円柱型に見せているだけなのでご注意ください。
デモバギーの構造は、ボックス型物体とボール型物体3個がそれぞれヒンジ2関節(1関節に2自由度を有する)で接続されており、前輪が2制御自由度、後輪がサスペンションと自由回転で構成される2自由度の、3物体6関節の車両型ロボットとなっています。なお、デモバギー手前の斜面は、ボックス型物体を斜めにして地面に埋め込んでいる状態となっています。
デモプログラム「demo_buggy.cpp」の構成
さて、実際にデモプログラム「demo_buggy.cpp」の内容を見ると、5つのルーチン「static void nearCallback」「static void start」「static void command」「static void simloop」「int main」から構成されていることがわかると思います(図1-2)。
図の左にある「int main」はメインルーチンであり、環境やロボットの設定を行う箇所です。そして、メインルーチン内にある「dsSimulationLoop」に情報処理が到達すると、「static void start」「static void command」「static void simloop」の順でサブルーチンが呼ばれます。
サブルーチン内の「static void start」は3次元描画におけるカメラの位置・角度の設定です。「static void command」はキーボードからの入力された値をシミュレーションに反映することを可能にします。「static void simloop」はシミュレーションの刻み時間(ステップタイム)1回分で行われるプロセスとなります。ここで、センサー読み取り・モータ制御・描画・ファイル書き込みの設定を行います。
メインルーチンで「dsSimulationLoop」が始まると、「static void start」は1回しか呼ばれませんが、「static void command」「static void simloop」は繰り返し呼び続けられ(図1-2:ループ1)、刻み時間の積み重ねでシミュレーション時間が進むこととなります。
なおループ1を終了させるには、ODEシミュレーションのウィンドウを閉じるか、「static void simloop」内に終了条件を設定し「dsStop();」コマンドを呼び出せば、「int main」内の「dsSimulationLoop」直後に戻ります。
最後に図右側の「nearCallback」ですが、これは物体の衝突に関する情報処理部です。「static void simloop」内の「dSpaceCollide」が呼び出されると開始され、ODE空間に存在するすべての物体・集合体(物体群のこと。後述します)間の衝突計算が行われます(図1-2:ループ2)。
ループ2における1ループは「任意の1物体」と「任意の1物体」の衝突計算が行われます。そして、すべての2物体の組み合わせの衝突計算が終わるまでループ2は止まりません。すなわち物体の数が増えれば、このループの回数も増え、計算時間がかかることとなります。なお、このサブルーチンで「物体/集合体の接触状態」・「接触センサー」の設定を行うこととなります。