cartogrpher环境配置
安装的官网网址:
https://google-cartographer-ros.readthedocs.io/en/latest/compilation.html#building-installation
- 首先确认自己的ros版本Kinetic(16.04),Melodic(18.04),Noetic(20.04)
- 此处选用ROS Melodic作为示范:
下面两行命令是先安装一些工具:wstool, rosdep和Ninja:
sudo apt-get update
sudo apt-get install -y python-wstool python-rosdep ninja-build stow
**注意:**在ros noetic中基本上是使用python3(此版本完全支持python3),此版本安装工具时是使用python3,若使用python(默认2)则可能会无法安装。如果 您的版本是ubuntu 20.04,则安装下列工具:
sudo apt-get update
sudo apt-get install -y python3-wstool python3-rosdep ninja-build stow
- 安装完工具之后,创建一个cartographer_ros 的工作空间
mkdir catkin_ws
cd catkin_ws
wstool init src //在没有rosinstall文件的情况下初始化工作区
wstool merge -t src https://raw.githubusercontent.com/cartographer-project/cartographer_ros/master/cartographer_ros.rosinstall //下载安装包
wstool update -t src
注意:在第4步执行时如果幸运的话,成功安装;如果倒霉的话,可能会报错(访问被拒绝)。但是不要慌…我们可以把命名后面https的网址打开,把里面的命令一个个运行执行即可。
我打开官网的网址是下面两行命令:(需要在工作空间src下执行!! cd src)
下载完成后在src文件下可以看到下面内容
4. 下面是安装依赖项:
sudo rosdep init
rosdep update
rosdep install --from-paths src --ignore-src --rosdistro=${ROS_DISTRO} -y
# Only on Ubuntu 16 / ROS Kinetic: src/cartographer/scripts/install_proto3.sh
此时如果‘sudo rosdep init’ 出现报错,或者是rosdep初始化超时问题 但是如果你已经安装过ros(因为ros安装最后一步就是rosdep),此报错可以直接忽略。
当然此报错也有很好的解决办法,六部工坊给出的解决方案可以轻松解决此问题
~~~
sudo apt-get install python3-pip
sudo pip3 install 6-rosdep
sudo 6-rosdep
~~~
如果系统无法安装pip3,可以安装pip。上述三条指令替换为:
sudo apt-get install python-pip
sudo pip install 6-rosdep
sudo 6-rosdep
-
安装abseil-cpp 库
src/cartographer/scripts/install_abseil.sh //由于版本冲突,您可能需要卸载ROS abseil-cpp sudo apt-get remove ros-${ROS_DISTRO}-abseil-cpp
-
编译
catkin_make_isolated --install --use-ninja
此命令的作用和catkin_make效果一样。但是不要使用catkin_make去编译此工作空间,会报错!!!包括后面修改一些文件,为了使之运行都是使用catkin_make_isolated --install --use-ninja 进行编译(或者catkin_make_isolated)。
-
成功后,即可下载cartographer 例子数据包进行测试
2D数据包下载命令如下:
wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/backpack_2d/cartographer_paper_deutsches_museum.bag
3D数据包下载命令如下:
wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/backpack_3d/with_intensities/b3-2016-04-05-14-14-00.bag
-
运行数据包:
直接执行launch语句来运行数据包,可能会报错,
通常加一句:source install_isolated/setup.bash(source install_isolated/setup.zsh)
运行2D.launch:
roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:=${HOME}/Downloads/cartographer_paper_deutsches_museum.bag
运行3D.launch:
roslaunch cartographer_ros demo_backpack_3d.launch bag_filename:=${HOME}/Downloads/b3-2016-04-05-14-14-00.bag
效果图:
4)适配环境(配置修改)
以上步骤完成后,cartographer的运行环境以及搭建完成,下面的修改是为了适配我们自己的环境(毕竟最终目的是落地,不是跑人家的demo)下面详细介绍我的步骤:
-
修改demo_revo_lds.launch
此文件路径/catkin _ws/src/cartographer_ros/cartographer_ros/launch
(1) 删除运行bag的node节点;
(2) 修改话题
修改映射<remap from="scan" to="scan" /> //修改为自己的激光发布的话题;
- 先启动底盘,然后通过rostopic list查看发布的话题即可。
(3)
<param name="/use_sim_time" value="false" />
如果跑的是实车,不是仿真,就把此句注释掉,或者改成false,此处好像是开始仿真时间。
至此launch文件基本可以使用了。
在这放上我的launch文件
<launch> <node name="cartographer_node" pkg="cartographer_ros" type="cartographer_node" args=" -configuration_directory $(find cartographer_ros)/configuration_files -configuration_basename spirit.lua" output="screen"> <remap from="scan" to="scan" /> </node> <node name="cartographer_occupancy_grid_node" pkg="cartographer_ros" type="cartographer_occupancy_grid_node" args="-resolution 0.05" /> </launch>
-
修改revo_lds.lua
此文件路径/catkin_ws/src/cartographer_ros/cartographer_ros/configuration_files下revo_lds.lua
主要修改下面四句
- map_frame = “map”, //cartographer中使用的全局坐标系,保持默认,否则ROS的Rviz不认识其它的定义,导致无法可视化建图过程
- tracking_frame = “base_link”,// 机器人中心坐标系,其它传感器数据都是以这个为基础进行插入的。cartographer_ros里面有个tf_bridge的类就是专门用来查询其它坐标系到此坐标系的转换关系的。根据tf_tree修改即可,一开始将此句修改成laser_link可以看到建的地图,也可以为base_link,具体看tf_tree
- published_frame = “base_link”,//可以将其修改成base_link即可
- odom_frame = “odom”,// 3句与4句是配合使用的,如果参数provide_odom_frame = true 那么在最后可视化的时侯,发布的转换消息是从 published_frame->odom_frame->map_frame, 也就是cartographer内部计算出了未经回环检测的局部图坐标到优化后的全局图坐标之间的转换关系并发布了出来。
这里的修改需要查看激光器在tf_tree中的名称,用实际的名称替换,否则rviz中看不到地图,因为tf有问题。可以通过rosrun rqt_tf_tree rqt_tf_tree 查看机器人发布的tf_tree。
在这放上我的lua文件,以及一些注释:
include "map_builder.lua" include "trajectory_builder.lua" options = { map_builder = MAP_BUILDER, trajectory_builder = TRAJECTORY_BUILDER, map_frame = "map", --为 cartographer中使用的全局坐标系,也是位姿的父坐标系,应当保持默认。 -- tracking_frame = "horizontal_laser_link", -- published_frame = "horizontal_laser_link", tracking_frame = "imu_link", --tracking_frame指的是由SLAM算法追踪的ROS坐标系的ID,如果在使用IMU的情况下,也可以(也最好)替换成“imu_link” published_frame = "dummy", --个可以被设置为odom,意为里程计坐标系,也可以被设置为base_link。 odom_frame = "odom", --只有在下一个选项provide_odom_frame为true时这个参数才启用,这个一般被设为odom,也是里程计的坐标系的名称。(注意published_frame和odom_frame) provide_odom_frame = true, --使得坐标系之间经过如下转换以后再发布:published_frame->odom_frame->map_frame。如果不是true,则是 published_frame ->map_frame进行发布。 publish_frame_projected_to_2d = false, -- use_pose_extrapolator = true, use_odometry = false, --如果为true,则会订阅“odom”这个topic的的nav_msgs/Odometry消息。 use_nav_sat = false, --是否使用GPS数据 use_landmarks = false, --是否使用GPS数据 num_laser_scans = 1, --指的是雷达的数量,也就是订阅的激光雷达的topic的数量,例如在“scan”的topic上订阅sensor_msgs/LaserScan信息,或者在多个激光扫描仪上订阅话题“scan_1”,“scan_2”等等。 num_multi_echo_laser_scans = 0, --这个是个高级的传感器,其值订阅的多回波激光扫描的topic的数量,例如在一个激光扫描仪的“echoes”话题上订阅sensor_msgs/MultiEchoLaserScan。 num_subdivisions_per_laser_scan = 1, --这个指的是将每个接收到的(多回波)激光扫描分成的点云数,说白了就是把激光一帧的数据拆分成几次发出来,正常为1即可。 num_point_clouds = 0, --这个指的是要订阅的点云话题的数量,主要是在points2的topic上订阅sensor_msgs/PointCloud2。 lookup_transform_timeout_sec = 0.2, --这个指使用tf2查找变换的超时秒数,默认都为0.2s。 submap_publish_period_sec = 0.3, --这个指发布submap的间隔,默认为 0.3s。cartographer与其他slam最大的一个不同点就是采用了submap概念,即采用一定数量的laser scan组成submap,然后再由n个submap组成整个地图空间。 pose_publish_period_sec = 5e-3, --发布位姿的间隔,单位为秒 trajectory_publish_period_sec = 30e-3, --发布轨迹的持续时间 rangefinder_sampling_ratio = 1., --以下5个是观测的权重比,当某个观测不太靠谱的时候,可以把1改为较小的权重,例如0.5,从而减小对整体优化的错误影响。 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 --用的是2D还是3D的SLAM 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 = true --是否使用imu数据 TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true --是否使用实时回环检测来进行前端的扫描匹配。最好是弄成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
-
保存地图
//完成轨迹, 不接受进一步的数据。
rosservice call /finish_trajectory 0
//序列化保存其当前状态
rosservice call /write_state "{filename: '${HOME}/Downloads/mymap.pbstream'}"
//将pbstream转换为pgm和yaml(这是一条命令,比较长)
rosrun cartographer_ros cartographer_pbstream_to_ros_map -map_filestem=${HOME}/Downloads/mymap -pbstream_filename=${HOME}/Downloads/mymap.pbstream -resolution=0.05
至此使用cartographer建图应该没有问题。
参考链接:
- https://blog.csdn.net/qq_34935373/article/details/111991920?spm=1001.2014.3001.5506
- https://blog.csdn.net/qq_26482237/article/details/92676267?ops_request_misc=&request_id=&biz_id=102&utm_term=cartographer%E5%AE%89%E8%A3%85&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-3-92676267.142v51control,201v3add_ask&spm=1018.2226.3001.4187