gazebo是一款机器人模拟软件,能在电脑中实现较为逼真的环境仿真并有较真实的物理引擎,可以达到简单的模拟任务。我们接下来直接实现一串用的比较多的代码。
要包括以下几个功能包:gazebo_plugins,gazebo_ros,gazebo_ros_control,urdf,xacro
先在src文件夹下创建多个文件夹:launch,urdf/gazebo,worlds(调用环境配置,在主文件夹下的sim_deno1中,我们把box_house.world复制到worlds文件夹下)
我们先写一份总体的集合文件car.xacro,来一次性调用所有子文件。用到的是xacro:include代码
<robot name="practice_robot" xmlns:xacro="http://wiki.ros.org/xacro" >
<xacro:include filename="head.xacro" />
<xacro:include filename="demo03_practice.xacro" />
<xacro:include filename="demo05_camera.xacro" />
<xacro:include filename="demo06_laser.xacro" />
<xacro:include filename="gazebo/move.xacro" />
<xacro:include filename="gazebo/laser.xacro" />
<xacro:include filename="gazebo/camera.xacro" />
<xacro:include filename="gazebo/kinect.xacro" />
</robot>
再编写head.xacro头文件文件提供各种形状的几何量
<robot name="base" xmlns:xacro="http://wiki.ros.org/xacro" >
<!-- Macro for inertia matrix __sphere -->
<xacro:macro name="sphere_inertial_matrix" params="m r">
<inertial>
<mass value="${m}" />
<inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
iyy="${2*m*r*r/5}" iyz="0"
izz="${2*m*r*r/5}" />
</inertial>
</xacro:macro>
<!-- Macro for inertia matrix __cylinder -->
<xacro:macro name="cylinder_inertial_matrix" params="m r h">
<inertial>
<mass value="${m}" />
<inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"
iyy="${m*(3*r*r+h*h)/12}" iyz = "0"
izz="${m*r*r/2}" />
</inertial>
</xacro:macro>
<!-- Macro for inertia matrix __square -->
<xacro:macro name="box_inertial_matrix" params="m l w h">
<inertial>
<mass value="${m}" />
<inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0"
iyy="${m*(w*w + l*l)/12}" iyz= "0"
izz="${m*(w*w + h*h)/12}" />
</inertial>
</xacro:macro>
</robot>
我们接下来添加之前编写的车体文件demo03_practice.xacro和其他附件文件demo05_camera.xacro以及demo06_laser.xacro(符合要求,直接复制过来调用即可,最好放在本文件夹下)
我们接下来在gazebo文件夹下编写第一个控制运动的move.xacro文件:
<robot name="my_car_move" xmlns:xacro="http://wiki.ros.org/xacro" >
<!-- conbine controller and joint -->
<xacro:macro name="joint_trans" params="joint_name" >
<transmission name="${joint_name}_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="${joint_name}">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
</joint>
<actuator name="${joint_name}_motor">
<hardwareInterface>hardware_interface/VeocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
</xacro:macro>
<xacro:joint_trans joint_name="left2link" />
<xacro:joint_trans joint_name="right2link" />
<!-- 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>left2link</leftJoint>
<rightJoint>right2link</rightJoint>
<wheelSeparation>${2 * base_radius}</wheelSeparation>
<wheelDiameter>${wheel_radius * 2}</wheelDiameter>
<broadcastTF>1</broadcastTF>
<wheelTorque>30</wheelTorque>
<wheelAcceleration>1.5</wheelAcceleration>
<commandTopic>cmd_vel</commandTopic>
<odometryFrame>odom</odometryFrame>
<odometryTopic>odom</odometryTopic>
<robotBaseFrame>base_footprint</robotBaseFrame>
</plugin>
</gazebo>
</robot>
我们在文件中设置宏(自定义函数)joint_trans,用于连接控制器和关节,解析其参数(主要是内置的文件和函数,简单介绍):
1、调用我们已有的负责坐标转换的文件:transmission_interface/SimpleTransmission
2、在关节中调用含速度控制的硬件接口:hardware_interface/VelocityJointInterface
3、在传动装置actuator中调用硬件接口和减速装置(缓速的加速度):<hardwareInterface>hardware_interface/VeocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
然后我们知道传入两个轮子的名字调用宏。
对于下面的roscontroller控制器:
1、<rosDebugLevel>Debug</rosDebugLevel>设置debug格式
2、<publishWheelTF>true</publishWheelTF>是否发布轮子的tf消息
3、<robotNamespace>/</robotNamespace>调用主文件夹为实现机器人的命名空间
4、<publishTF>1</publishTF>是否发布tf消息
5、<publishWheelJointState>true</publishWheelJointState>是否发布车轮关节的状态消息
6、<alwaysOn>true</alwaysOn> 常开
7、<updateRate>100.0</updateRate> 更新频率
8、<legacyMode>true</legacyMode> 继承状态模式
9、<leftJoint>left2link</leftJoint> 左轮关节
10、<rightJoint>right2link</rightJoint> 右轮关节
11、<wheelSeparation>${2 * base_radius}</wheelSeparation> 两轮距离
12、<wheelDiameter>${wheel_radius * 2}</wheelDiameter> 车轮直径
13、<broadcastTF>1</broadcastTF> tf中发布关节消息
14、<wheelTorque>30</wheelTorque> 车轮扭矩
15、<wheelAcceleration>1.5</wheelAcceleration> 车轮运动的加速度
16、<commandTopic>cmd_vel</commandTopic> 运动控制话题
17、<odometryFrame>odom</odometryFrame> 里程计参考系
18、<odometryTopic>odom</odometryTopic> 里程计话题
19、<robotBaseFrame>base_footprint</robotBaseFrame> 根坐标系
接下来编写激光雷达的laser.xacro文件:
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro" >
<gazebo reference="laser">
<sensor type="ray" name="rplidar">
<pose>0 0 0 0 0 0</pose>
<visualize>true</visualize>
<update_rate>5.5</update_rate>
<ray>
<scan>
<horizontal>
<samples>360</samples>
<resolution>1</resolution>
<min_angle>-3</min_angle>
<max_angle>3</max_angle>
</horizontal>
</scan>
<range>
<min>0.1</min>
<max>30.0</max>
<resolution>0.01</resolution>
</range>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
</ray>
<plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so">
<topicName>/scan</topicName>
<frameName>laser</frameName>
</plugin>
</sensor>
</gazebo>
</robot>
接下来解析代码:
1、<pose>0 0 0 0 0 0</pose> 激光的位姿
2、<visualize>true</visualize> 是否可视化
<scan>
<horizontal>
<samples>360</samples>
<resolution>1</resolution>
<min_angle>-3</min_angle>
<max_angle>3</max_angle>
</horizontal>
</scan>
在ray射线参数下:
设置扫描的参数horizontal中
1、sample旋转一周选取多少采样点
2、resolution分辨率,取值表示n个采样点之间有一个是测距的
3、max/min_angle采样范围(弧度)
<range>
<min>0.1</min>
<max>30.0</max>
<resolution>0.01</resolution>
</range>
range中:
1、min/max测距距离判定(少于0.1m或大于30m采样无效)
2、resolution精确率
<plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so">
<topicName>/scan</topicName>
<frameName>laser</frameName>
</plugin>
设置可调用插件,以供rviz调用
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
设置噪音(误差干扰)参数:
type噪音类型(高斯噪音)
接下来编写照相机的camera.xacro文件
<robot name="my_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<gazebo reference="camera">
<sensor type="camera" name="camera_node">
<update_rate>30</update_rate>
<camera name="head">
<horizontal_fov>1.3962634</horizontal_fov>
<image>
<width>1280</width>
<height>720</height>
<format>R8B8G8</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</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>
</robot>
1、horizontal_fov水平焦距
2、image设置照相机的成像长宽和色彩情况
3、clip拍摄范围[near,far]
接下来编写深度相机的kinect.xacro文件
<robot name="my_kinect" xmlns:xacro="http://wiki.ros.org/xacro" >
<gazebo reference="holder">
<sensor type="depth" name="camera">
<always_on>true</always_on>
<update_rate>20</update_rate>
<camera>
<horizontal_fov>${60.0 * PI / 180.0}</horizontal_fov>
<image>
<width>640</width>
<height>480</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.05</near>
<far>15.0</far>
</clip>
</camera>
<plugin name="kinect_camera_controller" filename="libgazebo_ros_openni_kinect.so">
<cameraName>camera</cameraName>
<alwaysOn>true</alwaysOn>
<updateRate>10</updateRate>
<imageTopicName>rgb/image_raw</imageTopicName>
<depthImageTopicName>depth/image_raw</depthImageTopicName>
<pointCloudTopicName>depth/points</pointCloudTopicName>
<cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName>
<depthImageCameraInfoTopicName>depth/camera_info</depthImageCameraInfoTopicName>
<frameName>holder_depth</frameName>
<baseline>0.1</baseline>
<distortion_k1>0.0</distortion_k1>
<distortion_k2>0.0</distortion_k2>
<distortion_k3>0.0</distortion_k3>
<distortion_t1>0.0</distortion_t1>
<distortion_t2>0.0</distortion_t2>
<pointCloudCutoff>0.4</pointCloudCutoff>
</plugin>
</sensor>
</gazebo>
</robot>
笔者能力有限,暂不作解释力(悲)这个就是官网那个文档复制下来的,照抄即可。
最后我们编写demo03_env.launch文件
<launch>
<!-- load the urdf file into param server -->
<param name="robot_description" command="$(find xacro)/xacro $(find gazebo_urdf)/urdf/car.xacro" />
<!-- start the sim environment -->
<include file="$(find gazebo_ros)/launch/empty_world.launch" >
<arg name="world_name" value="$(find gazebo_urdf)/worlds/box_house.world" />
</include>
<!-- in the gazebo show the robot model -->
<node pkg="gazebo_ros" type="spawn_model" name="spawn_model" args="-urdf -model robot -param robot_description" />
</launch>
然后roslaunch发布即可