- The added line is THIS COLOR.
- The deleted line is THIS COLOR.
Up:[[Tutorial]] Previous:[[視覚に関する操作]] Next:[[エージェント視点の画像取得]]
----
#contents
*サービスプロバイダの使用方法 [#a3b254c4]
*サービスプロバイダの使用方法 [#ed3f4c00]
※v2.1.0以降対応
ここではサービスプロバイダを使ったサンプルを紹介します。
※ビューワーによるSSH接続を利用している場合はバージョン2.0.1,2.0.3ではサービスプロバイダ機能には対応しておりません。以下で説明するCygwinでのポートフォワーディングの設定を行ってください。
**サービスプロバイダとは [#c7349c8d]
SIGVerseではさまざまな情報をサービスとしてコントローラに提供します。
ビューワーもその一つです。
#ref(./service_1.PNG,40%)
#ref(サービスプロバイダの使用方法(v2.0系)/service_1.PNG,40%)
ビューワーはカメラ画像のデータなどをコントローラに提供します。ビューワーの他にも例えばKinectをサービスとして利用することもできます。
ユーザーがオリジナルのサービスを作成することもできます。
**オレンジを認識するサンプル[#cef2b65c]
ここではエンティティに設置されたカメラ画像からオレンジを認識するサンプルを紹介します。
まずコントローラを作成します。
$ cd ..
$ cd ~/MyWorld
$ emacs WatchOrange.cpp
WatchOrange.cpp
#highlight(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:
//シミュレーション開始時に一度だけ呼出される関数onInitの利用を宣言します
void onInit(InitEvent &evt);
double onAction(ActionEvent &evt);
void onRecvMsg(RecvMsgEvent &evt);
private:
ViewService *m_view;
bool raise_hand;
};
void WatchController::onInit(InitEvent &evt)
{
raise_hand = false;
//サービス"SIGViewer"に接続します
m_view = (ViewService*)connectToService("SIGViewer", 9005);
m_view = (ViewService*)connectToService("SIGViewer");
}
//能動的行動を行います
double WatchController::onAction(ActionEvent &evt)
{
SimObj *my = getObj(myname());
//手をさげます
if(raise_hand)
my->setJointAngle("LARM_JOINT2", DEG2RAD(0));
//サービス利用可能か確認
if(m_view != NULL) {
//視野内のEntityを得ます
vector<string> ent;
bool b = m_view->detectEntities(ent,1);
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", name.c_str()));
if (name == "orange_0"){
LOG_MSG(("This is orange"));
//オレンジを見つけると手を挙げます
my->setJointAngle("LARM_JOINT2", DEG2RAD(180));
raise_hand = true;
}
}
}
}
return 1.0;
}
//受動的行動を行います
void WatchController::onRecvMsg(RecvMsgEvent &evt)
{
SimObj *my = getObj(myname());
const char *value = evt.getMsg();
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;
}
}}
これはオレンジを見つけたら手を挙げるサンプルです。
30行目のconnectToServiceでサービスに接続します。
#highlight(cpp:firstline[30]){{
m_view = (ViewService*)connectToService("SIGViewer", 9005);
m_view = (ViewService*)connectToService("SIGViewer");
}}
1番目の引数でビューワーからサーバに接続するときに入力したサービス名を指定します。2番目の引数はコントローラとサービスプロバイダが接続する際にサーバ側で使用するポート番号を指定します。このサンプルでは9005番を使います。
1番目の引数でビューワーからサーバに接続するときに入力したサービス名を指定します。サービスプロバイダと通信するためにはメインポート(9001)とは別のポートを取得する必要があります。デフォルトではメインポート+1を取得します。サービスプロバイダ用のポート番号を指定する場合は第2引数で指定します。
ポート番号は空いている番号であれば何番でも構わないという場合(ポートフォワーディングの必要がない場合)は2番目の引数を省略することもできます。その場合空いているポート番号をランダムに取得します。)
48行目のdetectEntitiesで視野内にあるエンティティを検出します。
#highlight(cpp:firstline[48]){{
bool b = m_view->detectEntities(ent,1);
}}
1番目の引数で検出したエンティティ名を取得することができます。
2番目の引数では検出に使用するカメラのID番号を指定します。省略した場合はデフォルトで1となります。
***コンパイル [#o9b2929f]
Makefileの変数OBJSにWatchOrange.soを追加してコンパイルします。
$ ./sigmake.sh WatchOrange.cpp
***サービスプロバイダ用ポートフォワーディング [#p5a1f159]
このサンプルではポート番号9005番を新しく使用します。SSH接続を利用している場合は追加でポートフォワーディングの設定が必要になります。SSHでログインするときに以下のように入力してログインします。
$ ssh hoge@socio.iir.nii.ac.jp -L 9001:localhost:9001 -L 9005:localhost:9005
***世界ファイル編集 [#d02191e6]
次に世界ファイルを作成します。前ページのリビングルームとほぼ同じものを使用します。
$ cd ..
$ emacs xml/WatchOrange.xml
$ emacs WatchOrange.xml
WatchOrange.xml
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
<world name="myworld5">
<gravity x="0.0" y="-980.7" 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++"/>
<!--コントローラの指定-->
<set-attr-value name="implementation"
value="./NewWorld/WatchOrange.so"/>
value="./WatchOrange.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="54.0"/>
<set-attr-value name="z" value="-40.0"/>
<!--カメラのID番号,リンク名、方向、位置の設定-->
<camera id="1"
link="HEAD_LINK"
direction="0 -1 1"
aspectRatio="1.5"
fov="45"
position="0.0 0.0 5.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="62.0"/>
<set-attr-value name="y" value="87.5"/>
<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="9.0"/>
<set-attr-value name="z" value="10.0"/>
<set-attr-value name="y" value="9.9"/>
<set-attr-value name="z" 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="7.0"/>
<set-attr-value name="y" value="6.15"/>
<set-attr-value name="z" value="-40.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="30.0"/>
<set-attr-value name="y" value="31.85"/>
<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="8.0"/>
<set-attr-value name="y" value="25.1"/>
<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="y" value="56.5"/>
<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="y" value="16.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="3.0"/>
<set-attr-value name="y" value="3.875"/>
<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="2.0"/>
<set-attr-value name="y" value="2.215"/>
<set-attr-value name="z" value="-30.0"/>
</instanciate>
</world>
}}
***実行 [#i1a28c90]
それでは実行してみましょう。
$ ./sigserver.sh -w WatchOrange.xml -p 9001
$ sigserver.sh -w ./WatchOrange.xml
#ref(./watch_6.PNG,40%)
#ref(サービスプロバイダの使用方法(v2.0系)/watch_6.PNG,40%)
前回同様メッセージを送信するとロボットが回転し、オレンジを見つけたら手を挙げます。
*Old Version [#i5a3cc2e]
-[[サービスプロバイダの使用方法(v2.0系)]]
#highlight(end)
Up:[[Tutorial]] Previous:[[視覚に関する操作]] Next:[[エージェント視点の画像取得]]