cartographer自动更新地图 初探

Posted Hill_LAI

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cartographer自动更新地图 初探相关的知识,希望对你有一定的参考价值。

其实cartographer的地图更新,就是用新扫描的地图替换老地图,这里在加载老地图的时候,要加载TrajectoryState::FROZEN状态的地图,这样新地图就按照老地图为坐标系进行匹配和导航了。
cartographer里面自带的移除老地图的功能是考虑建图模式的情况,所以在导航模式时,我们不能任性移除老地图,因为这样会带来定位灾难(老地图可能因为移除局部而整体变形)
所以我们加载老地图的时候,加载模式为TrajectoryState::FROZEN状态,所以我们只要在结束导航的时候,自己写一个接口实现新老地图的比较然后移除老地图,保存新地图即可。(效果还可以哦)

talk is cheap , show my code

  bool MapBuilder::SerializeStateToFileAfterUpdate(
      bool include_unfinished_submaps, const std::string& filename) {

    //. stop thread to trim submap 
    pose_graph_->SetTrimerFlag(false);

    // trim overlap submap first
    pose_graph_->TrimSubmapIdByManual();

    io::ProtoStreamWriter writer(filename);
    io::UpdateAndWritePbStream(map_trajectory_id_, *pose_graph_, all_trajectory_builder_options_, &writer,
                      include_unfinished_submaps);
    return (writer.Close());
  }

TrimSubmapIdByManual函数,

void PoseGraph2D::TrimSubmapIdByManual() {
  absl::MutexLock locker(&mutex_);

  //加载map的时候把约束关系保存在map_constraint_中,因为是FROZEN加载,
  //所以后端优化用不到这些约束,但是在地图更新时要用到,所以提前保存在map_constraint_中
  data_.constraints.insert(data_.constraints.end(), map_constraint_.begin(),
                           map_constraint_.end());

  TrimmingHandle trimming_handle(this);
  for (auto& trimmer : trimmers_) {
    trimmer->TrimBeforeUpdate(&trimming_handle);
  }

  return;
}

TrimBeforeUpdate函数,就是原来的Trim函数,由于我之前为了解决前端阻塞问题,修改了Trim函数,所以这里重写了一个。

void OverlappingSubmapsTrimmer2D::TrimBeforeUpdate(Trimmable* pose_graph) {
  const auto submap_data = pose_graph->GetOptimizedSubmapData();

  const MapLimits first_submap_map_limits =
      std::static_pointer_cast<const Submap2D>(submap_data.begin()->data.submap)
          ->grid()
          ->limits();
  SubmapCoverageGrid2D coverage_grid(first_submap_map_limits);
  const std::map<SubmapId, common::Time> submap_freshness =
      ComputeSubmapFreshness(submap_data, pose_graph->GetTrajectoryNodes(),
                             pose_graph->GetConstraints());
  const std::set<SubmapId> all_submap_ids = AddSubmapsToSubmapCoverageGrid2D(
      submap_freshness, submap_data, &coverage_grid);
  const std::vector<SubmapId> submap_to_remove = FindSubmapIdsToTrim(
      coverage_grid, all_submap_ids, fresh_submaps_count_,
      min_covered_area_ / common::Pow2(coverage_grid.resolution()));
  current_submap_count_ = submap_data.size() - submap_to_remove.size();
  for (const SubmapId& id : submap_to_remove) {
              pose_graph->TrimSubmap(id);
  }
}

还有一些细节,就是在保存地图的时候,也要适当修改,效果真的很赞!这样slam有了更新功能,是不是不用反复建图了!
因为是初步实现功能,这是一个LongLife的问题,所以后续是否还有其他问题,后面再分解。

以上是关于cartographer自动更新地图 初探的主要内容,如果未能解决你的问题,请参考以下文章

cartographer实现自动更新地图(打补丁),香不香?

导航的时候自动更新地图的思路,附使用cartographer的解决方案

cartographer导航的时候更新地图

InfoWindow中的Android Google地图摘要自动更新

Cartographer ROS for Turtlebots 初探

cartographer保存地图