[[Tutorial]] #contents *ロボット・ダイナミクス [#j7cc4426] ここでは関節を持ったオブジェクトのダイナミクスシミュレーションを行うサンプルを紹介します。 **単純モデル [#f84e822a] ***モデルの作成 [#q02438d0] SIGVerseのロボットモデルはOpenHRP形式で記述されています。ここでは簡単なモデルを作成してみます。 まずロボットの形状モデルなどが置かれたディレクトリに移動し、以下のファイルを作成します。 $ cd ~/sigverse-<version>/share/data/shape/ $ emacs robot_test.x3d <?xml version="1.0" encoding="UTF-8"?> <X3D profile="Immersive" version="3.0"> <Scene> <!--************PROTO宣言部***********--> <ProtoDeclare name='Joint' > <ProtoInterface> <field accessType='inputOutput' type='SFVec3f' name='center' value='0.0 0.0 0.0' /> <field accessType='inputOutput' type='MFNode' name='children' /> <field accessType='inputOutput' type='MFFloat' name='llimit' /> <field accessType='inputOutput' type='SFRotation' name='limitOrientation' value='0.0 0.0 1.0 0.0' /> <field accessType='inputOutput' type='SFString' name='name' value='' /> <field accessType='inputOutput' type='SFRotation' name='rotation' value='0.0 0.0 1.0 0.0' /> <field accessType='inputOutput' type='SFVec3f' name='scale' value='1.0 1.0 1.0' /> <field accessType='inputOutput' type='SFRotation' name='scaleOrientation' value='0.0 0.0 1.0 0.0' /> <field accessType='inputOutput' type='MFFloat' name='stiffness' value='0.0 ,0.0 ,0.0' /> <field accessType='inputOutput' type='SFVec3f' name='translation' value='0.0 0.0 0.0' /> <field accessType='inputOutput' type='MFFloat' name='ulimit' /> <field accessType='inputOutput' type='MFFloat' name='dh' value='0.0 ,0.0 ,0.0 ,0.0' /> <field accessType='inputOutput' type='SFString' name='jointType' value='' /> <field accessType='inputOutput' type='SFFloat' name='jointId' value='-1.0' /> <field accessType='inputOutput' type='SFVec3f' name='jointAxis' value='1.0 0.0 0.0' /> </ProtoInterface> <ProtoBody> <Transform> <IS> <connect nodeField='children' protoField='children' /> <connect nodeField='center' protoField='center' /> <connect nodeField='rotation' protoField='rotation' /> <connect nodeField='scale' protoField='scale' /> <connect nodeField='scaleOrientation' protoField='scaleOrientation' /> <connect nodeField='translation' protoField='translation' /> </IS> </Transform> </ProtoBody> </ProtoDeclare> <ProtoDeclare name='Segment' > <ProtoInterface> <field accessType='initializeOnly' type='SFVec3f' name='bboxCenter' value='0.0 0.0 0.0' /> <field accessType='initializeOnly' type='SFVec3f' name='bboxSize' value='-1.0 -1.0 -1.0' /> <field accessType='inputOutput' type='SFVec3f' name='centerOfMass' value='0.0 0.0 0.0' /> <field accessType='inputOutput' type='MFNode' name='children' /> <field accessType='inputOutput' type='SFNode' name='coord' /> <field accessType='inputOutput' type='MFNode' name='displacers' /> <field accessType='inputOutput' type='SFFloat' name='mass' value='0.0' /> <field accessType='inputOutput' type='MFFloat' name='momentsOfInertia' value='0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0' /> <field accessType='inputOutput' type='SFString' name='name' value='' /> <field accessType='inputOnly' type='MFNode' name='addChildren' /> <field accessType='inputOnly' type='MFNode' name='removeChildren' /> </ProtoInterface> <ProtoBody> <Group> <IS> <connect nodeField='children' protoField='children' /> <connect nodeField='addChildren' protoField='addChildren' /> <connect nodeField='removeChildren' protoField='removeChildren' /> <connect nodeField='bboxCenter' protoField='bboxCenter' /> <connect nodeField='bboxSize' protoField='bboxSize' /> </IS> </Group> </ProtoBody> </ProtoDeclare> <ProtoDeclare name='Humanoid' > <ProtoInterface> <field accessType='initializeOnly' type='SFVec3f' name='bboxCenter' value='0.0 0.0 0.0' /> <field accessType='initializeOnly' type='SFVec3f' name='bboxSize' value='-1.0 -1.0 -1.0' /> <field accessType='inputOutput' type='SFVec3f' name='center' value='0.0 0.0 0.0' /> <field accessType='inputOutput' type='MFNode' name='humanoidBody' /> <field accessType='inputOutput' type='MFString' name='info' /> <field accessType='inputOutput' type='MFNode' name='joints' /> <field accessType='inputOutput' type='SFString' name='name' value='' /> <field accessType='inputOutput' type='SFRotation' name='rotation' value='0.0 0.0 1.0 0.0' /> <field accessType='inputOutput' type='SFVec3f' name='scale' value='1.0 1.0 1.0' /> <field accessType='inputOutput' type='SFRotation' name='scaleOrientation' value='0.0 0.0 1.0 0.0' /> <field accessType='inputOutput' type='MFNode' name='segments' /> <field accessType='inputOutput' type='MFNode' name='sites' /> <field accessType='inputOutput' type='SFVec3f' name='translation' value='0.0 0.0 0.0' /> <field accessType='inputOutput' type='SFString' name='version' value='1.0' /> <field accessType='inputOutput' type='MFNode' name='viewpoints' /> </ProtoInterface> <ProtoBody> <Transform> <IS> <connect nodeField='bboxCenter' protoField='bboxCenter' /> <connect nodeField='bboxSize' protoField='bboxSize' /> <connect nodeField='center' protoField='center' /> <connect nodeField='rotation' protoField='rotation' /> <connect nodeField='scale' protoField='scale' /> <connect nodeField='scaleOrientation' protoField='scaleOrientation' /> <connect nodeField='translation' protoField='translation' /> </IS> <Group> <IS> <connect nodeField='children' protoField='viewpoints' /> </IS> </Group> <Group> <IS> <connect nodeField='children' protoField='humanoidBody' /> </IS> </Group> </Transform> </ProtoBody> </ProtoDeclare> <!--************実モデル定義部************--> <ProtoInstance name='Humanoid' DEF="HRP1" containerField='children'> <fieldValue name='info' value='"Test Joint"' /> <fieldValue name='name' value='sample' /> <fieldValue name='version' value='1.1' /> <!--ROOTジョイント この関節が回転するとオブジェクト全体が回転 --> <ProtoInstance name='Joint' DEF="JOINT0" containerField='humanoidBody'> <fieldValue name='name' value='JOINT0' /> <!--関節の種類free 自由度6(位置と姿勢) --> <fieldValue name='jointType' value='free' /> <fieldValue name='jointId' value='1.0' /> <!--JOINT1(JOINT0の子ジョイント)--> <ProtoInstance name='Joint' DEF="JOINT1" containerField='children'> <fieldValue name='name' value='JOINT1' /> <fieldValue name='jointId' value='2.0' /> <!--固定された関節--> <fieldValue name='jointType' value='fixed' /> <!--LINK0(JOINT1に付随したリンク)--> <ProtoInstance name='Segment' DEF="LINK0" containerField='children'> <fieldValue name='name' value='LINK0' /> <Transform> <Shape> <!--テクスチャ--> <Appearance> <ImageTexture url="tumiki_moku.jpg"/> </Appearance> <!--LINK0の形状(JOINT1に付随)--> <IndexedFaceSet DEF="link1" coordIndex="0 3 2 1 -1 4 5 6 7 -1 4 0 1 5 -1 5 1 2 6 -1 6 2 3 7 -1 7 3 0 4 -1" texCoordIndex="0 1 2 3 -1 0 1 2 3 -1 0 1 2 3 -1 0 1 2 3 -1 0 1 2 3 -1 0 1 2 3 -1" solid="false"> <TextureCoordinate point="0.0 0.0, 0.0 1.0, 1.0 1.0, 1.0 0.0," /> <Coordinate DEF="Coaster_c01GeoPoints" point="-1.0 0.0 -1.0, 1.0 0.0 -1.0, 1.0 0.0 1.0, -1.0 0.0 1.0, -1.0 10.0 -1.0, 1.0 10.0 -1.0, 1.0 10.0 1.0, -1.0 10.0 1.0," /> </IndexedFaceSet> </Shape> </Transform> </ProtoInstance> <!--JOINT2(JOINT1の子ジョイント)--> <ProtoInstance name='Joint' DEF="JOINT2" containerField='children'> <fieldValue name='name' value='JOINT2' /> <!--JOINT2のJOINT1からの位置--> <fieldValue name='translation' value='0.0 5.0 0.0' /> <!--ヒンジジョイント --> <fieldValue name='jointType' value='rotate' /> <!--回転軸 --> <fieldValue name='jointAxis' value='1.0 0.0 0.0' /> <fieldValue name='jointId' value='3.0' /> <!--JOINT2に付随したリンク--> <ProtoInstance name='Segment' DEF="LINK1" containerField='children'> <fieldValue name='name' value='LINK1' /> <!--質量中心の位置(JOINT2からの位置)--> <fieldValue name='centerOfMass' value='0.0 5.0 0.0' /> <Transform> <Shape> <Appearance> <ImageTexture url="tumiki_moku.jpg"/> </Appearance> <IndexedFaceSet USE="link1"/> </Shape> </Transform> </ProtoInstance> </ProtoInstance> </ProtoInstance> </ProtoInstance> </ProtoInstance> </Scene> </X3D> OpenHRP形式のロボットはプロト宣言部と実モデル定義部からなります。実モデル定義部でロボットを組み立てます。OpenHRP形式のモデルの作成方法は詳しくは[[OpenHRP3 モデル作成法>http://www.openrtp.jp/openhrp3/3.0.2/jp/create_model.html]]を参照ください。 このサンプルは2つの棒を関節で接続したモデルです。 同じ形状ファイルをクライアント側のSIGViewerのインストール先に置きます。 ※形状ファイルにコメント部分があるとクライアント側で正常に読み込まれない場合があるので、クライアント側ではコメントを削除するようにしてください。 ***Jointの親子関係 [#fed078fe] Jointの親子関係は以下のようになっています。 Humanoid sample(モデルのルート) + Joint JOINT0 (ルートジョイント、3軸における位置、回転の6つの自由度をもつ) + Joint JOINT1 :Segment LINK1 (固定ジョイント、自由度0) + Joint JOINT2 :Segment LINK2(ヒンジジョイント、自由度1) Jointの回転や移動に伴い、そのJointに付随するSegmentや子ジョイントが回転および移動を行います。 このモデルではLINK1とLINK2がJOINT2によって接続されています。 #ref(bou_2.jpg) ***設定ファイル [#e3db8144] エージェント設定ファイルと世界ファイルを作成します。 $ cd ../xml $ emacs robot_test.xml robot_test.xml <?xml version="1.0" encoding="utf8"?> <define-class name="robot_test" inherit="Agent.xml"> <x3d> <!--先ほど作成したモデルの読み込み--> <filename>robot_test.x3d</filename> </x3d> </define-class> $ emacs DynamicsWorld.xml DynamicsWorld.xml <?xml version="1.0" encoding="utf8"?> <world name="myworld"> <gravity x="0.0" y="-9.8" z="0.0"/> <instanciate class="robot_test.xml"> <set-attr-value name="name" value="robot_test"/> <!--dynamics true--> <set-attr-value name="dynamics" value="true"/> <set-attr-value name="x" value="0.0"/> <set-attr-value name="y" value="6.0"/> <set-attr-value name="z" value="0.2"/> <set-attr-value name="language" value="c++"/> </instanciate> </world> ダイナミクスをtrueに設定しました。 ***実行 [#l4c076b6] まずはコントローラなしで実行してみましょう。 $ cd ~/sigverse-<version>/bin $ ./sigserver.sh -p 9001 -w DynamicsWorld.xml