FAST-LIO2代码解析(一)

感谢FAST-LIO2代码解析(一) - 古月居,代码的注释内容主要参考古月居同志,特此声明,如有异议,欢迎反馈!

一、数据的处理

  • 对于FAST-LIO2代码来说,主要的数据是通过preprocessIMU_Processing拿到相应的传感器数据,并在主程序当中调用ESF与IKD-Tree完成优化。

1.1 激光雷达部分

(1)  preprocess.h

  • 首先在最上面先定义了一系列enum的信息,通过enum选择不同的激光雷达类型,特征点特征等,并通过orgtype存放一些激光雷达点的一些其他属性。
//1、枚举类型:表示支持的雷达类型;
enum LID_TYPE{AVIA = 1, VELO16, OUST64}; //{1, 2, 3}
//2、枚举类型:表示时间的类型;
enum TIME_UNIT{SEC = 0, MS = 1, US = 2, NS = 3};
//3、枚举类型:表示特征点的类型;
enum Feature{Nor, Poss_Plane, Real_Plane, Edge_Jump, Edge_Plane, Wire, ZeroPoint};
//4、枚举类型:位置标识
enum Surround{Prev, Next};
//5、枚举类型:表示有跨越边的类型
enum E_jump{Nr_nor, Nr_zero, Nr_180, Nr_inf, Nr_blind};


//orgtype类:用于存储激光雷达点的一些其他属性;  
struct orgtype 
{
  double range;     //点云在xy平面离雷达中心的距离;
  double dista;     //当前点与后一个点之间的距离;假设雷达原点为O 前一个点为M,当前点为A,后一个点为N. 
  double angle[2];  //这个是角OAM和角OAN的cos值;
  double intersect; //这个是角MAN的cos值;
  E_jump edj[2];    //前后两点的类型;
  Feature ftype;    //点类型;
  
  // 构造函数;
  orgtype()
  {
    range = 0;
    edj[Prev] = Nr_nor;
    edj[Next] = Nr_nor;
    ftype = Nor;  //默认为正常点;
    intersect = 2;
  }
};
  • 其中 LID_TYPE 这些与下面的数据结构有关系。通过enum选择不同的激光雷达数据,来设置不同的数据结构。
//velodyne数据结构-namespace velodyne_ros;
namespace velodyne_ros {
  struct EIGEN_ALIGN16 Point {
      PCL_ADD_POINT4D;  //4D点坐标类型;
      float intensity;  //强度;
      float time;       //时间;
      uint16_t ring;    //点所属的圈数;
      EIGEN_MAKE_ALIGNED_OPERATOR_NEW //进行内存对齐;
  };
}

//注册velodyne_ros的Point类型;
POINT_CLOUD_REGISTER_POINT_STRUCT(velodyne_ros::Point,
    (float, x, x)
    (float, y, y)
    (float, z, z)
    (float, intensity, intensity)
    (float, time, time)
    (uint16_t, ring, ring)
)

//ouster数据结构-namespace ouster_ros;
namespace ouster_ros {
  struct EIGEN_ALIGN16 Point {
      PCL_ADD_POINT4D;                //4D点坐标类型;
      float intensity;                //强度;
      uint32_t t;                     //时间;
      uint16_t reflectivity;          //反射率;
      uint8_t  ring;                  //点所属的圈数;
      uint16_t ambient;               //没用到;
      uint32_t range;                 //距离;
      EIGEN_MAKE_ALIGNED_OPERATOR_NEW //进行内存对齐;
  };
}  

//注册ouster的Point类型;
POINT_CLOUD_REGISTER_POINT_STRUCT(ouster_ros::Point,
    (float, x, x)
    (float, y, y)
    (float, z, z)
    (float, intensity, intensity)
    // use std::uint32_t to avoid conflicting with pcl::uint32_t
    (std::uint32_t, t, t)
    (std::uint16_t, reflectivity, reflectivity)
    (std::uint8_t, ring, ring)
    (std::uint16_t, ambient, ambient)
    (std::uint32_t, range, range)
)
  • 下面的这些是Preprocess的主体函数,主要作用是用于对激光雷达点云数据进行预处理。

class Preprocess
{
  public:
//   EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  Preprocess();  //构造函数;
  ~Preprocess(); //析构函数;
  
  //对Livox自定义Msg格式的激光雷达数据进行处理;
  void process(const livox_ros_driver2::CustomMsg::ConstPtr &msg, PointCloudXYZI::Ptr &pcl_out);
  //对ros的Msg格式的激光雷达数据进行处理;
  void process(const sensor_msgs::PointCloud2::ConstPtr &msg, PointCloudXYZI::Ptr &pcl_out);
  void set(bool feat_en, int lid_type, double bld, int pfilt_num);

  //全部点、边缘点、平面点; sensor_msgs::PointCloud2::ConstPtr pointcloud;
  PointCloudXYZI pl_full, pl_corn, pl_surf;
  PointCloudXYZI pl_buff[128]; //maximum 128 line lidar
  vector<orgtype> typess[128]; //maximum 128 line lidar
  float time_unit_scale;
  
