R3live笔记:r3live的几个线程分析

今天在r3live类的构造函数里看到这样一行代码:

        m_thread_pool_ptr = std::make_shared<Common_tools::ThreadPool>(6, true, false); // At least 5 threads are needs, here we allocate 6 threads.

大意是初始化一个包含6个线程的线程池子,然后作者注释
// At least 5 threads are needs, here we allocate 6 threads.
说明至少需要5个线程,就仔细来数一下都有哪些:

1. 一个取出image处理线程

订阅IMAGE_topic的回调函数image_callback和image_comp_callback里,开启一个取出image处理线程service_process_img_buffer:

  m_thread_pool_ptr->commit_task( &R3LIVE::service_process_img_buffer, this );

这个线程里的主要内容:
首先为防止等待vio处理的图像队列m_queue_image_with_pose占用过多的缓存,m_queue_image_with_pose超过4帧时,先减少内存的占用
然后,根据输入图像是压缩图还是原图作出相应的处理,主要是把ros格式的图像转换成cv格式
最后,调用process_image函数处理图像:

        process_image( image_get, img_rec_time );

2. 一个VIO线程

VIO线程之前介绍过参考:[R3live笔记:视觉-惯性里程计VIO部分]

3. 一个LIO线程


R3LIVE()构造函数最后一行代码:

        m_thread_pool_ptr->commit_task(&R3LIVE::service_LIO_update, this);//开启lio线程

开启lio线程

LIO线程来源于r2live,fast-lio,

主要是接收雷达数据,畸变补偿,特征提取,IMU状态传播,LIO状态更新

LIO线程参考:R3live笔记:从代码看lio线程

4. 一个发布rgb map的线程

在R3LIVE::process_image函数里,开启VIO线程和service_pub_rgb_maps线程:

        m_thread_pool_ptr->commit_task( &R3LIVE::service_pub_rgb_maps, this);
        m_thread_pool_ptr->commit_task( &R3LIVE::service_VIO_update, this);

VIO发布了一系列/RGB_map_xx话题(参见R3live:整体分析),这是将RGB点云地图拆分成了子点云发布,由一个线程专门负责,这个线程就是service_pub_rgb_maps线程

