计算两帧雷达数据之间的变换矩阵
文章目录
- package.xml
- CMakeLists.txt
- point_cloud_registration.cc
- 运行结果
package.xml
<?xml version="1.0"?>
<package format="2"><name>point_cloud_registration</name><version>0.0.0</version><description>The point_cloud_registration package</description><maintainer email="xiaoqiuslam@qq.com">xiaqiuslam</maintainer><license>TODO</license><buildtool_depend>catkin</buildtool_depend><build_depend>pcl_conversions</build_depend><build_depend>pcl_ros</build_depend><build_depend>roscpp</build_depend><build_depend>sensor_msgs</build_depend><build_export_depend>pcl_conversions</build_export_depend><build_export_depend>pcl_ros</build_export_depend><build_export_depend>roscpp</build_export_depend><build_export_depend>sensor_msgs</build_export_depend><exec_depend>pcl_conversions</exec_depend><exec_depend>pcl_ros</exec_depend><exec_depend>roscpp</exec_depend><exec_depend>sensor_msgs</exec_depend><export></export>
</package>
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)project(point_cloud_registration)add_compile_options(-std=c++11)find_package(catkin REQUIRED COMPONENTSpcl_conversionspcl_rosroscppsensor_msgs
)find_package(PCL REQUIRED QUIET)catkin_package()include_directories(
include${catkin_INCLUDE_DIRS}${PCL_INCLUDE_DIRS}
)add_executable(point_cloud_registration src/point_cloud_registration.cc)target_link_libraries(point_cloud_registration ${catkin_LIBRARIES})
point_cloud_registration.cc
#include <chrono>
#include <ros/ros.h>
#include <sensor_msgs/LaserScan.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/registration/icp.h>void ScanCallback(const sensor_msgs::LaserScan::ConstPtr &scan_msg);
void ConvertScan2PointCloud(const sensor_msgs::LaserScan::ConstPtr &scan_msg);
void ScanMatchWithICP(const sensor_msgs::LaserScan::ConstPtr &scan_msg);bool is_first_scan_ = true;
pcl::PointCloud<pcl::PointXYZ>::Ptr current_pointcloud_;
pcl::PointCloud<pcl::PointXYZ>::Ptr last_pointcloud_;
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp_;void ScanCallback(const sensor_msgs::LaserScan::ConstPtr &scan_msg)
{// 第一帧雷达数据if (is_first_scan_ == true){// 转换数据类型 并保存到current_pointcloud_ConvertScan2PointCloud(scan_msg);is_first_scan_ = false;}// 第二帧雷达数据else{// 数据类型转换std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();// 将current_pointcloud_赋值到last_pointcloud_进行保存*last_pointcloud_ = *current_pointcloud_; // 数据类型转换 ConvertScan2PointCloud(scan_msg);// 调用ICP进行计算 雷达前后两帧间的坐标变换ScanMatchWithICP(scan_msg);}
}void ConvertScan2PointCloud(const sensor_msgs::LaserScan::ConstPtr &scan_msg)
{pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_msg = boost::shared_ptr<pcl::PointCloud<pcl::PointXYZ>>(new pcl::PointCloud<pcl::PointXYZ>());cloud_msg->points.resize(scan_msg->ranges.size());for (unsigned int i = 0; i < scan_msg->ranges.size(); ++i){pcl::PointXYZ &point_tmp = cloud_msg->points[i];float range = scan_msg->ranges[i];if (!std::isfinite(range))continue;if (range > scan_msg->range_min && range < scan_msg->range_max){float angle = scan_msg->angle_min + i * scan_msg->angle_increment;point_tmp.x = range * cos(angle);point_tmp.y = range * sin(angle);point_tmp.z = 0.0;}}cloud_msg->width = scan_msg->ranges.size();cloud_msg->height = 1;cloud_msg->is_dense = true;pcl_conversions::toPCL(scan_msg->header, cloud_msg->header);*current_pointcloud_ = *cloud_msg;
}void ScanMatchWithICP(const sensor_msgs::LaserScan::ConstPtr &scan_msg)
{icp_.setInputSource(last_pointcloud_);icp_.setInputTarget(current_pointcloud_);pcl::PointCloud<pcl::PointXYZ> unused_result;icp_.align(unused_result);if (icp_.hasConverged() == false){return;}else{Eigen::Affine3f transfrom;transfrom = icp_.getFinalTransformation();float x, y, z, roll, pitch, yaw;pcl::getTranslationAndEulerAngles(transfrom, x, y, z, roll, pitch, yaw);std::cout << "transfrom: (x: " << x << ", y: " << y << ", yaw: " << yaw * 180 / M_PI << ")" << std::endl;}
}int main(int argc, char **argv)
{ros::init(argc, argv, "point_cloud_registration");ros::NodeHandle node_handle_; ros::Subscriber laser_scan_subscriber_;laser_scan_subscriber_ = node_handle_.subscribe("laser_scan", 1, &ScanCallback);current_pointcloud_ = boost::shared_ptr<pcl::PointCloud<pcl::PointXYZ>>(new pcl::PointCloud<pcl::PointXYZ>());last_pointcloud_ = boost::shared_ptr<pcl::PointCloud<pcl::PointXYZ>>(new pcl::PointCloud<pcl::PointXYZ>());ros::spin();return 0;
}
运行结果
roscore
source devel/setup.bash && rosrun point_cloud_registration point_cloud_registration
rosbag play 1.bag

