本文在Ubuntu18.04 + ROS melodic环境下完成,其他ROS版本类似。

一、简介

gazebo提供了一组ROS API,允许用户修改并获取有关模拟世界各个方面的信息。在以下各节中,我们将演示一些用于操纵仿真世界和对象的实用程序。gazebo的ROS消息和服务的完整列表也可以在这里找到。

前提:如果您想按照示例进行操作,请确保已按照之前教程中所述安装了RRBot。在本教程中,我们将使用各种技术让RRBot“踢倒”可乐罐。

术语:下文中,刚体对象的姿势称为其“state”。对象还具有固有属性“properties”,例如质量和摩擦系数。在gazebo中,''body'''是指刚体,与urdf中的''link'''同义。 gazebo的“model”是由“joints”连接物体而成的集合体。

插件

  • gazebo_ros_api_plugin:gazebo_ros功能包中的gazebo_ros_api_plugin插件会初始化一个名为“gazebo”的ROS节点。 它将ROS回调调度程序(消息传递)与gazebo内部的调度程序集成在一起,以提供以下所述的ROS接口。该ROS API使用户可以在ROS上操纵仿真环境的属性,以及在环境中生成模型的状态。此插件仅与gzserver一起加载。
  • gazebo_ros_paths_plugin:gazebo_ros软件包中提供了一个名为gazebo_ros_paths
    _plugin的辅助插件,该插件仅允许gazebo查找ROS资源,即解析ROS功能包路径名。此插件随着gzserver和gzclient一起加载。

gazebo发布的参数

  • /use_sim_time:Bool,通知ROS使用已发布的/clock话题作为ROS时间。
  • 如果通过/use_sim_time参数使用仿真时间,则gazebo使用ROS参数服务器通知其他应用程序,尤其是rviz。
  • 如果gazebo_ros发布ROS/clock话题,为ROS系统提供模拟同步时间,则/use_sim_time自动设为true。有关仿真时间的更多信息,请参见ROS C ++ Time

查看参数设置

$ roslaunch rrbot_gazebo rrbot_world.launch 
$ rosparam get /use_sim_time

二、gazebo订阅的话题

1、Topics列表

  • ~/set_link_state:gazebo_msgs/LinkState,设置连杆的姿态。
  • ~/set_model_state:gazebo_msgs/ModelState,设置模型的姿态。

2、通过topics设置模型的姿态

topics可用于快速设置模型的姿势,而无需等待姿势设置动作完成。为此,请将所需的模型状态消息发布到/gazebo/set_model_state话题。

首先,先将gazebo模型文件夹路径添加到环境路径中:

$ export GAZEBO_MODEL_PATH=/home/pan/.gazebo/models

然后,向仿真环境中添加可乐罐:

$ rosrun gazebo_ros spawn_model -file `echo $GAZEBO_MODEL_PATH`/coke_can/model.sdf -sdf -model coke_can1 -y 1

并通过在/gazebo/set_model_state话题上发布消息来设置可乐罐的姿势:

$ rostopic pub -r 20 /gazebo/set_model_state gazebo_msgs/ModelState '{model_name: coke_can1, pose: { position: { x: 1, y: 0, z: 2 }, orientation: {x: 0, y: 0.491983115673, z: 0, w: 0.870604813099 } }, twist: { linear: { x: 0, y: 0, z: 0 }, angular: { x: 0, y: 0, z: 0}  }, reference_frame: world }'

您应该看到可乐可以悬浮在RRBot的前面:

三、gazebo发布的话题

1、Topics列表

  • /clock:rosgraph_msgs/Clock,发布仿真时间,与/use_sim_timeparameter一起使用。
  • ~/link_states:gazebo_msgs/LinkStates,发布仿真中所有连杆的状态。
  • ~/model_states:gazebo_msgs/ModelStates,发布仿真中所有模型的状态。

2、使用Topics检索模型和连杆的状态

gazebo发布/gazebo/link_states和/gazebo/model_states话题,其中包含有关gazebo世界框架的仿真对象的姿态信息。 您可以通过运行以下命令查看它们的运行情况:

$ rostopic echo -n 1 /gazebo/model_states

$ rostopic echo -n 1 /gazebo/link_states

重申一下,“link”被定义为具有给定的惯性,视觉和碰撞属性的刚体。而“model”定义为连杆和关节的集合。模型的状态是其规范连杆的状态。假定urdf强制采用树结构,则模型的规范连杆由其根连杆定义。

四、服务——在仿真中创建和销毁模型

1、Services列表

  • ~/spawn_urdf_model:gazebo_msgs/SpawnModel,使用此服务生成通用机器人描述格式(urdf)。
  • ~/spawn_sdf_model:gazebo_msgs/SpawnModel,使用此服务生成以gazebo仿真描述格式(sdf)编写的模型。
  • ~/delete_model:gazebo_msgs/DeleteModel,此服务允许用户从仿真中删除模型。

2、生成模型

