文章目录

  • 具体操作
    • 1、头文件中定义新的点类型
    • 2、在PCL项目中使用自定义点云类型
    • 3、在ROS项目中使用自定义点云类型

具体操作

1、头文件中定义新的点类型

例如我想要自定义点类型PointXYZR,在XYZ属性的基础上增加ring属性用来包含点云中每个点所属的激光雷达哪根线束;

同时我还想定义点类型PointXYZIR,其在PointXYZR类型基础上还增加了点的强度intensity属性;

所以我新建一个头文件point_type_define.h,内容如下:


#ifndef PROJECT_POINT_TYPE_DEFINE_H
#define PROJECT_POINT_TYPE_DEFINE_H#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>#define PCL_NO_PRECOMPILEnamespace perception {struct EIGEN_ALIGN16 _PointXYZR
{PCL_ADD_POINT4D;                  // preferred way of adding a XYZ+paddinguint32_t ring;EIGEN_MAKE_ALIGNED_OPERATOR_NEW   // make sure our new allocators are aligned
};/*** @brief A point structure representing Euclidean xyz coordinates, and the ring value.*/
struct EIGEN_ALIGN16 PointXYZR : public _PointXYZR
{inline PointXYZR (const _PointXYZR &p){x = p.x; y = p.y; z = p.z; data[3] = 1.0f;ring = p.ring;}inline PointXYZR (){x = y = z = 0.0f;data[3] = 1.0f;ring = 0;}inline PointXYZR (float _x, float _y, float _z, uint32_t ring){x = _x; y = _y; z = _z;data[3] = 1.0f;ring = ring;}friend std::ostream& operator << (std::ostream& os, const PointXYZR& p){os << "(" << p.x << "," << p.y << "," << p.z << " - " << p.ring << ")";return (os);}EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};struct EIGEN_ALIGN16 _PointXYZIR
{PCL_ADD_POINT4D;                  // preferred way of adding a XYZ+paddingfloat intensity;uint32_t ring;EIGEN_MAKE_ALIGNED_OPERATOR_NEW   // make sure our new allocators are aligned
};/*** @brief A point structure representing Euclidean xyz coordinates, and the ring value.*/
struct EIGEN_ALIGN16 PointXYZIR : public _PointXYZIR
{inline PointXYZIR (const _PointXYZIR &p){x = p.x; y = p.y; z = p.z; data[3] = 1.0f;intensity = p.intensity;ring = p.ring;}inline PointXYZIR (){x = y = z = 0.0f;data[3] = 1.0f;ring = 0;ring = 0;}inline PointXYZIR (float _x, float _y, float _z, float _intensity, uint32_t _ring){x = _x; y = _y; z = _z; data[3] = 1.0f;intensity = _intensity;ring = _ring;}friend std::ostream& operator << (std::ostream& os, const PointXYZIR& p){os << "(" << p.x << "," << p.y << "," << p.z << " - " << p.ring << ")";return (os);}EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};} // namespace perceptionPOINT_CLOUD_REGISTER_POINT_STRUCT(perception::PointXYZR,(float, x, x)(float, y, y)(float, z, z)(uint32_t, ring, ring)
)POINT_CLOUD_REGISTER_POINT_STRUCT(perception::PointXYZIR,(float, x, x)(float, y, y)(float, z, z)(float, intensity, intensity)(uint32_t, ring, ring)
)
#endif //PROJECT_POINT_TYPE_DEFINE_H

其中要特别注意如果你想要把你自定义的数据类型放在一个命名空间下,就像上面我的自定义类型放在perception命名空间下了,此时不能把POINT_CLOUD_REGISTER_POINT_STRUCT对自定义点类型进行注册的操作放在命名空间里,否则就会出现:

/usr/include/pcl-1.8/pcl/point_traits.h:176:12: error: invalid use of incomplete type ‘struct pcl::traits::fieldList<perception::PointXYZIR>’
或者
/usr/include/pcl-1.8/pcl/common/impl/io.hpp:83:3: error: no type named ‘type’ in ‘struct pcl::traits::fieldList<perception::PointXYZIR>’pcl::for_each_type<typename pcl::traits::fieldList<PointT>::type>(pcl::detail::FieldAdder<PointT>(fields));

等类似编译错误。

点云数据类型:
PCLPointField.h:

 enum PointFieldTypes { INT8 = 1,UINT8 = 2,INT16 = 3,UINT16 = 4,INT32 = 5,UINT32 = 6,FLOAT32 = 7,FLOAT64 = 8 };

2、在PCL项目中使用自定义点云类型

在头文件里定义好了自定义的点数据类型之后,我们就可以使用自定义的点数据类型来存储我们想要的点云了。

新建一个main.cpp文件,内容如下:

