上一节介绍了路标Landmark数据的订阅和发布,各类数据的发布和订阅基本阐述完毕。
本节会介绍cartographer的主要配置参数,研究这些参数的使用和对算法的影响。
目录
首先还是得回到Ros运行demo(第二节)的launch脚本上。 launch脚本中可以看到demo所用的配置文件是【backpack_2d.lua】。
而backpack_2d.lua在一开始通过include语句加载了map_builder和trajectory_builder的配置:
include "map_builder.lua" include "trajectory_builder.lua"
所以从这两个配置文件先入手
1,map_builder.lua
从名字可以看出【map_builder.lua】是对于类MapBuilder的参数配置。具体参数如下:
include "pose_graph.lua"MAP_BUILDER = {use_trajectory_builder_2d = false, --使用2d轨迹use_trajectory_builder_3d = false, --使用3d轨迹num_background_threads = 4, --核心线程数pose_graph = POSE_GRAPH, --位置图赋值collate_by_trajectory = false, --是否根据轨迹构建修正器}
2,pose_graph.lua
【map_builder.lua 】中引入了【pose_graph.lua】,【pose_graph.lua】是全局位姿优化。具体参数如下:
POSE_GRAPH = {optimize_every_n_nodes = 90, --每次整体优化间隔nodes数constraint_builder = {sampling_ratio = 0.3, --全局约束采样比率(nodes)max_constraint_distance = 15., --全局约束最大间距(当前node与当前submap之间的距离)min_score = 0.55, --全局约束当前最小得分(当前node与当前submap的匹配得分)global_localization_min_score = 0.6, --全局约束全局最小得分(当前node与全局submap的匹配得分)loop_closure_translation_weight = 1.1e4,--闭环检测平移权重loop_closure_rotation_weight = 1e5, --闭环检测旋转权重log_matches = true, --是否打开直方图约束fast_correlative_scan_matcher = {linear_search_window = 7., --fast_CSM匹配搜索距离angular_search_window = math.rad(30.),--fast_CSM匹配搜索角度branch_and_bound_depth = 7, --fast_CSM分支定界深度},ceres_scan_matcher = {occupied_space_weight = 20., --ceres_scan匹配占据空间权重translation_weight = 10., --ceres_scan匹配平移权重rotation_weight = 1., --ceres_scan匹配旋转权重ceres_solver_options = {use_nonmonotonic_steps = true, --是否使用梯度下降策略max_num_iterations = 10, --最大迭代次数num_threads = 1, --使用线程数},},fast_correlative_scan_matcher_3d = {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 = {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, --匹配平移约束(当前submap与在当前submap内的某个node)matcher_rotation_weight = 1.6e3, --匹配旋转约束(当前submap与在当前submap内的某个node)optimization_problem = {huber_scale = 1e1, --Huber因子(与离群值(错误的数据)对整体的影响正相关)。acceleration_weight = 1e3, --IMU加速度的权重rotation_weight = 3e5, --IMU旋转项的权重local_slam_pose_translation_weight = 1e5, --平移约束权重(前后两个node之间的局部观测与全局优化)local_slam_pose_rotation_weight = 1e5, --旋转约束权重(前后两个node之间的局部观测与全局优化)odometry_translation_weight = 1e5, --平移约束权重(前后两个node之阿的局部观测与里程计观测)odometry_rotation_weight = 1e5, --旋转约束权重(前后两个node之阿的局部观测与里程计观测)fixed_frame_pose_translation_weight = 1e1, 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, ceres_solver_options = {use_nonmonotonic_steps = false, --是否使用梯度下降策略max_num_iterations = 50, --最大迭代次数num_threads = 7, --使用线程数},},max_num_final_iterations = 200, --建图结束后最终优化迭代次数global_sampling_ratio = 0.003, --全局地图匹配约束采样比率(nodes)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,--},}
3,trajectory_builder.lua
从名字可以看出【trajectory_builder.lua】是对于类TrajectoryBuilder的参数配置。具体参数如下:
include "trajectory_builder_2d.lua"include "trajectory_builder_3d.lua"TRAJECTORY_BUILDER = {trajectory_builder_2d = TRAJECTORY_BUILDER_2D, --2d轨迹赋值trajectory_builder_3d = TRAJECTORY_BUILDER_3D, --3d轨迹赋值--pure_localization_trimmer = {--max_submaps_to_keep = 3,--},collate_fixed_frame = true, --是否通过固定帧修正collate_landmarks = false, --是否通过反光板修正}
4,trajectory_builder_2d.lua
【trajectory_builder_2d.lua 】中引入了【trajectory_builder_2d.lua】和【trajectory_builder_3d.lua】,两个配置内容是大致类似的,但各自有些特有参数。这里主要说明2D轨迹的参数【trajectory_builder_2d.lua】。具体参数如下:
TRAJECTORY_BUILDER_2D = {use_imu_data = true, --是否使用imu数据min_range = 0., --激光的最近距离max_range = 30., --激光的最远距离min_z = -0.8, --激光的最小高度max_z = 2., --激光的最大高度missing_data_ray_length = 5., --激光的默认数值num_accumulated_range_data = 1, --单个Node节点累积激光帧数voxel_filter_size = 0.025, --激光的网格滤波大小adaptive_voxel_filter = { --自适应滤波 max_length = 0.5, --网格滤波的大小min_num_points = 200, --最小点云数据max_range = 50., --最远点云距离},loop_closure_adaptive_voxel_filter = { --闭环检测自适应滤波max_length = 0.9, min_num_points = 100, max_range = 50.,},use_online_correlative_scan_matching = false, --是否使用CSM激光匹配real_time_correlative_scan_matcher = { --快速CSN激光匹配linear_search_window = 0.1, --平移搜索范围angular_search_window = math.rad(20.), --角度搜索范围translation_delta_cost_weight = 1e-1, --平移代价权重rotation_delta_cost_weight = 1e-1, --旋转代价权重},ceres_scan_matcher = { --ceres优化激光匹配occupied_space_weight = 1., --占据空间权重translation_weight = 10., --平移权重rotation_weight = 40., --旋转权重ceres_solver_options = { use_nonmonotonic_steps = false, --是否使用梯度下降策略max_num_iterations = 20, --最大迭代次数num_threads = 1, --使用线程数},},motion_filter = { --移动滤波max_time_seconds = 5., --2帧激光最小间隔max_distance_meters = 0.2, --2帧激光最小距离max_angle_radians = math.rad(1.), --2帧激光最小角度},-- TODO(schwoere,wohe): Remove this constant. This is only kept for ROS.imu_gravity_time_constant = 10., --imu的重力常数pose_extrapolator = { use_imu_based = false, --是否使用3d初始化位姿预估器constant_velocity = {imu_gravity_time_constant = 10., --imu的重力常数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加速度权重imu_rotation_weight = 1., --IMU旋转权重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, --子图中Node的数量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, --是否改变改变占用网格中的概率。hit_probability = 0.55, --hit(占用) 时的概率miss_probability = 0.49, --miss(空闲) 时的概率},tsdf_range_data_inserter = {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,},},},}
以上就是cartographer中的主要配置参数,这里只是简单的介绍说明,要更加深入的了解还需要到实际案例中使用或者查看其在代码中的功能作用。
【完】
下一节就结合demo案例一起说明,在Ros中使用这些参数时实际的配置及效果。