提供了一个名为spawn_model的程序脚本,用于调用gazebo_ros提供的模型生成服务。使用服务调用方法生成模型的最实用方法是使用roslaunch文件。使用roslaunch文件生成模型教程中提供了详细信息。有很多方法可以使用spawn_model将urdf和sdf添加到gazebo。 以下是一些示例:

  • run gazebo
$ roscore & rosrun gazebo_ros gazebo
  • 从文件生成urdf:首先将xacro文件转换为xml,然后生成urdf:
$ rosrun xacro xacro `rospack find rrbot_description`/urdf/rrbot.xacro >> `rospack find rrbot_description`/urdf/rrbot.xml
$ rosrun gazebo_ros spawn_model -file `rospack find rrbot_description`/urdf/rrbot.xml -urdf -y 1 -model rrbot1 -robot_namespace rrbot1
  • 来自本地模型数据库的SDF:
$ rosrun gazebo_ros spawn_model -file `echo $GAZEBO_MODEL_PATH`/coke_can/model.sdf -sdf -model coke_can1 -y 0.2 -x -0.3
  • 在线模型数据库中的SDF:
$ rosrun gazebo_ros spawn_model -database coke_can -sdf -model coke_can1 -y 2.2 -x -0.3
  • 要查看spawn_model的所有可用参数,包括名称空间,trimesh属性,关节位置和RPY方向,请运行:
$ rosrun gazebo_ros spawn_model -h

3、删除模型

只要您知道模型的名称,就可以轻松删除gazebo中已经存在的模型。如果您按照上一节中的描述生成了一个名为“rrbot1”的rrbot,则可以使用以下方法将其删除:

$ rosservice call gazebo/delete_model '{model_name: rrbot1}'

五、服务——设置姿态和属性

1、Services列表

  • ~/set_link_properties:gazebo_msgs/SetLinkProperties
  • ~/set_physics_properties:gazebo_msgs/SetPhysicsProperties
  • ~/set_model_state:gazebo_msgs/SetModelState
  • ~/set_model_configuration:gazebo_msgs/SetModelConfiguration,此服务允许用户在不调用动力学的情况下设置模型的关节位置。
  • ~/set_joint_properties: gazebo_msgs/SetJointProperties
  • ~/set_link_state : gazebo_msgs/SetLinkState
  • ~/set_link_state : gazebo_msgs/LinkState
  • ~/set_model_state : gazebo_msgs/ModelState

2、设置模型姿态的示例

将可乐罐移动到RRBot的前方,请运行以下命令:

$ roslaunch rrbot_gazebo rrbot_world.launch
$ export GAZEBO_MODEL_PATH=/home/pan/.gazebo/models
$ rosrun gazebo_ros spawn_model -file `echo $GAZEBO_MODEL_PATH`/coke_can/model.sdf -sdf -model coke_can1 -x=0.3 -y=0.2

现在,使用以下命令使RRBot开始旋转:

$ rosservice call /gazebo/set_model_state '{model_state: { model_name: rrbot, pose: { position: { x: 1, y: 1 ,z: 10 }, orientation: {x: 0, y: 0.491983115673, z: 0, w: 0.870604813099 } }, twist: { linear: {x: 0.0 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'

位置放的好的话,可乐罐会被击飞,您可以改变可乐罐位置重试一遍。

gazebo中控制RRBot击飞可乐罐
Melody的视频

六、服务——获取姿态和属性

1、服务列表

  • ~/get_model_properties : gazebo_msgs/GetModelProperties,此服务返回仿真中模型的属性。
  • ~/get_model_state : gazebo_msgs/GetModelState,此服务返回仿真中模型的姿态。
  • ~/get_world_properties : gazebo_msgs/GetWorldProperties,此服务返回模拟世界的属性。
  • ~/get_joint_properties : gazebo_msgs/GetJointProperties,此服务返回仿真中关节的属性。
  • ~/get_link_properties : gazebo_msgs/GetLinkProperties,此服务返回仿真中连杆的属性。
  • ~/get_link_state : gazebo_msgs/GetLinkState,此服务返回仿真中连杆的姿态。
  • ~/get_physics_properties : gazebo_msgs/GetPhysicsProperties,此服务返回用于仿真的物理引擎的属性。
  • ~/link_states : gazebo_msgs/LinkStates,在世界框架中发布完整的连杆姿态。
  • ~/model_states : gazebo_msgs/ModelStates,在世界框架中发布完整的模型姿态。

备注:link_name在gazebo作用域名称表示法中,[model_name::body_name]。

2、获取模型姿态的示例

既然您已经“踢过”可乐罐了,您还想知道它被踢了多远。在前面的示例的基础上,我们将通过服务调用查询可乐罐的姿态:

$ rosservice call gazebo/get_model_state '{model_name: coke_can1}'

您将获得以下相关信息:

pose:
position:
x: 0.0
y: 0.0
z: 0.0
orientation:
x: 0.0
y: 0.0
z: 0.0
w: 1.0
twist:
linear:
x: nan
y: nan
z: nan
angular:
x: nan
y: nan
z: nan

我的机器人把罐子击飞出世界了哈哈哈,所以值为nan,你的呢?

