#contents
*エージェントの関節操作方法 [#v2485f29]
人間またはロボットの形をしたエージェントの関節の操作方法を説明します。

**手を上げる [#f5cb7768]
人間が手を上げるサンプルコードを紹介します。
***ソースコードの作成 [#oc032119]
NewWorldディレクトリに新しくAgentController.cppを作成します。
 $ cd ~/sigverse-<version>/bin/NewWorld
 $ emacs AgentController.cpp

AgentController.cpp

 #include "Controller.h"
 #include "Logger.h"
 
 #define PI 3.141592
 #define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 ) 
 
 class AgentController : public Controller
 {
 public:
   double onAction(ActionEvent &evt);
 }; 
 
 
 
 double AgentController::onAction(ActionEvent &evt)
 {
   try {
     // 自分自身を得る
     SimObj *my = getObj(myname());
     if (!my->dynamics()) { 
 
      // "LARM_JOINT2" を45度に設定する
       my->setJointAngle("LARM_JOINT2", DEG2RAD(45));
 
    }
 
  } catch(SimObj::Exception &) {
    ;
  }
 
  return 5.0;
 }
 
 
 extern "C"  Controller * createController ()
 {
   return new AgentController;
 }

my->setJointAngle("LARM_JOINT2", DEG2RAD(45));で左肩を上に45°に上げます。

***コンパイル [#o78ee00f]
Makefileの以下の2行を変更します。

変更前
 #自作コード
 CPP_SRCS = MoveController.cpp
 
 #オブジェクトファイル
 OBJS     = MoveController.so

変更後
 #自作コード
 CPP_SRCS = AgentController.cpp
 
 #オブジェクトファイル
 OBJS     = AgentController.so

コンパイルします。
 $ make

***世界ファイル作成 [#l5dd7972]
次に世界ファイルを作成します。SIGVerse起動時に-wオプションで毎回世界ファイルを指定するのは面倒なので、MyWorld.xmlに記述します。

 $ cd ~/sigverse-<version>/bin
 $ ln -s ../share/sigverse/data/xml/ xml
xmlファイルがあるディレクトリまで遠いのでリンクを貼りました。
 $ cp xml/MyWorld.xml xml/MyWorld_org.xml
念のためデフォルトのMyWorld.xmlファイルを残しておきました。

 $ emacs xml/MyWorld.xml

MyWorld.xml

 <?xml version="1.0" encoding="utf8"?>
 <world name="newworld">
 
 <!--重力の設定-->
   <gravity x="0.0" y="-9.8" z="0.0"/>  
 
 <!--エージェントMan-niiの設定-->
   <instanciate class="Man-nii.xml"> 
 
 <!--エージェント名-->
         <set-attr-value name="name" value="man_000"/> 
 
 <!--C++言語の指定-->
         <set-attr-value name="language" value="c++"/> 
 
 <!--オブジェクトファイルAgentController.soの指定-->
         <set-attr-value name="implementation"
 value="./NewWorld/AgentController.so"/> 
 
 <!--動力学演算をfalseに設定-->
         <set-attr-value name="dynamics" value="false"/> 
 
 <!--エージェントの位置(x,y,z)-->
        <set-attr-value name="x" value="0.0"/>
        <set-attr-value name="y" value="50.0"/>
        <set-attr-value name="z" value="0.0"/>
 
 </instanciate>
エージェントとしてMan-nii.xmlを読み込むように設定し、動力学演算をfalseにしました。

***SIGVerse起動 [#g6cf60e0]
それではSIGVerseを起動してみましょう。
 $ ./sigserver.sh -p 9001
SIGViewerを起動して見てみると人間のエージェントが手を広げてスタンバイしていると思います。
シミュレーションを開始するとエージェントの左腕が45°上がります。

#ref(man_1.jpg)

今回setJointAngleという関数を用いて"LARM_JOINT2" を45°にする設定を行いました。"LARM_JOINT2"は左肩のz軸での回転として定義された関節の名前です。同様に"LARM_JOINT0","LARM_JOINT1"はそれぞれ左肩のx軸、y軸の回転として定義されています。これらの関節はsigverse-<version>/share/sigverse/data/shape/にあるx3dファイルで定義されています。

***パーツ [#nb731d79]
このエージェントさまざまなパーツからできていて、それらを関節でつないでできています。SIGViewerでエージェントをクリックするとエージェントの名前や位置などの属性を見ることができます。さらにさまざまなパーツをクリックするとその属性を見ることができます。

#ref(atr_1.jpg)

**コマンドによるエージェントの操作 [#ta077379]
前回は定期的に呼び出されるonActionで手を上げる設定を行いました。次はSIGViewerからのメッセージを送信することによりエージェントがお辞儀をするようなサンプルコードを紹介します。

まずAgentController.cppを変更します。
 $ emacs AgentController.cpp

 #include <string>  //
 #include "Controller.h"
 #include "Logger.h"
 #include "ControllerEvent.h"
 
 
 #define PI 3.141592
 #define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 ) 
 
 using namespace std; 
 
 class AgentController : public Controller
 {
 public:
   double onAction(ActionEvent &evt);
   
   // メッセージを受信したときの関数onRecvMessageの利用を宣言します。
   void onRecvMessage(RecvMessageEvent &evt);
 };
 
 double AgentController::onAction(ActionEvent &evt)
 {
   try {
     SimObj *my = getObj(myname());
     if (!my->dynamics()) { 
 
       // 左手を90°下に下げます。
       my->setJointAngle("LARM_JOINT2", DEG2RAD(-90));
 
       // 右手を90°下に下げます。
      my->setJointAngle("RARM_JOINT2", DEG2RAD(90));
 
     }
   } catch(SimObj::Exception &) {
     ;
   }
   return 5.0;
 }
 
 
 void AgentController::onRecvMessage(RecvMessageEvent &evt)
 {
   SimObj *my = getObj(myname());
 
   //string型のメッセージを取得します。
   string value(evt.getString(0)); 
   if (value =="Hello"){
 
     //腰の関節を45°曲げます。
     my->setJointAngle("WAIST_JOINT1", DEG2RAD(45));
   } 
 
 }
 
 extern "C"  Controller * createController ()
 {
   return new AgentController;
 }

onRecvMessageはメッセージを受信したときに呼び出される関数です。メッセージが"Hello"だったときにお辞儀をするサンプルコードです。

それではコンパイルして実行してみましょう。

 $ make
 $ cd ..
 $ ./sigserver.sh -p 9001

SIGViewerで見てみると手を広げたエージェントが見えると思います。
sendボタンをクリックしてシミュレーションを開始すると、onActionが呼び出されて右手と左手を下に下げます。
#ref(man_2.jpg)

Front page   New List of pages Search Recent changes   Help   RSS of recent changes