最近在搞p3at,因此下载了p3at的urdf模型,并在其中加入了激光雷达插件、imu插件等等。

然后想用现成的gmapping跑跑建图。期间遇到了无数个坑,特此记录。

(一)gmapping的下载

直接使用

sudo install ros-melodic-.......

是一定会报错的。。。很奇怪。报错内容大致为[slam_gmapping-2] process has died可能是因为ubuntu自带的gmapping版本很旧。

解决办法:
在工作空间的src下:

git clone https://github.com/ros-perception/slam_gmapping
git clone https://github.com/ros-perception/openslam_gmapping

将openslam_gmapping/include/gmapping/scanmatcher/scanmatcher.h中做如下更改:

//#define LASER_MAXBEAMS 2048
#define LASER_MAXBEAMS 4096

然后再在工作空间下catkin_make编译。

如果想把他替换之前安装的可执行文件进行如下操作:

cd /opt/ros/melodic/lib/gmapping
sudo rm slam_gmapping
sudo rm slam_gmapping_replay

拷贝重新编译的可执行文件:

cd ~/catkin_ws/devel/lib/gmapping   # 反正就是你自己工作空间下的devel
sudo cp slam_gmapping /opt/ros/melodic/lib/gmapping
sudo cp slam_gmapping_replay /opt/ros/melodic/lib/gmapping

感谢博主:

(二)gmapping参数的设置

我的launch文件(gmapping.launch)如下:

<launch>
    <arg name="scan_topic" default="scan" />
    <arg name="base_frame"  default="base_link"/>  <!--机器人的坐标系 -->
    <arg name="odom_frame"  default="odom"/> <!--世界坐标-->

    <node name="base2laser" pkg="tf" type="static_transform_publisher" args="0 0 0 0 0 0 1 base_link lidar_link 50"/>
    <node pkg="gmapping" type="slam_gmapping" name="simple_gmapping" output="screen" clear_params="true">

        <param name="odom_frame" value="odom"/>
        <param name="base_frame" value="base_link"/>
        <param name="map_frame" value="map" /> <!--***地图坐标系-->
        <param name="map_update_interval" value="1.0"/>
        <!-- Set maxUrange < actual maximum range of the Laser -->
        <param name="maxRange" value="70.5"/>
        <param name="maxUrange" value="69.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="-50.0"/>
        <param name="ymin" value="-50.0"/>
        <param name="xmax" value="50.0"/>
        <param name="ymax" value="50.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>

注意事项:
1 <arg name="scan_topic" default="scan" />代表了gmapping接收的激光为/scan话题
2 必须使用一个static_transform_publisher,否则会报错。并且后面必须设置为:0 0 0 0 0 0 1,后面跟着base_link和激光所在参考link。我一开始设置的是0 0 0 0 0 0 0,竟然报如下错误:

[ERROR] [1584194344.911065094]: Ignoring transform for child_frame_id “lidar_link” from authority “unknown_publisher” because of a nan value in the transform (-nan -nan -nan) (-nan -nan -nan -nan)

20200802更新

后来我发现,是多了一位数字。。。。。手残了,直接删掉最后的1即可——即六个0

其他的参数说明见:

(三)激光话题的适配

由于gmapping只能订阅sensor_msgs/LaserScan类型,但是激光雷达插件发出来的是sensor_msgs/PointCloud2。因此需要进行如下转换:

sensor_msgs/PointCloud2 —> sensor_msgs/LaserScan

这就涉及到一个新的ros包,叫做:pointcloud_to_laserscan

需要在你的工作空间下编译:

cd ~/catkin_ws/src
    git clone https://github.com/ros-perception/pointcloud_to_laserscan.git
     
    cd ~/catkin_ws
    catkin_make

上述参考了:

安装时遇见报错:

Could not find a package configuration file provided by "tf2_sensor_msgs"

则需要:

sudo apt-get install ros-melodic-tf2-sensor-msgs

然后在你的launch文件中加入如下代码以启动此节点:

<node pkg="pointcloud_to_laserscan" type="pointcloud_to_laserscan_node" 
         name="pointcloud_to_laserscan">
 <remap from="cloud_in" to="/scan1"/> 
 
 <rosparam>
     transform_tolerance: 0.01
     min_height: 0.4
     max_height: 0.5
 
     angle_min: -3.1415926
     angle_max: 3.1415926 
     angle_increment: 0.003 
     range_min: 0.2
     range_max: 5000000
     use_inf: true
     inf_epsilon: 1.0
     concurrency_level: 1
 </rosparam>
</node>

由于我在urdf中设置了激光雷达输出话题为scan1,如下:

ROS安装KVM ros安装gmapping_工作空间


因此需要<remap from="cloud_in" to="/scan1"/> 使得scan1被节点调用。此外要注意,激光雷达输出的话题不能设置为scan,因为pointcloud_to_laserscan节点输出的就是scan话题。

下面的参数中,最重要的参数为:

min_height: 0.4
    max_height: 0.5

相当于截取这两者高度之间的点云,从而实现3d点云到2d点云的转换。设置不当,将看不到点云,或看到很奇怪的点云。echo话题时候容易出现inf:

ROS安装KVM ros安装gmapping_激光雷达_02


这个高度设置就按照你激光雷达的安装高度对应即可。(强调!

其他参数设置见:http://wiki.ros.org/pointcloud_to_laserscan

最终效果:

ROS安装KVM ros安装gmapping_工作空间_03