用自己的雷达和IMU运行cartographer

您所在的位置:网站首页 找不到launch文件 用自己的雷达和IMU运行cartographer

用自己的雷达和IMU运行cartographer

2023-08-29 00:54| 来源: 网络整理| 查看: 265

  最近在做项目,需要用雷达和IMU去建图,根据系统算法的输入,目前可以使用IMU的系统只有cartographer,而且图优化的cartographer更适合于大范围场景的地图构建,非常适用于工厂AGV的作业。   如果不是搞cartographer内部算法,只是想要运用自己的传感器来复现,其实不需要看内部算法,只需要配置launch文件、lua文件以及urdf文件就可以了!   我刚开始跑cartographer的时候,是直接按照官网的方法直接运行数据集,那时候感觉效果真的非常棒,于是想用自己的传感器去试试,但是自己又不知道该从哪下手,后面就是从网上找各种方法,发现按照网上的方法配置以后效果非常差。其实原因主要有以下几点:

  1.传感器不适用

   一开始运行cartographer的时候并没有用IMU。此时用的是EAI的YDLIDAR—G2,只需要配置revo_lds.lua文件以及demo_revo_lds.launch文件。具体配置如下: 原revo_lds.launch文件

include "map_builder.lua" include "trajectory_builder.lua" options = { map_builder = MAP_BUILDER, trajectory_builder = TRAJECTORY_BUILDER, map_frame = "map", tracking_frame = "horizontal_laser_link", published_frame = "horizontal_laser_link", odom_frame = "odom", provide_odom_frame = true, publish_frame_projected_to_2d = false, use_pose_extrapolator = true, use_odometry = false, use_nav_sat = false, use_landmarks = false, num_laser_scans = 1, num_multi_echo_laser_scans = 0, num_subdivisions_per_laser_scan = 1, num_point_clouds = 0, lookup_transform_timeout_sec = 0.2, submap_publish_period_sec = 0.3, pose_publish_period_sec = 5e-3, trajectory_publish_period_sec = 30e-3, rangefinder_sampling_ratio = 1., odometry_sampling_ratio = 1., fixed_frame_pose_sampling_ratio = 1., imu_sampling_ratio = 1., landmarks_sampling_ratio = 1., } MAP_BUILDER.use_trajectory_builder_2d = true TRAJECTORY_BUILDER_2D.submaps.num_range_data = 35 TRAJECTORY_BUILDER_2D.min_range = 0.3 TRAJECTORY_BUILDER_2D.max_range = 8. TRAJECTORY_BUILDER_2D.missing_data_ray_length = 1. TRAJECTORY_BUILDER_2D.use_imu_data = false TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.linear_search_window = 0.1 TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.translation_delta_cost_weight = 10. TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.rotation_delta_cost_weight = 1e-1 POSE_GRAPH.optimization_problem.huber_scale = 1e2 POSE_GRAPH.optimize_every_n_nodes = 35 POSE_GRAPH.constraint_builder.min_score = 0.65 return options

修改后的revo_lds.lua文件

include "map_builder.lua" include "trajectory_builder.lua" options = { map_builder = MAP_BUILDER, trajectory_builder = TRAJECTORY_BUILDER, map_frame = "map", tracking_frame = "laser", published_frame = "laser", odom_frame = "odom", provide_odom_frame = true, publish_frame_projected_to_2d = false, use_pose_extrapolator = true, use_odometry = false, use_nav_sat = false, use_landmarks = false, num_laser_scans = 1, num_multi_echo_laser_scans = 0, num_subdivisions_per_laser_scan = 1, num_point_clouds = 0, lookup_transform_timeout_sec = 0.2, submap_publish_period_sec = 0.3, pose_publish_period_sec = 5e-3, trajectory_publish_period_sec = 30e-3, rangefinder_sampling_ratio = 1., odometry_sampling_ratio = 1., fixed_frame_pose_sampling_ratio = 1., imu_sampling_ratio = 1., landmarks_sampling_ratio = 1., } MAP_BUILDER.use_trajectory_builder_2d = true TRAJECTORY_BUILDER_2D.submaps.num_range_data = 35 TRAJECTORY_BUILDER_2D.min_range = 0.3 TRAJECTORY_BUILDER_2D.max_range = 8. TRAJECTORY_BUILDER_2D.missing_data_ray_length = 1. TRAJECTORY_BUILDER_2D.use_imu_data = false TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.linear_search_window = 0.1 TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.translation_delta_cost_weight = 10. TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.rotation_delta_cost_weight = 1e-1 POSE_GRAPH.optimization_problem.huber_scale = 1e2 POSE_GRAPH.optimize_every_n_nodes = 35 POSE_GRAPH.constraint_builder.min_score = 0.65 return options

  其实就是将坐标系改为自己的雷达坐标系就可以了。我的雷达坐标系是laser,如果不知道自己雷达坐标系,可以先启动雷达,然后另起终端输入:

