ROS2集成
在本教程中,我们将学习如何将 ROS 2 与 Gazebo 集成。我们将在它们之间建立通信。这在许多方面都有帮助;我们可以从 ROS 接收数据(如关节状态、TF)或命令,并将其应用于 Gazebo,反之亦然。这也有助于使 RViz 能够可视化由 Gazebo 世界同时仿真的机器人模型。
ros_gz_bridge
ros_gz_bridge (我测试发现仅ubuntu22.04及以上才能安装,ubuntu20.04可安装ros_ign_bridge)提供了一个网络桥,使 ROS 2 和 Gazebo Transport 之间能够交换消息。它的支持仅限于某些消息类型。请查看此自述文件,以验证你的消息类型是否受桥接器支持。
要求
在开始本教程之前,请遵循安装 Gazebo 和 ROS 文档。需要安装并运行 ROS 2 和 Gazebo 才能继续。
双向通信
我们可以初始化一个双向桥,这样我们就可以让 ROS 作为发布者,Gazebo 作为订阅者,反之亦然。
例如:
ros2 run ros_gz_bridge parameter_bridge /TOPIC@ROS_MSG@GZ_MSG
(如果没有ros_gz_bridge,使用以下命令
ros2 run ros_ign_bridge parameter_bridge /TOPIC@ROS_MSG@GZ_MSG
)
ros2 run ros_gz_bridge parameter_bridge 命令简单地运行来自 ros_gz_bridge 包的 parameter_bridge 代码。然后,我们指定要发送消息的话题 /TOPIC。第一个@符号将主题名称与消息类型分开。第一个@符号后面是 ROS 消息类型。
ROS 消息类型后面是@、[或]符号,其中:
- @ 是双向桥。
- [ 是从 Gazebo 到 ROS 的桥。
- ] 是从 ROS 到 Gazebo 的桥。
看一下这些示例如何从 ROS 到 Gazebo 以及反之亦然建立通信连接的示例。
将按键值发布到 ROS
让我们使用 Key Publisher 作为 Gazebo 插件向 ROS 发送消息。
注意: 确保已为所有工作区(ROS、Gazebo 和 ros_gz…)提供源。
首先,我们将在 ROS 和 Gazebo 之间启动一座桥,指定 Key Publisher 插件发送消息的主题以及消息类型,如下所示:
ros2 run ros_gz_bridge parameter_bridge /keyboard/keypress@std_msgs/msg/Int32@gz.msgs.Int32
(如果没有ros_gz_bridge,使用以下命令
ros2 run ros_ign_bridge parameter_bridge /keyboard/keypress@std_msgs/msg/Int32@ignition.msgs.Int32
)
我们在 /keyboard/keypress 话题上启动了一个 Int32 类型消息的桥。对于 ROS,它是 std_msgs/msg/Int32,对于 Gazebo,它是 gz.msgs.Int32
在另一个终端中,启动一个 Gazebo Sim 仿真世界,例empty.sdf 世界:
gz sim empty.sdf
(如果没有gz sim命令,使用以下命令
ign gazebo empty.sdf
)
然后从顶部右角的下拉菜单中添加 Key Publisher 插件。
在另一个终端启动 ROS 监听器:
ros2 topic echo /keyboard/keypress
此命令监听通过 /keyboard/keypress 话题发送的消息。
在 Gazebo 窗口上,按下键盘上的按键,你应该在监听器终端上找到数据。
现在轮到你了!尝试从 ROS 向 Gazebo 发送数据。你也可以尝试不同的数据类型和不同的通信方向。
附
ROS2与Gazebo(Ignition)中的消息的对应关系
提示: 如果你的环境中不支持gz sim命令,则将gz.msgs替换为ignition.msgs
Topic
ROS type | Gazebo Transport Type |
---|---|
actuator_msgs/msg/Actuators | gz.msgs.Actuators |
builtin_interfaces/msg/Time | gz.msgs.Time |
geometry_msgs/msg/Point | gz.msgs.Vector3d |
geometry_msgs/msg/Pose | gz.msgs.Pose |
geometry_msgs/msg/PoseArray | gz.msgs.Pose_V |
geometry_msgs/msg/PoseStamped | gz.msgs.Pose |
geometry_msgs/msg/PoseWithCovariance | gz.msgs.PoseWithCovariance |
geometry_msgs/msg/PoseWithCovarianceStamped | gz.msgs.PoseWithCovariance |
geometry_msgs/msg/Quaternion | gz.msgs.Quaternion |
geometry_msgs/msg/Transform | gz.msgs.Pose |
geometry_msgs/msg/TransformStamped | gz.msgs.Pose |
geometry_msgs/msg/Twist | gz.msgs.Twist |
geometry_msgs/msg/TwistStamped | gz.msgs.Twist |
geometry_msgs/msg/TwistWithCovariance | gz.msgs.TwistWithCovariance |
geometry_msgs/msg/TwistWithCovarianceStamped | gz.msgs.TwistWithCovariance |
geometry_msgs/msg/Vector3 | gz.msgs.Vector3d |
geometry_msgs/msg/Wrench | gz.msgs.Wrench |
geometry_msgs/msg/WrenchStamped | gz.msgs.Wrench |
gps_msgs/msg/GPSFix | gz.msgs.NavSat |
nav_msgs/msg/Odometry | gz.msgs.Odometry |
nav_msgs/msg/Odometry | gz.msgs.OdometryWithCovariance |
rcl_interfaces/msg/ParameterValue | gz.msgs.Any |
ros_gz_interfaces/msg/Altimeter | gz.msgs.Altimeter |
ros_gz_interfaces/msg/Contact | gz.msgs.Contact |
ros_gz_interfaces/msg/Contacts | gz.msgs.Contacts |
ros_gz_interfaces/msg/Dataframe | gz.msgs.Dataframe |
ros_gz_interfaces/msg/Entity | gz.msgs.Entity |
ros_gz_interfaces/msg/Float32Array | gz.msgs.Float_V |
ros_gz_interfaces/msg/GuiCamera | gz.msgs.GUICamera |
ros_gz_interfaces/msg/JointWrench | gz.msgs.JointWrench |
ros_gz_interfaces/msg/Light | gz.msgs.Light |
ros_gz_interfaces/msg/ParamVec | gz.msgs.Param |
ros_gz_interfaces/msg/ParamVec | gz.msgs.Param_V |
ros_gz_interfaces/msg/SensorNoise | gz.msgs.SensorNoise |
ros_gz_interfaces/msg/StringVec | gz.msgs.StringMsg_V |
ros_gz_interfaces/msg/TrackVisual | gz.msgs.TrackVisual |
ros_gz_interfaces/msg/VideoRecord | gz.msgs.VideoRecord |
rosgraph_msgs/msg/Clock | gz.msgs.Clock |
sensor_msgs/msg/BatteryState | gz.msgs.BatteryState |
sensor_msgs/msg/CameraInfo | gz.msgs.CameraInfo |
sensor_msgs/msg/FluidPressure | gz.msgs.FluidPressure |
sensor_msgs/msg/Image | gz.msgs.Image |
sensor_msgs/msg/Imu | gz.msgs.IMU |
sensor_msgs/msg/JointState | gz.msgs.Model |
sensor_msgs/msg/Joy | gz.msgs.Joy |
sensor_msgs/msg/LaserScan | gz.msgs.LaserScan |
sensor_msgs/msg/MagneticField | gz.msgs.Magnetometer |
sensor_msgs/msg/NavSatFix | gz.msgs.NavSat |
sensor_msgs/msg/PointCloud2 | gz.msgs.PointCloudPacked |
std_msgs/msg/Bool | gz.msgs.Boolean |
std_msgs/msg/ColorRGBA | gz.msgs.Color |
std_msgs/msg/Empty | gz.msgs.Empty |
std_msgs/msg/Float32 | gz.msgs.Float |
std_msgs/msg/Float64 | gz.msgs.Double |
std_msgs/msg/Header | gz.msgs.Header |
std_msgs/msg/Int32 | gz.msgs.Int32 |
std_msgs/msg/String | gz.msgs.StringMsg |
std_msgs/msg/UInt32 | gz.msgs.UInt32 |
tf2_msgs/msg/TFMessage | gz.msgs.Pose_V |
trajectory_msgs/msg/JointTrajectory | gz.msgs.JointTrajectory |
vision_msgs/msg/Detection2D | gz.msgs.AnnotatedAxisAligned2DBox |
vision_msgs/msg/Detection2DArray | gz.msgs.AnnotatedAxisAligned2DBox_V |
Service
ROS type | Gazebo request | Gazebo response |
---|---|---|
ros_gz_interfaces/srv/ControlWorld | gz.msgs.WorldControl | gz.msgs.Boolean |