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的方法,从名字来看,先猜测他是前端和后端的结合点,将前端的结果传到后端。
这个类的讨论就先到这里,我们即将真正的接触到算法了,这个学习进度也没有之前那么快了,作者得一边看代码,边学理论了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值