最近打算自己完成一个无人驾驶汽车仿真运行的项目,因此记录一下过程,希望能帮助到需要搭建ROS仿真环境的人,主要参考了冰达机器人的课程,在B站上也有相关视频可以学习
实现过程
1.创建工作区
2.gazebo 绘制地图,并保存为 .world 文件
3.urdf 小车模型和 xacro 小车模型
4.ros 运行地图和小车模型
5.查看传感器数据
一、创建工作区
mkdir -p ~/catkin_ws/src/tutorials // 创建文件夹
cd ~/catkin_ws/src/tutorials
mkdir launch // 存放 launch 文件
mkdir urdf // 存放小车模型文件
mkdir world // 存放地图文件
一个简单的工作区就创建好了,后续再一步步往里面添加文件
二、gazebo绘制地图
1.打开gazebo
sudo gazebo // 打开gazebo,后续保存文件可能需要管理员权限
2.进入编辑界面
3.点击 wall 后可绘制墙壁
4.点击 Add Texture 可修改墙壁纹理
5.点击 file 的 save as 保存模型文件
6.选择保存名称和保存位置
7.点击模型,通过 pose 修改模型位置
8.通过 insert 可添加其他模型
9.地图绘制好后,保存为 .world 地图文件(文件后缀名一定要是 .world)
10.将 .world 文件复制到 ~/catkin_ws/src/world 文件夹内,地图环境就搭建好了
三、小车模型
小车模型通常有两种,一种是 urdf,一种是 sacro,两种都有差不多,定义也是有固定模板,因此这里直接放两种模型的代码
1.urdf 小车模型文件1:myrot.urdf,具体内容如下:
<?xml version="1.0"?><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>
上述小车模型文件没有传感器配置!
2.xacro小车模型文件分为两部分,分别为 myrot.xacro 和 myrot.gazebo.xacro ,具体内容如下:
myrot.xacro:
<?xml version="1.0"?><robot name="mybot"xmlns:xacro="http://ros.org/wiki/xacro"><xacro:include filename="$(find tutorials)/urdf/mybot.gazebo.xacro"/><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><!-- imu sensor --><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><!-- camera --><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><!-- laser lidar --><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>
myrot.gazebo.xacro:
<?xml version="1.0"?><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/DarkGrey</material></gazebo><gazebo reference="left_wheel_link"><mu1>0.5</mu1><mu2>0.5</mu2><kp>500000.0</kp><kd>10.0</kd><minDepth>0.001</minDepth><maxVel>1.0</maxVel><fdir1>100</fdir1><material>Gazebo/DarkGrey</material></gazebo><gazebo reference="right_wheel_link"><mu1>0.5</mu1><mu2>0.5</mu2><kp>500000.0</kp><kd>10.0</kd><minDepth>0.001</minDepth><maxVel>1.0</maxVel><fdir1>100</fdir1><material>Gazebo/FlatBlack</material></gazebo><gazebo reference="ball_wheel_link"><mu1>0.1</mu1><mu2>0.1</mu2><kp>500000.0</kp><kd>100.0</kd><minDepth>0.001</minDepth><maxVel>1.0</maxVel><material>Gazebo/FlatBlack</material></gazebo><gazebo reference="imu"><sensor type="imu" name="imu"><always_on>true</always_on><visualize>$(arg imu_visual)</visualize></sensor><material>Gazebo/FlatBlack</material></gazebo><gazebo><plugin name="mybot_controller" filename="libgazebo_ros_diff_drive.so"><commandTopic>cmd_vel</commandTopic><odometryTopic>odom</odometryTopic><odometryFrame>odom</odometryFrame><odometrySource>world</odometrySource><publishOdomTF>true</publishOdomTF><robotBaseFrame>base_footprint</robotBaseFrame><publishWheelTF>false</publishWheelTF><publishTf>true</publishTf><publishWheelJointState>true</publishWheelJointState><legacyMode>false</legacyMode><updateRate>30</updateRate><leftJoint>left_wheel_joint</leftJoint><rightJoint>right_wheel_joint</rightJoint><wheelSeparation>0.180</wheelSeparation><wheelDiameter>0.05</wheelDiameter><wheelAcceleration>10</wheelAcceleration><wheelTorque>100</wheelTorque><rosDebugLevel>na</rosDebugLevel></plugin></gazebo><gazebo><plugin name="imu_plugin" filename="libgazebo_ros_imu.so"><alwaysOn>true</alwaysOn><bodyName>imu</bodyName><frameName>imu</frameName><topicName>imu</topicName><serviceName>imu_service</serviceName><gaussianNoise>0.0</gaussianNoise><updateRate>0</updateRate><imu><noise><type>gaussian</type><rate><mean>0.0</mean><stddev>2e-4</stddev><bias_mean>0.0000075</bias_mean><bias_stddev>0.0000008</bias_stddev></rate><accel><mean>0.0</mean><stddev>1.7e-2</stddev><bias_mean>0.1</bias_mean><bias_stddev>0.001</bias_stddev></accel></noise></imu></plugin></gazebo><gazebo reference="base_laser_link"><material>Gazebo/FlatBlack</material><sensor type="ray" name="rplidar_sensor"><pose>000000</pose><visualize>$(arg laser_visual)</visualize><update_rate>7</update_rate><ray><scan><horizontal><samples>720</samples><resolution>0.5</resolution><min_angle>0.0</min_angle><max_angle>6.28319</max_angle></horizontal></scan><range><min>0.120</min><max>12.0</max><resolution>0.015</resolution></range><noise><type>gaussian</type><mean>0.0</mean><stddev>0.01</stddev></noise></ray><plugin name="gazebo_ros_rplidar_controller" filename="libgazebo_ros_laser.so"><topicName>scan</topicName><frameName>base_laser_link</frameName></plugin></sensor></gazebo><gazebo reference="base_camera_link"><sensor type="camera" name="csi Camera"><always_on>true</always_on><visualize>$(arg camera_visual)</visualize><camera><horizontal_fov>1.085595</horizontal_fov><image><width>640</width><height>480</height><format>R8G8B8</format></image><clip><near>0.03</near><far>100</far></clip></camera><plugin name="camera_controller" filename="libgazebo_ros_camera.so"><alwaysOn>true</alwaysOn><updateRate>30.0</updateRate><cameraName>/</cameraName><frameName>base_camera_link</frameName><imageTopicName>image_raw</imageTopicName><cameraInfoTopicName>camera_info</cameraInfoTopicName><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>
3.将小车模型文件 myrot.xacro 和 myrot.gazebo.xacro 放到 ~/catkin_ws/src/tutorials/urdf/ 文件夹下
四、ROS 运行环境和小车模型
1.编写 .launch 文件,放到 ~/catkin/src/tutorials/launch 文件夹
gazebo_world.launch:
<launch><include file="$(find gazebo_ros)/launch/empty_world.launch"><arg name="world_name" value="$(find tutorials)/world/room.world"/>// 注意这里是你的地图文件名<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>
simulation_robot.launch:
<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 tutorials)/launch/gazebo_world.launch"/><param name="robot_description" command="$(find xacro)/xacro --inorder $(find 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>
2.编写 CMakeLists.txt 和 package.xml 文件
CMakeLists.txt:
cmake_minimum_required(VERSION2.8.3)project(tutorials)find_package(catkin REQUIREDCOMPONENTS)
package.xml:
<?xml version="1.0"?><package format="2"><name>tutorials</name><version>0.0.0</version><description>The tutorials package</description><maintainer email="[email protected]">nanorobot</maintainer><license>TODO</license></package>
3.编写好后,放在 ~/catkin_ws/src/tutorials 文件夹下
4.在 ~/catkin_ws 文件夹下 catkin 编译
catkin build
5.不要忘了 source 一下,否则会报错
source devel/setup.bash
6.运行 launch 文件
roslaunch tutorials simulation_robot.launch
7.运行结果如图:
到这里你的仿真环境和小车都已经搭建完成啦!
五、查看传感器数据
1.首先可以在终端通过 rostopic list 查看 ros 节点数据,我的结果如下
/camera_info
/clock
/cmd_vel
/gazebo/link_states
/gazebo/model_states
/gazebo/parameter_descriptions
/gazebo/parameter_updates
/gazebo/set_link_state
/gazebo/set_model_state
/image_raw // 图像传感器数据节点/image_raw/compressed
/image_raw/compressed/parameter_descriptions
/image_raw/compressed/parameter_updates
/image_raw/compressedDepth
/image_raw/compressedDepth/parameter_descriptions
/image_raw/compressedDepth/parameter_updates
/image_raw/theora
/image_raw/theora/parameter_descriptions
/image_raw/theora/parameter_updates
/imu
/joint_states
/odom
/parameter_descriptions
/parameter_updates
/rosout
/rosout_agg
/scan // 激光传感器数据节点/tf
/tf_static
2.然后通过 rviz 可视化查看数据,终端输入 rviz 进入如下界面:
3.修改 frame 为 odom,点击 Add,添加 TF、RobotModel、LaserScan、Image
4.添加后如图所示:
5.修改 LaserScan 和 Image 的 Topic 为 ros 节点的输出,分别为 /Scan 和 /Image_raw,显示结果如图:
至此完成了基于 gazebo 的环境和小车仿真
再次推荐大家去B站观看视频学习,本博客内容大部分参考冰达机器人的B站视频,视频链接如下:
版权归原作者 凯凯王1998 所有, 如有侵权,请联系我们删除。