用数据集跑Hector SLAM(非常详细,尽力了)

  • Post author:
  • Post category:其他


参考链接(根据博主的步骤一次成功):


Hector_slam(数据集)

说明第一点:这个是可以成功的,但是这个数据集跑出来好乱呀,也看不出什么东西,可能是数据采集的质量不太好吧。然后我想用别的数据集来跑跑试试,于是我找到了这个比较常用的数据集,链接如下:


公开数据集

说明第二点:这个数据集下载下来不是bag文件,好像是.clf文件或者.html文件,所以需要先转化成bag文件呀。转化文件代码:

#!/usr/bin/env python
#coding=utf8
 
 
'''This is a converter for the Intel Research Lab SLAM dataset
   ( http://kaspar.informatik.uni-freiburg.de/~slamEvaluation/datasets/intel.clf )
   to rosbag'''
 
import rospy
import rosbag
from sensor_msgs.msg import LaserScan
from nav_msgs.msg import Odometry
from math import pi
from tf2_msgs.msg import TFMessage
from geometry_msgs.msg import TransformStamped
import tf
import sys
 
def make_tf_msg(x, y, theta, t,base,base0):
    trans = TransformStamped()
    trans.header.stamp = t
    trans.header.frame_id = base
    trans.child_frame_id = base0
    trans.transform.translation.x = x
    trans.transform.translation.y = y
    q = tf.transformations.quaternion_from_euler(0, 0, theta)
    trans.transform.rotation.x = q[0]
    trans.transform.rotation.y = q[1]
    trans.transform.rotation.z = q[2]
    trans.transform.rotation.w = q[3]
 
    msg = TFMessage()
    msg.transforms.append(trans)
    return msg
 
if __name__ == "__main__":
 
    if len(sys.argv) < 3:
        print("请输入dataset文件名。")
        exit()
    print("正在处理" + sys.argv[1] + "...")
 
    with open(sys.argv[1]) as dataset:
        with rosbag.Bag(sys.argv[2], 'w') as bag:
            i = 1
            for line in dataset.readlines():
                line = line.strip()
                tokens = line.split(' ')
                if len(tokens) <= 2:
                    continue
                if tokens[0] == 'FLASER':
                    msg = LaserScan()
                    num_scans = int(tokens[1])
 
                    if num_scans != 180 or len(tokens) < num_scans + 9:
                        rospy.logwarn("unsupported scan format")
                        continue
 
                    msg.header.frame_id = 'base_laser_link'
                    t = rospy.Time(float(tokens[(num_scans + 8)]))
                    msg.header.stamp = t
                    msg.header.seq = i
                    i += 1
                    msg.angle_min = -90.0 / 180.0 * pi
                    msg.angle_max = 90.0 / 180.0 * pi
                    msg.angle_increment = pi / num_scans
                    msg.time_increment = 0.2 / 360.0
                    msg.scan_time = 0.2
                    msg.range_min = 0.001
                    msg.range_max = 50.0
                    msg.ranges = [float(r) for r in tokens[2:(num_scans + 2)]]
 
                    bag.write('scan', msg, t)
 
                    odom_x, odom_y, odom_theta = [float(r) for r in tokens[(num_scans + 2):(num_scans + 5)]]
                    tf_msg = make_tf_msg(odom_x, odom_y, odom_theta, t,'odom','base_link')
                    bag.write('tf', tf_msg, t)
 
                elif tokens[0] == 'ODOM':
                    odom_x, odom_y, odom_theta = [float(t) for t in tokens[1:4]]
                    t = rospy.Time(float(tokens[7]))
                    tf_msg = make_tf_msg(0, 0, 0, t,'base_link','base_laser_link')
                    bag.write('tf', tf_msg, t)

转换方法参考如下链接(注意用上述代码):


注意:仅参考数据集转化部分操作步骤哈

此时,我们可以把转化好的数据集放到src同级的目录下等待测试。

然后,我们如果还是按照第一个参考链接来运行的话,发现会缺少tf转化,所以我们需要改写一下其中的两个launch文件,不组要动源码哈。

首先,在
在这里插入图片描述
如上的路径下,重新新建一个文件:hector_mapping_demo.launch,内容参考如下链接:

hector_mapping_demo.launch


这里为了大家方便,我直接把代码贴出来(跟原文中的不太一样,我把路径改了一下,这样的话,如果按照我的步骤做到这里,直接用这个应该没问题的):

    <launch>
      <!-- this launch used to run hector mapping by rosbag-->
     
      <param name="use_sim_time" value="true"/>
      
      <node pkg="tf" type="static_transform_publisher" name="map_to_odom" args="0.0 0.0 0.0 0 0 0.0 /odom /base_footprint 100" /> 
      <node pkg="tf" type="static_transform_publisher" name="base_frame_laser" args="0 0 0 0 0 0 /base_footprint /scan 100" /> 
     
      <!-- hector mapping -->
      <include file="$(find hector_mapping)/launch/includes/hector_mapping.launch.xml"/>
    </launch>

然后,需要再新建一个文件,在如下的路径中:

在这里插入图片描述
如上所示,新建hector_mapping.launch.xml文件。内容如下:

    <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="scan_topic"  value="scan" />
    <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" />
     
    <!--
    this is not include in mapping_default.launch
    <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" />
    <param name="tf_map_scanmatch_transform_frame_name" value="scanmatcher_frame" />
    -->
     
    <!-- Map update parameters -->
    <param name="update_factor_free" value="0.4"/>
    <param name="update_factor_occupied" value="0.9" />    
    <param name="map_update_distance_thresh" value="0.4"/>
    <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"/>
    </node>
    </launch>

然后,源码文件就改好啦。接下来我们用命令来启动试试把:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这样,应该没啥问题了,注意数据集的名字可替换哈。

最后,我运行的结果是这样的:

在这里插入图片描述

跑成这样是算法本身的原因了。好啦,本篇到此结束。希望能帮到你。



版权声明:本文为qq_38338228原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。