Up:Tutorial? Previous:車輪移動ロボット? Next: 眼球運動?
※このチュートリアルはv2.1.0以降で動作可能です。
SIGVerseでは距離センサはカメラを用います。 ここではSIGViewerサービスから距離データを取得するサンプルを紹介します。
カメラから取得可能な距離データは3つあります。一つ目はカメラから視線方向にあるオブジェクトまでの点と点の距離(スカラ値)、2つ目はエージェントの視線から水平面に沿って,物体までの距離を連続的に得るベクトル値(一次元配列)、3つ目は視野全体に渡る,二次元配列の距離データです。
distanceSensor()を使ってカメラの視線方向にあるオブジェクトまでの距離を取得するサンプルを紹介します。
作業ディレクトリに移動しコントローラを作成します。
$ cd ~/MyWorld $ emacs distanceSensor.cpp
distanceSensor.cpp
このサンプルでは62行目のdistanceSensor()で距離データを取得しています。
戻り値はunsigned char型です。つまり取得できる距離データは0~255までの整数です。デフォルトでは255cmまでの距離を取得することができ、255よりも遠くにオブジェクトがある場合はすべて255が返ってきます。 引数を変えることによってこれらの距離を変更することができます。
より遠くの距離を取得したい場合はdistanceSensor()の引数に取得したい距離データの範囲を指定することができます。
distanceSensor()を例えば以下のように修正します。
↓
最初2つの引数で距離センサが取得できる距離の範囲を変更することができます。第一引数にoffset値、第2引数に取得する距離データの範囲を指定します。この例ではカメラから距離が50.0~550.0(cm)までの距離データを取得できることになります。このとき戻り値は先ほどと同様0~255です。つまりカメラからの距離が50.0cm以下の場合は戻り値が0になり、550.0cm以上の場合は255となります。取得できる距離データの値と実際の距離は常に比例関係にあります。範囲を大きくすると広範囲の距離データを取得することができますが分解能が悪くなります。
最後の引数はカメラID番号です。 何も指定しない場合はカメラのID番号1から距離データを取得します。
このコントローラではロボットは向いている方向に進み、視線方向のオブジェクトまでの距離が100cmよりも近くなるとロボットの体全体の向きをランダムに変えます。
コンパイルします。
$ ./sigmake.sh distanceSensor.cpp
次に世界ファイルを作成します。
$ emacs distanceSensor.xml
distanceSensor.xml
今回は車輪付き移動ロボットを使用します。
それでは実行してみましょう。
$ sigserver.sh -w ./distanceSensor.xml
シミュレーションを実行するとロボットが前に進み始めます。そしてオブジェクトに衝突しそうになると方向転換します。
次にエージェントの視線方向の水平面に沿って距離データを取得するサンプルを紹介します。水平面の距離データを配列データとして一度に取得します。
コントローラを新しく作成します
$ emacs distanceSensor1D.cpp
distanceSensor1D.cpp
このサンプルは水平面の距離データの最小値(いちばん近い距離)が100cm以下の場合に方向を変えるサンプルです。
distanceSensor1D()で視線方向の水平面に沿った1次元の距離データを取得します。戻り値はViewImageクラスです。 デフォルトではカメラの水平方向の視野角を320等分したデータを取得します。距離データを取得するにはgetBuffer()を使います。0が横方向の視野角内のいちばん左、319がいちばん右のデータになります。
カメラの水平方向視野角は直接設定することはできませんが、垂直方向視野角とアスペクト比を世界ファイルで設定することにより調節できます。
ただし、視野角が大きくなると解像度が悪くなるため、視野角(水平方向)30°~80°くらいの範囲に設定することをお勧めします。
コンパイルします。
$ ./sigmake.sh distanceSensor1D.cpp
コントローラdistanceSensor1D.soに変えます。
$ emacs distanceSensor.xml
↓
実行してみましょう。
$ sigserver.sh -w ./distanceSensor.xml
先ほどのサンプルでは近くにオブジェクトがあっても視線方向と外れていたら向きを変えませんでした。 このサンプルでは近くにオブジェクトがあれば向きを変えます。 4つのオブジェクトに囲まれたロボットはなかなか外に出られなくなります。
次は視野全体の距離データを取得します。
コントローラを新しく作成します。
$ emacs distanceSensor2D.cpp
distanceSensor2D.cpp
distanceSensor2D()により2次元距離データを取得します。
取得した距離データの配列位置からその方向を極座標系で得ることができます。 このサンプルでは方向をカメラ視線方向を基準に垂直方向の角度Θと水平方向の角度φで求めています。
captureViewで取得した画像と同様に距離データをファイルに保存する場合は以下の関数を使います。
$ emacs distanceSensor.xml
コントローラをdistanceSensor1D.soからdistanceSensor2D.soに変えます。
それでは実行してみましょう。
$ sigserver.sh -w ./distanceSensor.xml
保存した距離データ画像を見てみると以下のような距離データが見ることができます。
#ref(): File not found: "distance.bmp" at page "Distance sensor"
遠いオブジェクトほど色が薄くなり、近いオブジェクトほど色が濃くなっています。