  //雷达类型、采样间隔、扫描线数、扫描频率;
  int lidar_type, point_filter_num, N_SCANS, SCAN_RATE, time_unit;
  //最小距离阈值(盲区);
  double blind; 
  //是否提取特征、是否进行时间偏移;
  bool feature_enabled, given_offset_time;
  //发布全部点、发布平面点、发布边缘点;
  ros::Publisher pub_full, pub_surf, pub_corn;
    

  private:
  //用于对Livox激光雷达数据进行处理;    
  void avia_handler(const livox_ros_driver2::CustomMsg::ConstPtr &msg);
  //用于对ouster激光雷达数据进行处理;
  void oust64_handler(const sensor_msgs::PointCloud2::ConstPtr &msg);
  //用于对velodyne激光雷达数据进行处理l;
  void velodyne_handler(const sensor_msgs::PointCloud2::ConstPtr &msg);
  void give_feature(PointCloudXYZI &pl, vector<orgtype> &types);
  void pub_func(PointCloudXYZI &pl, const ros::Time &ct);
  int  plane_judge(const PointCloudXYZI &pl, vector<orgtype> &types, uint i, uint &i_nex, Eigen::Vector3d &curr_direct);
  bool small_plane(const PointCloudXYZI &pl, vector<orgtype> &types, uint i_cur, uint &i_nex, Eigen::Vector3d &curr_direct);
  bool edge_jump_judge(const PointCloudXYZI &pl, vector<orgtype> &types, uint i, Surround nor_dir);
  
  int group_size;
  double disA, disB, inf_bound;
  double limit_maxmid, limit_midmin, limit_maxmin;
  double p2l_ratio;
  double jump_up_limit, jump_down_limit;
  double cos160;
  double edgea, edgeb;
  double smallp_intersect, smallp_ratio;
  double vx, vy, vz;
};

(2)  preprocess.cpp

  • 上面是头文件,详细的代码在preprocess.cpp中,这里我们来详细介绍每一个函数,首先是构造函数和析构函数,里面主要存放一些雷达的参数
Preprocess::Preprocess()
  :feature_enabled(0), lidar_type(AVIA), blind(0.01), point_filter_num(1)
{
  inf_bound = 10;        //有效点集合,大于10m则是盲区;
  N_SCANS   = 6;         //多线激光雷达的线数;
  SCAN_RATE = 10;        //平面斜率?
  group_size = 8;        //8个点为一组;
  disA = 0.01;           //点集合的距离阈值,判断是否为平面;
  disA = 0.1;            //点集合的距离阈值,判断是否为平面;
  p2l_ratio = 225;       //点到线的距离阈值,需要大于这个值才能判断组成面;
  limit_maxmid =6.25;    //中点到左侧的距离变化率范围;
  limit_midmin =6.25;    //中点到右侧的距离变化率范围;
  limit_maxmin = 3.24;   //左侧到右侧的距离变化率范围;
  jump_up_limit = 170.0;
  jump_down_limit = 8.0;
  cos160 = 160.0;
  edgea = 2;                //点与点距离超过两倍则认为遮挡;
  edgeb = 0.1;              //点与点距离超过0.1m则认为遮挡
  smallp_intersect = 172.5;
  smallp_ratio = 1.2;       //三个点如果角度大于172.5度,且比例小于1.2倍,则认为是平面
  given_offset_time = false;//是否提供时间偏移;

  jump_up_limit = cos(jump_up_limit/180*M_PI);      //角度大于170度的点跳过;
  jump_down_limit = cos(jump_down_limit/180*M_PI);  //角度小于8度的点跳过;
  cos160 = cos(cos160/180*M_PI);                    //夹角限制;
  smallp_intersect = cos(smallp_intersect/180*M_PI);//三个点如果角度大于172.5度,且比例小于1.2倍,则认为是平面;
}

相关推荐

  1. FAST-LIO2代码解析()

    2024-03-28 04:04:01       22 阅读
  2. ChatPDF代码解读2

    2024-03-28 04:04:01       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-28 04:04:01       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-28 04:04:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-28 04:04:01       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-28 04:04:01       20 阅读

热门阅读

  1. codeforces - 1703 - D - Double String (字符串)

    2024-03-28 04:04:01       17 阅读
  2. 2024年通信安全员考试真题题库

    2024-03-28 04:04:01       18 阅读
  3. vs code

    vs code

    2024-03-28 04:04:01      21 阅读
  4. Android中的有序广播与无序广播

    2024-03-28 04:04:01       19 阅读
  5. 基于STM32的智能书房系统的设计

    2024-03-28 04:04:01       17 阅读
  6. Vue项目中引入地图的详细教程

    2024-03-28 04:04:01       22 阅读
  7. tewa-707e光猫超级密码获取方法

    2024-03-28 04:04:01       91 阅读
  8. Mybatis

    Mybatis

    2024-03-28 04:04:01      15 阅读