首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MRPT图Slam最小示例

MRPT图Slam最小示例
EN

Stack Overflow用户
提问于 2018-07-19 11:48:40
回答 1查看 279关注 0票数 0

我正试图想出一种使用MRPT运行图形slam应用程序的“最小”方法。传感器数据(LaserScan /计量学)将由类似于ROS的定制中间件提供。在广泛阅读了文档和源代码(包括MRPT和ROS桥)之后,我想出了以下代码片段:

代码语言:javascript
复制
std::string config_file = "../../../laser_odometry.ini";   
std::string rawlog_fname = "";   
std::string fname_GT = "";   
auto node_reg = mrpt::graphslam::deciders::CICPCriteriaNRD<mrpt::graphs::CNetworkOfPoses2DInf>{}; 
auto edge_reg = mrpt::graphslam::deciders::CICPCriteriaERD<mrpt::graphs::CNetworkOfPoses2DInf>{}; 
auto optimizer = mrpt::graphslam::optimizers::CLevMarqGSO<mrpt::graphs::CNetworkOfPoses2DInf>{};

auto win3d = mrpt::gui::CDisplayWindow3D{"Slam", 800, 600};
auto win_observer = mrpt::graphslam::CWindowObserver{};
auto win_manager = mrpt::graphslam::CWindowManager{&win3d, &win_observer};

auto engine = mrpt::graphslam::CGraphSlamEngine<mrpt::graphs::CNetworkOfPoses2DInf>{
  config_file, rawlog_fname, fname_GT, &win_manager, &node_reg, &edge_reg, &optimizer};

for (size_t measurement_count = 0;;) {
   // grab laser scan from the network, then fill it (hardcoded values for now), e.g:
   auto scan_ptr = mrpt::obs::CObservation2DRangeScan::Create();
   scan_ptr->timestamp = std::chrono::system_clock::now().time_since_epoch().count();
   scan_ptr->rightToLeft = true;
   scan_ptr->sensorLabel = "";
   scan_ptr->aperture = 3.14;  // rad (max-min)
   scan_ptr->maxRange = 3.0;   // m
   scan_ptr->sensorPose = mrpt::poses::CPose3D{};

   scan_ptr->resizeScan(30);
   for (int i = 0; i < 30; ++i) {
     scan_ptr->setScanRange(i, 0.5);
     scan_ptr->setScanRangeValidity(i, true);
   }

   { // Send LaserScan measurement to the slam engine
     auto obs_ptr = std::dynamic_pointer_cast<mrpt::obs::CObservation>(scan_ptr);
     engine.execGraphSlamStep(obs_ptr, measurement_count);
     ++measurement_count;
   }


   // grab odometry from the network, then fill it (hardcoded values for now), e.g:
   auto odometry_ptr = mrpt::obs::CObservationOdometry::Create();
   odometry_ptr->timestamp = std::chrono::system_clock::now().time_since_epoch().count();
   odometry_ptr->hasVelocities = false;
   odometry_ptr->odometry.x(0);
   odometry_ptr->odometry.y(0);
   odometry_ptr->odometry.phi(0);

   { // Send Odometry measurement to the slam engine
     auto obs_ptr = std::dynamic_pointer_cast<mrpt::obs::CObservation>(odometry_ptr);
     engine.execGraphSlamStep(obs_ptr, measurement_count);
     ++measurement_count;
   }

   // Get pose estimation from the engine
   auto pose = engine.getCurrentRobotPosEstimation();

}

我在这里的方向对吗?我错过了什么吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-19 15:49:10

嗯,乍一看,剧本看上去很好,你用两个不同的步骤和观察形式提供了测定仪和激光扫描。

  • 小音符 auto node_reg = mrpt::graphslam::deciders::CICPCriteriaNRD{};

如果您想要运行与节理+激光扫描使用CFixedIntervalsNRD代替。这是更好的测试,并实际使用这些测量。

目前MRPT中没有最小的图形slam引擎示例,但是下面是使用数据集运行图形slam的主要方法:

impl.h#L395

代码语言:javascript
复制
template <class GRAPH_T>
void CGraphSlamHandler<GRAPH_T>::execute()
{
    using namespace mrpt::obs;
    ASSERTDEB_(m_engine);

    // Variables initialization
    mrpt::io::CFileGZInputStream rawlog_stream(m_rawlog_fname);
    CActionCollection::Ptr action;
    CSensoryFrame::Ptr observations;
    CObservation::Ptr observation;
    size_t curr_rawlog_entry;
    auto arch = mrpt::serialization::archiveFrom(rawlog_stream);

    // Read the dataset and pass the measurements to CGraphSlamEngine
    bool cont_exec = true;
    while (CRawlog::getActionObservationPairOrObservation(
               arch, action, observations, observation, curr_rawlog_entry) &&
           cont_exec)
    {
        // actual call to the graphSLAM execution method
        // Exit if user pressed C-c
        cont_exec = m_engine->_execGraphSlamStep(
            action, observations, observation, curr_rawlog_entry);
    }
    m_logger->logFmt(mrpt::system::LVL_WARN, "Finished graphslam execution.");
}

基本上,您可以获取数据,然后通过execGraphSlamStep或_execGraphSlamStep方法不断地将它们提供给_execGraphSlamStep。

下面还有相应的ROS包装器中处理度量的相关片段,该包装器使用来自ROS主题的度量操作:

impl.h#L719

代码语言:javascript
复制
template<class GRAPH_T>
void CGraphSlamHandler_ROS<GRAPH_T>::processObservation(
        mrpt::obs::CObservation::Ptr& observ) {
  this->_process(observ);
}

template<class GRAPH_T>
void CGraphSlamHandler_ROS<GRAPH_T>::_process(
        mrpt::obs::CObservation::Ptr& observ) {
  using namespace mrpt::utils;
  if (!this->m_engine->isPaused()) {
        this->m_engine->execGraphSlamStep(observ, m_measurement_cnt);
        m_measurement_cnt++;
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51421935

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档