Isaac SimでROSで動かせるロボットを作成する
はじめに
ここでは以下のようなロボットを作成します。
- Isaac Sim上で動かせる
- ROS側からの/cmd_velで動かせる
- 2輪型
- カメラやLidarが搭載されている
完成形
先にここで作成するロボットの完成形を見せます。
こんな2輪型ロボットを作ります
2輪型ロボットの作成
ロボットの作成手順を以下に記載しています。同じ手順を踏めばROSから動かせるロボットが完成するはずです。ちなみに、以下ではオブジェクトのパラメータを変更しますが、これは数値をダブルクリックすることで変更することができます。
地面を作成
以下の操作で地面を作成します。
- メニュー
Crete -> Pysics -> Ground Plane
Physics Sceneの作成
以下の操作でPhysics Sceneを作成します。
- メニュー
Crete -> Pysics -> Pysics Scene
これを配置すると物理演算が有効となります。もっとも、配置していなくても物理演算が必要なシミュレーションを開始する時に自動で有効になるようです。
ロボットのPrimを作成
以下の操作でロボットのRootとなるPrimを作成します。
- メニュー
Create -> Xform
作成したPrimを"vehicle_robo"という名前に変更します。右のウィンドウのメニューからShow Rootを選択して、表示されたRootに"vehicle_robo"をドラッグして"World"と並列に配置します。
Articulation Rootの追加
作成した"vehicle_robo"を選択し、Propertyタブの+addからPhysics -> Articulation Rootを選択して、Articulation Rootを追加します。これを追加しないとDifferential Baseを使ってロボットを動かそうとしたときうまく動きません。これはロボットの各関節の位置関係を管理するもののようですが、正直よくわかりません。
オブジェクトの作成
ここでは胴体や車輪を作成していきます。
base_linkの作成
以下の操作で胴体のPrimを作成します。
- メニュー
Create -> Xform
作成したPrimを"base_link"という名前にして"vehicle_robo"下に配置します。
bodyの作成
以下の操作でロボットの胴体を作成します。
- メニュー
Create -> Mesh -> Cube
作成したCubeを"body"という名前にして"base_link"下に配置します。また、"body"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 10.0 | 0.0 | 10.0 |
Orient | 0.0 | 0.0 | 0.0 |
Scale | 0.4 | 0.2 | 0.05 |
right_wheel_linkの作成
以下の操作でロボットの右車輪のPrimを作成します。
- メニュー
Create -> Xform
作成したPrimを"right_wheel_link"という名前にして"vehicle_robo"下に配置します。また、"right_wheel_link"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 0.0 | -15.0 | 10.0 |
Orient | -90.0 | 0.0 | 0.0 |
Scale | 1.0 | 1.0 | 1.0 |
right_wheelの作成
以下の操作でロボットの右車輪を作成します。
- メニュー
Create -> Mesh -> Cylinder
作成したCylinderを"right_wheel"という名前にして"right_wheel_link"下に配置します。また、"right_wheel"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 0.0 | 0.0 | 0.0 |
Orient | 0.0 | 0.0 | 0.0 |
Scale | 0.2 | 0.2 | 0.05 |
left_wheel_linkの作成
以下の操作でロボットの左車輪のPrimを作成します。
- メニュー
Create -> Xform
作成したPrimを"left_wheel_link"という名前にして"vehicle_robo"下に配置します。また、"left_wheel_link"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 0.0 | 15.0 | 10.0 |
Orient | -90.0 | 0.0 | 0.0 |
Scale | 1.0 | 1.0 | 1.0 |
left_wheelの作成
以下の操作でロボットの左車輪を作成します。
- メニュー
Create -> Mesh -> Cylinder
作成したCylinderを"left_wheel"という名前にして"left_wheel_link"下に配置します。また、"left_wheel"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 0.0 | 0.0 | 0.0 |
Orient | 0.0 | 0.0 | 0.0 |
Scale | 0.2 | 0.2 | 0.05 |
support_linkの作成
以下の操作で支柱のPrimを作成します。今回の2輪型ロボットはこのままでは胴体が前方に傾いてしまうので支柱で支える構成になっています。
- メニュー
Create -> Xform
作成したPrimを"support_link"という名前にして"vehicle_robo"下に配置します。また、"support_link"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 25.0 | 0.0 | 5.0 |
Orient | 0.0 | 0.0 | 0.0 |
Scale | 1.0 | 1.0 | 1.0 |
supportの作成
以下の操作で支柱を作成します。
- メニュー
Create -> Shapes -> Capsule
作成したCapsuleを"support"という名前にして"support_link"下に配置します。また、"support"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 0.0 | 0.0 | 0.0 |
Orient | 0.0 | 0.0 | 0.0 |
Scale | 0.2 | 0.2 | 0.1 |
Rigid Bodyの追加
Rigid Bodyを適用したオブジェクトは物理演算が適用されるようになります。例えば、Cubeを空中に配置してPlayするとCubeが落下するようになります。
以下のPrimに対して、Propertyタブの+addからPhysics -> Rigid Bodyを選択して、Rigid Bodyを追加します。
- "base_link"
- "right_wheel_link"
- "left_wheel_link"
- "support_link"
※Ctrlと左クリックで複数選択して一括して追加することもできます。
Colliderの追加
Colliderを適用したオブジェクトには衝突判定が発生します。Rigid Bodyを適用すると物理演算が適用されるようになりましたが、Colliderを設定してないと他のオブジェクトとの衝突判定が行われないためすり抜けてしまいます。例えば、Rigid Bodyを適用したCubeをGround Plane上に配置してPlayするとCubeはGround Planeをすり抜けて落ちてしまいます。これはGround PlaneにはColliderが設定されていますが、Cubeには設定されていないのでこのような現象になります。
以下のオブジェクトに対して、Propertyタブの+addからPhysics -> Colliderを選択して、Colliderを追加します。
- "body"
- "right_wheel"
- "left_wheel"
"support"については"body"と重なっている部分があるため、Colliderを上記のように設定すると"body"と干渉してしまうので後で別途設定します。
Jointの作成
ここでは各オブジェクトを接続していきます。
ホイールジョイントの作成
"right_wheel_link"を選択後、Ctrlを押しながら"base_link"を選択した状態で以下の操作をします。
- メニュー
Create -> Pysics -> Joint -> Revolute Joint
作成したRevoluteJointを"right_wheel_joint"という名前にしてJointパラメータを以下のように設定します。
Revolute Joint | X | Y | Z |
---|---|---|---|
Local Position 0 | 0.0 | -15.0 | 10.0 |
Local Position 1 | 0.0 | 0.0 | 0.0 |
Local Rotation 0 | -90.0 | -90.0 | 0.0 |
Local Rotation 1 | 0.0 | -90.0 | 0.0 |
同様に"left_wheel_joint"も作成して、Jointパラメータを以下のように設定します。
Revolute Joint | X | Y | Z |
---|---|---|---|
Local Position 0 | 0.0 | 15.0 | 10.0 |
Local Position 1 | 0.0 | 0.0 | 0.0 |
Local Rotation 0 | -90.0 | -90.0 | 0.0 |
Local Rotation 1 | 0.0 | -90.0 | 0.0 |
固定ジョイントの作成
"support_link"を選択後、Ctrlを押しながら"base_link"を選択した状態で以下の操作をします。
- メニュー
Create -> Pysics -> Joint -> Fixed Joint
作成したJointの名前を"support_joint"に変更します。パラメータは特に変更しません。
supportのCollider設定
"support"のColliderを設定します。以下の操作でColliderの範囲となるCubeを作成します。
- メニュー
Create -> Mesh -> Cube
作成したCubeを"support_collider"という名前にして"support_link"下に配置します。また、"support_collider"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 0.0 | 0.0 | -1.3 |
Orient | 0.0 | 0.0 | 0.0 |
Scale | 0.1 | 0.1 | 0.075 |
次に"support_collider"にColliderを追加します。Propertyタブの+addからPhysics -> Colliderを選択して、Colliderを追加します。
このままの状態では"support_collider"の位置にCubeが表示されているので、VisualプロパティのPurposeを"guide"に設定します。この設定によってCubeが見えなくなります。
Angular Driveの追加
駆動するための動力部となるAngular Driveを追加します。以下の2つのRevoluteJointを選択して、Propertyタブの+addからPhysics -> Angular Driveを選択して、駆動部を追加します。
- "right_wheel_joint"
- "left_wheel_joint"
それぞれのJointのパラメータを以下のように設定します。
Drive | Angular |
---|---|
Target Velocity | 0.0 |
Damping | 10000.0 |
動くかどうか試す場合は、両方のJointのTarget Velocityを"100.0"に設定した状態で、Playを押します。うまく作成できていればロボットが前方に進みます。
Default Primの設定
右ウィンドウで"vehicle_robo"を選択した状態で、右クリックから"Set as Default Prim"を選択します。これにより"vehicle_robo"がDefault Primとして設定されます。
USDファイルを読み込む際に、File -> Add ReferenceからUSDファイルを選択することでDefault Primのみ読み込むことができます。つまり、ロボットだけでなくGround Planeや障害物などを配置して作成されているUSDファイルからロボットのみロードするということができます。
完成形
上記手順を実行すると以下のようなロボットができるはずです。
斜め視点
正面から見た図(Collider表示)
右から見た図(Collider表示)
カメラやLidarなどを搭載
ロボットはできましたので、これからカメラやLidarといったものを搭載し、ROS側にトピックとして出力できるようにします。
camera_linkの作成
以下の操作でカメラのPrimを作成します。
- メニュー
Create -> Xform
作成したPrimを"camera_link"という名前にして"vehicle_robo"下に配置します。また、"camera_link"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 0.0 | 0.0 | 25.0 |
Orient | 90.0 | -90.0 | 0.0 |
Scale | 1.0 | 1.0 | 1.0 |
カメラの作成
以下の操作でカメラを作成します。
- メニュー
Create -> Camera
作成したCameraを"robo_camera"という名前にして"camera_link"下に配置します。また、"robo_camera"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 0.0 | 0.0 | 0.0 |
Orient | 0.0 | 0.0 | 0.0 |
Scale | 1.0 | 1.0 | 1.0 |
Rigid Bodyの追加
"camera_link"に対して、Propertyタブの+addからPhysics -> Rigid Bodyを選択して、Rigid Bodyを追加します。
固定ジョイントの作成
"camera_link"を選択後、Ctrlを押しながら"base_link"を選択した状態で以下の操作をします。
- メニュー
Create -> Pysics -> Joint -> Fixed Joint
作成したJointの名前を"camera_joint"に変更します。パラメータは特に変更しません。
ROSカメラの作成
以下の操作でROSカメラを作成します。
- メニュー
Create -> Isaac -> ROS -> Camera
これを作成することによってIsaac Simからカメラ画像をROS側に渡すことができるようになります。デフォルトではIsaac Simで見ているViewport画面が転送されますので、設置したカメラの画像を出力するように変更します。ROS_cameraの"Raw USD Properties"のcameraPrimの"Add Target(s)"から上記で作成した"robo_camera"を指定します。これでPlayを押すとカメラ画像が出力されます。
デフォルトのトピックとしては以下のものが出力されます。
- /camera_info(sensor_msgs/CameraInfo)
- /rgb(sensor_msgs/Image)
各トピック名は"Raw USD Properties"から変更できます。
lidar_linkを追加
以下の操作でLidarのPrimを作成します。
- メニュー
Create -> Xform
作成したPrimを"lidar_link"という名前にして"vehicle_robo"下に配置します。また、"lidar_link"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 0.0 | 0.0 | 25.0 |
Orient | 0.0 | 0.0 | 0.0 |
Scale | 1.0 | 1.0 | 1.0 |
Lidarの作成
以下の操作でLidarを作成します。
- メニュー
Create -> Isaac -> Sensors -> Rotating
作成したLidarを"lidar"という名前にして"lidar_link"下に配置します。また、"lidar"のTransformを以下のように設定します。
Transform | X | Y | Z |
---|---|---|---|
Translate | 0.0 | 0.0 | 0.0 |
Rotate | 0.0 | 0.0 | 0.0 |
また、"Raw USD Propaties"のdrawLinesをチェックしておきます。この設定によりLidarから出ているレーザーが可視化されます。
Rigid Bodyの追加
"lidar_link"に対して、Propertyタブの+addからPhysics -> Rigid Bodyを選択して、Rigid Bodyを追加します。
固定ジョイントの作成
"lidar_link"を選択後、Ctrlを押しながら"base_link"を選択した状態で以下の操作をします。
- メニュー
Create -> Pysics -> Joint -> Fixed Joint
作成したJointの名前を"lidar_joint"に変更します。パラメータは特に変更しません。
ROS Lidarを追加
以下の操作でROS Lidarを作成します。
- メニュー
Create -> Isaac -> ROS -> Lidar
カメラ同様これを作成することによってLidarのデータをROS側に渡すことができるようになります。ROS_lidarの"Raw USD Properties"のlidarPrimの"Add Target(s)"から上記で作成した"lidar"を、frameidに"lidar_link"を指定します。あとはmaxRangeを30.0にしておきます(Lidarの最大範囲です)。
Pose Treeを作成
ここまででカメラとLidarは追加できましたが、tfがありません。Isaac SimではロボットのPrimをそのままtf treeとして配信してくれるPose Treeというものがあります。以下の操作でPose Treeを作成します。
- メニュー
Create -> Isaac -> ROS -> Pose Tree
作成されたROS_PoseTreeの"Raw USD Properties"の"parentPrims"の"Add Target(s)"から"base_link"を追加します。次に"targetPrims"の"Add Target(s)"から以下のPrimを追加します。
- right_wheel_link
- left_wheel_link
- support_link
- camera_link
- lidar_link
これで各Primがtfトピックとして出力されるようになります。
rqtで表示した例
Differential Baseの作成
最後にROS側からのコマンドでロボットを動かすための駆動部を作成します。以下の操作でDifferential Baseを作成します。
- メニュー
Create -> Isaac -> ROS -> Differential Base
作成されたROS_DifferentialBaseの"Raw USD Properties"のchassisPrimの"Add Target(s)"から"vehicle_robo"を追加します。次に以下のようにパラメータを設定します。
parameter | value |
---|---|
leftWheelJointName | left_wheel_joint |
rightWheelJointName | right_wheel_joint |
maxSpeed | 0.15 |
wheelBase | 0.3 |
wheelRadius | 0.1 |
動かしてみる
これでロボットが完成しました。ROS側から動かしてみましょう。
Terminalで以下のコマンドを実行してroscoreを起動します。
$ roscore
Isaac SimでPlayボタンを押し、シミュレーションを開始します。Playボタンを押すと画面がカメラ視点になります。
別のTerminalで以下のコマンドを実行して"teleop_twist_keyboard"を起動します。
$ rosrun teleop_twist_keyboard teleop_twist_keyboard.py
パッケージがインストールされていない場合は以下のコマンドでインストールします(※ROS versionが"noetic"の場合の例)。
$ sudo apt install ros-noetic-teleop-twist-keyboard
"teleop_twist_keyboard"の起動後はそのTerminal上で以下のキーを押すとロボットが動きます。
- "j":左旋回
- "i":前進
- "l":右旋回
- "k":停止
- ",":後進
ちなみにこのときROS上ではIsaac Sim側は/OmniIsaacSimBridgeというノードとして見えています。
Isaac Simのサンプル環境"Office"にadd referenceで追加した例
rvizの表示例
課題など
以上で完成です。あと改良するのであれば以下のようなことが考えられます。
- 前進する際にカメラ画像がガタガタするので少し支柱が床に引っかかっているような気がします。支柱の摩擦を減らしてなめらかにしたほうがいいかもしれません
- ロボットにマテリアルを適用して見た目を変える
Discussion
記事作成ありがとうございます。書いていただいた記事を参考にrobotの組み立てを行ってみたんですが、車輪と胴体の相対位置が定まらず、バラバラに分離してしまう現象が発生しました。revolute jointの作成だけではobject同士は相対位置が固定されないのでしょうか?ご存知でしたら教えていただきたいです。
その後試してみたのですが問題なく相対位置が固定されました、ただロボットの質量が大きいのかロボットのvehicle_roboのxformのscaleを0.1にしたら動きました!