#include "point_type_define.h"int main(int argc, char** argv) {pcl::PointCloud<perception::PointXYZIR>::Ptr cloud(new pcl::PointCloud<perception::PointXYZIR>);cloud->header.frame_id = "base_link";cloud->width = 100;cloud->height = 1;cloud->points.resize(cloud->width * cloud->height);for (size_t i = 0; i < cloud->points.size (); ++i) {cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);cloud->points[i].intensity = i;cloud->points[i].ring = 100 - i;}pcl::io::savePCDFile ("test.pcd", *cloud);return 0;
}

编译之后,运行就可以得到test.pcd点云文件,我们可以执行命名:

pcl_viewer test.pcd -ps 8

其中-ps选项指定了点的显示尺寸。

效果如下:

在选中该界面时,按下键盘L键,此时终端会显示:

Available dimensions: x y z intensity ring
List of available geometry handlers for actor test.pcd-0: xyz(1)
List of available color handlers for actor test.pcd-0: [random](1) x(2) y(3) z(4) intensity(5) ring(6)

可以通过按数字来切换以不同点的属性值来显示点的颜色,从终端打印结果也能看出此时保存的点结果中确实有intensityring属性。

其实pcd格式也是一种文本文件格式,你也可以用编辑器打开,确认一下是否保存了点的intensityring属性:

3、在ROS项目中使用自定义点云类型

在使用ROS过程中会经常和点云打交道,ROS中点云的消息格式一般为sensor_msgs::PointCloud2,如果我们想要使用自定义点类型,如何进行发布和接收呢?

其实和正常点云操作大同小异,下面直接看代码。

// ROS
#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_ros/point_cloud.h>
// PCL
#include <pcl/point_cloud.h>
// Projects
#include "point_type_define.h"ros::Publisher g_pub_cloud;using namespace perception;
using std::cout;
using std::endl;template <typename PointType>
void PublishCloud(const typename pcl::PointCloud<PointType>::Ptr msg)
{//    pcl::PointCloud<pcl::PointXYZI>::Ptr temp_cloud(new pcl::PointCloud<pcl::PointXYZI>);
//    pcl::fromROSMsg(*msg, *temp_cloud);
//
//    temp_cloud->header.stamp = pcl_conversions::toPCL(msg->header.stamp);g_pub_cloud.publish(msg);
}int main(int argc, char** argv)
{ros::init(argc, argv, "cloud_publisher_node");ros::NodeHandle nh;g_pub_cloud = nh.advertise<sensor_msgs::PointCloud2>("/velody_cloud", 2);pcl::PointCloud<PointXYZIR>::Ptr cloud(new pcl::PointCloud<PointXYZIR>);cloud->header.frame_id = "base_link";cloud->width = 100;cloud->height = 1;cloud->points.resize(cloud->width * cloud->height);for (size_t i = 0; i < cloud->points.size (); ++i) {cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);cloud->points[i].intensity = i;cloud->points[i].ring = 100 - i;}// pcl::PointCloud<PointXYZR>::Ptr cloud_xyz(new pcl::PointCloud<PointXYZR>);// pcl::copyPointCloud(*cloud, *cloud_xyz);ros::Rate rate(10);while (ros::ok()) {ROS_INFO("--------");ros::spinOnce();PublishCloud<PointXYZIR>(cloud);rate.sleep();}return 0;
}

运行节点后,打开rviz,显示PointCloud类型,就可以得到如下可视化结果:

注意此时如何将Color Transformer修改为Intensity属性,即可以根据点云中点的不同属性值来设置颜色显示模式,此时可以看到Channel Name中果然有x,y,z,ring,intensity五种可选属性,这也说明我们确实成功发布了自定义点云数据。

一切OK!

【参考】:
https://pointclouds.org/documentation/tutorials/adding_custom_ptype.html
https://blog.csdn.net/qq_33287871/article/details/106348507
https://blog.csdn.net/Linear_Luo/article/details/52723321
http://news.migage.com/articles/PCL+point%E7%9A%84%E7%B1%BB%E5%9E%8B%E8%A7%A3%E6%9E%90_4064560_csdn.html
https://blog.csdn.net/PengPengBlog/article/details/77374594

union用处:https://blog.csdn.net/xy010902100449/article/details/48292527
https://blog.csdn.net/u013566722/article/details/79430652

匿名union:
https://blog.csdn.net/u013566722/article/details/79430652