// /RGB_map_xx:将RGB点云地图拆分成子点云发布,由一个线程专门负责
void R3LIVE::service_pub_rgb_maps()
{
    int last_publish_map_idx = -3e8;
    int sleep_time_aft_pub = 10;  
    int number_of_pts_per_topic = 1000;
    if ( number_of_pts_per_topic < 0 )
    {
        return;
    }
    while ( 1 )
    {
        ros::spinOnce();
        std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
        pcl::PointCloud< pcl::PointXYZRGB > pc_rgb;
        sensor_msgs::PointCloud2            ros_pc_msg;
        int pts_size = m_map_rgb_pts.m_rgb_pts_vec.size();
        pc_rgb.resize( number_of_pts_per_topic );
        // for (int i = pts_size - 1; i > 0; i--)
        int pub_idx_size = 0;
        int cur_topic_idx = 0;
        if ( last_publish_map_idx == m_map_rgb_pts.m_last_updated_frame_idx )
        {
            continue;
        }
        last_publish_map_idx = m_map_rgb_pts.m_last_updated_frame_idx;
        for ( int i = 0; i < pts_size; i++ )
        {
            if ( m_map_rgb_pts.m_rgb_pts_vec[ i ]->m_N_rgb < 1 )
            {
                continue;
            }
            pc_rgb.points[ pub_idx_size ].x = m_map_rgb_pts.m_rgb_pts_vec[ i ]->m_pos[ 0 ];
            pc_rgb.points[ pub_idx_size ].y = m_map_rgb_pts.m_rgb_pts_vec[ i ]->m_pos[ 1 ];
            pc_rgb.points[ pub_idx_size ].z = m_map_rgb_pts.m_rgb_pts_vec[ i ]->m_pos[ 2 ];
            pc_rgb.points[ pub_idx_size ].r = m_map_rgb_pts.m_rgb_pts_vec[ i ]->m_rgb[ 2 ];
            pc_rgb.points[ pub_idx_size ].g = m_map_rgb_pts.m_rgb_pts_vec[ i ]->m_rgb[ 1 ];
            pc_rgb.points[ pub_idx_size ].b = m_map_rgb_pts.m_rgb_pts_vec[ i ]->m_rgb[ 0 ];
            // pc_rgb.points[i].intensity = m_map_rgb_pts.m_rgb_pts_vec[i]->m_obs_dis;
            pub_idx_size++;
            if ( pub_idx_size == number_of_pts_per_topic )
            {
                pub_idx_size = 0;
                pcl::toROSMsg( pc_rgb, ros_pc_msg );
                ros_pc_msg.header.frame_id = "world";       
                ros_pc_msg.header.stamp = ros::Time::now(); 
                if ( m_pub_rgb_render_pointcloud_ptr_vec[ cur_topic_idx ] == nullptr )
                {
                    m_pub_rgb_render_pointcloud_ptr_vec[ cur_topic_idx ] =
                        std::make_shared< ros::Publisher >( m_ros_node_handle.advertise< sensor_msgs::PointCloud2 >(
                            std::string( "/RGB_map_" ).append( std::to_string( cur_topic_idx ) ), 100 ) );
                }
                m_pub_rgb_render_pointcloud_ptr_vec[ cur_topic_idx ]->publish( ros_pc_msg );
                std::this_thread::sleep_for( std::chrono::microseconds( sleep_time_aft_pub ) );
                ros::spinOnce();
                cur_topic_idx++;
            }
        }

        pc_rgb.resize( pub_idx_size );
        pcl::toROSMsg( pc_rgb, ros_pc_msg );
        ros_pc_msg.header.frame_id = "world";       
        ros_pc_msg.header.stamp = ros::Time::now(); 
        if ( m_pub_rgb_render_pointcloud_ptr_vec[ cur_topic_idx ] == nullptr )
        {
            m_pub_rgb_render_pointcloud_ptr_vec[ cur_topic_idx ] =
                std::make_shared< ros::Publisher >( m_ros_node_handle.advertise< sensor_msgs::PointCloud2 >(
                    std::string( "/RGB_map_" ).append( std::to_string( cur_topic_idx ) ), 100 ) );
        }
        std::this_thread::sleep_for( std::chrono::microseconds( sleep_time_aft_pub ) );
        ros::spinOnce();

        // /RGB_map_xx:将RGB点云地图拆分成子点云发布,由一个线程专门负责
        m_pub_rgb_render_pointcloud_ptr_vec[ cur_topic_idx ]->publish( ros_pc_msg );
        cur_topic_idx++;
        if ( cur_topic_idx >= 45 ) // Maximum pointcloud topics = 45.
        {
            number_of_pts_per_topic *= 1.5;
            sleep_time_aft_pub *= 1.5;
        }
    }
}

5. 一个将点投影到图像的线程

在VIO线程里,又单独申请一个线程render_pts_in_voxels_mp,并行地将点云地图的active点投影到图像上,用对应的像素对地图点rgb的均值和方差用贝叶斯迭代进行更新。

m_render_thread = std::make_shared< std::shared_future< void > >( m_thread_pool_ptr->commit_task(
                    render_pts_in_voxels_mp, img_pose, &m_map_rgb_pts.m_voxels_recent_visited, img_pose->m_timestamp ) );

6. 一个refresh线程

refresh线程严格讲不是前面讲的m_thread_pool_ptr线程池,属于 m_thread_service 线程池,里面只有一个线程service_refresh_pts_for_projection,在VIO线程里有一行代码:

        m_map_rgb_pts.update_pose_for_projection( img_pose, -0.4 );

主要用于更新m_img_for_projection的位姿和id,以触发refresh线程

        m_thread_service = std::make_shared< std::thread >( &Global_map::service_refresh_pts_for_projection, this );

该线程将点云的active点投影到2D(方便后面新增跟踪点)

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值