雷达标定与解析

2024-06-21 08:44
文章标签 解析 标定 雷达

本文主要是介绍雷达标定与解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

融合雷达与解析雷达数据的相关代码。感谢开源社区的贡献。以下代码继承了很多人的工作。
如果是单雷达:
直接进行标定,所以就是接收相关的话题然后发布。
lidar_calibration_params.yaml:

calibration:在这个接口里面x_offset: 0.0y_offset: 0.0z_offset: 0.4roll_offset: -0.074pitch_offset: 0yaw_offset: -1.57input_topic: "/lslidar_point_cloud"
output_topic: "/fusion_points"

lidar_calibration_node.cpp

#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <tf2/LinearMath/Quaternion.h>
#include <tf2/LinearMath/Matrix3x3.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl_ros/transforms.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <Eigen/Geometry>
#include <iostream>// 标定参数结构体
struct CalibrationParams
{double x_offset;double y_offset;double z_offset;double roll_offset;double pitch_offset;double yaw_offset;
};ros::Publisher calibrated_pub;
CalibrationParams calibration_params;void loadCalibrationParams(const ros::NodeHandle& nh)
{nh.getParam("calibration/x_offset", calibration_params.x_offset);nh.getParam("calibration/y_offset", calibration_params.y_offset);nh.getParam("calibration/z_offset", calibration_params.z_offset);nh.getParam("calibration/roll_offset", calibration_params.roll_offset);nh.getParam("calibration/pitch_offset", calibration_params.pitch_offset);nh.getParam("calibration/yaw_offset", calibration_params.yaw_offset);// 打印加载的参数以确认ROS_INFO("Loaded calibration parameters:");ROS_INFO("x_offset: %f", calibration_params.x_offset);ROS_INFO("y_offset: %f", calibration_params.y_offset);ROS_INFO("z_offset: %f", calibration_params.z_offset);ROS_INFO("roll_offset: %f", calibration_params.roll_offset);ROS_INFO("pitch_offset: %f", calibration_params.pitch_offset);ROS_INFO("yaw_offset: %f", calibration_params.yaw_offset);
}void laserCallback(const sensor_msgs::PointCloud2ConstPtr& cloud_msg)
{// Create transformation matrixEigen::Affine3f transform = Eigen::Affine3f::Identity();transform.translation() << calibration_params.x_offset, calibration_params.y_offset, calibration_params.z_offset;Eigen::AngleAxisf rollAngle(calibration_params.roll_offset, Eigen::Vector3f::UnitX());Eigen::AngleAxisf pitchAngle(calibration_params.pitch_offset, Eigen::Vector3f::UnitY());Eigen::AngleAxisf yawAngle(calibration_params.yaw_offset, Eigen::Vector3f::UnitZ());transform.rotate(yawAngle * pitchAngle * rollAngle);// 打印转换矩阵以确认std::cout << "Transformation Matrix:" << std::endl;std::cout << transform.matrix() << std::endl;// Transform the point cloudsensor_msgs::PointCloud2 calibrated_cloud_msg;pcl_ros::transformPointCloud(transform.matrix(), *cloud_msg, calibrated_cloud_msg);// Publish the calibrated point cloudcalibrated_cloud_msg.header = cloud_msg->header;calibrated_pub.publish(calibrated_cloud_msg);
}int main(int argc, char** argv)
{ros::init(argc, argv, "lidar_calibration_node");ros::NodeHandle nh;// 获取参数服务器中的参数std::string input_topic;std::string output_topic;int queue_size;nh.param<std::string>("input_topic", input_topic, "/lslidar_point_cloud");nh.param<std::string>("output_topic", output_topic, "/calibrated_point_cloud");nh.param<int>("queue_size", queue_size, 10);// 加载标定参数loadCalibrationParams(nh);// std::cout<<input_topic<<std::endl;// std::cout<<output_topic<<std::endl;// 订阅输入点云话题ros::Subscriber laser_sub = nh.subscribe(input_topic, queue_size, laserCallback);// 发布标定后的点云话题calibrated_pub = nh.advertise<sensor_msgs::PointCloud2>(output_topic, queue_size);ros::spin();return 0;
}

启动launch:

<launch><rosparam file="$(find lidar_calibration)/config/lidar_calibration_params.yaml" command="load"/><node pkg="lidar_calibration" type="lidar_calibration_node" name="lidar_calibration_node" output="screen"></node></launch>

以上是单个雷达的标定的,接下来是融合点云的数据标定:
来源于一个开源项目:git clone https://github.com/Hliu0313/fusion_pointclouds
也是直接修改接口就行了:

