cartographer建图参数配置详细说明

  • Post author:
  • Post category:其他

cartographer也调试了一段时间,并使用它进行了室内的建图和定位导航,在这里对它的建图参数调试进行一个说明,希望能帮助到一些朋友。

如果大家想看英文版参数配置,可以点击链接进入。

基本参数配置

  map_frame = "map",--生成的地图坐标系
  tracking_frame = "base_link",--跟踪的坐标系,可以是imu、小车、雷达
  published_frame = "base_link",--cartographer正在发布pose的坐标,一般就是小车
  odom_frame = "odom",--cartographer的里程计坐标系
  provide_odom_frame = false,-- cartographer是否发布里程计坐标
  publish_frame_projected_to_2d = true,--是否无滚动、俯仰或z偏移
  use_odometry = false,--订阅里程计
  use_nav_sat = false,--订阅GPS
  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,--tf2查找变换超时(s)
  submap_publish_period_sec = 0.3,--发布子图实时间间隔(s)
  pose_publish_period_sec = 5e-3,--发布pose时间间隔(s)
  trajectory_publish_period_sec = 30e-3,--发布轨迹标记间隔(s,这里为30ms)
  rangefinder_sampling_ratio = 1.,--以下5个参数为传感器采样比例
  odometry_sampling_ratio = 1.,
  fixed_frame_pose_sampling_ratio = 1.,
  imu_sampling_ratio = 1.,
  landmarks_sampling_ratio = 1.,

前端参数配置项(trajectory_builder_2d)

这里以2D雷达为例进行说明,如需单独配置前端参数,请关闭后端算法,关闭方式如下:

optimize_every_n_nodes = 0, --设置为0,关闭后端优化。

具体的前端配置参数选项说明如下:

TRAJECTORY_BUILDER_2D = {
  use_imu_data = true,--是否使用imu
  min_range = 0.,--雷达距离配置
  max_range = 30.,
  min_z = -0.8,--雷达高度配置,将高度数据转换成2D
  max_z = 2.,
  missing_data_ray_length = 5.,--超出max_range将以此长度进行free插入,充分利用max_range外的数据,也可以不使用。
  num_accumulated_range_data = 1,--将一帧雷达数据分成几个ros发出来,减少运动畸变影响。
  voxel_filter_size = 0.025,--体素滤波,使远处和近处的点云权重一致
  adaptive_voxel_filter = {
    max_length = 0.5,--最大边长0.5
    min_num_points = 200,--大于此数据,则减小体素滤波器的大小。
    max_range = 50.,--大于max_range的值被移除
  },
  loop_closure_adaptive_voxel_filter = {--闭环的体素滤波器,同上
    max_length = 0.9,
    min_num_points = 100,
    max_range = 50.,
  },
  use_online_correlative_scan_matching = false,--csm算法解决在线扫描匹配问题,为ceres优化提供先验,如果无IMU或odom的情况下,如无此项前端效果较差。但是一旦使用该项,IMU和Odom的效果将会变得很弱。
  real_time_correlative_scan_matcher = {--开启online后使用,分配搜索窗口的参数
    linear_search_window = 0.1, --线窗口
    angular_search_window = math.rad(20.),--角度窗口
    translation_delta_cost_weight = 1e-1,--这两个为平移和旋转的比例,如你知道你的机器人旋转不多,则可以较少它的权重,一般情况下1:1.
    rotation_delta_cost_weight = 1e-1,
  },
--通过online或者imu/odom的先验输入ceres,然后进行优化,以下为优化的参数配置
  ceres_scan_matcher = {
    occupied_space_weight = 1.,--数据源的权重
    translation_weight = 10.,
    rotation_weight = 40.,
    ceres_solver_options = {--谷歌开发的最小二乘库ceres Solver配置
      use_nonmonotonic_steps = false,--是否使用非单调的方法
      max_num_iterations = 20,--迭代次数
      num_threads = 1,--使用线程数
    },
  },
--运动过滤器,避免静止的时候插入scans
  motion_filter = {
    max_time_seconds = 5.,--过滤的时间、距离、角度
    max_distance_meters = 0.2,
    max_angle_radians = math.rad(1.),
  },
  imu_gravity_time_constant = 10.,--一定时间内观察imu的重力,以确定是否使用imu数据
-- pose_extrapolator为位姿推测器的参数,好像已经不用了???
  pose_extrapolator = {
    use_imu_based = false,
    constant_velocity = {
      imu_gravity_time_constant = 10.,
      pose_queue_duration = 0.001,
    },
    imu_based = {
      pose_queue_duration = 5.,
      gravity_constant = 9.806,
      pose_translation_weight = 1.,
      pose_rotation_weight = 1.,
      imu_acceleration_weight = 1.,
      imu_rotation_weight = 1.,
      odometry_translation_weight = 1.,
      odometry_rotation_weight = 1.,
      solver_options = {
        use_nonmonotonic_steps = false;
        max_num_iterations = 10;
        num_threads = 1;
      },
    },
  },
  submaps = {
    num_range_data = 90,--submaps插入的数量
    grid_options_2d = {--子图的形式
      grid_type = "PROBABILITY_GRID",
      resolution = 0.05,
    },
    range_data_inserter = {--概率模型插入
      range_data_inserter_type = "PROBABILITY_GRID_INSERTER_2D",
      probability_grid_range_data_inserter = {
        insert_free_space = true,--插入free空间,没击中
        hit_probability = 0.55,--hit和miss的概率
        miss_probability = 0.49,
      },
      tsdf_range_data_inserter = {--除了2D概率模型,还可以进行TSDF模式插入,没有使用。
        truncation_distance = 0.3,
        maximum_weight = 10.,
        update_free_space = false,
        normal_estimation_options = {
          num_normal_samples = 4,
          sample_radius = 0.5,
        },
        project_sdf_distance_to_scan_normal = true,
        update_weight_range_exponent = 0,
        update_weight_angle_scan_normal_to_ray_kernel_bandwidth = 0.5,
        update_weight_distance_cell_to_hit_kernel_bandwidth = 0.5,
      },
    },
  },
}

