1 机器人必备条件
1.1 硬件要求
(1)差分轮式机器人,可使用twist速度指令控制
$ rosmsg show geometry_msgs/Twist geometry_msgs/Vector3 linear # linear:xyz方向上的线速度,单位是m/s; float64 x float64 y float64 z geometry_msgs/Vector3 angular # angular:xyz方向上的角速度,单位是rad/s。 float64 x float64 y float64 z
(2)机器人必须安装激光雷达等测距设备,可以获取环境深度信息。
(3)最好使用正方形和圆形的机器人,其他外形的机器人虽然可以使用但是效果可能不佳。
1.2 深度信息
1.2.1 激光雷达
$ rosmsg show sensor_msgs/LaserScan # 查看激光雷达消息结构 std_msgs/Header header uint32 seq time stamp string frame_id float32 angle_min float32 angle_max float32 angle_increment float32 time_increment float32 scan_time float32 range_min float32 range_max float32[] ranges float32[] intensities angle_min:可检测范围的起始角度; (—180——180度 ) angle_max:可检测范围的终止角度,与angle_min组成激光雷达的可检测范围; angle_increment:相邻数据帧之间的角度步长; time_incremen:采集到相邻数据帧之间的时间步长,当传感器处于相对运动状态时进行补偿使用。 scan_time:采集一帧数据所需要的视觉; rang_min:最近可检测深度的阈值; rang_max:最远可检测深度的阈值; ranges:一帧深度数据的存储数组。 intensities:每个激光点的强度
1.2.2 kinect
Kinect等GRB-D摄像头,也可以通过红外摄像头获取周围环境的深度信息。
depthimage_to_laserscan功能包:将三维点云数据转换为二维激光雷达数据;
<!--depthimage_to_laserscan节点,将点云深度数据转换成激光数据--> <node pkg="depthimage_to_laserscan" type="depthimage_to_laserscan" name="depthimage_to_laserscan" output="screen"> <remap from="image" to="/kinect/depth/image_raw"/> <remap from="camera_info" to=/kinect/depth/camera_info"/> <remap froam="scan" to="/scan"/> <param name="output_frame_id" value="/camera_link"/> </node>
1.3 里程计信息
$ rosmsg show nav_msgs/odometry pose:机器人当前位置坐标,包括机器人的XYZ三轴位置与方向参数,以及用于校正误差的方差矩阵 twist:机器人当前的运动状态,包括XYZ三轴的线速度与角速度,以及用于校正误差的方差矩阵。 注意:ROS中所有的坐标系都是右手坐标系。 ————————————————
1.4 仿真环境
在视频中给出了一个仿真环境:
$ roslaunch mbot_gazebo mbot_laser_nav_gazebo.launch # 启动仿真环境 # 使用Building Editor创建仿真环境cloister.world
2 SLAM功能包的使用方法
论文参考:https://openslam-org.github.io/gmapping.html
2.1 gmapping
2.1.1 gmapping 功能包
基于激光雷达
Rao-Blackwellized 粒子滤波算法
二维栅格地图
需要机器人提供里程计信息
OpenSlam开源算法
输出地图话题:nav_msgs/OccupancyGrid
$ rosmsg show nav_msgs/OccupancyGrid
2.1.2 栅格地图取值原理
2.1.3 gmapping安装
$ sudo apt-get install ros-kinetic-gmapping
2.1.4 配置gmapping节点
参考: http://wiki.ros.org/gmapping
catkin_ws/src/mbot_navigation/launch/gmapping.launch
<launch> <arg name="scan_topic" default="scan" /> <node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen" clear_params="true"> <param name="odom_frame" value="odom"/> <param name="map_update_interval" value="5.0"/> <!-- Set maxUrange < actual maximum range of the Laser --> <param name="maxRange" value="5.0"/> <param name="maxUrange" value="4.5"/> <param name="sigma" value="0.05"/> <param name="kernelSize" value="1"/> <param name="lstep" value="0.05"/> <param name="astep" value="0.05"/> <param name="iterations" value="5"/> <param name="lsigma" value="0.075"/> <param name="ogain" value="3.0"/> <param name="lskip" value="0"/> <param name="srr" value="0.01"/> <param name="srt" value="0.02"/> <param name="str" value="0.01"/> <param name="stt" value="0.02"/> <param name="linearUpdate" value="0.5"/> <param name="angularUpdate" value="0.436"/> <param name="temporalUpdate" value="-1.0"/> <param name="resampleThreshold" value="0.5"/> <param name="particles" value="80"/> <param name="xmin" value="-1.0"/> <param name="ymin" value="-1.0"/> <param name="xmax" value="1.0"/> <param name="ymax" value="1.0"/> <param name="delta" value="0.05"/> <param name="llsamplerange" value="0.01"/> <param name="llsamplestep" value="0.01"/> <param name="lasamplerange" value="0.005"/> <param name="lasamplestep" value="0.005"/> <remap from="scan" to="$(arg scan_topic)"/> </node> </launch>
2.1.5 启动gmapping演示(激光雷达)
分别开启三个终端运行以下命令:
$ roslaunch mbot_gazebo mbot_laser_nav_gazebo.launch # 启动仿真环境 $ roslaunch mbot_navigation gmapping_demo.launch # 启动建图节点,灰色地图建成,黑色障碍物 $ roslaunch mbot_teleop mbot_teleop.launch #启动键盘控制节点
建图完毕,保存地图
$ rosrun map_server map_saver -f cloister_gmapping # cloister_gmapping是文件名的意思,是自己保存文件名的意思 # 保存的路径在当前/home文件夹下,有两个文件.pgm和.yaml
2.1.6 启动gmapping(kinect)
建图效果不佳(不推荐)
$ roslaunch mbot_gazebo mbot_kinect_nav_gazebo.launch $ roslaunch mbot_navigation gmapping_demo.launch $ roslaunch mbot_teleop mbot_teleop.launch
2.2 hector_slam
2.2.1 hector_slam功能包
基于激光雷达
高斯牛顿方法
二维栅格地图
不需要里程计数据
输出地图话题:
nav_msgs/OccupancyGrid
2.2.2 安装hector_slam
$ sudo apt-get install ros-kinetic-hector-slam
2.2.3 配置hector_mapping节点
参数说明可参考:http://wiki.ros.org/hector_slam
catkin_ws/src/mbot_navigation/launch/hector.launch
<launch> <node pkg = "hector_mapping" type="hector_mapping" name="hector_mapping" output="screen"> <!-- Frame names --> <param name="pub_map_odom_transform" value="true"/> <param name="map_frame" value="map" /> <param name="base_frame" value="base_footprint" /> <param name="odom_frame" value="odom" /> <!-- Tf use --> <param name="use_tf_scan_transformation" value="true"/> <param name="use_tf_pose_start_estimate" value="false"/> <!-- Map size / start point --> <param name="map_resolution" value="0.05"/> <param name="map_size" value="2048"/> <param name="map_start_x" value="0.5"/> <param name="map_start_y" value="0.5" /> <param name="laser_z_min_value" value = "-1.0" /> <param name="laser_z_max_value" value = "1.0" /> <param name="map_multi_res_levels" value="2" /> <param name="map_pub_period" value="2" /> <param name="laser_min_dist" value="0.4" /> <param name="laser_max_dist" value="5.5" /> <param name="output_timing" value="false" /> <param name="pub_map_scanmatch_transform" value="true" /> <!-- Map update parameters --> <param name="update_factor_free" value="0.4"/> <param name="update_factor_occupied" value="0.7" /> <param name="map_update_distance_thresh" value="0.2"/> <param name="map_update_angle_thresh" value="0.06" /> <!-- Advertising config --> <param name="advertise_map_service" value="true"/> <param name="scan_subscriber_queue_size" value="5"/> <param name="scan_topic" value="scan"/> </node> </launch>