3. 新しいモデルを追加して拡張する
3.1 カメラを作ってみましょう
カメラのモデルを作ってみましょう.モデルは保存して,カタログに追加することが出来ます.
ここは新しいシーンで始めると良いです.
メニューから, Add > Primitive Shapes > Cuboidを選ぶと,直方体を追加します.
ダイアログが表示されます.とりあえず,デフォルトのまま,一辺が,0.1 [m]の立方体を作ります.
追加される場所は世界の中心.(0, 0, 0)に置かれます.
さらに,Add > Primitive Shapes > Cylinderを選びます.X-sizeが半径,Z-sizeが高さです.どちらもデフォルトで良いでしょう.同じ場所に生成されるので重なってしまいます.
これらを組み合わせます.CylinderをCuboidにドラッグすると,Cuboidのツリーの下にCylinderが追加されます.
オブジェクトツリーでCylinderを選択した状態で,Object / item shiftボタンを選択して,移動用のダイアログを開きます.
Transitionを選択して,Relative To:の項目をParent Frameを選択します.これでツリー上位のCuboidの座標系での移動が可能です.
X軸方向に0.1移動します.
Rotationを選んで,中段のBetaを1.5708に変更します.BetaはY軸周りの回転です.1.5708で90度回転します.
せっかくなので,Cylinderは色を変えてみましょう.
Cylinderを選択した状態で,Tools > Scene Object Propertiesを選び,ダイアログを開きます.
中段のAdjust outside colorを選択すると,またダイアログが出ます.Colorにもいろいろあるようで.
とりあえず,Ambient Color (環境光)を変えます.とりあえず黒くしてみましょう.(R, G, B) = (0.2, 0.2, 0.2) としましょう.
次に,Shapeを組み合わせます.
Shapeを組み合わせるときは,Groupingと,Mergingがあります.Mergeを使うと,二つのShapeが一つになりますが,この方法は色分けが面倒です.
今回はGroupingを使いましょう.
オブジェクトツリーでCuboidとCylinderの両方を選び,右クリックで表示されたメニューから,Edit > Grouping / Merging > Group selected shapesを選択します.
これで一つのCuboidというShapeになっちゃいました.これにVision Sensorを追加しましょう.Add > Vision Sensor > Perspective Typeを選択します.そしてVision SensorをCuboidにドラッグしてツリーに追加します.
Vision_Sensorが変な方向を向いています.位置もずれています.
まずはObject / item translation を使って移動させます.(0, 0, 0)に置く,というのは上位のShapeの中心に置く,ということです.これはCuboidとCylinderが同じ大きさですから,その接合面の中心になるということですね.
次にObject / item rotationを使って回転させます.とりあえず,カメラの前方向を向かせてみましょう.
とりあえず,(3.1416, 0, 0)とすると,カメラの方向を向きます.
ただし,これだとVision Sensorを選択した時に出ている赤・青・緑の矢印,これがVision Sensorの座標系になるのですが,赤が上を向いてしまっています.R, G, B軸 == X, Y, Z軸です.なので,Z軸周りに-90度,回転させてやります.
これでほぼ完成.
次に,今の状態を位置,姿勢ともにゼロとさせます.Cuboidを右クリックして,Edit > Reorient bounding box > with reference frame of worldとします.これで,World座標系で,位置・姿勢ともにゼロである状態になりました.これをやらないと,オブジェクトを追加するたびに位置や姿勢を変更しないと行けなくなります.
名前を変えましょう.Cuboidを選択してダブルクリックすると名前を変更できます.
とりあえず,CuboidをMyCameraとし,Vision SensorをMyCamera_visionSensorとしましょう.この名前は間違わないようにしましょう.あとで使うので.
ここでカメラの画像をシミュレータに表示するスクリプトを追加しておきましょう.とりあえず,便利なので.あとで消せるし.
V-REPでは,オブジェクトにスクリプトを追加して,動かすことが出来ます.
このスクリプトは,シミュレーションを動かすタイミングに同期して実行されます.だから,基本的には,このスクリプトだけでやりたいシミュレーションを実現することが出来ます.
スクリプトはLuaという言語で書かなくてはなりませんが,とてもシンプルな言語で,C++言語などがわかる人ならばあっという間にマスター出来ますが,
Luaの実行速度は遅く,またコードの再利用性が低くなってしまいます.
この記事では,RTコンポーネントと連携させることで,再利用性の高いシミュレーションの実現を目指します.
オブジェクトツリーからMyCameraを右クリックして,Add > Associated Child Script > Non Threadedを選びます.
これで,オブジェクトツリーのMyCameraの横に,スクリプトのアイコンが追加されます.
これをダブルクリックしてください.スクリプトエディタが開きます.
スクリプトエディタには以下のように書きます.
if (simGetScriptExecutionCount()==0) then cam=simGetObjectHandle('MyCamera_visionSensor') camView=simFloatingViewAdd(0.9,0.9,0.2,0.2,0) simAdjustView(camView,cam,64) end simHandleChildScript(sim_handle_all_except_explicit) |
1行目では,スクリプトの実行回数がゼロの時,すなわち最初の一回だけ呼ばれる,という条件を記述しています.
ここで,simGetObjectHandleを使って,オブジェクトの参照を取得します.このときにオブジェクト名が重要で,Vision Sensorに付いている名前を使います.
次に,simFloatingViewAddで,シミュレータにビューを追加します.引数は位置と大きさです.
最初の二つの引数が位置で,[0, 1]の値がシミュレーションのビューの位置に相当します.原点は左下です.座標は中心座標を表します.
次の値が横・縦のサイズで,これもシミュレーションビューとの比です.
この引数だと,右上ぴったりの位置に,シミュレーション全体の長さ比で20[%]のウィンドウが表示されることになります.
最後の引数は,ウィンドウの属性についてです.ヘルプを参照すると,
options: bit-coded: bit0 set=double click allows swapping the floating view with the main view bit1 set=the floating view doesn't have a close button bit2 set=the floating view cannot be shifted bit3 set=the floating view cannot be resized
というビットフラグになっています.
シミュレーションを再生してみてください.ウィンドウが表示されたと思います.
次に,Vision Sensorの視野角や解像度を決定します.MyCamera_visionSensorを選択して,Tools > Scene object propertiesを選びます.
ここでVision Sensorをプロパティを変更します. Near / far clipping planeは,遠近のカメラの見える範囲です.[0.2, 10]としましょう.
Perspective angleとは視野角で,radian表記です.とりあえず70度のカメラという設定で,1.2217とします.
解像度は640 x 480とします.2の階乗になっていない場合はエラーが起こりますよ,と言われますが,とりあえず640×480ということで.ワイドにしても良いけど.
Vision Sensorはいじりがいがあるオブジェクトで,Depthセンサーもかねています.一つのオブジェクトで両方をやることは出来ません.Depthの情報をignoreすることで,純粋にカメラとしてしか使えませんが,高速にはなります.
あと,Show filter dialogをクリックすると,カメラの取得した情報にフィルタを掛けることが出来ます.
細かい解説はしませんが,ちょっとしたプログラミングができます.
上の行から実行しますので,現状では,Original Imageをwork imageにコピーして,work imageをoutput imageにコピーする,という手順です.
これを,一行目をOriginal Depth Image to work imageとすれば,深度センサに変えることが出来ます.(ただ,シミュレータに表示するときは注意が必要ですが)
最後に,これを単なるShapeではなくObjectとするおまじないをします.
MyCameraを選択した状態で,メニューからTools > Scene Object Propertiesを選びます.
開いたダイアログからCommonメニューを選択し,Object special propertiesをCollidable, Renderable, Detectable, MesurableをONにします.
また,Object is model baseをONにします.最後のチェックで,ShapeがObjectになります.これで保存することができます.
FileメニューからSave object asというメニューを選択します.
すると,今の位置が,ドラッグ&ドロップされた時のオフセット位置になりますよ,というメッセージが出ます.とりあえずオーケーとしましょう.本当は0, 0は避けたいところですが.
ここで,アイコンをKinectのモノにしますか?と言われます.これはNOとしておきましょう.
実際のオブジェクトを使ってアイコンを作れますが,Vision Sensorの視界もオブジェクトなので,すごく引きのイメージです.何か画像を用意しておくと良いです.
(ちなみに,僕の環境だと,なぜか上下反転されてしまうので,下記のような画像を用意して使いました)
最後に保存.
components > sensors > myCamera.ttmとして保存しました.この時,ファイル名の欄に.ttmという拡張子を必ず付けて保存してください.忘れると後で自動的にロードしてくれないです.
オブジェクトカタログにMyCameraが追加されているのを確認したら,Pioneerのプロジェクトに戻って,Pioneerのconnection4に付けてみましょう.先ほどの手順だと,Pioneerにめり込んでしまいますが,Object / item shiftを使ってZ軸方向に0.05だけシフトしてあげると,キチンと乗っかります.
(文責: 菅 佑樹)