- The added line is THIS COLOR.
- The deleted line is THIS COLOR.
Up:[[Tutorial]] Previous:[[HMD+KINECT]]
----
#contents
*Clean Up タスクサンプル 1[#m4114c6c]
※このサンプルはv2.1.1以降で動作します。
ロボットがゴミをゴミ箱に捨てるサンプルを紹介します。
**サンプルコード取得 [#s25b412a]
以下をサーバ側でダウンロードします。
#ref(CleanUp_v1.tar.gz)
**コンパイル [#l257db11]
次に展開してコンパイルします。
$ tar xzvf CleanUp_v1.tar.gz
$ cd CleanUp_v1
$ make
***コンパイルに失敗する場合 [#yd4d49df]
コンパイルするには環境変数SIGVERSE_PATHにバージョンSIGVerseのバージョン2.1.1以降を設定する必要があります。
$ export SIGVERSE_PATH=/home/<username>/sigverse-<バージョン2.1.1以降>
$ export PATH=$PATH:$SIGVERSE_PATH/bin
$ bash
※注意)動作環境によっては以下のコードをコントローラの最初に追加する必要があります。
#include <unistd.h>
**実行 [#zf79c3b1]
それでは実行してみましょう。
$ sigserver.sh -w ./CleanUp.xml
ビューワーで接続するとロボットが机の前に立っていて、机の上に缶とペットボトルが置いてあります。
#ref(./CleanUp_1.PNG,60%)
シミュレーションをスタートさせるとロボットが空き缶もしくはペットボトルに手を伸ばし、それをもってゴミ箱へと運びます。
#ref(./CleanUp_3.PNG,60%)
**ゴミ認識 [#c0141f0e]
このサンプルでは缶、もしくはペットボトルをゴミと認識してゴミ箱に運びます。
ロボットのコントローラを見てみます。
$ emacs CleanUpRobot.cpp
#highlight(cpp:firstline[300]){{
bool MyController::recognizeTrash(Vector3d &pos, std::string &name)
{
/////////////////////////////////////////////
///////////ここでゴミを認識します////////////
/////////////////////////////////////////////
// 候補のゴミが無い場合
if(m_trashes.empty()){
return false;
}
// ここでは乱数を使ってゴミを決定します
int trashNum = rand() % m_trashes.size();
// ゴミの名前と位置を取得します
name = m_trashes[trashNum];
SimObj *trash = getObj(name.c_str());
// ゴミの位置取得
trash->getPosition(pos);
return true;
}
}}
300行目あたりにrecognizeTrashという関数がありここでゴミを認識します。
このサンプルではゴミの名前が既に分かっていて、乱数でゴミを決定し、直接ゴミの位置を取得しています。
画像処理や距離センサなどでゴミを認識する場合はここにコードを追加していきます。
*Clean Up タスクサンプル 2 [#t6e5479d]
サンプル1ではゴミの名前からゴミの位置を直接取得しました。次のサンプルではゴミの名前をロボットがあらかじめ知ることができず、画像処理や距離センサの情報のみからゴミの位置を推定するためのサンプルプログラムを紹介します。
ロボットはゴミの名前を知ることはできないので、このサンプルではロボットの手と衝突したオブジェクトをgraspします。
さらにこのサンプルではサービスプロバイダを作成しクライアント側でゴミの位置を認識します。
**コントローラサンプルコード取得 [#s25b412a]
以下をサーバ側でダウンロードします。
以下のサンプル(最新版)をダウンロードします。
#ref(CleanUp_v3.tar.gz)
#ref(CleanUp_v2.tar.gz)
***v3 修正点 [#m79134c1]
-ゴミ箱コントローラによるゴミがゴミ箱に入ったかどうかの判定箇所修正.ゴミ箱上空でゴミをリリースすることが条件。
-ロボットに設置するカメラを2つに修正。
-テーブルの衝突判定形状修正。
-(※注意)SIGVerse v2.2.0以降で正常に動作します。
**コンパイル [#l257db11]
次に展開してコンパイルします。
$ tar xzvf CleanUp_v2.tar.gz
$ cd CleanUp_v2
$ tar xzvf CleanUp_<version>.tar.gz
$ cd CleanUp_<version>
$ make
**ゴミ認識サービス [#j18fe4a8]
ゴミを認識するサービスプロバイダのサンプルをクライアント側で以下からダウンロードします。
***vc2008 [#p0f4c65b]
#ref(RecogTrashService_v2_vc2008.zip)
***vc2010 [#cd42793f]
#ref(RecogTrashService_v2_vc2010.zip)
ダウンロードしたファイルを展開したらvc++2008(または2010)でRecogTrashService_****.slnファイルを開きます。
**編集 [#q2ae4227]
サーバ名を自分の環境に合わせて修正します。
RecogTrashService.cppの105行目あたりでSIGVerseサーバに接続します。
srv.connect("hostname", 9001);
"hostname"とポート番号9001を自分の環境に合わせて修正してからビルドします。
**実行 [#d5f70464]
それでは実行してみましょう。
サーバ側でまずSIGVerseサーバを実行します。
$ sigserver.sh -w ./CleanUp.xml -p 9001
次にビューワーでサーバに接続してシミュレーションを開始します。この時点ではロボットは認識を開始せず、ゴミ認識サービスが起動するのを待っています。
次にクライアント側でゴミ認識サービスを起動します。するとゴミ認識サービスによりゴミの位置が認識されてロボットがペットボトルをゴミ箱に運び始めます。
**終了 [#m997d185]
終了するときはゴミ認識サービスプロバイダの終了→ビューワーでシミュレーション終了(もしくはQuit)→ビューワーでdisconnect→サーバの終了の順に行います。
**ゴミ認識 [#j69da4dd]
このサンプルではゴミ認識はクライアント側で行います。サンプルコードを見てましょう。
#highlight(cpp:firstline[78]){{
void MyService::recognizeTrash(std::string sender, vector3 campos, vector3 camdir, vector3 &trashpos)
{
// カメラ画像を取得する
sigverse::ViewImage *img = this->captureView(sender);
// 視野角取得
double fovy = img->getFOVy();
// アスペクト比取得
double aspectRatio = img->getAspectRatio();
// 画像データを取得する
char* buf = img->getBuffer();
// ゴミの位置
trashpos.x = 0.0;
trashpos.y = 52.0;
trashpos.z = 60.0;
}
}}
関数recognizeTrashで画像や距離センサのデータからゴミの位置を推定し、trashposにゴミの位置を代入します。
このサンプルでは真ん中の缶の位置を既知として代入しています。
#highlight(end)