后端参数配置项(pose_graph.lua)

前端产生连续子图的同时,全局优化也会在后台运行。它的作用是更新子图位姿,优化全局地图。

POSE_GRAPH = {
optimize_every_n_nodes = 90,--多少节点进行一次优化,0为关闭后端优化。
--constraint_builder为约束项参数
--非全局约束(intra submaps constraints):一条轨迹上的不同节点约束。
--全局约束(inter submaps constraints或者loop closure constrains):新子图与先前的足够近(search window)的节点之间的约束。
constraint_builder = {
sampling_ratio = 0.3,--约束采样,太多则速度慢,太少则会导致约束丢失,闭环效果不好
max_constraint_distance = 15.,--最大约束距离
min_score = 0.55,--Fast csm的最低分数,高于此分数才进行优化。
global_localization_min_score = 0.6,--全局定位最小分数,低于此分数则全局定位不可靠。
loop_closure_translation_weight = 1.1e4,--闭环平移约束权重
loop_closure_rotation_weight = 1e5,--闭环旋转约束权重
log_matches = true,--除了rviz中的约束显示,还可以打开直方图约束,直方图的约束构建器是否开启
fast_correlative_scan_matcher = {--fast csm的搜索窗口参数
linear_search_window = 7.,
angular_search_window = math.rad(30.),
branch_and_bound_depth = 7,--分支定界的最深节点,深度优先搜索
},
ceres_scan_matcher = {--ceres优化器的参数,可以参考前端
occupied_space_weight = 20.,
translation_weight = 10.,
rotation_weight = 1.,
ceres_solver_options = {
use_nonmonotonic_steps = true,
max_num_iterations = 10,
num_threads = 1,
},
},
fast_correlative_scan_matcher_3d = {--3d fast csm参数配置
branch_and_bound_depth = 8,
full_resolution_depth = 3,
min_rotational_score = 0.77,
min_low_resolution_score = 0.55,
linear_xy_search_window = 5.,
linear_z_search_window = 1.,
angular_search_window = math.rad(15.),
},
ceres_scan_matcher_3d = {--3d ceres优化器配置
occupied_space_weight_0 = 5.,
occupied_space_weight_1 = 30.,
translation_weight = 10.,
rotation_weight = 1.,
only_optimize_yaw = false,
ceres_solver_options = {
use_nonmonotonic_steps = false,
max_num_iterations = 10,
num_threads = 1,
},
},
},
matcher_translation_weight = 5e2,--匹配的平移权重(这个是非全局的约束,区别于上面的全局约束)
matcher_rotation_weight = 1.6e3,--匹配的旋转权重
--残差方程的参数配置
optimization_problem = {
huber_scale = 1e1,--huber损失函数,数值越大,离群值(异常值)影响越大
acceleration_weight = 1.1e2,--imu的加速度权重
rotation_weight = 1.6e4,--imu的旋转权重
local_slam_pose_translation_weight = 1e5,--局部匹配的平移权重(局部匹配的粗略估计)
local_slam_pose_rotation_weight = 1e5,--局部匹配的旋转权重
odometry_translation_weight = 1e5,--odom的平移权重
odometry_rotation_weight = 1e5,--odom的旋转权重
fixed_frame_pose_translation_weight = 1e1,--固定帧的平移权重(类似于gps),以下都是固定帧,目前我们还没有用全局定位的传感器
fixed_frame_pose_rotation_weight = 1e2,
fixed_frame_pose_use_tolerant_loss = false,
fixed_frame_pose_tolerant_loss_param_a = 1,
fixed_frame_pose_tolerant_loss_param_b = 1,
log_solver_summary = false,--是否记录ceres的全局优化结果,用于改进外部校准。
use_online_imu_extrinsics_in_3d = true,--是否使用全局优化结果对imu进行优化。
fix_z_in_3d = false,--3d雷达的z轴是否可以变化???
ceres_solver_options = {--可以参考前端
use_nonmonotonic_steps = false,
max_num_iterations = 50,
num_threads = 7,
},
},
max_num_final_iterations = 200,--结束建图之后的优化迭代次数
global_sampling_ratio = 0.003,--全局定位时使用,生成单个定位速率
log_residual_histograms = true,--记录残差直方图
global_constraint_search_after_n_seconds = 10.,
-- overlapping_submaps_trimmer_2d = {
-- fresh_submaps_count = 1,
-- min_covered_area = 2,
-- min_added_submaps_count = 5,
-- },
}

版权声明:本文为QLeelq原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。