头文件中自定义PCL点云数据类型并在项目中使用相关推荐

  1. pycharm的中自定义库和关键字_Python“库”在树莓派中的应用解析

    一.何谓Python语言的"库"? 与其它编程语言类似,Python语言中也提供有内置的或用户可自定义编写的"函数"(Function),即能够完成某具体功能的 ...

  2. 使用git拉取阿里云code托管的项目中的指定分支

    1. 注册阿里云(略) 2. 下载git并配置 打开Git Bash工具, 配置git的user.name和user.email, 分别对应阿里云的账户名和邮箱: git config --globa ...

  3. 项目中的难点怎么克服_克服大型项目中的文档挑战

    项目中的难点怎么克服 鉴于最近熊猫( Pandas) ,NumPy和Matplotlib等开放源数据科学项目的普及Swift增长,人们对文档的兴趣日益浓厚 ,这不足为奇. 为了帮助您了解所面临的问题, ...

  4. vue 项目中使用粘性布局不起作用_vue项目中常见问题及解决方案

    webpack项目中自动引入全局scss变量文件 假设我们有一个公共的scss变量文件variables.scss /*存放所有全局变量*/$card-title:#C7D200; //首页 卡片标题 ...

  5. Mac笔记本中是用Idea开发工具在Java项目中调用python脚本遇到的环境变量问题解决...

    问题描述: mac笔记本本身会自带几个python版本,比如python2.7版本,我没有改动mac默认的python版本,只是安装了python3.7版本. 使用Pycharm开发Python项目没 ...

  6. 建模大师怎么安装到revit中_全面解析Revit软件在装配式建筑项目中的建模思路...

    Revit软件在装配式建筑项目中的建模思路 Revit是Autodesk公司出品的一套软件,可帮助建筑设计师设计.建造和维护质量更好.能效更高的建筑,在建筑行业中的应用非常广泛. 在2019版的Rev ...

  7. 项目中使用粘性布局不起作用_项目中的 Git 使用规范

    祖师爷 Linus 在创造了伟大的 Linux 之后,又创造了应用最广泛的代码管理工具 -- Git,极大地提高了程序员的生产力. 现如今大部分项目都在使用 Git 作为代码管理工具,不论是在代码管理 ...

  8. 记一次使用MySQL5.7数据库数据目录下的文件恢复数据到个人云主机(CentOS7)中MySQL5.7的过程

    一.背景 个人笔记本电脑主板挂了拿去维修了,手头就一个固态盘.因项目需要,不得不还原数据库到个人云主机(CentOS).由于没有数据库管理软件,所以只能使用固态盘中mysql的数据目录下的数据文件完成 ...

  9. EXCEL 中自定义函数的应用(关于 XOR 在 EXCEL 中的用法 及 文本型数字求和)

    EXCEL 中,能否同调用内置函数一样在工作表中调用自已制作的自定义函数,出现对话框.同时也能做到像内置函数对话框里的说明?答案是肯定的,下面举例说明: 题目: ①对文本型一系列数字进行求和(SUM( ...

最新文章

  1. 【译】Monolith first —— Martin Fowler 对于微服务架构的看法
  2. 华为新版交换机端口配置由TRUNK改为ACCESS
  3. 菜鸟级springmvc+spring+mybatis整合开发用户登录功能(下)
  4. mac下用vim编写程序
  5. 汇编语言 LOOP和[BX]的联合应用
  6. 超赞!这些 “电子” 艺术品,真绝了!
  7. WeakHashMap和Java引用类型详细解析
  8. mysql的cpu飙升到500_[MySQLCPU]线上飙升800%,load达到12的解决过程
  9. 87说明书 ikbc_女性玩家的首选!——IKBC白无垢. 樱机械键盘赏评
  10. mysql数据库字段字符转数字批量语句_MySQL数据库批量替换指定字段字符串SQL语句命令...
  11. sklearn.metrics.roc_curve
  12. 拓端tecdat|R语言中的生存分析Survival analysis晚期肺癌患者4例
  13. 【趋势分析】EXPMA四色均线指标优化版主图 通达信 东财等通用
  14. 黑客攻防与电脑安全-从新手到高手
  15. python随机漫步_【Python】随机漫步
  16. 手风琴效果案例(jQuery)
  17. ClickOnce 程序安装路径
  18. JVM知识点整理2——(类加载)
  19. 无法安装office此计算机安装了32位,在电脑上安装64位Office2013出错提示找到了32位程序如何解决...
  20. kernel .config优化

热门文章

  1. 亚马逊关键词库的精细化管理分享值得你看!
  2. MySQL选错索引导致的线上慢查询事故复盘
  3. 关于iOS证书申请及安装流程
  4. 三分钟看Netty(一) 纵观全局
  5. 计算机在针灸推拿学中的应用论文,针灸推拿学论文.doc
  6. 五、无人机知识笔记(中级:控制原理与程序实现)
  7. Github 创建新分支
  8. 使用Zuul构建微服务网关(路由)
  9. [数据湖] 基于flink hudi的批流一体实践
  10. redis第九课-击穿,穿透,雪崩,redis作为分布式锁的可行性