cartographer_learn_8
续接上一篇
上一篇讨论到了说给不同的数据配备数据队列分配处理函数,即第7篇中的最后一个函数的,最后一个函数的最后一句又调用了Dispatchable::AddToTrajectoryBuilder,代码如下:
void AddToTrajectoryBuilder(
mapping::TrajectoryBuilderInterface *const trajectory_builder) override {
trajectory_builder->AddSensorData(sensor_id_, data_);
}
看来是调用了CollatedTrajectoryBuilder::wrapped_trajectory_builder_的类方法了,那下个要讨论的就是这个wrapped_trajectory_builder_,首先确定它的类型,在collated_trajectory_builder.h文件中看到类型是TrajectoryBuilderInterface这一看肯定是个基类指向派生类的操作,所以回到map_builder.h中看MapBuilder::AddTrajectoryBuilder这个函数的。看2d时的情况:
int MapBuilder::AddTrajectoryBuilder(
const std::set<SensorId>& expected_sensor_ids,
const proto::TrajectoryBuilderOptions& trajectory_options,
LocalSlamResultCallback local_slam_result_callback) {
......//一堆操作
trajectory_builders_.push_back(absl::make_unique<CollatedTrajectoryBuilder>(
trajectory_options, sensor_collator_.get(), trajectory_id,
expected_sensor_ids,
CreateGlobalTrajectoryBuilder2D(
std::move(local_trajectory_builder), trajectory_id,
static_cast<PoseGraph2D*>(pose_graph_.get()),
local_slam_result_callback, pose_graph_odometry_motion_filter)));
......//又是一堆操作
}
看来它真正的类型时CreateGlobalTrajectoryBuilder2D这个函数的返回值。F12进去查看这个函数
std::unique_ptr<TrajectoryBuilderInterface> CreateGlobalTrajectoryBuilder2D(
std::unique_ptr<LocalTrajectoryBuilder2D> local_trajectory_builder,
const int trajectory_id, mapping::PoseGraph2D* const pose_graph,
const TrajectoryBuilderInterface::LocalSlamResultCallback&
local_slam_result_callback,
const absl::optional<MotionFilter>& pose_graph_odometry_motion_filter) {
return absl::make_unique<
GlobalTrajectoryBuilder<LocalTrajectoryBuilder2D, mapping::PoseGraph2D>>(
std::move(local_trajectory_builder), trajectory_id, pose_graph,
local_slam_result_callback, pose_graph_odometry_motion_filter);
}
哦,看到了这个wrapped_trajectory_builder_真正的类型是GlobalTrajectoryBuilder<LocalTrajectoryBuilder2D, mapping::PoseGraph2D>>,让我们记住LocalTrajectoryBuilder2D和mapping::PoseGraph2D这两个模板参数,接下来我们的讨论来到了GlobalTrajectoryBuilder这个类中。它在src/cartographer/cartographer/mapping/internal/global_trajectory_builder.cc中。
GlobalTrajectoryBuilder的类成员
template <typename LocalTrajectoryBuilder, typename PoseGraph>
class GlobalTrajectoryBuilder : public mapping::TrajectoryBuilderInterface {
......//一堆类方法
private:
const int trajectory_id_; //轨迹id
PoseGraph* const pose_graph_; //实际的类型为PoseGraph2D
std::unique_ptr<LocalTrajectoryBuilder> local_trajectory_builder_; //实际类型为LocalTrajectoryBuilder2D
LocalSlamResultCallback local_slam_result_callback_; //貌似是做记录的一个回调函数
absl::optional<MotionFilter> pose_graph_odometry_motion_filter_; //运动滤波器
}
这里存储了两个指针。pose_graph_(类型为PoseGraph2D),第5篇的时候遇到过这个类型(PoseGraph),当时说它是后端。local_trajectory_builder_(类型为LocalTrajectoryBuilder2D),相信它就是前端了。运动滤波器pose_graph_odometry_motion_filter_,只是知道它会忽略掉那些运动幅度过小或者时间间隔过小的运动,但是至于对整个slam过程起到什么作用相信我们往后会讨论到它。
GlobalTrajectoryBuilder的类方法
这里又要回到本篇一开始的那个代码块,为了给不同的数据队列赋予不同的处理函数,cartographer的做法是调用一个模板类Dispatchable的类方法AddToTrajectoryBuilder,可以看到这个类方法又调用了TrajectoryBuilderInterface::AddSensorData(其实就是这个类的类方法)。我们看到GlobalTrajectoryBuilder为各种数据类型重载了了一个叫AddSensorData的函数,有点云的,有imu的,里程计的,gps的等。最后它还有一个类方法AddLocalSlamResultData,上代码
void AddLocalSlamResultData(std::unique_ptr<mapping::LocalSlamResultData>
local_slam_result_data) override {
CHECK(!local_trajectory_builder_) << "Can't add LocalSlamResultData with "
"local_trajectory_builder_ present.";
local_slam_result_data->AddToPoseGraph(trajectory_id_, pose_graph_);
}
先是检查了一下什么东西,然后调用一个名为局部slam结果的类的AddToPoseGraph的方法,从名字来看,先猜测他是前端和后端的结合点,将前端的结果传到后端。
这个类的讨论就先到这里,我们即将真正的接触到算法了,这个学习进度也没有之前那么快了,作者得一边看代码,边学理论了。