Tutorial?

視覚に関する操作方法

視覚に関する操作方法を説明します。

周りを見渡す

エージェントがいろいろな方向を見渡すことができるサンプルコードを紹介します。

コントローラ作成

$ cd ~/sigverse-<version>/bin/NewWorld
$ emacs WatchController.cpp

WatchController.cpp

#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"


#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )


class WatchController : public Controller
{
public:
  void onRecvMessage(RecvMessageEvent &evt);
};


void WatchController::onRecvMessage(RecvMessageEvent &evt)
{
  SimObj *my = getObj(myname());

  //受け取ったメッセージをint型に変換します。
  const char *value(evt.getString(0));
  int angle = atoi(value);
  if (angle <= 180 && angle >=-180){

    //体全体をz軸から指定した角度だけ回転します.
    my->setAxisAndAngle(0, 1.0, 0, angle);
  }
}

extern "C"  Controller * createController ()
{
  return new WatchController;
}

これは回転する角度をメッセージとして受信して、その角度だけ体を回転させるサンプルです。

z軸方向(ロボットが最初に前を向いている方向)からの角度を指定します。回転する角度は-180°から180°まで指定することができます。

それではコンパイルします。

$ emacs Makefile

変更前

#オブジェクトファイルの指定
OBJS     = SendController.so RecvController.so

変更後

#オブジェクトファイルの指定
OBJS     = WatchController.so
$ make

リビングルームの世界ファイル作成

新しく世界ファイルを作成します。

$ cd ~/sigverse-<version>/bin
$ emacs xml/WatchWorld.xml

WatchWorld.xml

<?xml version="1.0" encoding="utf8"?>
<world name="VisTest2">

  <gravity x="0.0" y="-9.8" z="0.0"/>

<!--エージェントRobot-niiの設定-->
  <instanciate class="Robot-nii.xml">

<!--エージェント名-->
       <set-attr-value name="name" value="robot_000"/>

<!--C++言語の指定-->
       <set-attr-value name="language" value="c++"/>

<!--オブジェクトファイルAgentController.soの指定-->
       <set-attr-value name="implementation"
value="./NewWorld/WatchController.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="60.0"/>
       <set-attr-value name="z" value="-40.0"/>

<!--エージェントの視点の位置-->
       <set-attr-value name="vpx" value="0.0"/>
       <set-attr-value name="vpy" value="70.0"/>
       <set-attr-value name="vpz" value="5.0"/>


<!--エージェントの視点の向き-->
       <set-attr-value name="vvx" value="0.0"/>
       <set-attr-value name="vvy" value="-1.0"/>
       <set-attr-value name="vvz" value="1.0"/>

</instanciate>

<!--リビングルーム作成-->
  <instanciate class="seTV.xml">
       <set-attr-value name="name" value="TV_0"/>
       <set-attr-value name="dynamics" value="false"/> 

       <set-attr-value name="x" value="-20.0"/>
       <set-attr-value name="y" value="82.0"/>
       <set-attr-value name="z" value="-250.0"/>


       <set-attr-value name="visStateAttrName" value="switch"/>
       <set-attr-value name="switch" value="on"/>

  </instanciate>

  <instanciate class="seDoll_Bear.xml">
       <set-attr-value name="name" value="kuma_0"/>
       <set-attr-value name="dynamics" value="false"/>

       <set-attr-value name="x" value="0.0"/>
       <set-attr-value name="y" value="5.0"/>
       <set-attr-value name="z" value="0.0"/>

       <set-attr-value name="vpx" value="0.0"/>
  </instanciate>

  <instanciate class="seToy_D.xml">
       <set-attr-value name="name" value="penguin_0"/>
       <set-attr-value name="dynamics" value="false"/>

       <set-attr-value name="x" value="50.0"/>
       <set-attr-value name="y" value="10.0"/>
       <set-attr-value name="z" value="-40.0"/>

       <set-attr-value name="vpx" value="0.0"/>
       <set-attr-value name="vpy" value="10.0"/>
       <set-attr-value name="vpz" value="0.0"/>

       <set-attr-value name="vvx" value="0.0"/>
       <set-attr-value name="vvy" value="0.0"/>
       <set-attr-value name="vvz" value="1.0"/>

 </instanciate>

 <instanciate class="seSofa_2seater.xml">
       <set-attr-value name="name" value="sofa_0"/>
       <set-attr-value name="dynamics" value="false"/>

       <set-attr-value name="x" value="-200.0"/>
       <set-attr-value name="y" value="20.0"/>
       <set-attr-value name="z" value="-100.0"/>

       <set-attr-value name="qw" value="0.707"/>
       <set-attr-value name="qx" value="0.0"/>
       <set-attr-value name="qy" value="0.707"/>
       <set-attr-value name="qz" value="0.0"/>
 </instanciate>

 <instanciate class="seTVbass_B.xml">
       <set-attr-value name="name" value="TVdai_0"/>
       <set-attr-value name="dynamics" value="false"/>

       <set-attr-value name="x" value="-20.0"/>
       <set-attr-value name="y" value="13.0"/>
       <set-attr-value name="z" value="-250.0"/>
 </instanciate>

 <instanciate class="sePlant_B.xml">
       <set-attr-value name="name" value="ki_0"/>
       <set-attr-value name="dynamics" value="false"/>

       <set-attr-value name="x" value="100.0"/>
       <set-attr-value name="y" value="35.0"/>
       <set-attr-value name="z" value="-250.0"/>
 </instanciate>

 <instanciate class="seSidetable_B.xml">
       <set-attr-value name="name" value="sidetable_0"/>
       <set-attr-value name="dynamics" value="false"/>

       <set-attr-value name="x" value="-100.0"/>
       <set-attr-value name="y" value="23.0"/>
       <set-attr-value name="z" value="-100.0"/>

       <set-attr-value name="qw" value="0.707"/>
       <set-attr-value name="qx" value="0.0"/>
       <set-attr-value name="qy" value="0.707"/>
       <set-attr-value name="qz" value="0.0"/>
 </instanciate>

 <instanciate class="seApple.xml">
       <set-attr-value name="name" value="apple_0"/>
       <set-attr-value name="dynamics" value="false"/>

       <set-attr-value name="x" value="-50.0"/>
       <set-attr-value name="y" value="10.0"/>
       <set-attr-value name="z" value="30.0"/>
 </instanciate>

 <instanciate class="seOrange.xml">
       <set-attr-value name="name" value="orange_0"/>
       <set-attr-value name="dynamics" value="false"/>

       <set-attr-value name="x" value="70.0"/>
       <set-attr-value name="y" value="10.0"/>
       <set-attr-value name="z" value="-30.0"/>
 </instanciate>

