差速小车的Cartographer建图
目录
在之前的一些文章中,我们创建了DiffCart的仿真模型并能通过键盘控制它。 还为之提供了里程计和IMU用于估计机器人的位姿。 现在我们来给DiffCart装上激光雷达,并使用Cartographer进行建图。
Cartographer是google的工程师开发的一个用于室内实时建图的SLAM解决方案。目前这种方案支持单线激光的2D建图, 也支持多线激光的3D建图。我们的初衷是使用多线激光进行3D建图,在写本文的demo的时候,虽然成功地对接上了Cartographer的3D建图方法,但是不清楚是算力不够还是建图参数没有调整, 3D定位建图过程非常缓慢,需要DiffCart走走停停才能看到建图效果。因此,我们还是额外提供了一个2D建图的demo,它就要流畅很多。
本文中,我们先进行3D建图,再在此基础上进行修改提供2D的建图方案。我们将记录下demo的编写调试过程,以及中间遇到的坑和相关思考。
1. 安装多线激光
安装多线激光,我一开始的想法是直接把之前创建的32线的Velodyne雷达模型直接include到DiffCart的模型文件中。 但是出于两方面的考虑,最后还是没有这么做。
- 其一,我不清楚如何把这个雷达固定到小车上。我知道在SDF文件的<include>标签是可以添加<pose>子标签来指定放置位置的, 通过fixed类型的joint可以把两个link固连在一起。但是DiffCart和Velodyne的模型中都有多个link,我不知道该怎样指定具体的link固连起来。这方面的资料比较少,扒源码也比较麻烦。
- 其二,demo的编写过程并没有过多的考虑模块化的问题。如果直接把模型文件include进来,那么以后我们将维护两个demo的插件。在系统的模块化设计比较合理,耦合度比较低的情况下, 这样处理还是比较方便的。但是我根本没考虑过这方面问题,而且还想着以后逐渐剥离ROS系统,纯粹使用Gazebo进行仿真。
所以,我们还是参考Velodyne仿真插件的套路, 在DiffCart的模型文件中新增了一个link来安装激光雷达。 如下图所示,我们在[−0.10.00.24]T的位置上安放了雷达的link,这个位置在xy平面上的投影正好与小车两轮的中点投影重合。 我们还使用一个fixed的joint将之与车体固连起来。如下面右图所示,小车上面那个圆柱就是新安装的雷达。
这仍然是一个32线的激光雷达,每线有90个采样点,更新频率是5Hz。一开始每线的采样点也是2187个,而且更新频率是10Hz。发现仿真跑不动,小车走起来有明显的卡滞, 而且Cartographer几乎没有输出。所以就调低了采样频率和采样点数量。然后,我们在仿真插件中按照Velodyne仿真插件的套路, 订阅激光传感器的数据消息,并在回调函数中解析消息,填充ROS的sensor_msgs::PointCloud2消息并发布。
2. 3D建图
现在,我们已经准备好了传感器和控制器,可以开始对接Cartographer进行建图了。 我们曾经按照官方教程安装过Cartographer, 但是在另外一个ROS工作空间下进行的,使用起来多少有些麻烦。可以将两个工作空间合并,但还是有点麻烦,所以我直接按照如下的指令安装了ROS官方维护的Cartographer。
$ sudo apt install ros-melodic-cartographer*
在launch子目录下新建一个launch脚本diffcart_3d_cartographer.launch, 参考cartographer_ros的官方demo,如下面的代码片段所示, 我们在其中的第1到7行中运行cartographer_node节点,通过参数args指定配置文件所在目录和配置文件。 同时还将cartographer_node中所用的主题"imu"和"points2"重映射为我们在仿真插件中发布的关于IMU数据和点云数据主题。最后第7,8行中运行的节点cartographer_occupancy_grid_node, 将Cartographer生成的子图合并成为一个占用删格地图并通过ROS的主题发布出去。
<node pkg="cartographer_ros" type="cartographer_node" name="cartographer_node" args="-configuration_directory $(find gazebo_demos)/config -configuration_basename diffcart_3d.lua" output="screen"><remap from="imu" to="/imu_data"/><remap from="points2" to="/point_cloud"/></node><node name="cartographer_occupancy_grid_node" pkg="cartographer_ros"type="cartographer_occupancy_grid_node" args="-resolution 0.05" />
为了方便调整Cartographer的运行参数,我们在gazebo_demos的根目录下创建了一个子目录config,并将cartographer_ros中的配置文件backpack_3d.lua文件拷贝过来, 命名为diffcart_3d.lua。 官方教程中,详细的说明了各个配置项的意义。 在下表中,我们列出一些比较重要的字段。
字段 | 值 | 说明 |
---|---|---|
map_frame | "map" | 地图坐标系名称 |
tracking_frame | "base_link" | Cartographer将要跟踪的机器人坐标系名称 |
provide_odom_frame | true | Cartographer将使用Local SLAM的位姿估计作为里程计 |
odom_frame | "odom" | 里程计坐标系名称。 |
use_odometry | true | 在Local SLAM中使用里程计信息,Cartographer将订阅主题"odom"接收nav_msgs/Odometry类型的消息。 |
num_point_clouds | 1 | 激光点云主题数量,由于我们只有一个激光雷达,所以Cartographer将订阅主题"points2"接收sensor_msgs/PointCloud2类型的消息。 |
MAP_BUILDER.use_trajectory_builder_3d | true | 启用3D建图引擎。 |
这些配置项要求Cartographer维护从"map"到"odom"再到"base_link"的坐标变换。我们的插件只需要提供"/odom", "/imu_data"和"/point_cloud"三个主题的消息就可以驱动Cartographer进行定位和建图了。 所以,我们对DiffCart的里程计做了一些简单的修改,不再发布从"odom"到"base_link"的tf变换消息,而是nav_msgs/Odometry类型的消息。
此外,为了防止Cartographer出现一些莫名奇妙的错误,我们增加了"imu_link"和"laser_link"两个坐标系,并通过tf工具直接发布静态坐标关系,将之与机器人坐标系"base_link"固连在一起。 如下面的代码片段所示:
<node pkg="tf" type="static_transform_publisher" name="laser_base_link_transform" args="0 0 0 0 0 0 base_link laser_link 100"/><node pkg="tf" type="static_transform_publisher" name="imu_base_link_transform" args="0 0 0 0 0 0 base_link imu_link 100" />
我们还需要设置ROS运行参数"/use_sim_time"为true,来统一ROS与Gazebo之间的时间体系。调用脚本"bringup_gazebo.sh"运行Gazebo加载仿真环境。 世界文件diffcart_willowgarage.world还从Gazebo官方维护的模型仓库gazebo_models中引入了"willowgarage"模型,提供了一个室内场景。
<param name="/use_sim_time" value="true" /><node name="gazebo" pkg="gazebo_demos" type="bringup_gazebo.sh"args="$(find gazebo_demos)/worlds/diffcart_willowgarage.world" output="screen"/>
完成必要的准备工作之后,我们就可以通过指令$ roslaunch gazebo_demos diffcart_3d_cartographer.launch
运行launch脚本,开始Cartographer建图仿真了。 下面左右两幅图分别是Gazebo仿真环境和rviz中激光扫描和建图过程的截图。
由于系统运行十分缓慢,Cartographer响应很迟钝,需要走走停停才能看到建图效果,所以这里的截图只是走了一小段而已。估计需要比较细致的调整一下Cartographer的运行参数才能看到比较流畅的效果。
3. 2D建图
我还是希望能够看到一个比较流畅的效果的,可能3D的建图方法对算力的要求比较高,所以我们将DiffCart上的32线激光改成了单线激光,进行2D建图。主要有以下几个方面的改动:
- 新建了一个模型diffcart_with_single_laser,安装的是单线激光。
- 提供了一个世界文件将其中的DiffCart模型替换为单线激光版本的。
- 在config子目录下增加用于2D建图的配置文件。
- 针对单线激光修改了接收激光扫描数据的回调函数OnLaserScanMsg, 具体修改内容参见源码,不再细述。
- 增加用于2D建图的launch脚本。
修改完成之后,通过指令$ roslaunch gazebo_demos diffcart_2d_cartographer.launch
运行2D建图的demo,并使用键盘控制DiffCart在仿真世界中运动一段时间后, 就可以看到下图的效果。整个过程还是比较流畅的,而且可以看到运动的轨迹和不断增加的约束。
4. 完
要运行Cartographer,我们需要根据传感器的类型和建图方法提供cartographer_ros的系统的*.lua配置文件。并根据该配置文件组织传感器数据消息的主题,以及相关的坐标系统。 我们的demo中Cartographer维护了地图、里程计和机器人本体之间的坐标关系。修改配置项provide_odom_frame为false,Cartographer将不再提供局部的位姿估计,需要用户自己根据实际情况提供。 由于SLAM问题本身就有定位和建图两个方面,所以建议将该配置项置为true。
差速小车的Cartographer建图相关推荐
- 【工程记录】基于松灵Scout mini底盘实现小车自主探索建图
一.硬件配置 松灵scout mini底盘 速腾robense 16线激光雷达 瑞芬imu 因特尔nuc 二.工程技术栈 IMU驱动包(原创) 松灵底盘包(改写,里程计融合IMU角度信息) ROS N ...
- Cartographer建图和纯定位
(一)cartographer在ros下安装参考: 要求: 64-bit, modern CPU (e.g. 3rd generation i7) 16 GB RAM Ubuntu 18.04 (Bi ...
- 机器人学习--Turtelbot3学习--如何使用cartographer建图
问题描述: 按照创客智造官网的教程:https://www.ncnynl.com/category/turtlebot3-tutorial/ 安装好turtlebot3的配套软件后,默认是使用 gma ...
- odomimu融合用于Cartographer建图
任务动机:使用odom&imu融合用于Cartographer建图,提高Cartographer建图时的匹配精度,同时降低运算消耗. 任务描述:使用odom&imu融合用于Cartog ...
- 用自己的机器人实现cartographer建图测试与地图保存应该这样做
用自己的机器人实现cartographer建图测试与地图保存应该这样做 1.安装 2.测试 3.保存地图 亲测可行.(该教程使用github的代码地址,速度相对慢了一点,极速安装,请看这里: 极速安装 ...
- ros2 -foxy安装cartographer建图定位-- 源码安装 使用
foxy 的cartographer_ros 和dashing 的兼容 cd ~/xx__ws/src 安装源码 git clone https://ghproxy.com/https://gith ...
- 用自己的雷达进行Cartographer建图或仿真
首先需要进行Cartographer安装以及雷达驱动安装等准备工作, 直至我们能够在雷达运行时找到发布LaserScan的Topic并获取数据, 以开始下一步的建图. 基本信息获取 启动雷达或gaze ...
- cartographer建图,重定位及发布消息结构为nav_msgs::Odometry的odom话题
完整功能包(包含carto建图,重定位以及odom话题发布)上传至https://download.csdn.net/download/zhaohaowu/33647981 众所周知,cartogra ...
- HANDSFREE 2代小车 用xtion建图导航
博主的实验室之前购买了HANDSFREE 2代的小车,因为手头没有激光雷达,所以使用了华硕的xtion pro摄像头来进行建图和导航 由于HANDSFREE 2代小车原生支持激光雷达,所以我们要用xt ...
最新文章
- CocosCreator上的游戏(调试)发布到微信小程序
- 如何用R和API免费获取Web数据?
- 【生活】 戴尔XPS 插上耳机之后,说话没声音,麦克风失效 window10 系统
- 可视化GDI操作题目
- boost::callable_traits移除const成员的测试程序
- 如果你想写自己的Benchmark框架
- python转嵌入式c_在C嵌入式python中刷新导入
- java break 在if 中使用_java中使用国密SM4算法详解
- 【学习笔记】JavaScript基础(一)
- jQuery对象与DOM对象的相互转换
- 前端学习(1698):前端系列javascript之原型链和instance
- http请求前后监听工具
- mysql有哪几种索引
- 20150409作业3 阅读《构建之法》1-5章
- C++ std::function怎么用
- 计算机分区格式转换,硬盘GPT分区与MBR分区如何转换
- 引用nbsp;TDA2030功放电路图
- BUUCTF[强网杯 2019]随便注 的三种解法
- WIN10安装VMware的管理员权限问题
- DropDownMenu下拉菜单