hector 源码分析

参考论文《A Flexible and Scalable SLAM System with Full 3D Motion Estimation》

https://github.com/tu-darmstadt-ros-pkg/hector_slam 上下载hector 源码,用understand 打开。

总的来说,hector的实现过程要比gmapping简单些,但由于博主是c++ 小白一个,门都没入,看着各种函数、运算符的重载,以及一些标准库的应用,简直想死。

main()函数在hector_mapping文件夹下。
转到 HecMappingRos.cpp 文件下,
进入HectorMappingRos 类的构造函数。挑出几个重要的函数(其实就一个是最重要的,其它的都是,都是一些与初始化相关的,以及调试相关的)。

  scanSubscriber_ = node_.subscribe(p_scan_topic_, p_scan_subscriber_queue_size_, &HectorMappingRos::scanCallback, this);

查看scanCallback()这个函数。

void HectorMappingRos::scanCallback(const sensor_msgs::LaserScan& scan)
{
/*这个函数太长了,全部粘贴出来看的就吧清晰了,挑重点*/
...
...
...
/*
重点在这里 ,update()函数,第一个参数,激光数据的封装包,第二个参数,上一次机器人在世界坐标系下的位姿
*/
          slamProcessor->update(laserScanContainer,slamProcessor->getLastScanMatchPose());
...
...
...
}

查看 update()函数

  void update(const DataContainer& dataContainer, const Eigen::Vector3f& poseHintWorld, bool map_without_matching = false)
  {
   
    Eigen::Vector3f newPoseEstimateWorld;
/*重点来了,

扫描匹配
====

的核心代码matchDate()函数
arg1 : t-1时刻机器人在世界坐标系下的位姿
arg2 : 激光数据
arg3 : t-1时刻扫描匹配的协方差
*/
    if (!map_without_matching){
        newPoseEstimateWorld = (mapRep->matchData(poseHintWorld, dataContainer, lastScanMatchCov));
    }else{
        newPoseEstimateWorld = poseHintWorld;
    }

    lastScanMatchPose = newPoseEstimateWorld;

    /*判断位移增量与角度增量是否符合要求*/
    if(util::poseDifferenceLargerThan(newPoseEstimateWorld, lastMapUpdatePose, paramMinDistanceDiffForMapUpdate, paramMinAngleDiffForMapUpdate) || map_without_matching){
   

/*重点,

地图更新
====

  updateByScan
  arg1 : 激光数据
  arg2 : 机器人在世界坐标系下的位姿
*/
      mapRep->updateByScan(dataContainer, newPoseEstimateWorld);

      mapRep->onMapUpdated();
      lastMapUpdatePose = newPoseEstimateWorld;
    }
  }

开始寻找mapRep->matchDate()函数,由于mapRep声明的是 MapRepresentationInterface* 类型,实例化为MapRepMultiMap类型,所以转到 MapRepMultiMap.h 下

  virtual Eigen::Vector3f matchData(const Eigen::Vector3f& beginEstimateWorld, 
                                    const DataContainer& dataContainer, 
                                    Eigen::Matrix3f& covMatrix)
  {
    size_t size = mapContainer.size();

    Eigen::Vector3f tmp(beginEstimateWorld);

    /*默认三层地图,分辨率0.025m 0.05m 0.1m 从0.1m层开始处理
    论文中说,使用分层地图计算是为了避免陷入局部最小值,且其地图的分层,并不是通过高分辨率的地图降采样得到,
    而是使用不同的地图存储器,每种分辨率的地图单独极端,从低分辨率的地图开始进行扫描匹配,然后将方程的解迭代进入高精度的地图再解算,多次迭代后,得到当前时刻,机器人的位姿(更精确)。另一个优点是:使用多分辨率的地图,可是导航,路径规划更高效。
    */
    for (int index = size - 1; index >= 0; --index){
      //std::cout << " m " << i;
      if (index == 0){
        tmp  = (mapContainer[index].matchData(tmp, dataContainer, covMatrix, 5));
      }else{
      /*pow(x,y)为求x的y次幂*/
        dataContainers[index-1].setFrom(dataContainer, static_cast<float>(1.0 / pow(2.0, static_cast<double>(index))));
        tmp  = (mapContainer[index].matchData(tmp, dataContainers[index-1], covMatrix, 3));
      }
    }
    return tmp;
  }

转到 MapProcContainer.h 查看 matchDate()

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值