激光SLAM放弃指南4:PL-ICP的实现

参考链接:1.李太白lx 系列文章 从零开始搭二维激光SLAM link

计算运算时间差值

// step1 进行数据类型转换
std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();
...
std::chrono::steady_clock::time_point end_time = std::chrono::steady_clock::now();
std::chrono::duration<double> time_used = std::chrono::duration_cast<std::chrono::duration<double>>(end_time - start_time);
std::cout << "\n转换数据格式用时: " << time_used.count() << " 秒。" << std::endl;

ICP的函数

#include <iostream>                 //标准输入输出头文件
#include <pcl/io/pcd_io.h>          //I/O操作头文件
#include <pcl/point_types.h>        //点类型定义头文件
#define BOOST_TYPEOF_EMULATION  //要加在#include <pcl/registration/icp.h>前
#include <pcl/registration/icp.h>   //ICP配准类相关头文件
#include <pcl/visualization/cloud_viewer.h>//点云查看窗口头文件
#include <pcl/visualization/pcl_visualizer.h>//可视化头文件

pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;  //创建ICP的实例类
icp.setInputSource(cloud_sources); // 源点云。指将要被旋转和平移的点云。
icp.setInputTarget(cloud_target);// 目标点云。从Source到Target匹配,将源点云变换到目标点云的相对位置。
icp.setMaxCorrespondenceDistance(100);   //设置对应点对之间的最大距离(此值对配准结果影响较大)如果两个点云距离大于此值,则被忽略(PCL默认距离单位是m),一般根据两个点云之间的距离估计,这个值对点云匹配的结果影响较大。
icp.setTransformationEpsilon(1e-10); //  设置两次变化矩阵之间的差值(一般设置为1e-10即可)
icp.setEuclideanFitnessEpsilon(0.001);   //设置收敛条件是均方误差和小于阈值, 停止迭代;
nline void setEuclideanFitnessEpsilon (doubleepsilon)      前后两次迭代方差的差值,可以用来终止迭代次数。
icp.setMaximumIterations(100);     //  最大迭代次数,icp是一个迭代的方法,最多迭代这些次
icc.align(final)// final 为配准后点云。
inline Matrix4 getFinalTransformation ()    获取最终的转换矩阵。

如果由于设置相关参数过于苛刻,而造成没有匹配成功法, icp.hasConverged() 会提示匹配失败,并且 icp.getFitnessScore() 为0,相关的转换矩阵为单位矩阵。

 if (icp_.hasConverged() == false)
    {
        std::cout << "not Converged" << std::endl;
    }

CSM的数据格式

struct sm_params {
// 第一个雷达数据
LDP laser_ref;
//第二个雷达数据
LDP laser_sens;
//位姿的预测值多少.设置为0 就是不预测
double first_guess[3]; 
//扫描之间的最大角位移(度)/
double max_angular_correction_deg;
//扫描之间的最大平移(米)
double max_linear_correction;
//最大迭代次数
int max_iterations;
//停止阀值
double epsilon_xy;
double epsilon_theta;
//通信有效的最大距离
double max_correspondence_dist;
// ???不懂这个是什么
int use_corr_tricks;
//如果错误低于阈值(0或1),则重新启动*
int restart;
//重新启动阈值
double restart_threshold_mean_error;
//重新启动位移
double restart_dt;
double restart_dtheta;
//异常值的最大百分比
double outliers_maxPerc;
// 异常值自适应顺序
double outliers_adaptive_order; /* 0.7 */
double outliers_adaptive_mult; /* 2 */

//不允许两个不同的通信共享一个点
int outliers_remove_doubles; 
 // 聚类阈值
double clustering_threshold;
//用于估计方向的相邻光线数
int orientation_neighbourhood;
//根据角度丢弃对应关系
int do_alpha_test;
double do_alpha_test_thresholdDeg;

// 可见性测试
int do_visibility_test;

//判断点到线的距离 如果为1,则使用PlICP;如果为0,则使用ICP
int use_point_to_line_distance;
// ??? 不懂
int use_ml_weights;
int use_sigma_weights;

//计算协方差
int do_compute_covariance;

//检查是否找到对应项,并给出正确答案
int debug_verify_tricks;

//传感器相对于机器人的姿态:用于计算给出了里程计的第一个估计值
double laser[3]; 

// 数据中有无效值
double sigma;

// 将此间隔之外的数据标记为无效(=不使用)
double min_reading, max_reading;

//特定于GPM的参数(未完成:-/)
double gpm_theta_bin_size_deg;
double gpm_extend_range_deg; 
int gpm_interval;
// 特定于HSM的参数(未完成:-/)
struct hsm_params hsm;
};

struct sm_result {
//如果是否有效
int valid;
//扫描匹配结果(x,y,θ)
double x[3];
//完成的迭代次数
int iterations;
//最后有效通信数
int nvalid;
//总通讯错误数
double error;

// 用于协方差计算的字段
#ifndef RUBY
gsl_matrix *cov_x_m;	
gsl_matrix *dx_dy1_m;
gsl_matrix *dx_dy2_m;
#endif
};

运行的时候报错

gsl: lu.c:266: ERROR: matrix is singular
Default GSL error handler invoked.

需要设置这个参数

input_.do_compute_covariance = 0;
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值