参考视频教程:《70分钟快速入门Gazebo机器人仿真》。
实验用功能包:
git clone https://gitee.com/bingda-robot/bingda_tutorials
git clone https://gitee.com/bingda-robot/gazebo_models
clone结束以后找到/home/.gazebo,里面有个models,需要把刚才下载的文件放进去。
这一步可能遇到的问题:Gazebo有时无法弹出文件管理器,这时候最小化一下再打开就好了。但我用物理机装ubuntu20.04和noetic没发现这个问题,猜测可能和虚拟机有关。
<launch>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find bingda_tutorials)/world/myroom"/>
<arg name="paused" value="false"/>
<arg name="use_sim_time" value="true"/>
<arg name="gui" value="true"/>
<arg name="headless" value="false"/>
<arg name="debug" value="false"/>
include>
launch>
<robot name="mybot">
<link name="base_footprint"/>
<joint name="base_joint" type="fixed">
<parent link="base_footprint"/>
<child link="base_link"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
joint>
<link name="base_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.001" />
inertial>
<visual>
<geometry>
<box size="0.25 0.16 0.05"/>
geometry>
<origin rpy="0 0 0" xyz="0 0 0"/>
<material name="blue">
<color rgba="0 0 0.8 1"/>
material>
visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="0.25 0.16 0.05"/>
geometry>
collision>
link>
<link name="right_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001" />
inertial>
<visual>
<geometry>
<cylinder length="0.02" radius="0.025"/>
geometry>
<material name="black">
<color rgba="0 0 0 1"/>
material>
visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="0.02" radius="0.025"/>
geometry>
collision>
link>
<joint name="right_wheel_joint" type="continuous">
<axis xyz="0 0 -1"/>
<parent link="base_link"/>
<child link="right_wheel_link"/>
<origin rpy="1.5707 0 0" xyz=" 0.1 -0.09 -0.03"/>
joint>
<link name="left_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001" />
inertial>
<visual>
<geometry>
<cylinder length="0.02" radius="0.025"/>
geometry>
<material name="black">
<color rgba="0 0 0 1"/>
material>
visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="0.02" radius="0.025"/>
geometry>
collision>
link>
<joint name="left_wheel_joint" type="continuous">
<axis xyz="0 0 -1"/>
<parent link="base_link"/>
<child link="left_wheel_link"/>
<origin rpy="1.5707 0 0" xyz="0.1 0.09 -0.03"/>
joint>
<link name="ball_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0" />
inertial>
<visual>
<geometry>
<sphere radius="0.025"/>
geometry>
<material name="black">
<color rgba="0 0 0 1"/>
material>
visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.025"/>
geometry>
collision>
link>
<joint name="ball_wheel_joint" type="fixed">
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="ball_wheel_link"/>
<origin rpy="0 0 0" xyz="-0.10 0 -0.03"/>
joint>
robot>
可以运行check_urdf来检查
首先要cd到存放urdf的目录下
check_urdf yoururdf.urdf
此处可能提示找不到命令,安装一下工具即可
sudo apt install liburdfdom-tools
成功运行以后应该显示出link情况
同样可以用launch文件来使用它,下面的指令用于在rviz中观察
roslaunch bingda_tutorials display_robot.launch
同样,gazebo中启动也需要用到launch文件
<launch>
<include file="$(find bingda_tutorials)/launch/gazebo_world.launch"/>
<node name="spawn_model" pkg="gazebo_ros" type="spawn_model" args="-file $(find bingda_tutorials)/urdf/mybot.urdf -urdf -model robot_description" output="screen" />
launch>
xacro文件是urdf文件的一种补充和完善
示例的xacro文件与urdf文件主要不同如下
<link name="imu">
<visual>
<geometry>
<box size="0.01 0.01 0.01"/>
geometry>
<material name="white">
<color rgba="1 1 1 1"/>
material>
visual>
link>
<joint name="imu_joint" type="fixed">
<parent link="base_link"/>
<child link="imu"/>
<origin xyz="0.08 0 0.025"/>
joint>
<link name="base_camera_link">
<visual>
<geometry>
<box size="0.02 0.03 0.03"/>
geometry>
<material name="white">
<color rgba="1 1 1 1"/>
material>
visual>
link>
<joint name="camera_joint" type="fixed">
<parent link="base_link"/>
<child link="base_camera_link"/>
<origin xyz="0.1 0 0.025"/>
joint>
<link name="base_laser_link">
<visual>
<geometry>
<cylinder length="0.06" radius="0.04"/>
geometry>
<material name="white">
<color rgba="1 1 1 1"/>
material>
visual>
link>
<joint name="laser_joint" type="fixed">
<parent link="base_link"/>
<child link="base_laser_link"/>
<origin xyz="0 0.0 0.06"/>
joint>
<robot name="mybot" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:include filename="$(find bingda_tutorials)/urdf/mybot.gazebo.xacro" />
最好把模型xacro文件和仿真相关的文件分开,这样可以提高我们的代码的复用性
关于gazebo仿真的xacro文件
Tutorial: Using a URDF in Gazebo 这个连接详细讲解了标签的用法和含义
Tutorial: Using Gazebo plugins with ROS 传感器和雷达要使用plugin的方式插入
<robot name="mybot" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:arg name="laser_visual" default="false"/>
<xacro:arg name="camera_visual" default="false"/>
<xacro:arg name="imu_visual" default="false"/>
<gazebo reference="base_link">
<material>Gazebo/DarkGreymaterial>
gazebo>
<gazebo reference="left_wheel_link">
<mu1>0.5mu1>
<mu2>0.5mu2>
<kp>500000.0kp>
<kd>10.0kd>
<minDepth>0.001minDepth>
<maxVel>1.0maxVel>
<fdir1>1 0 0fdir1>
<material>Gazebo/DarkGreymaterial>
gazebo>
<gazebo reference="right_wheel_link">
<mu1>0.5mu1>
<mu2>0.5mu2>
<kp>500000.0kp>
<kd>10.0kd>
<minDepth>0.001minDepth>
<maxVel>1.0maxVel>
<fdir1>1 0 0fdir1>
<material>Gazebo/FlatBlackmaterial>
gazebo>
<gazebo reference="ball_wheel_link">
<mu1>0.1mu1>
<mu2>0.1mu2>
<kp>500000.0kp>
<kd>100.0kd>
<minDepth>0.001minDepth>
<maxVel>1.0maxVel>
<material>Gazebo/FlatBlackmaterial>
gazebo>
<gazebo reference="imu">
<sensor type="imu" name="imu">
<always_on>truealways_on>
<visualize>$(arg imu_visual)visualize>
sensor>
<material>Gazebo/FlatBlackmaterial>
gazebo>
<gazebo>
<plugin name="mybot_controller" filename="libgazebo_ros_diff_drive.so">
<commandTopic>cmd_velcommandTopic>
<odometryTopic>odomodometryTopic>
<odometryFrame>odomodometryFrame>
<odometrySource>worldodometrySource>
<publishOdomTF>truepublishOdomTF>
<robotBaseFrame>base_footprintrobotBaseFrame>
<publishWheelTF>falsepublishWheelTF>
<publishTf>truepublishTf>
<publishWheelJointState>truepublishWheelJointState>
<legacyMode>falselegacyMode>
<updateRate>30updateRate>
<leftJoint>left_wheel_jointleftJoint>
<rightJoint>right_wheel_jointrightJoint>
<wheelSeparation>0.180wheelSeparation>
<wheelDiameter>0.05wheelDiameter>
<wheelAcceleration>10wheelAcceleration>
<wheelTorque>100wheelTorque>
<rosDebugLevel>narosDebugLevel>
plugin>
gazebo>
<gazebo>
<plugin name="imu_plugin" filename="libgazebo_ros_imu.so">
<alwaysOn>truealwaysOn>
<bodyName>imubodyName>
<frameName>imuframeName>
<topicName>imutopicName>
<serviceName>imu_serviceserviceName>
<gaussianNoise>0.0gaussianNoise>
<updateRate>0updateRate>
<imu>
<noise>
<type>gaussiantype>
<rate>
<mean>0.0mean>
<stddev>2e-4stddev>
<bias_mean>0.0000075bias_mean>
<bias_stddev>0.0000008bias_stddev>
rate>
<accel>
<mean>0.0mean>
<stddev>1.7e-2stddev>
<bias_mean>0.1bias_mean>
<bias_stddev>0.001bias_stddev>
accel>
noise>
imu>
plugin>
gazebo>
<gazebo reference="base_laser_link">
<material>Gazebo/FlatBlackmaterial>
<sensor type="ray" name="rplidar_sensor">
<pose>0 0 0 0 0 0pose>
<visualize>$(arg laser_visual)visualize>
<update_rate>7update_rate>
<ray>
<scan>
<horizontal>
<samples>720samples>
<resolution>0.5resolution>
<min_angle>0.0min_angle>
<max_angle>6.28319max_angle>
horizontal>
scan>
<range>
<min>0.120min>
<max>12.0max>
<resolution>0.015resolution>
range>
<noise>
<type>gaussiantype>
<mean>0.0mean>
<stddev>0.01stddev>
noise>
ray>
<plugin name="gazebo_ros_rplidar_controller" filename="libgazebo_ros_laser.so">
<topicName>scantopicName>
<frameName>base_laser_linkframeName>
plugin>
sensor>
gazebo>
<gazebo reference="base_camera_link">
<sensor type="camera" name="csi Camera">
<always_on>truealways_on>
<visualize>$(arg camera_visual)visualize>
<camera>
<horizontal_fov>1.085595horizontal_fov>
<image>
<width>640width>
<height>480height>
<format>R8G8B8format>
image>
<clip>
<near>0.03near>
<far>100far>
clip>
camera>
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
<alwaysOn>truealwaysOn>
<updateRate>30.0updateRate>
<cameraName>/cameraName>
<frameName>base_camera_linkframeName>
<imageTopicName>image_rawimageTopicName>
<cameraInfoTopicName>camera_infocameraInfoTopicName>
<hackBaseline>0.07hackBaseline>
<distortionK1>0.0distortionK1>
<distortionK2>0.0distortionK2>
<distortionK3>0.0distortionK3>
<distortionT1>0.0distortionT1>
<distortionT2>0.0distortionT2>
plugin>
sensor>
gazebo>
robot>
启动文件
<launch>
<arg name="x_pos" default="0.0"/>
<arg name="y_pos" default="0.0"/>
<arg name="z_pos" default="0.0"/>
<param name="/use_sim_time" value="true" />
<include file="$(find bingda_tutorials)/launch/gazebo_world.launch"/>
<param name="robot_description" command="$(find xacro)/xacro --inorder $(find bingda_tutorials)/urdf/mybot.xacro" />
<node pkg="gazebo_ros" type="spawn_model" name="spawn_urdf" args="-urdf -model mybot.xacro -x $(arg x_pos) -y $(arg y_pos) -z $(arg z_pos) -param robot_description" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
launch>