机器人模型添加Gazebo属性
使用xacro设计的机器人URDF模型已经描述了机器人的外观特征和物理特性,虽然已经具备在Gazebo中仿真的基本条件,但是,由于没有在模型中加入Gazebo的相关属性,还是无法让模型在Gazebo仿真环境中动起来。那么如何开始仿真呢?
首先我们需要确保每个link的元素已经进行了合理的设置,然后要为每个必要的、、设置标签。标签是URDF模型中描述gazebo仿真时所需要的扩展属性。
添加Gazebo属性之后的模型文件放置在本书配套源码mrobot_gazebo功能包的urdf文件夹下,以区别于mrobot_description中的URDF模型。
1.为link添加标签
针对机器人模型,需要对每一个link添加标签,包含的属性仅有material。material 属性的作用与link里中material属性的作用相同,Gazebo无法通过中的material参数设置外观颜色,所以需要单独设置,否则默认情况下Gazebo中显示的模型全是灰白色。
以base_link为例,标签的内容如下:
<gazebo reference="wheel_${lr}_link">
<material>Gazebo/Black</material>
</gazebo>
2.添加传动装置
我们的机器人模型是一个两轮差速驱动的机器人,通过调节两个轮子的速度比例,完成前
进、转向、倒退等动作。火车跑得快,全靠车头带,在之前的模型中,并没有加入驱动机器人
运动的动力源,这当然是仿真必不可少的部分。
为了使用ROS控制器驱动机器人,需要在模型中加入元素,将传动装置与
joint绑定:
<transmission name="wheel_${lr}_joint_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="base_to_wheel_${lr}_joint" />
<actuator name="wheel_${lr}_joint_motor">
<hardwareInterface>VelocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
以上代码中,定义了将要绑定驱动器的joint,标签声明了所使用的传
动装置类型,定义了硬件接口的类型,这里使用的是速度控制接口。
到现在为止,机器人还是一个静态显示的模型,如果要让它动起来,还需要使用Gazebo插
件。Gazebo插件赋予了URDF模型更加强大的功能,可以帮助模型绑定ROS消息,从而完成传
感器的仿真输出以及对电机的控制,让机器人模型更加真实。
3.添加Gazebo控制器插件
Gazebo插件可以根据插件的作用范围应用到URDF模型的robot>、link>、joint>上,需要使用标签作为封装。
(1)为元素添加插件
为元素添加Gazebo插件的方式如下:
<gazebo>
<plugin name="unique_name" filename="plugin_name.so">
... plugin parameters ...
</plugin>
</gazebo>
(2)为、标签添加插件
如果需要为、标签添加插件,则需要设置标签中的reference="x"属性:
<gazebo reference="your_link_name">
<plugin name=" unique_name " filename="plugin_name.so">
... plugin parameters ...
</plugin>
</gazebo>
至于Gazebo目前支持的插件种类,可以查看ROS默认安装路径下的/opt/ros/kinetic/lib文件夹,所有插件都是以libgazeboXXX.so的形式命名的。
Gazebo已经提供了一个用于差速控制的插件libgazebo_ros_diff_drive.so,可以将其应用到现有的机器人模型上。在mrobot_gazebo/urdf/mrobot_body.urdf.xacro文件中添加如下插件声明:
<!-- controller -->
<gazebo>
<plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
<rosDebugLevel>Debug</rosDebugLevel>
<publishWheelTF>true</publishWheelTF>
<robotNamespace>/</robotNamespace>
<publishTf>1</publishTf>
<publishWheelJointState>true</publishWheelJointState>
<alwaysOn>true</alwaysOn>
<updateRate>100.0</updateRate>
<legacyMode>true</legacyMode>
<leftJoint>base_to_wheel_left_joint</leftJoint>
<rightJoint>base_to_wheel_right_joint</rightJoint>
<wheelSeparation>${base_link_radius*2}</wheelSeparation>
<wheelDiameter>${2*wheel_radius}</wheelDiameter>
<broadcastTF>1</broadcastTF>
<wheelTorque>30</wheelTorque>
<wheelAcceleration>1.8</wheelAcceleration>
<commandTopic>cmd_vel</commandTopic>
<odometryFrame>odom</odometryFrame>
<odometryTopic>odom</odometryTopic>
<robotBaseFrame>base_footprint</robotBaseFrame>
</plugin>
</gazebo>
在加载差速控制器插件的过程中,需要配置一系列参数,其中比较关键的参数如下。
robotNamespace
:机器人的命名空间,插件所有数据的发布、订阅都在该命名空间下。leftJoint
>和rightJoint
>:左右轮转动的关节joint,控制器插件最终需要控制这两个joint转
动。wheelSeparation
>和-wheelDiameter
>:这是机器人模型的相关尺寸,在计算差速参数时需
要用到。wheelAcceleration
>:车轮转动的加速度。commandTopic
>:控制器订阅的速度控制指令,ROS中一般都命名为cmd_vel,生成全局
命名时需要结合中设置的命名空间。odometryFrame
>:里程计数据的参考坐标系,ROS中一般都命名为odom。
在Gazebo中显示机器人模型
创建一个启动文件robot_mrobot/mrobot_gazebo/view_mrobot_gazebo.launch,运行Gazebo,加载机器人模型,并且启动一些必要的节点:
<launch>
<!-- 设置launch文件的参数 -->
<arg name="world_name" value="$(find mrobot_gazebo)/worlds/playground.world"/>
<arg name="paused" default="false"/>
<arg name="use_sim_time" default="true"/>
<arg name="gui" default="true"/>
<arg name="headless" default="false"/>
<arg name="debug" default="false"/>
<!-- 运行Gazebo仿真环境 -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(arg world_name)" />
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
<arg name="paused" value="$(arg paused)"/>
<arg name="use_sim_time" value="$(arg use_sim_time)"/>
<arg name="headless" value="$(arg headless)"/>
</include>
<!-- 加载机器人模型描述参数 -->
<param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mrobot_gazebo)/urdf/mrobot.urdf.xacro'" />
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node>
<!-- 运行robot_state_publisher节点,发布TF -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" >
<param name="publish_frequency" type="double" value="50.0" />
</node>
<!-- 在gazebo中加载机器人模型-->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn= "false" output="screen"
args="-urdf -model mrobot -param robot_description"/>
</launch>
以上launch文件主要做了两项工作:
1)启动机器人的状态发布节点,同时加载带有Gazebo属性的机器人URDF模型。
2)启动Gazebo,并且将机器人模型加载到Gazebo仿真环境中。
现在,启动这个launch文件,如果一切正常,应该可以看到如图所示的界面,机器人模型已经加载进入仿真环境中。
roslaunch mrobot_gazebo view_mrobot_gazebo.launch
控制机器人在Gazebo中运动
机器人模型中已经加入了libgazebo_ros_diff_drive.so插件,可以使用差速控制器实现机器人运动。查看系统当前的话题列表
rostopic list
Gazebo仿真中已经开始订阅cmd_vel话题了。接下来可以运行键盘控制节点,发布该话题的速度控制消息,机器人就会在Gazebo中开始运动了
roslaunch mrobot_teleop mrobot_teleop.launch
当机器人在仿真环境中撞到障碍物时,会根据两者的物理属性决定机器人是否反弹,或者障碍物是否会被推动,这也证明了Gazebo是一种贴近真实环境的物理仿真平台。
摄像头仿真
在之前rviz+ArbotiX搭建的机器人仿真环境中,机器人装配了多种传感器模型,但是这些模型并无法获取任何环境数据。Gazebo的强大之处还在于提供了一系列传感器插件,可以帮助我们仿真传感器数据,获取Gazebo虚拟环境中的传感信息。
首先为机器人模型添加一个摄像头插件,让机器人看到Gazebo中的虚拟世界。
1.为摄像头模型添加Gazebo插件
类似于机器人模型中的差速控制器插件,传感器的Gazebo插件也需要在URDF模型中配置。复制mrobot_description中的传感器模型到mrobot_gazebo包中,然后在摄像头的模型文件
mrobot_gazebo/urdf/camera.xacro中添加的相关标签,代码如下:
<gazebo reference="${prefix}_link">
<material>Gazebo/Black</material>
</gazebo>
<gazebo reference="${prefix}_link">
<sensor type="camera" name="camera_node">
<update_rate>30.0</update_rate>
<camera name="head">
<horizontal_fov>1.3962634</horizontal_fov>
<image>
<width>1280</width>
<height>720</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.02</near>
<far>300</far>
</clip>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.007</stddev>
</noise>
</camera>
<plugin name="gazebo_camera" filename="libgazebo_ros_camera.so">
<alwaysOn>true</alwaysOn>
<updateRate>0.0</updateRate>
<cameraName>/camera</cameraName>
<imageTopicName>image_raw</imageTopicName>
<cameraInfoTopicName>camera_info</cameraInfoTopicName>
<frameName>camera_link</frameName>
<hackBaseline>0.07</hackBaseline>
<distortionK1>0.0</distortionK1>
<distortionK2>0.0</distortionK2>
<distortionK3>0.0</distortionK3>
<distortionT1>0.0</distortionT1>
<distortionT2>0.0</distortionT2>
</plugin>
</sensor>
</gazebo>
新的摄像头模型文件在模型描述部分没有变化,只需要加入两个gazebo 标签。
第一个gazebo 标签用来设置摄像头模型在Gazebo中的material,与机器人模型的配置相似,只需要设置颜色参数。
重点是第二个设置摄像头插件的 gazebo>标签。在加载传感器插件时,需要使用 sensor> 标签来包含传感器的各种属性。
例如现在使用的是摄像头传感器,需要设置type为camera,传 感器的命名(name)可以自由设置;然后使用 camera>标签具体描述摄像头的参数,包括分辨率、编码格式、图像范围、噪音参数等;最后需要使用 plugin>标签加载摄像头的插件 libgazebo_ros_camera.so,同时设置插件的参数,包括命名空间、发布图像的话题、参考坐标系 等。
2.运行仿真环境
现在摄像头插件已经配置完成,使用如下命令启动仿真环境,并加载装配了摄像头的机器人模型:
roslaunch mrobot_gazebo view_mrobot_with_camera_gazebo.launch
启动成功后,可以看到机器人已经在仿真环境中就位了,如图
查看当前系统中的话题列表
从上图发布的话题中可以看到摄像头已经开始发布图像消息了,使用rqt工具查看当前机器人眼前的世界:
rqt_image_view
选择仿真摄像头发布的图像话题/camera/image_raw,即可看到如图所示的图像信息。