【cartographer without ros】八、使用MapBuilder建图,存储,定位

上一节介绍了在脱离ros环境后,引入和使用Rosbag,并进行传感器数据的读写。
本节就将介绍在自己的工程中,使用cartographer的接口进行功能实现。
事实上,这部分是仿照cartographer_ros进行实现:通过使用MapBuilderInterfaceTrajectoryBuilderInterface实现对应的建图,存储和定位。

目录

1:定义和实现接口指针以及参数文件

2:添加传感器数据

3:建图保存

4:加载地图

5:定位回调


1:定义和实现接口指针以及参数文件

#include "cartographer/mapping/map_builder.h"

std::unique_ptr<MapBuilderInterface> map_builder_;
std::unique_ptr<TrajectoryBuilderInterface> trajectory_builder_;
proto::MapBuilderOptions map_builder_options_;
proto::TrajectoryBuilderOptions trajectory_builder_options_;
int trajectory_id_;

void MyMapBuilder::MyMapBuilder()
{
    const std::string kMapBuilderLua = R"text(
            include "my_map_builder.lua"
            return MAP_BUILDER)text";
    auto map_builder_parameters = cartographer::mapping::slamhelper::ResolveLuaParameters(kMapBuilderLua);
    map_builder_options_ = CreateMapBuilderOptions(map_builder_parameters.get());

    const std::string kTrajectoryBuilderLua = R"text(
        include "my_trajectory_builder.lua"
        return TRAJECTORY_BUILDER)text"
    auto trajectory_builder_parameters = cartographer::mapping::slamhelper::ResolveLuaParameters(kTrajectoryBuilderLua);
    trajectory_builder_options_ = CreateTrajectoryBuilderOptions(trajectory_builder_parameters.get());

    map_builder_ = CreateMapBuilder(map_builder_options_);

    std::set<TrajectoryBuilderInterface::SensorId> expected_sensors;
    expected_sensors.insert(kRangeSensorId);
    trajectory_id_ = map_builder_->AddTrajectoryBuilder(
        expected_sensors, trajectory_builder_options_,
         GetLocalSlamResultCallback());
    trajectory_builder_ = map_builder_->GetTrajectoryBuilder(trajectory_id_);
}

2:添加传感器数据

void MyMapBuilder::AddData(cartographer::sensor::TimedPointCloudData measurement)
{
   trajectory_builder_->AddSensorData(kRangeSensorId.id, measurement); 
}

3:建图保存

void MyMapBuilder::SaveLoadState()
{
    const std::string filename = "mymap.pbstream";

    LOG(WARNING) << "  MyMapBuilder::SaveLoadState: Save '" << filename << "' Start";
    map_builder_->FinishTrajectory(trajectory_id_);
    LOG(WARNING) << "  MyMapBuilder::SaveLoadState: Running final trajectory optimization...";
    map_builder_->pose_graph()->RunFinalOptimization();
    int num_constraints = map_builder_->pose_graph()->constraints().size();
    int num_nodes =
        map_builder_->pose_graph()->GetTrajectoryNodes().SizeOfTrajectoryOrZero(
            trajectory_id_);
    EXPECT_GT(num_constraints, 0);
    EXPECT_GT(num_nodes, 0);

    cartographer::io::ProtoStreamWriter writer(filename);
    map_builder_->SerializeState(/*include_unfinished_submaps=*/true, &writer);
    writer.Close();
    LOG(WARNING) << "  MyMapBuilder::SaveLoadState: Save '" << filename << "' End";
}

4:加载地图

void MyMapBuilder::LoadMap()
{
    LOG(WARNING) << "  MyMapBuilder::LoadMap: Loading '" << map_load_path << "'";
    cartographer::io::ProtoStreamReader reader(map_load_path);
    map_builder_->LoadState(&reader, true /* load_frozen_state */);
    map_builder_->pose_graph()->RunFinalOptimization();
}

5:定位回调

    MapBuilderInterface::LocalSlamResultCallback MyMapBuilder::GetLocalSlamResultCallback()
    {
        return [=](const int trajectory_id_, const ::cartographer::common::Time time,
                   const ::cartographer::transform::Rigid3d local_pose,
                   ::cartographer::sensor::RangeData range_data_in_local,
                   const std::unique_ptr<
                       const cartographer::mapping::TrajectoryBuilderInterface::
                           InsertionResult>)
        {
               cartographer::transform::Rigid3d global_pose = map_builder_->pose_graph()->GetLocalToGlobalTransform(trajectory_id_) * local_pose;
        }
    }

【完】


至此在不带ros的环境中,引入cartographer的开发部分结束。
下一节将介绍cartographer的移植,以ARM的交叉编译为例。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CloudFlame

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值