#参数加载对应 loadparams.h/loadparams.cpp,若修改params.yaml对应修改加载函数即可
fusion_lidar_num: 3                                                      #融合 lidar 点云数量 2/3/4
topics:                                                                                 #订阅 lidar 点云话题
#   parent_pc_topic: "/livox/lidar"
#   child_pc_topic1: "/right/rslidar_points"
#   child_pc_topic2: "/left/rslidar_points"
#   child_pc_topic3: "/livox/lidar"parent_pc_topic: "/livox/lidar"child_pc_topic1: "/right/rslidar_points"child_pc_topic2: "/left/rslidar_points"child_pc_topic3: "/livox/lidar"fusion_pc_topic: "/fusion_points"                       #融合后发布点云话题名称fusion_pc_frame_id: "rslidar"                 #融合后发布点云话题名称#注意
#1.点云话题少于4个时,为了时间同步回调函数适应不同数量雷达,空位child_pc_topic可以填入parent_pc_topic
#例如 需要融合"/front/rslidar_points" 与"/left/rslidar_points"点云数据
#
#fusion_lidar_num: 2
#parent_pc_topic: "/front/rslidar_points"
#child_pc_topic1: "/left/rslidar_points"
#child_pc_topic2: "/front/rslidar_points" "
#child_pc_topic3: "/front/rslidar_points" #---->   如果只是融合点云数据,下方参数填 false 即可    <------- 
set_params_tf:  true                                                     #是否对点云进行坐标变换 
set_params_internal_bounds: true                       #是否对点云内边界 XYZ 滤除
set_params_external_bounds: true                       #是否对点外内边界 XYZ 滤除
set_dynamic_params: true                                        #是否开启动态调整,配合 rqt_reconfigure 动态调整坐标变化参数 ---> 解决标定参数不准确,实时微调# cpc1_to_ppc:                                                                   #child_pc1_to_parent_pc,坐标变化信息传入节点,按需填写即可
#    x: -0.75
#    y: -0.8
#    z: 0.58
#    roll: 0.05
#    pitch: 0.01
#    yaw: 0.06
# cpc2_to_ppc:
#    x: -0.75
#    y: 0.72
#    z: 0.58
#    roll: 0.0
#    pitch: 0.0
#    yaw: -0.1
# cpc3_to_ppc:
#    x: 0.0
#    y: 0.0
#    z: 0.0
#    roll: 0.0
#    pitch: 0.0
#    yaw: 0.0cpc1_to_ppc:                                                                   #child_pc1_to_parent_pc,坐标变化信息传入节点,按需填写即可x: -0.8y: -0.5z: 1.06roll: 0.04pitch: 0.0yaw: 0.0cpc2_to_ppc:x: -0.75y: 0.75z: 1.06roll: -0.018pitch: 0.018yaw: -0.168# cpc2_to_ppc:
#    x: -0.
#    y: 0.
#    z: 0.0
#    roll: -0.0
#    pitch: -0.0
#    yaw: -0.0cpc3_to_ppc:x: 0.0y: 0.0z: 0.0roll: 0.0pitch: 0.0yaw: 0# Dynamic rqt_reconfigure default bounds
internal_bounds :  #内边界x_min: 0.0x_max: 0.0y_min: 0.0y_max: 0.0z_min: 0.0z_max: 0.0external_bounds :  #外边界x_min: -100x_max: 100y_min: -100y_max: 100z_min: -5z_max: 5

最后是聚类,也是来源于一个开源项目:
https://blog.csdn.net/weixin_42905141/article/details/122977315?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171888729016777224495812%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=171888729016777224495812&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-122977315-null-null.142v100control&utm_term=%E4%B8%9A%E4%BD%99%E5%86%99%E7%9A%84%E4%B8%80%E4%B8%AA%E7%B2%97%E7%89%88demo%EF%BC%8C%E6%9C%89%E5%BE%88%E5%A4%9A%E5%9C%B0%E6%96%B9%E6%98%AF%E5%8F%AF%E4%BB%A5%E6%94%B9%E8%BF%9B%E7%9A%84%EF%BC%8C%E5%A4%A7%E5%AE%B6%E8%87%AA%E8%A1%8C%E4%BF%AE%E6%94%B9%E5%90%A7&spm=1018.2226.3001.4187
非常感谢他的工作,接下来要做的就是把障碍物的信息用我们需要的方式重新就行发布就行了。我这里直接借鉴一下之前的比赛所遇到的障碍物的接口,我很喜欢他的这一系列的定义。
请添加图片描述
在这个接口里面主要是用上述msg来定义雷达给出的数据。
上述单雷达标定,多雷达融合,以及雷达的聚类都放到这里面了:

https://github.com/chan-yuu/lidar_ws

后续会继续做雷达处理的相关的工作

这篇关于雷达标定与解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1080748

相关文章

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

Spring MVC使用视图解析的问题解读

《SpringMVC使用视图解析的问题解读》:本文主要介绍SpringMVC使用视图解析的问题解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC使用视图解析1. 会使用视图解析的情况2. 不会使用视图解析的情况总结Spring MVC使用视图

利用Python和C++解析gltf文件的示例详解

《利用Python和C++解析gltf文件的示例详解》gltf,全称是GLTransmissionFormat,是一种开放的3D文件格式,Python和C++是两个非常强大的工具,下面我们就来看看如何... 目录什么是gltf文件选择语言的原因安装必要的库解析gltf文件的步骤1. 读取gltf文件2. 提

Java中的runnable 和 callable 区别解析

《Java中的runnable和callable区别解析》Runnable接口用于定义不需要返回结果的任务,而Callable接口可以返回结果并抛出异常,通常与Future结合使用,Runnab... 目录1. Runnable接口1.1 Runnable的定义1.2 Runnable的特点1.3 使用Ru

使用EasyExcel实现简单的Excel表格解析操作

《使用EasyExcel实现简单的Excel表格解析操作》:本文主要介绍如何使用EasyExcel完成简单的表格解析操作,同时实现了大量数据情况下数据的分次批量入库,并记录每条数据入库的状态,感兴... 目录前言固定模板及表数据格式的解析实现Excel模板内容对应的实体类实现AnalysisEventLis

Java的volatile和sychronized底层实现原理解析

《Java的volatile和sychronized底层实现原理解析》文章详细介绍了Java中的synchronized和volatile关键字的底层实现原理,包括字节码层面、JVM层面的实现细节,以... 目录1. 概览2. Synchronized2.1 字节码层面2.2 JVM层面2.2.1 ente

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

IDEA与JDK、Maven安装配置完整步骤解析

《IDEA与JDK、Maven安装配置完整步骤解析》:本文主要介绍如何安装和配置IDE(IntelliJIDEA),包括IDE的安装步骤、JDK的下载与配置、Maven的安装与配置,以及如何在I... 目录1. IDE安装步骤2.配置操作步骤3. JDK配置下载JDK配置JDK环境变量4. Maven配置下