相关文章:
计算两帧雷达数据之间的变换矩阵
文章目录 package.xmlCMakeLists.txtpoint_cloud_registration.cc运行结果 package.xml <?xml version"1.0"?> <package format"2"><name>point_cloud_registration</name><version>0.0.0</version><descriptio…...
2. gin中间件注意事项、路由拆分与注册技巧
文章目录 一、中间件二、Gin路由简介1、普通路由2、路由组 三、路由拆分与注册1、基本的路由注册2、路由拆分成单独文件或包3、路由拆分成多个文件4、路由拆分到不同的APP 一、中间件 在日常工作中,经常会有一些计算接口耗时和限流的操作,如果每写一个接…...
R语言复现:如何利用logistic逐步回归进行影响因素分析?
Logistic回归在医学科研、特别是观察性研究领域,无论是现况调查、病例对照研究、还是队列研究中都是大家经常用到的统计方法,而在影响因素研究筛选自变量时,大家习惯性用的比较多的还是先单后多,P<0.05纳入多因素研究&…...
【MySQL使用】show processlist 命令详解
show processlist 命令详解 一、命令含义二、命令返回参数三、Command值解释四、State值解释五、参考资料 一、命令含义 对于一个MySQL连接,或者说一个线程,任何时刻都有一个状态,该状态表示了MySQL当前正在做什么。SHOW PROCESSLIST 命令的…...
分类算法(Classification algorithms)
逻辑回归(logical regression): 逻辑回归这个名字听上去好像应该是回归算法的,但其实这个名字只是在历史上取名有点区别,但实际上它是一个完全属于是分类算法的。 我们为什么要学习它呢?在用我们的线性回归时会遇到一…...
深度学习-Softmax 回归 + 损失函数 + 图片分类数据集
Softmax 回归 损失函数 图片分类数据集 1 softmax2 损失函数1均方L1LossHuber Loss 3 图像分类数据集4 softmax回归的从零开始实现 1 softmax Softmax是一个常用于机器学习和深度学习中的激活函数。它通常用于多分类问题,将一个实数向量转换为概率分布。Softmax函…...
分布式锁从0到1落地实现01(mysql/redis/zk)
1 准备数据库表 CREATE TABLE user ( id bigint(20) NOT NULL COMMENT 主键ID, name varchar(30) DEFAULT NULL COMMENT 姓名, age int(11) DEFAULT NULL COMMENT 年龄, email varchar(50) DEFAULT NULL COMMENT 邮箱, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8;I…...
安全运营方案的基本框架和关键要素
一、前言 阐述安全运营方案的目的和重要性。强调安全运营与组织整体战略目标的关联。 二、安全运营原则 确立安全运营的基本原则,如保密性、完整性和可用性。明确安全责任划分,确保各部门和人员履行安全职责。 三、安全风险评估与管理 进行全面的安…...
用C语言执行SQLite3的gcc编译细节
错误信息: /tmp/cc3joSwp.o: In function main: execSqlite.c:(.text0x100): undefined reference to sqlite3_open execSqlite.c:(.text0x16c): undefined reference to sqlite3_exec execSqlite.c:(.text0x174): undefined reference to sqlite3_close execSqlit…...
matlab双目相机标定-需要什么参数、怎么获得
相机标定目的:获得相机内参、外参、畸变系数,摄像头的内参(f,1/dx,1/dy,cx,cy)、畸变参数(k1,k2,k3,p1,p1)和外参(R,t),用于接下来的双目校正和深度图生成从而实现二维到三维的转换。 相机标定方法:opencv 双目相机标定以及立体…...
大型语言模型的智能助手:检索增强生成(RAG)
背景 在人工智能的浪潮中,大型语言模型(LLMs)如GPT系列和LLama系列在自然语言处理(NLP)领域取得了显著成就。它们能够完成复杂的语言任务,如文本摘要、机器翻译、甚至创作诗歌。然而,这些模型在…...
Ubuntu 安装谷歌拼音输入法
一、Fcitx 安装 在Ubuntu 下,谷歌拼音输入法是基于Fcitx输入法的。所以,首先需要安装Fcitx。一般来说,Ubuntu最新版中都默认安装了Fcitx,但是为了确保一下,我们可以在系统终端中运行如下命令: sudo apt ins…...
修改MonkeyDev默认配置适配Xcode15
上一篇文章介绍了升级Xcode15后,适配MonkeyDev的一些操作,具体操作可以查看:Xcode 15 适配 MonkeyDev。 但是每次新建项目都要去修改那些配置,浪费时间和精力,这篇文章主要介绍如何修改MonkeyDev的默认配置࿰…...
deepinlinux打包deb文件完善
最近学习了一篇qt入门文章,做了一个小应用,要给另一台电脑用时发现还需考虑另一台没有qt,要把相关库带过去,后来就学了打包成deb安装包,看起来更专业。 win下搜索qt依赖库的程序是windeployqt,先将应用输出…...
Android studioSDK集成:com.yechaoa.yutilskt
文章目录 1、工具介绍2、集成 1、工具介绍 com.yechaoa.yutilskt是一个Android开发工具库,提供了一些常用的工具类和方法,方便开发者进行Android应用程序的开发。该库包含了以下功能: 网络请求工具类:提供了简化的网络请求方法&…...
openssl3.2 - exp - PEM <==> DER
文章目录 openssl3.2 - exp - PEM <> DER概述笔记加密用的私钥(带口令保护) - PEM > DER加密用的私钥(不带口令保护) - DER > PEM将不带口令的PEM转成带口令的PEM支持口令的算法备注END openssl3.2 - exp - PEM <> DER 概述 想将客户端私钥 服务端公钥 数…...
云计算的部署方式(公有云、私有云、混合云、社区云)
云计算的部署方式(公有云、私有云、混合云、社区云) 目录 零、00时光宝盒 一、云计算的部署方式 1.1、公有云(Public Cloud) 1.2、私有云(Private Cloud) 1.3、混合云(Hybrid Cloud) 1.4、社区云&am…...
umi4 项目使用 keepalive 缓存页面(umi-plugin-keep-alive、react-activation)
umi4使用keepalive 配置文件config\config.ts export default defineConfig({plugins: [umi-plugin-keep-alive], });安装add umi-plugin-keep-alive yarn add umi-plugin-keep-alive页面 A import { KeepAlive, history, useAliveController } from umijs/max; const Page…...
new;getline();重载<<和>>
面向对象程序设计的优点: 易维护易扩展模块化:通过设置访问级别,限制别人对自己的访问,保护了数据安全 int main(){ return 0;} 返回值0在windows下编程一般没用,但是在linux中编程,返回值有时有用 汇编与…...
python报错
Missing optional dependency ‘xlrd’. Install xlrd > 1.0.0 for Excel support Use pip or conda to install xlrd 安装xlrd库...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
智能职业发展系统:AI驱动的职业规划平台技术解析
智能职业发展系统:AI驱动的职业规划平台技术解析 引言:数字时代的职业革命 在当今瞬息万变的就业市场中,传统的职业规划方法已无法满足个人和企业的需求。据统计,全球每年有超过2亿人面临职业转型困境,而企业也因此遭…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...
aardio 自动识别验证码输入
技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”,于是尝试整合图像识别与网页自动化技术,完成了这套模拟登录流程。核心思路是:截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...
【深尚想】TPS54618CQRTERQ1汽车级同步降压转换器电源芯片全面解析
1. 元器件定义与技术特点 TPS54618CQRTERQ1 是德州仪器(TI)推出的一款 汽车级同步降压转换器(DC-DC开关稳压器),属于高性能电源管理芯片。核心特性包括: 输入电压范围:2.95V–6V,输…...
