赞
踩
Cartographer是一个支持多平台和传感器配置的SLAM的系统。
本文主要讲述在ros2 humble系统上cartographer的安装方法,以及如何配置参数实现自己的ros2 bag包的离线建图。
官方cartographer的github地址:https://github.com/ros2/cartographer
官方cartographer_ros的github地址:https://github.com/ros2/cartographer_ros
官方cartographer说明文档(非ROS2版本)地址:https://google-cartographer.readthedocs.io/en/latest/
官方cartographer_ros说明文档(非ROS2版本)地址:https://google-cartographer-ros.readthedocs.io/en/latest/
sudo apt install ros-humble-cartographer ros-humble-cartographer-ros
# 等待安装完成,输入如下指令查看是否安装完成;先source一下环境
ros2 pkg list | grep cartographer
# 正常可看到返回如下pkg
cartographer_ros
cartographer_ros_msgs
cartographer_rviz
sudo apt-get update sudo apt-get install -y python3-wstool python3-rosdep ninja-build stow # 根据个人意愿,建立新的工作空间 mkdir cartogrpaher_ws cd cartogrpaher_ws wstool init src cd src git clone https://ghproxy.com/https://github.com/ros2/cartographer.git git clone https://ghproxy.com/https://github.com/ros2/cartographer_ros.git wstool update -t src sudo rosdep init rosdep update rosdep install --from-paths src --ignore-src --rosdistro=humble -y colcon build # 如果提示缺少依赖,命令行安装一下即可 # 同上述apt安装,安装完成,source一下环境,检查是否成功
因为是用纯激光的bag数据仿真运行,一般只需要.launch.py+.lua+(urdf)即可;没有用到imu和odom数据;
这里参考的demo_backpack_2d.launch.py和backpack_2d.launch.py;(参考demo_revo_lds.launch.py更好,只用一个文件即可)
# demo_my_robot_2d.launch.py def generate_launch_description(): # 未配置默认bag包的打开位置,启动时需要加指令: bag_filename:= bag包的位置 bag_filename_arg = DeclareLaunchArgument('bag_filename') ## ***** Nodes ***** 修改参数为my_robot_2d.launch.py my_robot_2d_launch = IncludeLaunchDescription( PythonLaunchDescriptionSource(FindPackageShare('cartographer_ros').find('cartographer_ros') + '/launch/my_robot_2d.launch.py'), launch_arguments = {'use_sim_time': 'True'}.items() ) # 以下均未调整 rviz_node = Node( package = 'rviz2', executable = 'rviz2', on_exit = Shutdown(), arguments = ['-d', FindPackageShare('cartographer_ros').find('cartographer_ros') + '/configuration_files/demo_2d.rviz'], parameters = [{'use_sim_time': True}], ) ros2_bag_play_cmd = ExecuteProcess( cmd = ['ros2', 'bag', 'play', LaunchConfiguration('bag_filename'), '--clock'], name = 'rosbag_play', ) return LaunchDescription([ # Launch arguments bag_filename_arg, # Nodes my_robot_2d_launch, rviz_node, ros2_bag_play_cmd ])
# my_robot_2d.launch.py def generate_launch_description(): ## ***** Launch arguments ***** use_sim_time_arg = DeclareLaunchArgument('use_sim_time', default_value = 'False') ## ***** File paths ****** pkg_share = FindPackageShare('cartographer_ros').find('cartographer_ros') ''' 去掉了urdf以及robot_state_publisher_node ''' # 修改为my_robot_2d.lua 文件 以及 激光雷达话题remapping(一个激光雷达的话,映射为scan即可;多个激光雷达需要映射为scan1、scan2...) cartographer_node = Node( package = 'cartographer_ros', executable = 'cartographer_node', parameters = [{'use_sim_time': LaunchConfiguration('use_sim_time')}], arguments = [ '-configuration_directory', FindPackageShare('cartographer_ros').find('cartographer_ros') + '/configuration_files', '-configuration_basename', 'my_robot_2d.lua'], remappings = [ ('scan', '/sick_lms_1xx/scan')], output = 'screen' ) cartographer_occupancy_grid_node = Node( package = 'cartographer_ros', executable = 'cartographer_occupancy_grid_node', parameters = [ {'use_sim_time': True}, {'resolution': 0.05}], ) return LaunchDescription([ use_sim_time_arg, # Nodes # robot_state_publisher_node, 注释了这个node cartographer_node, cartographer_occupancy_grid_node, ])
这里参考的revo_lds.lua;因为只用了激光雷达数据,所以tracking_frame、published_frame设置为雷达的坐标系lidar_link;
# my_robot_2d.lua options = { map_builder = MAP_BUILDER, trajectory_builder = TRAJECTORY_BUILDER, --map坐标系 map_frame = "map", --通常为发布频率最高的传感器的frame_id,例如imu_link tracking_frame = "lidar_link", --cartographer发布发布map到published_frame之间的tf;此处设置错误,建图异常;程序正常运行,使用ros2 run tf2_tools view_frames可以看到map-> lidar_link; published_frame = "lidar_link", --odom坐标系 odom_frame = "odom", --设置为true,cartographer会发布一个 odom 坐标系;--程序正常运行,使用ros2 run tf2_tools view_frames可以看到map->odom->lidar_link; provide_odom_frame = false, publish_frame_projected_to_2d = true, use_pose_extrapolator = true, use_odometry = false, use_nav_sat = false, use_landmarks = false, --订阅的lidar scan数量 num_laser_scans = 1, num_multi_echo_laser_scans = 0, --扫描分割数量,为1不分割 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.min_range = 0.5 -- 根据激光雷达的性能,最大范围 TRAJECTORY_BUILDER_2D.max_range = 30 -- 无效激光数据设置距离为该数值 TRAJECTORY_BUILDER_2D.missing_data_ray_length = 3. -- false,不使用IMU数据 TRAJECTORY_BUILDER_2D.use_imu_data = false -- true,使用实时回环检测来进行前端的扫描匹配 TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true --尽量小点;如果移动距离或旋转过小, 或者时间过短, 不进行地图的更新 TRAJECTORY_BUILDER_2D.motion_filter.max_distance_meters = 0.05 TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = math.rad(0.1) TRAJECTORY_BUILDER_2D.motion_filter.max_time_seconds = 0.2 --FastCorrelativeScanMatcher初步匹配的结果分数,高于此分数才进入下一步的Ceres Scan Matcher处理。 POSE_GRAPH.constraint_builder.min_score = 0.65 --全局定位最小分数,低于此分数则认为目前全局定位不准确 POSE_GRAPH.constraint_builder.global_localization_min_score = 0.7 return options
cd cartogrpaher_ws
colcon build
source ./install/setup.bash
ros2 launch cartographer_ros demo_my_robot_2d.launch.py bag bag_filename:=/home/bag_filename
#地图的保存
mkdir map
cd map
# 默认由/map话题输出(-t map),Free threshold = 0.25,Occupied threshold = 0.65;会生成carto_map.pgm和carto_map.yaml两个文件。
ros2 run nav2_map_server map_saver_cli -f carto_map
使用tf2_ros提供的static_transform_publisher,具体参数含义如下:
static_transform_publisher [--x X] [--y Y] [--z Z] [--qx QX] [--qy QY] [--qz QZ] [--qw QW] [--roll ROLL] [--pitch PITCH] [--yaw YAW] --frame-id FRAME_ID --child-frame-id CHILD_FRAME_ID
例如:
ros2 run tf2_ros static_transform_publisher 0.1 0 0.2 0 0 0 base_link link_1
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。