</world>

これはリビングルームにヒューマノイドロボット(Robot-nii.xml)が立っているというxmlファイルです。リビングルームにはテレビやソファなどがおかれています。

このxmlファイルではエージェントの視点の位置や、視点の向きの設定がされています。これらはすべてエージェント座標系で設定されます。エージェント座標系とはエージェントが基準となる座標系で、x軸がエージェントから見て左右(左が正方向)、y軸が上下(上が正方向)、z軸が前後(前が正方向)となります。原点はエージェントの位置です。エージェントのお腹あたりにあるようです。

視点の向きはベクトルで表されます。今回視点の向きを(vvx,vvy,vvz)=(0,-1,1)と設定しました。つまりエージェントはまっすぐ前を向いた方向から、下方向45°に目線があるということになります。

起動

それでは起動してみましょう。

$ ./sigserver.sh -w WatchWorld.xml -p 9001

SIGViewerでサーバに接続して、シミュレーションを開始します。リビングルームに立っているヒューマノイドロボット型のエージェントが見えると思います。

watch_1.jpg

次に、ヒューマノイドロボットをクリックすると、左上の小さい画面にロボットの目線から見た映像が表示されます。

Watch_3.jpg

ロボットの目線からはりんごが見えているのがわかります。右のDetected Entitiesを見てみると、ロボットから見て、りんごが検出されているのがわかります。

watch_2.jpg

次に右側のコマンドタブをクリックして、ヒューマノイド型ロボットのエージェントに回転する角度を指定して、実行ボタンを押し、メッセージを送信します。例えば180を送信します。

watch_4.jpg

ロボットが180°回転して今度はテレビや、木、テーブルなどが検出されているのがわかります。

オレンジを見つけたら手を挙げる

次にオレンジを見つけたら手を挙げるサンプルを紹介します。

※注意)ポートフォワーディングによる接続の場合正常に動作しない場合があります。

コントローラ作成

コントローラを作成します。

$ cd ..
$ emacs WatchOrange.cpp

WatchOrange.cpp

#include <string>
#include <iostream>
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"

#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )

//利用する名前空間の宣言
using namespace std;

class WatchController : public Controller
{
public:
  double onAction(ActionEvent &evt);
  void onRecvMessage(RecvMessageEvent &evt);
};

//能動的行動を行います。
double WatchController::onAction(ActionEvent &evt)
{
  try {
    SimObj *my = getObj(myname());

    //手をさげます。
     my->setJointAngle("LARM_JOINT2", DEG2RAD(0));

    //視野内のEntityを得ます。
     vector<string>  ent; 
    bool b = detectEntities(ent);
    if(b && ent.size() > 0) { 

     //検出したEntityの名前を取得します。
      vector<string>::iterator i;
     for ( i = ent.begin(); i!= ent.end(); i++) {
       string name = *i;

       //検出したEntityを表示します。
        LOG_MSG(("detected %s\n", name.c_str()));

       if (name == "orange_0"){
         LOG_MSG(("This is orange"));

         //オレンジを見つけると手を挙げます。
          my->setJointAngle("LARM_JOINT2", DEG2RAD(180));
        }
      }
    }
  } catch(SimObj::Exception &) {
    LOG_ERR(("Exception"));
  }

  return 1.0;
}

//受動的行動を行います。
void WatchController::onRecvMessage(RecvMessageEvent &evt)
{
  SimObj *my = getObj(myname());
  const char *value(evt.getString(0));
  int angle = atoi(value);

  if (angle <= 180 && angle >=-180){
      //体全体をz軸から指定した角度だけ回転します.
      my->setAxisAndAngle(0, 1.0, 0, DEG2RAD(angle));

    }
}

extern "C"  Controller * createController ()
{
  return new WatchController;
}

これはオレンジを見つけたら手を挙げるサンプルです。detectEntitiesで視野内にあるエンティティを検出します。

それではコンパイルします。

$ emacs Makefile

編集前

#オブジェクトファイルの指定
OBJS     = WatchController.so

編集後

#オブジェクトファイルの指定
OBJS     = WatchOrange.so
$ make

世界ファイル編集

次に世界ファイルを編集します。

$ cd ..
$ emacs xml/WatchWorld.xml

編集前

<!--コントローラの指定-->
       <set-attr-value name="implementation"
value="./NewWorld/WatchController.so"/>

編集後

<!--コントローラの指定-->
       <set-attr-value name="implementation"
value="./NewWorld/WatchOrange.so"/>

実行

それでは実行してみましょう。

$ ./sigserver.sh -w WatchWorld.xml -p 9001
watch_5.jpg

オレンジを見つけたら手を挙げます。

戻る?


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