将镭神C32激光雷达的PointXYZ数据转化为PointXYZIR格式 - 附代码

之前遇到过“镭神32线激光雷达ROS下运行fromRosMsg()报错 Failed to find match for field “intensity“ 问题”,
当时确定了是镭神C32雷达缺少相应字段,并记录博客【学习记录】镭神32线激光雷达ROS下运行fromRosMsg()报错 Failed to find match for field “intensity“ 问题

这次写了一个ros的节点代码,接受原始雷达数据,并转化为相应格式。
完整代码:https://github.com/LarryDong/lslidar_PointXYZ2PointXYZIR
说明:是另写了一个节点,接受雷达发出的原始数据,再赋予ring字段的信息,然后再发布带有这个字段的点云。
但原始并没有包括intensity字段,这个信息是丢失的,所以intensity我就瞎补了一个0,至少保证了格式正确。

基本原理

计算每个点对应的角度,看距离激光雷达定义的哪条ring最接近。
如何判断最接近?计算定义的两条ring平均值,如果在左右两个平均值之间,则认为是这个ring。

在这里插入图片描述
由于镭神32线雷达有两种角度模式,左边这种均匀分布,直接将角度近似取整就可以,比较简单。但右侧这种不均匀分布的,就需要按照手册给出的角度信息去解算到底属于哪根。

代码说明

首先列出雷达定义的角度,并计算与上一个/下一个线束的平均值。

const vector<float> g_ring_angle = {-18, -15, -12, -10, -8, -7, -6, -5,
                              -4, -3.33, -3, -2.66, -2.33, -2, -1.66, -1.33,
                              -1, -0.66, -0.33, 0, 0.33, 0.66, 1, 1.33, 
                              1.66, 2, 3, 4, 6, 8, 11, 14};   // ring angles defined by leishen
vector<float> g_angle_range;                                  // define a range between each ring angle.

void initRingAngleRange(void){
    // calculate angle range
    assert(RING_NUMBER==g_ring_angle.size());
    g_angle_range.push_back(-100);            // assign a very large value
    for(int i=0; i<RING_NUMBER-1; ++i){
        float middle_value = (g_ring_angle[i] + g_ring_angle[i + 1]) / 2;   // calculate the average value between two ring.
        g_angle_range.push_back(middle_value);
    }
    g_angle_range.push_back(100);
}

然后计算实际角度,并赋予线束id即可:

void lidarCallback(const sensor_msgs::PointCloud2ConstPtr &msg_pc){
    pcl::PointCloud<pcl::PointXYZ> pc;
    pcl::PointCloud<myPointXYZIR> pc_new;
    pcl::fromROSMsg(*msg_pc, pc);
    // convert to PointXYZIR.
    pc_new.points.reserve(pc.points.size());
    myPointXYZIR pt_new;
    for(const pcl::PointXYZ& p : pc.points){
        float angle = atan(p.z / sqrt(p.x * p.x + p.y * p.y)) * 180 / M_PI;
        if(std::isnan(angle))           // remove nan point.
            continue;
        // int scanID = int(angle + 17);           // 对于1°分辨率的雷达,直接用这行指令就可以了,不需要计算下面的不均匀分布角度。
        // for 0.33 degree mode.
        int scanID = -1;
        for(int i=0; i<RING_NUMBER; ++i){
            if(angle > g_angle_range[i] && angle <= g_angle_range[i+1]){
                scanID = i;
                break;
            }
        }
        pt_new.x = p.x;
        pt_new.y = p.y;
        pt_new.z = p.z;
        pt_new.intensity = 0;       // intensity is not used.
        pt_new.ring = scanID;
        pc_new.points.push_back(pt_new);
    }
    sensor_msgs::PointCloud2 msg_pc_new;
    pcl::toROSMsg(pc_new, msg_pc_new);
    msg_pc_new.header.frame_id = "laser_link";
    msg_pc_new.header.stamp = msg_pc->header.stamp;
    g_pub_pc.publish(msg_pc_new);
    ROS_INFO("Published new pointcloud.");
 }

