cartographer坐标系_大大西瓜/cartographer代码解读

cartographer代码解读

0. 说明

只列主要示意性代码,其他代码省略

以处理LaserScan, 2D为例

采用Collator(参数map_builder.collate_by_trajectory 为false)

使用 --> 表示后续函数调用,或经过某个变量调用的后续函数

使用

使用 >>> 表示topic的回调函数中的后续函数调用

1. 总览

成员变量

MapBuilder* map_builder_;

map sensor_bridges_;

构造函数 MapBuilderBridge(..., map_builder, ...)

设置成员变量 map_builder_ = map_builder;

成员函数 AddTrajectory

初始化 MapBuilder 内容

map_builder_ --> 调用 MapBuilder::AddTrajectoryBuilder,获得trajectory_id

添加 SensorBridge(..., MapBuilder::GetTrajectoryBuilder(trajectory_id)

成员变量

TrajectoryBuilderInterface* (

构造函数 SensorBridge(..., trajectory_builder)

设置成员变量 trajectory_builder_ = trajectory_builder;

成员变量

vector trajectory_builders_;

PoseGraph* (

CollatorInterface* (

ThreadPool thread_pool_;

构造函数 MapBuilder(...)

thread_pool_(options.num_background_threads);

根据配置设置成员变量pose_graph_ 和 sensor_collator_,以开始所假设的配置

pose_graph_ = new PoseGraph2D(..., new optimization::OptimizationProblem2D(...), ...);

sensor_collator_ = new Collator();

成员函数 AddTrajectoryBuilder

int trajectory_id = trajectory_builders_.size();

local_trajectory_builder = new LocalTrajectoryBuilder2D(...);

g_trajectory_builder = new GlobalTrajectoryBuilder(local_trajectory_builder, trajectory_id, pose_graph_, res_callback);

trajectory_builders_.push_back( new CollatedTrajectoryBuilder(..., sensor_collator_, trajectory_id, ..., g_trajectory_builder) );

成员函数 GetTrajectoryBuilder(trajectory_id)

return trajectory_builders_[trajectory_id];

成员函数 FinishTrajectory(trajectory_id)

sensor_collator_ --> 调用Collator::FinishTrajectory(trajectory_id);

pose_graph_ --> 调用 PoseGraph2D::FinishTrajectory(trajectory_id);

成员变量

int trajectory_id_;

CollatorInterface* (

TrajectoryBuilderInterface* (

构造函数 CollatedTrajectoryBuilder(..., sensor_collator, trajectory_id, ..., wrapped_trajectory_builder)

trajectory_id_ = trajectory_id;

sensor_collator_ = sensor_collator;

wrapped_trajectory_builder_ = wrapped_trajectory_builder;

sensor_collator_ --> 调用Collator::AddTrajectory(trajectory_id, ..., HandleCollatedSensorData);

成员函数 AddSensorData(sensor_id, raw_data)

sensor_collator_ --> 调用Collator::AddSensorData(MakeDispatchable(sensor_id, raw_data))

成员变量

string sensor_id_ (基类Data的成员);

DataType data_;

构造函数 Dispatchable(string sensor_id, DataType data)

设置相应成员变量;

成员函数 AddToTrajectoryBuilder(TrajectoryBuilderInterface* trajectory_builder)

trajectory_builder --> 调用 GlobalTrajectoryBuilder::AddSensorData(sensor_id_, data_);

成员变量

OrderedMultiQueue queue_;

成员函数 AddTrajectory(trajectory_id, topicIDList, callback)

key = QueueKey{trajectory_id, topicID};

queue_.AddQueue(key, callback);

成员函数 AddSensorData(topicID, data)

key = QueueKey{trajectory_id, topicID};

queue_.Add(key, data) --> OrderedMultiQueue::Dispatch --> CollatedTrajectoryBuilder::HandleCollatedSensorData

成员函数 FinishTrajectory(trajectory_id)

queue_.MarkQueueAsFinished(queue_key);

成员变量

int trajectory_id_;

PoseGraph* pose_graph_;

LocalTrajectoryBuilder* local_trajectory_builder_;

LocalSlamResultCallback local_slam_result_callback_;

构造函数 GlobalTrajectoryBuilder(local_trajectory_builder, trajectory_id, pose_graph_, result_callback)

设置相应成员变量;

成员函数 AddSensorData(sensor_id, timed_point_cloud_data)

local_trajectory_builder_ --> 调用 matching_result = LocalTrajectoryBuilder2D::AddRangeData(sensor_id, timed_point_cloud_data);

pose_graph_ --> 调用 node_id = PoseGraph2D::AddNode(matching_result..., trajectory_id_, ...);

local_slam_result_callback_(...);

成员函数 AddSensorData(sensor_id, imu_data)

local_trajectory_builder_ --> 调用 LocalTrajectoryBuilder2D::AddImuData(imu_data);

pose_graph_ --> 调用 PoseGraph2D::AddImuData(trajectory_id_, imu_data);

成员函数 AddSensorData(sensor_id, odometry_data)

local_trajectory_builder_ --> 调用 LocalTrajectoryBuilder2D::AddOdometryData(odometry_data);

pose_graph_ --> 调用 PoseGraph2D::AddOdometryData(trajectory_id_, odometry_data);

成员变量

PoseExtrapolator* extrapolator_;

RangeDataCollator range_data_collator_;

proto::LocalTrajectoryBuilderOptions2D options_; // TRAJECTORY_BUILDER_2D

ActiveSubmaps2D active_submaps_;

成员函数 AddImuData(imu_data)

LocalTrajectoryBuilder2D::InitializeExtrapolator(imu_data.time);

extrapolator_->AddImuData(imu_data);

成员函数 AddOdometryData(odometry_data)

extrapolator_->AddOdometryData(odometry_data);

成员函数 AddRangeData(sensor_id, unsynchronized_data)

利用range_data_collator_ 调用 RangeDataCollator::AddRangeData将不同传感器的unsynchronized_data按时间戳先后顺序重新编排,获得synchronized_data;

利用extrapolator_进行运动补偿,将不同时刻的synchronized_data变换到统一时刻下;

按距离对数据切割和初始化;

丢弃掉距离小于options_.min_range的点云数据;

将距离小于 options_.max_range数据累积到accumulated_range_data_.returns里;

将距离大于 options_.max_range数据累积到accumulated_range_data_.misses里,

累积前先把数据的距离变到options_.missing_data_ray_length;

如果累积消息数达到options_.num_accumulated_range_data,则开始处理数据;

调用 TransformToGravityAlignedFrameAndFilter 预处理数据;

调用 AddAccumulatedRangeData 开始正式SLAM处理;

按照重力方向对点云数据进行变换,使得z轴与重力方向重合;

保留z坐标在options_.min_z和options_.max_z间的数据;

用VoxelFilter对点云数据进行滤波,即按照options_.voxel_filter_size参数划分格子,每个格子只保留一个点

利用 extrapolator_生成预测位姿;

按照 options_.adaptive_voxel_filter里面的参数,用AdaptiveVoxelFilter对点云数据进行滤波;

用预测位姿,将滤波后的点云数据和地图做 ScanMatch(预测位姿, 点云数据),获得位姿pose_estimate;

extrapolator_->AddPose(time, pose_estimate);

利用pose_estimate对点云数据变换到地图坐标系下,InsertIntoSubmap(地图坐标系下的点云数据, ...);

成员函数 ScanMatch(预测位姿,点云数据)

取当前活跃子地图列表中的最新一个作为 matching_submap;

initial_ceres_pose = pose_prediction;

如果 options_.use_online_correlative_scan_matching 为真,按照 options_.real_time_correlative_scan_matcher 里面的参数,调用 RealTimeCorrelativeScanMatcher2D ::Match(预测位姿, 点云数据, matching_submap),修改initial_ceres_pose;

按照 options_.ceres_scan_matcher 里面的参数,调用 CeresScanMatcher2D::Match(预测位姿, initial_ceres_pose, 点云数据, matching_submap),获得最终位姿;

成员函数 InsertIntoSubmap(地图坐标系下的点云数据)

active_submaps_ --> 调用 ActiveSubmaps2D::InsertRangeData(地图坐标系下的点云数据);

成员函数 Filter及后续调用函数FilterByMaxRange和AdaptivelyVoxelFiltered

剔除距离大于 adaptive_voxel_filter.max_range的点;

如果点云数小于 adaptive_voxel_filter.min_num_points,返回当前点云;

用 adaptive_voxel_filter.max_length 为参数,用VoxelFilter对点云数据进行滤波,如果点云数大于 adaptive_voxel_filter.min_num_points(点数足够密),则返回当前点云;

从 adaptive_voxel_filter.max_length 开始,做二分查找VoxelFilter参数,使得滤波后的点云数点云数尽量接近 adaptive_voxel_filter.min_num_points;

2. cartographer_ros

2.1 主函数 Run (node_main.cc) 返回总览

Node node(..., new MapBuilder(...), ...)

node.StartTrajectoryWithDefaultTopics(...)

::ros::spin()

node.FinishAllTrajectories();

node.RunFinalOptimization();

2.2 主节点类 Node (node.h, node.cc)

成员变量

MapBuilderBridge* map_builder_bridge_;

Node(..., map_builder, ...)

设置成员变量 map_builder_bridge_(..., map_builder, ...)

StartTrajectoryWithDefaultTopics(...) --> AddTrajectory(...) 返回总览

map_builder_bridge_.AddTrajectory(topicIDList, ...);

AddExtrapolator(...);

LaunchSubscribers(...);

LaunchSubscribers(...) 返回总览

scanTopic >>> HandleLaserScanMessage

if (trajectory_builder_2d.use_imu_data)

imuTopic >>> HandleImuMessage

if (options.use_odometry)

odomTopic >>> HandleOdometryMessage

HandleLaserScanMessage(trajectory_id, ...) 返回总览

map_builder_bridge_.sensor_bridge_[trajectory_id]->HandleLaserScanMessage(...);

HandleImuMessage(trajectory_id, ...) 返回总览

extrapolators.AddImuData(...);

map_builder_bridge_.sensor_bridge_[trajectory_id]->HandleImuMessage(...);

HandleOdometryMessage(trajectory_id, ...) 返回总览

extrapolators.AddOdometryData(...);

map_builder_bridge_.sensor_bridge_[trajectory_id]->HandleOdometryMessage(...);

FinishAllTrajectories() 返回总览

...

map_builder_bridge_.FinishTrajectory(...);

RunFinalOptimization() 返回总览

...-->map_builder_bridge_.FinishTrajectory(...);

map_builder_bridge_.RunFinalOptimization();

2.3 MapBuilderBridge 类 (map_builder_bridge.h, map_builder_bridge.cc)

成员变量

MapBuilder* map_builder_;

map sensor_bridges_;

MapBuilderBridge(..., map_builder, ...)

设置成员变量 map_builder_ = map_builder;

AddTrajectory(topicIDList, ...) 返回总览

trajectory_id = map_builder_->AddTrajectoryBuilder(topicIDList, ...);

sensor_bridges_[trajectory_id] = new SensorBridge(..., map_builder_->GetTrajectoryBuilder(trajectory_id));

FinishTrajectory(trajectory_id) 返回总览

map_builder_->FinishTrajectory(trajectory_id);

RunFinalOptimization() 返回总览

map_builder_->pose_graph()->RunFinalOptimization();

2.4 SensorBridge 类 (sensor_bridge.h, sensor_bridge.cc)

成员变量

TrajectoryBuilderInterface* (

SensorBridge(..., trajectory_builder)

设置成员变量 trajectory_builder_ = trajectory_builder;

HandleLaserScanMessage(...) --> HandleLaserScan(...) 返回总览

for (num_subdivisions_per_laser_scan){

set subdivision data;

HandleRangefinder(topicID, ..., subdivision) --> trajectory_builder_->AddSensorData(topicID, TimedPointCloudData);

}

HandleImuMessage(...) 返回总览

trajectory_builder_->AddSensorData(topicID, ImuData);

HandleOdometryMessage(...) 返回总览

trajectory_builder_->AddSensorData(topicID, OdometryData);

3. cartographer

3.1 MapBuilder 类 (map_builder.h, map_builder.cc)

成员变量

vector trajectory_builders_

PoseGraph* (

CollatorInterface* (

MapBuilder(...)

if (map_builder.use_trajectory_builder_2d){

pose_graph_ = new PoseGraph2D(..., new optimization::OptimizationProblem2D(...), ...);

}

if (map_builder.use_trajectory_builder_3d){

pose_graph_ = new PoseGraph3D(..., new optimization::OptimizationProblem3D(...), ...);

}

if (map_builder.collate_by_trajectory)

sensor_collator_ = new TrajectoryCollator();

else

sensor_collator_ = new Collator();

AddTrajectoryBuilder(topicIDList, ...) 返回总览

int trajectory_id = trajectory_builders_.size();

if (map_builder.use_trajectory_builder_3d){

if (!map_builder.has_trajectory_builder_3d_options)

local_trajectory_builder = new LocalTrajectoryBuilder3D(topicIDList, ...)

trajectory_builders_.push_back( CollatedTrajectoryBuilder(..., sensor_collator, trajectory_id, topicIDList,

new GlobalTrajectoryBuilder(local_trajectory_builder, trajectory_id, pose_graph, result_callback) ) );

}else{

if (!map_builder.has_trajectory_builder_2d_options)

local_trajectory_builder = new LocalTrajectoryBuilder2D(topicIDList, ...)

trajectory_builders_.push_back( CollatedTrajectoryBuilder(..., sensor_collator, trajectory_id, topicIDList,

new GlobalTrajectoryBuilder(local_trajectory_builder, trajectory_id, pose_graph, result_callback) ) );

}

MaybeAddPureLocalizationTrimmer(trajectory_id, ..., pose_graph_);

if (trajectory_builder.has_initial_trajectory_pose)

pose_graph_->SetInitialTrajectoryPose(trajectory_id, trajectory_builder.initial_trajectory_pose, ...);

GetTrajectoryBuilder(trajectory_id) 返回总览

return trajectory_builders_[trajectory_id]; // CollatedTrajectoryBuilder

FinishTrajectory(...) 返回总览

sensor_collator_->FinishTrajectory(trajectory_id);

pose_graph_->FinishTrajectory(trajectory_id);

3.2 CollatedTrajectoryBuilder 类 (collated_trajectory_builder.h, collated_trajectory_builder.cc)

CollatedTrajectoryBuilder(..., sensor_collator, trajectory_id, topicIDList, wrapped_trajectory_builder)

sensor_collator->AddTrajectory(trajectory_id, topicIDList, HandleCollatedSensorData);

HandleCollatedSensorData(topicID, data) 返回总览

data->AddToTrajectoryBuilder(wrapped_trajectory_builder); // GlobalTrajectoryBuilder

AddSensorData(topicID, TimedPointCloudData/ImuData/OdometryData) --> AddData --> sensor_collator->AddSensorData

3.3 Collator 类 (collator.h, collator.cc) // sensor_collator

AddTrajectory(trajectory_id, topicIDList, callback) 返回总览

for (topicID: topicIDList){

queue_key = QueueKey{trajectory_id, topicID};

queue_.AddQueue(queue_key, callback);

}

AddSensorData(topicID, data) 返回总览

queue_key = QueueKey{trajectory_id, topicID};

queue_.Add(queue_key, data) --> Dispatch --> callback

3.4 GlobalTrajectoryBuilder 类 (map_builder.h, map_builder.cc)

3.5 LocalTrajectoryBuilder2D 类 (map_builder.h, map_builder.cc)

3.6 PoseGraph2D 类 (map_builder.h, map_builder.cc)

RunFinalOptimization(...) 返回总览

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值