rostopic echo /雷达话题

  其中的frame id就是雷达对应的坐标系。接着就是修改launch文件。 原demo_revo_lds.launch文件

  /use_sim_time对应是否离线还是在线跑系统(类似时间戳),默认的value=“true”,就是离线跑数据包的意思,因此后面加上了node name=“playbag” pkg=“rosbag” type=“play” args="–clock $(arg bag_filename)" bag包回放。如果要在线跑的话,只需将value改为false,并将bag包回放这句话删除就可以了。remap重映射话题,改为自己的雷达话题就可以了。因此修改后的launch文件如下。

  值得注意的是,修改后的launch文件中用到的lua文件是自己修改后的lua文件。    最后的建图效果如下: 在这里插入图片描述

  可以看出,单纯用雷达建出的效果非常差,重影非常多,根本用不起来。后面就参考了链接: Cartographer中对激光雷达运动畸变的处理方法分析.对代码进行了修改,矫正雷达数据反序以及频率不稳定的问题,但是发现建图效果还是一样的差。然后看到了这个博客: 用自己的雷达进行Cartographer建图或仿真.这个博客里面说到各种雷达跑cartographer的效果是不一样的,正好实验室有个思岚雷达,换上试了试,发现效果真的很棒!如下图: 在这里插入图片描述

   还真的是雷达的问题。

   2.urdf文件和lua文件配置不正确

  以上只是单纯的用雷达建图,为了进一步提升建图效果,需要加IMU,此时还需要配置urdf文件。一开始配置urdf的时候都是参考网上的步骤,但其实还是要依据自身传感器的情况去撰写urdf文件,假如想用机器人完成建图,那么就定义三个坐标系,分别是laser_joint、imu_joint以及base_link坐标系,base_link坐标系是机器人的底盘坐标系,这个可以随意定制,一般选取机器人中心就行。而laser_joint和imu_joint坐标系需要计算它们的外参,这个比较麻烦,目前我还没找到标定二维激光雷达和IMU外参的工具。我的方法就是将IMU放到它的正下方,这样的话相当于就是y轴差了1-2cm。坐标系的旋转情况根据各传感器的基准而定,具体可以参考传感器的出厂文件。比如思岚A2的传感器定义如下: 在这里插入图片描述

  因为我想要实现和数据集一样的效果,因此在demo_backpack_2d.urdf文件的基础上进行了修改,最后撰写的urdf文件如下:

  其次要修改lua文件,也是在backpack_2d.lua文件的基础上进行修改。如下:

include "map_builder.lua" include "trajectory_builder.lua" options = { map_builder = MAP_BUILDER, trajectory_builder = TRAJECTORY_BUILDER, map_frame = "map", tracking_frame = "imu_link", published_frame = "base_link", odom_frame = "odom", provide_odom_frame = true, publish_frame_projected_to_2d = false, use_pose_extrapolator = true, use_odometry = false, use_nav_sat = false, use_landmarks = false, num_laser_scans = 1, num_multi_echo_laser_scans = 0, num_subdivisions_per_laser_scan = 1, num_point_clouds = 0, lookup_transform_timeout_sec = 0.2, submap_publish_period_sec = 0.3, pose_publish_period_sec = 5e-3, trajectory_publish_period_sec = 30e-3, rangefinder_sampling_ratio = 1., odometry_sampling_ratio = 1., fixed_frame_pose_sampling_ratio = 1., imu_sampling_ratio = 1., landmarks_sampling_ratio = 1., } MAP_BUILDER.use_trajectory_builder_2d = true TRAJECTORY_BUILDER_2D.num_accumulated_range_data = 1 return options

  通样也要修改launch文件,首先是backpack_2d.launch:

  然后是demo_backpack_2d.launch:

  这些文件的名字都是自己随意定义的,只要将urdf、lua、launch文件对应起来即可。每次修改文件后要记得重新编译:

catkin_make_isolated --install --use-ninja source install_isolated/setup.bash

  值得注意的是,urdf里的坐标系一定要和lua文件对应,不对应的话会出现坐标系之间的警告,假如将urdf中的link name=laser改为了link name=laser_link,会出现如下错误: 在这里插入图片描述   如果不知道自己的传感器的frame id的,可以通过rostopic echo /传感器数据进行查看。   其次,lua文件中的tracking frame一定要是urdf中IMU的坐标系。假如写成了base_link坐标系,也会出错sensor_bridge.cc:136] Check failed: sensor_to_tracking->translation().norm() < 1e-5 The IMU frame must be colocated with the tracking frame. Transforming linear acceleration into the tracking frame will otherwise be imprecise.: 在这里插入图片描述   只要注意以上问题,相信走到这一步绝大部分人都能够运行了,这些文件的具体参数修改暂且没有探究过,博主也只是对传感器的外参和坐标系名称进行了修改。后续有知道的小伙伴可以在下方评论区一块探讨。

  3.parent坐标系转换有误

  这个问题大部分人遇不到,困扰了我很久。因为我在网上并没有找到解决办法,后来想出来的。在上一步修改完urdf、lua、launch文件后,重新运行的时候出现了如下问题: 请添加图片描述   根据错误提示,是因为IMU坐标系和雷达坐标系的父亲坐标系不是同一个坐标系,然后我就通过

rosrun tf view_frames

查看了坐标系变换,如下图: 请添加图片描述

而数据集中的tf变化是这样的: 请添加图片描述

  这就很奇怪了,我明明就已经在urdf文件中设置了它们各自的父亲坐标系了,为啥会出现问题,然后就是各种重新些urdf文件,差点怀疑人生,都已经感觉上天和我作对哈哈哈。暂停了一段时间后,这天我突然想到会不会是传感器本身驱动有问题。果真,雷达没有问题,而IMU驱动有问题!原来xsens系列IMU驱动的官方文件中就已经定义了IMU的坐标系为world!于是我就去修改了IMU的驱动文件,根据launch文件提示的内容: 请添加图片描述   然后找到了xsens_mti_node.yaml文件,里面有一个publish_transfrom: 请添加图片描述   这个参数将IMU的parent坐标系设为world,于是将其改为false,最终重新启动了IMU、lidar、cartographer,总算是成功了,效果如下: 请添加图片描述  蓝色小车是通过urdf文件定义出来的,想要的可以去参考上面的urdf文件,开心!   加了IMU后,最终的建图效果如下: 请添加图片描述

  very nice!几乎和数据集一样喽。   如果这篇文章对你有帮助的话,点个赞加关注吧!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3