踩坑记录

  • 一开始以为直接将雷达设置为1°模式扫描就可以了,结果发现精度不正常。问了客服才知道1°模式和0.33°模式不能调整。所以无奈,只能再重写这个转换代码。但还行,算的挺对。
  • rviz中PointCloud2的intensity选项,点击后会出现一个channel,还包括XYZ以及intensity等,一开始没搞明白啥意思,说明如下:
  • About RViz: If you open a PointCloud2 display and select the “Intensity” color transformer, you can select a channel to display. This doesn’t have to be intensity, it can actually be any channel of your point cloud. If you leave “autocompute intensity bounds” checked, it will compute the min + max for each point cloud separately and scale the color spectrum to that range. If you disable the check box, you can enter min + max intensity manually (good if the min/max varies a lot between point clouds and you want the colors to be consistent between point clouds).

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 智能激光雷达C32是一款高性能的激光雷达产品,它具有多项优秀的特点和功能。 首先,C32采用了先进的激光雷达技术,能够有效地探测和识别周围环境的物体。其激光发射器和接收器的精确度非常高,可以提供精准的测距和扫描能力。这使得C32在各种复杂环境下都能够提供可靠的数据。 其次,C32具有全方位的感知能力。它可以实时地获取360度水平和垂直方向的数据,能够准确地绘制出周围环境的三维点云图,并识别其中的物体。这使得C32在自动驾驶、智能导航和环境感知等领域具有广泛的应用价值。 此外,C32还具有较大的探测范围和高分辨率。它可以在200米的距离范围内进行精确的探测和测距,而且能够提供高达0.7°的水平和垂直角分辨率。这使得C32能够获取更为详细和准确的环境信息,帮助用户做出更好的决策。 最后,C32还具有优秀的稳定性和可靠性。它采用了先进的滤波算法和噪声抑制技术,能够有效地降低误报率和虚警率。同时,C32还具备良好的抗干扰和环境适应能力,能够在各种复杂环境下稳定运行。 总的来说,智能激光雷达C32是一款功能强大、性能稳定的激光雷达产品,具有全方位的感知能力和高精度的数据获取能力。它在自动驾驶、智能导航等领域有着广泛的应用前景。 ### 回答2: 智能激光雷达C32是一款高性能的激光雷达产品,具有多种创新技术和功能。 首先,C32采用了全新的光学设计和激光发射器,能够实现更长的探测距离和更高的分辨率。其最大探测距离可达到200米,同时具备毫米级的高分辨率能力,能够精准地探测周围环境的细节。 其次,C32具备全方位的感知能力,能够实现360度的环境感知和障碍物检测。它采用多线激光束设计,能够广泛扫描周围环境并实时生成高精度的三维点云地图,为自动驾驶和智能导航系统提供重要的信息支持。 此外,C32还具有自适应扫描模式,能够根据不同的场景和需求进行自动调节。它可以根据车辆的速度和行驶路况,实时调整扫描频率和角度范围,保证在高速行驶和复杂路况下依然能够提供可靠的感知数据C32还内置了多种传感器融合算法和智能决策系统,能够快速准确地分析和判断周围环境。它可以实现多目标检测和跟踪,同时能够识别不同类型的障碍物,并根据优先级进行智能路径规划和避障决策。 综上所述,智能激光雷达C32产品手册详细介绍了该产品的技术特点和应用场景,为用户提供了全面的了解和使用指导。它将为无人驾驶、智能导航和机器人等领域的科研和应用提供强有力的支持。 ### 回答3: 智能激光雷达C32产品手册是一份详细介绍该产品功能、特点和使用方法的文档。智能激光雷达C32是一款先进的激光雷达产品,具有高精度、高分辨率和高可靠性的特点。 该产品手册首先详细介绍了C32的基本参数和技术指标,包括扫描频率、角分辨率、测距范围、功耗等信息。这些参数对于用户选择和使用该产品非常重要,可以根据实际需要进行合理的配置和安装。 接下来,手册介绍了C32的工作原理和技术特点。激光雷达是一种通过激光束进行距离测量和环境感知的设备,而C32采用了先进的光电混合技术和多传感器融合算法,能够实现更高的测距精度和图像分辨率。此外,C32还具有抗干扰、高速运动物体检测和低功耗等优势。 在产品使用方面,手册详细介绍了C32的软件安装和硬件连接方法。用户可以通过软件界面进行参数设置和数据输出,同时可以通过USB或以太网接口与其他设备进行通信和数据传输。 手册还提供了C32的应用示例和使用注意事项。C32广泛应用于自动驾驶、机器人导航、智能交通等领域,可以实现环境感知和障碍物检测。用户在使用C32时需遵守相应的安全规范,确保设备的正常运行和数据的准确性。 总之,智能激光雷达C32产品手册提供了全面的产品介绍和使用指南,帮助用户了解和使用该产品。无论是技术人员还是终端用户,都可以从中获取到所需的信息和帮助,以便更好地利用C32进行相关应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值