激光slam第5章作业

  • Post author:
  • Post category:其他



1.1编译abs 错误

1 改pcl   1.10  c++14

2、解决方法:将 unsigned int 改为 int 即可

error: call of overloaded ‘abs(unsigned int)’ is ambiguous

121 |   unsigned int di = abs(i – src_i);

编译通过

1.2

map –> odom –> base_link –> laser_link

1. 补充代码,实现 gaussian_newton_scanmatcher 模块;(6 分)

(补充代码)

1  InterpMapValueWithDerivatives()函数

Eigen::Vector3d InterpMapValueWithDerivatives(map_t* map,Eigen::Vector2d& coords)
{
    Eigen::Vector3d ans;
    //TODO
    //求出附近左上角最小整数值
    int x_0=floor((coords(0)-map->origin_x)/map->resolution+0.5)+map->size_x/2;
    int y_0=floor((coords(1)-map->origin_y)/map->resolution+0.5)+map->size_y/2;
    //由x1-x0=1,所以u=x-x0,v=y-y0;
    //求出离附近整数值差值
      double u = (coords(0) - map->origin_x) / map->resolution + 0.5 +double(map->size_x / 2)- (double)x_0 ;
    double v  = (coords(1) - map->origin_y) / map->resolution + 0.5  + double(map->size_y / 2)- (double)y_0;
 

    //搜索附近分值
    double P1,P2,P3,P4;
     P1=map->cells[MAP_INDEX(map,x_0,y_0)].score;
     P2=map->cells[MAP_INDEX(map,x_0+1,y_0)].score;
     P3=map->cells[MAP_INDEX(map,x_0+1,y_0+1)].score;
     P4=map->cells[MAP_INDEX(map,x_0,y_0+1)].score;
    
    //插值计算分值
   //M(ST)
    ans(0) = v*(u*P3+(1-u)*P4)+(1-v)*(u*P2+(1-u)*P1);

     //对函数进行x和y求导
    //STdx
    ans(1)=(v*(P3-P4) + (1-v)*(P2-P1))/map->resolution;
    //STdy
    ans(2)=( u*(P3-P2) + (1-u)*(P4 - P1) )/map->resolution; 

   
    //END OF TODO

    return ans;
}

2  ComputeHessianAndb()函数

double ComputeHessianAndb(map_t* map, Eigen::Vector3d now_pose,
                        std::vector<Eigen::Vector2d>& laser_pts,
                        Eigen::Matrix3d& H, Eigen::Vector3d& b)
{
    H = Eigen::Matrix3d::Zero();
    b = Eigen::Vector3d::Zero();

    //TODO
    Eigen::Matrix3d T;

    T<<cos(now_pose(2)),-sin(now_pose(2)),now_pose(0),
    sin(now_pose(2)),cos(now_pose(2)),now_pose(1),
    0,0,1;

    Eigen::Vector3d laser_pose;
    Eigen::Vector3d ST3d;
    Eigen::Vector2d ST2d;
    Eigen::Vector3d ans;
    Eigen::Vector2d coords ;
    Eigen::Vector2d dMst ;
    Eigen::Matrix<double,2,3>dST;

    double error=0.0;

    for(int i=0;i<laser_pts.size();i++)
    {
        laser_pose<<laser_pts[i][0],laser_pts[i][1],1;
           //M(S(T)) 计算
           ST3d=T*laser_pose;
           ST2d <<ST3d(0),ST3d(1);
           ans=InterpMapValueWithDerivatives(map,ST2d);
           //dst
            dMst <<  ans(1), ans(2);
        double J1 = ans(1) ;  double J2 =    ans(2);

       double J3 =   ans(1)*dST(0,2)+dST(1,2)*ans(2); 
        H(0,0) += J1*J1;       H(0,1) += J1*J2;     H(0,2) += J3*J1;
        H(1,0) += H(0,1);      H(1,1) += J2*J2;     H(1,2) += J3*J2;
        H(2,0) += H(0,2) ;     H(2,1) += H(1,2) ;   H(2,2) +=J3*J3;
       
        double er = 1-ans(0);
        Eigen::Vector3d  ver;
         ver  << J1*er,J2*er,J3*er; 
         b += ver;
         error += er*er;
    }
    return error*0.5;
    //END OF TODO
}

3  GaussianNewtonOptimization()函数

void GaussianNewtonOptimization(map_t*map,Eigen::Vector3d& init_pose,std::vector<Eigen::Vector2d>& laser_pts)
{
    int maxIteration = 20;
    double lasrterror =0; 
    Eigen::Vector3d now_pose = init_pose;
    bool flat=true;
    Eigen::Vector3d DT;
    static Eigen::Vector3d DT_sum;
    
    for(int i = 0; i < maxIteration;i++)
    {
        //TODO
       Eigen::Matrix3d H;
       Eigen::Vector3d b;
       double error=ComputeHessianAndb(map,now_pose,laser_pts,H,b);
       Eigen::Vector3d dT=H.ldlt().solve(b);
       if( lasrterror > 0 && error > lasrterror)//分值越大,函数结果越小
      {
         break;
      }
      if(std::isnan(dT[0]))
      {
          std::cout<<"result is nan!"<<std::endl;
          break;
      }
       lasrterror = error;
       DT += dT;
       now_pose += dT;
        //END OF TODO
        if(error <10e-5)
        break;
        
        //END OF TODO
    }
    init_pose = now_pose;

}

运行说明:

source 之后用 rosrun gaussian_newton_scanmatcher gaussian_newton_node 命令运行。播放

bag 包,之后可用 rviz 查看轨迹。


2. 简答题,开放性答案:提出一种能提升第一题激光匹配轨迹精度的方法,并解释原因;(2 分)


3. 阅读论文 The Normal Distributions Transform: A New Approach to Laser Scan Matching,

回答以下问题:(2 分)

(1) NDT 的优化函数(score)是什么?

(2) 简述 NDT 根据 score 函数进行优化求解的过程。

4. 机器人在 XY 方向上进行 CSM 匹配。下图左为机器人在目标区域粗分辨率下 4 个位置的匹配得分,得分越高说明机器人在该位置匹配的越好,下图右为机器人在同一块地图细分辨率下每个位置的匹配得分(右图左上 4 个小格对应左图左上一个大格,其它同理)。如果利用分枝定界方法获取最终细分辨率下机器人的最佳匹配位置,请简述匹配和剪枝流程

4-1—遍历粗分辨率下 4 个位置, best_score=-无穷,第一次选取左图最大的 99 分粗分辨率节点;

4-2—对 99 分粗分辨率节点进行分枝,进入细分辨率节点,此时为叶子节点,遍历后选取最大的 87 分的

细分辨率节点,best_score=87;

4-3—返回粗分辨率节点,第一个节点是 85 分,小于 best_score=87 ,进行剪枝;

4-4—在粗分辨率节点继续查找,循环到第三节点 98 分,大于 best_score=87,进入细分辨率节点,此

时为叶子节点,遍历后得到 95 分节点大于 best_socre=87,则 bust_score=95;

4-5—返回粗分辨率节点继续查找,循环到第四节点 96 分,大于 beat_score=95 ,进入细分辨率节点,

遍历后所有叶子节点都小于 best_score=95,返回粗分辨率节点,粗分辨率节点为空,结束



版权声明:本文为ChenXiaoFeng0420原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。