1.mian函数:初始化参数
初始化previous_pose,current _pose,ndt_pose,guess_pose,diff(前后两帧的位置与角度变化),offset(位置与角度的偏差矫正)
根据launch文件初始化参数method_type,use_odom,use_imu,imu_upside_down,imu_topic,incremental_voxel_update
申明发布的话题有ndt_map,current_pose;
订阅的话题有config/ndt_mapping,回调函数param_callback
config/ndt_mapping_output,回调函数output_callback
points_raw,回调函数points_callback
/vehicle/odom,回调函数odom_callback
_imu_topic,回调函数imu_callback
2.param_callback函数:设置NDT参数
设置NDT算法配准时的参数:牛顿优化的最大步长step_size,用于判断是否收敛至与之的trans_eps;优化迭代的最大次数max_iter;体素滤波叶的大小voxel_leaf_size用于原始点云过滤;激光点云数据有效扫描距离min_scan_range,max_scan_range;前后两帧距离阈值min_add_scan_shift
3.output_callback函数:输出点云建图
从参数文件读取过滤分辨率参数filter_res,把原始地图map实例化给map_ptr,声明过滤地图的指针map_filtered
如果分辨率为0,map_ptr转化为ros数据map_msg_ptr
否则把map_ptr体素滤波后到map_filtered,再转换到map_msg_ptr
发布*map_msg_ptr到ndt_map话题
最后把点云数据写入到pcd文件中
4.odom_callback函数:根据odom得到NDT初值
接受里程计数据时间戳作为输入参数,调用odom_calc函数得到NDT初始位姿估计
5.imu_callback函数:处理imu数据
计算前后两帧时间差,根据输入的四元数转化为rpy角得到前后两帧rpy角度偏差,然后计算的阿斗imu三个轴上的角速度,调用imu_calc计算位置初值
6.points_callback函数:处理点云数据
输入sensor_msgs::PointCloud2::ConstPtr& input
pcl::fromROSMsg(*input,tmp);//将当前点云信息转化为pcl类型存入tmp
然后把tmp中的点逐一处理,在一定范围内的点云push_back进scan,再实例化到scan_ptr
如果当前地图为空,通过tf_btol把scan_ptr转换到全局地图中的transformed_scan_ptr,然后map+=*transformed_scan_ptr,再把标志位置为1
对scan_ptr进行体素化滤波到filtered_scan_ptr
把点云map实例化给map_ptr(pcl::PointCloud
进行NDT参数设置,把map_ptr设置为目标点云
预测当前位置(imu,里程计,imu+里程计)给NDT作为初值
根据_method_type的类型进行NDT配准结果输出到output_cloud点云中,并得到转换矩阵t_localizer,从而根据t_base_link=t_localizer*tf_ltob得到当前点云到全局坐标的转换t_base_link
把原始点云scan_ptr经过NDT变换后到transformed_scan_ptr
根据转换矩阵t_base_link更新当前帧小车在全局下的位姿ndt_pose,然后设置为当前位置current_pose
计算当前帧与上一帧的距离,如果大于min_add_scan_shift,则将transformed_scan_ptr加入到map中
再把map_ptr转换到ROS数据类型map_msg_ptr发布到ndt_map话题,再把当前位姿发布到current_pose话题上