3、检索仿真世界和对象属性

您可以通过运行以下命令获取仿真世界中的模型列表:

$ rosservice call gazebo/get_world_properties
sim_time: 1013.366
model_names: ['ground_plane', 'rrbot', 'coke_can']
rendering_enabled: True
success: True
status_message: GetWorldProperties: got properties

并通过以下方式检索特定模型的详细信息:

$ rosservice call gazebo/get_model_properties '{model_name: rrbot}'
parent_model_name: ''
canonical_body_name: ''
body_names: ['link1', 'link2', 'link3']
geom_names: ['link1_geom', 'link2_geom', 'link3_geom', 'link3_geom_camera_link', 'link3_geom_hokuyo_link']
joint_names: ['fixed', 'joint1', 'joint2']
child_model_names: []
is_static: False
success: True
status_message: GetModelProperties: got properties

七、服务——力控制

这些服务允许用户在仿真中将转矩和力施加到物体和关节上:

  • ~/apply_body_wrench : gazebo_msgs/ApplyBodyWrench,在仿真中将转矩施加到刚体上。应用于同一主体的所有活动转矩都是累积的。
  • ~/apply_joint_effort : gazebo_msgs/ApplyJointEffort,在仿真中对关节施加力。应用于同一关节的所有力都是累积的。
  • ~/clear_joint_forces : gazebo_msgs/JointRequest,清除施加在关节上的力。
  • ~/clear_body_wrenches : gazebo_msgs/ClearBodyWrenches,清楚施加在刚体上的转矩。

1、将转矩应用于连杆

为了演示转矩在gazebo上的应用,让我们在关闭重力的情况下生成一个对象。

chongqi gazebo:

$ roslaunch rrbot_gazebo rrbot_world.launch 

将可乐罐添加到模拟中:

$ export GAZEBO_MODEL_PATH=/home/pan/.gazebo/models
$ rosrun gazebo_ros spawn_model -file `echo $GAZEBO_MODEL_PATH`/coke_can/model.sdf -sdf -model coke_can1 -y=1

然后要关闭重力,将服务调用发送到/gazebo/set_physics_properties,而在任何轴上都没有重力:

$ rosservice call /gazebo/set_physics_properties "
time_step: 0.001
max_update_rate: 1000.0
gravity:
  x: 0.0
  y: 0.0
  z: 0.0
ode_config:
  auto_disable_bodies: False
  sor_pgs_precon_iters: 0
  sor_pgs_iters: 50
  sor_pgs_w: 1.3
  sor_pgs_rms_error_tol: 0.0
  contact_surface_layer: 0.001
  contact_max_correcting_vel: 100.0
  cfm: 0.0
  erp: 0.2
  max_contacts: 20"

通过调用/gazebo/apply_body_wrench服务,在可乐罐起始处施加0.01 Nm的转矩,持续1秒钟,您应该看到可乐粉可以沿x轴正方向旋转:

$ rosservice call /gazebo/apply_body_wrench '{body_name: "coke_can1::link" , wrench: { torque: { x: 0.01, y: 0 , z: 0 } }, start_time: 10000000000, duration: 1000000000 }'
gazebo可乐罐悬浮
Melody的视频

在可乐罐起点施加反向-0.01 Nm转矩1秒钟,罐应停止旋转:

$ rosservice call /gazebo/apply_body_wrench '{body_name: "coke_can1::link" , wrench: { torque: { x: -0.01, y: 0 , z: 0 } }, start_time: 10000000000, duration: 1000000000 }'

通常,负的转矩会无限期地持续。要清除施加在主体上的所有活动转矩,您可以:

$ rosservice call /gazebo/clear_body_wrenches '{body_name: "coke_can1::link"}'

2、在仿真中对关节施加力

调用/gazebo/apply_joint_effort向关节施加力:

$ rosservice call /gazebo/apply_joint_effort "joint_name: 'joint2'
effort: 10.0
start_time:
  secs: 0
  nsecs: 0
duration:
  secs: 10
  nsecs: 0"

要清除针对特定关节的关节运动,调用服务:

$ rosservice call /gazebo/clear_joint_forces '{joint_name: joint2}'

八、服务——仿真控制

1、服务列表

  • ~/pause_physics : std_srvs/Empty,暂停物理更新。
  • ~/unpause_physics : std_srvs/Empty,恢复物理更新。
  • ~/reset_simulation : std_srvs/Empty,重置整个模拟,包括时间。
  • ~/reset_world : std_srvs/Empty,重置模型的姿态。

2、暂停和取消暂停物理引擎

假设您想获得汽水罐在空中飞行的良好屏幕截图。您可以通过调用以下命令来暂停物理引擎:

$ rosservice call gazebo/pause_physics

暂停仿真后,仿真时间将停止,并且对象将变为静态。但是,gazebo的内部更新循环(例如自定义动态插件更新)仍在运行,但是鉴于仿真时间没有改变,因此任何受仿真时间限制的内容都不会更新。要恢复仿真,请通过调用以下命令取消暂停物理引擎:

$ rosservice call gazebo/unpause_physics