概要
ROS 2のサービスを使用して、GazeboのModel位置の取得と設定を行う方法を解説します。
検証環境
- ROS 2 Humble
- Gazebo 11.10.2
検証手順
gazebo_ros_state プラグインを使用します。このプラグインを使用することで、set_entity_stateやget_entity_stateと行ったサービスが使用できるようになります。(ROS 1ではget_model_state、set_model_stateに対応するもの)
参考:
ROS 2 Migration: Entity states
Wrappers, tools and additional API's for using ROS with Gazebo - ros-simulation/gazebo_ros_pkgs
今回使用するサンプルのworldファイルを作成します。場所は任意で、sample_world.worldというファイル名で以下の内容で作成します。ポイントは、libgazebo_ros_stateプラグインを指定して読み込んでいるところと、操作するBOXをsample_boxという名前で配置しているところです。
<?xml version="1.0"?>
<sdf version="1.6">
<world name="default">
<!-- Load gazebo_ros_state plugin -->
<plugin filename="libgazebo_ros_state.so" name="gazebo_ros_state">
<!-- Set the ROS node name for the plugin -->
<ros>
<namespace>/gazebo</namespace>
</ros>
</plugin>
<!-- A global light source -->
<include>
<uri>model://sun</uri>
</include>
<!-- Ground Plane -->
<include>
<uri>model://ground_plane</uri>
</include>
<!-- Other world entities and settings go here -->
<!-- Your robot, models, light, physics, etc. -->
<!-- Add a box model -->
<model name="sample_box">
<pose>0 0 0.5 0 0 0</pose> <!-- Initial position and orientation -->
<link name="link">
<collision name="collision">
<geometry>
<box>
<size>1 1 1</size> <!-- Size of the box -->
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>1 1 1</size> <!-- Size of the box -->
</box>
</geometry>
</visual>
</link>
</model>
</world>
</sdf>
このファイルを指定して、gazeboを以下のコマンドで起動します。(ここでは、ホームディレクトリにworldファイルを配置した例で記載しています)
gazebo ~/sample_world.world
以下のようにBOXが原点に表示されるはずです。
libgazebo_ros_stateプラグインがうまく読み込めている場合は、サービスの一覧にset_entity_stateとget_entity_stateが表示されるはずです。
ros2 service list # Output /gazebo/gazebo_ros_state/describe_parameters /gazebo/gazebo_ros_state/get_parameter_types /gazebo/gazebo_ros_state/get_parameters /gazebo/gazebo_ros_state/list_parameters /gazebo/gazebo_ros_state/set_parameters /gazebo/gazebo_ros_state/set_parameters_atomically /gazebo/get_entity_state /gazebo/set_entity_state
CLIより、get_entity_stateで位置を取得する場合は以下のコマンドを起動します。
ros2 service call /gazebo/get_entity_state gazebo_msgs/GetEntityState '{name: sample_box, referenence_frame: world}'
# Output
requester: making request: gazebo_msgs.srv.GetEntityState_Request(name='sample_box', reference_frame='world')
response:
gazebo_msgs.srv.GetEntityState_Response(header=std_msgs.msg.Header(stamp=builtin_interfaces.msg.Time(sec=268, nanosec=207000000), frame_id='world'), state=gazebo_msgs.msg.EntityState(name='', pose=geometry_msgs.msg.Pose(position=geometry_msgs.msg.Point(x=-7.946256933856395e-16, y=1.064254438566415e-15, z=0.49999999999510003), orientation=geometry_msgs.msg.Quaternion(x=4.6421123990452285e-17, y=-2.3220531991947308e-17, z=-1.5547407845533404e-15, w=1.0)), twist=geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0)), reference_frame=''), success=True)
CLIより、set_entity_stateで位置を設定する場合は以下のコマンドを起動します。
ros2 service call /gazebo/set_entity_state gazebo_msgs/SetEntityState "state: {name: sample_box, pose: {position:{x: 1.0, y: 2.0, z: 0.0}}, reference_frame: world}"
# Output
requester: making request: gazebo_msgs.srv.SetEntityState_Request(state=gazebo_msgs.msg.EntityState(name='sample_box', pose=geometry_msgs.msg.Pose(position=geometry_msgs.msg.Point(x=1.0, y=2.0, z=0.0), orientation=geometry_msgs.msg.Quaternion(x=0.0, y=0.0, z=0.0, w=1.0)), twist=geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0)), reference_frame='world'))
response:
gazebo_msgs.srv.SetEntityState_Response(success=True)
コマンド実行後は以下のように、x=1.0, y=2.0の位置に移動します。
CLIから呼び出しましたが、ROS 2のサービスコールで呼び出せるため、rclcppやrclpyでの呼び出しも可能です。




コメント