当前位置:   article > 正文

ros2 humble cartographer 2D激光雷达建图_cartographer ros2

cartographer ros2

1.概述

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/

2.安装cartographer

2.1 apt安装

sudo apt install ros-humble-cartographer ros-humble-cartographer-ros
  • 1
# 等待安装完成,输入如下指令查看是否安装完成;先source一下环境
ros2 pkg list | grep cartographer
# 正常可看到返回如下pkg
cartographer_ros
cartographer_ros_msgs
cartographer_rviz
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.2 源码安装

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一下环境,检查是否成功
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3.cartographer参数配置

因为是用纯激光的bag数据仿真运行,一般只需要.launch.py+.lua+(urdf)即可;没有用到imu和odom数据;

3.1 .launch.py文件

这里参考的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
    ])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
# 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,
    ])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

3.2 .lua文件

这里参考的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 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

4 建图与地图保存

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5 节点话题图

在这里插入图片描述

6 TF静态坐标变换发布

使用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
  • 1

例如:

ros2 run tf2_ros static_transform_publisher 0.1 0 0.2 0 0 0 base_link link_1
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/557943
推荐阅读
相关标签
  

闽ICP备14008679号