node节点主程序源码文件为laserMapping.cpp。

1.公布的Topic话题:"/cloud_registered",配准后的单帧点云,消息类型:sensor_msgs::PointCloud2,以IMU为基准坐标系,当前帧往第一帧配准。

ros::Publisher pubLaserCloudFull = nh.advertise<sensor_msgs::PointCloud2>
            ("/cloud_registered", 100000);//创建topic

  if (scan_pub_en || pcd_save_en)      publish_frame_world(pubLaserCloudFull);//调用公布函数

公布函数源码:

void publish_frame_world(const ros::Publisher & pubLaserCloudFull)
{
    if(scan_pub_en)  //是否公布,在/FAST_LIO-main/config/mid360.yaml文件中设置
    {
        PointCloudXYZI::Ptr laserCloudFullRes(dense_pub_en ? feats_undistort : feats_down_body);//是否公布体素网格降采样后的点云,dense_pub_en在mid360.yaml文件中设置,采样参数在/FAST_LIO-main/launch/mapping_mid360.launch文件中设置参数filter_size_surf
        int size = laserCloudFullRes->points.size();
        PointCloudXYZI::Ptr laserCloudWorld( \
                        new PointCloudXYZI(size, 1));//配准后的点云

        for (int i = 0; i < size; i++)
        {
            RGBpointBodyToWorld(&laserCloudFullRes->points[i], \
                                &laserCloudWorld->points[i]);
        }//雷达点云配准并变换至IMU坐标系

        sensor_msgs::PointCloud2 laserCloudmsg;
        pcl::toROSMsg(*laserCloudWorld, laserCloudmsg);
        laserCloudmsg.header.stamp = ros::Time().fromSec(lidar_end_time);
        laserCloudmsg.header.frame_id = "camera_init";//点云转换为sensor_msgs::PointCloud2类型
        pubLaserCloudFull.publish(laserCloudmsg);//公布
        publish_count -= PUBFRAME_PERIOD;
    }

    /**************** save map ****************/
    /* 1. make sure you have enough memories
    /* 2. noted that pcd save will influence the real-time performences **/
    if (pcd_save_en)//是否保存PCD文件,在mid360.yaml文件中设置
    {
        int size = feats_undistort->points.size();
        PointCloudXYZI::Ptr laserCloudWorld( \
                        new PointCloudXYZI(size, 1));

        for (int i = 0; i < size; i++)
        {
            RGBpointBodyToWorld(&feats_undistort->points[i], \
                                &laserCloudWorld->points[i]);//雷达点云配准并变换至IMU坐标系
        }
        *pcl_wait_save += *laserCloudWorld;//内存中累加当前帧点云至历史点云

        static int scan_wait_num = 0;
        scan_wait_num ++;
        if (pcl_wait_save->size() > 0 && pcd_save_interval > 0  && scan_wait_num >= pcd_save_interval)//间隔固定帧保存至pcd文件,pcd_save_interval在mid360.yaml文件中设置
        {
            pcd_index ++;
            string all_points_dir(string(string(ROOT_DIR) + "PCD/scans_") + to_string(pcd_index) + string(".pcd"));//pcd文件保存路径
            pcl::PCDWriter pcd_writer;
            cout << "current scan saved to /PCD/" << all_points_dir << endl;
            pcd_writer.writeBinary(all_points_dir, *pcl_wait_save);//写pcd文件
            pcl_wait_save->clear();//清空内存中历史点云
            scan_wait_num = 0;
        }
    }
}

2.公布的Topic话题:"/cloud_registered_body",未经配准的单帧点云,消息类型:sensor_msgs::PointCloud2,以IMU为基准坐标系。

 ros::Publisher pubLaserCloudFull_body = nh.advertise<sensor_msgs::PointCloud2>
            ("/cloud_registered_body", 100000);//创建topic话题

 if (scan_pub_en && scan_body_pub_en) publish_frame_body(pubLaserCloudFull_body);//调用公布函数  变量scan_pub_en和scan_body_pub_en的值在/FAST_LIO-main/config/mid360.yaml文件中设置。

公布函数源码:

void publish_frame_body(const ros::Publisher & pubLaserCloudFull_body)
{
    int size = feats_undistort->points.size();
    PointCloudXYZI::Ptr laserCloudIMUBody(new PointCloudXYZI(size, 1));

    for (int i = 0; i < size; i++)
    {
        RGBpointBodyLidarToIMU(&feats_undistort->points[i], \
                            &laserCloudIMUBody->points[i]);  //雷达点云变换至IMU坐标系
    }

    sensor_msgs::PointCloud2 laserCloudmsg;
    pcl::toROSMsg(*laserCloudIMUBody, laserCloudmsg);//格式转换至消息 sensor_msgs::PointCloud2
    laserCloudmsg.header.stamp = ros::Time().fromSec(lidar_end_time);
    laserCloudmsg.header.frame_id = "body";
    pubLaserCloudFull_body.publish(laserCloudmsg);//公布消息
    publish_count -= PUBFRAME_PERIOD;
}

函数RGBpointBodyLidarToIMU源码:

void RGBpointBodyLidarToIMU(PointType const * const pi, PointType * const po)
{
    V3D p_body_lidar(pi->x, pi->y, pi->z);//雷达点云坐标转3D向量
    V3D p_body_imu(state_point.offset_R_L_I*p_body_lidar + state_point.offset_T_L_I);//雷达点云坐标系变换至IMU坐标系,state_point.offset_R_L_I和state_point.offset_T_L_I为雷达和IMU的旋转和平移变换参数,在/FAST_LIO-main/config/mid360.yaml文件中设置,extrinsic_T为平移向量,extrinsic_R为旋转矩阵。

    po->x = p_body_imu(0);
    po->y = p_body_imu(1);
    po->z = p_body_imu(2);
    po->intensity = pi->intensity;
}

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