当前位置:网站首页>Pcl:: fromrosmsg alarm failed to find match for field 'intensity'
Pcl:: fromrosmsg alarm failed to find match for field 'intensity'
2022-07-04 09:40:00 【Ly. Leo】
pcl::fromROSMsg Warning Failed to find match for field 'intensity'
1 Problem description
The original point cloud PointCloud2 Types of topics contain intensity data , And in Rviz The intensity information can be displayed in . Use pcl::fromROSMsg() Function will ROS Of PointCloud2 Messages of type are converted to pcl::PointXYZI After data of type , There is Failed to find match for field ‘intensity’ The problem of 1.
2 Cause analysis
- Emitted topic The data structure of point cloud is different from that of the received point cloud ;
such as , Emitted topic Point cloud type is PointXYZI( contain x, y, z, intensity), What you receive is customized PointXYZIRT( contain x, y, z, intensity, ring, timestamp)
Issued point cloud data structure
struct PointXYZI
{
PCL_ADD_POINT4D;
float intensity;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
} EIGEN_ALIGN16;
Received point cloud data structure
struct PointXYZIRT
{
PCL_ADD_POINT4D;
uint8_t intensity;
uint16_t ring;
double timestamp;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
} EIGEN_ALIGN16;
- The data types in the point cloud structure are different ;
In fact, if only the data structure is different, it may not lead to this problem , If intensity The data type is consistent ,pcl::fromROSMsgFunction can still convert the previous consistent part , At least x, y, z, i It can be received normally . But in the example above PointXYZI Ofintensityyes float, Self defined PointXYZIRTintensitynevertheless uint8_t, suchpcl::fromROSMsgFunction will report an error 【 reference 】.
3 Solution
3.1 get topic data structure
First of all, you need to know the data type of each member in the issued data structure , If you know in advance , This part can be skipped . But in many cases, you may not know the data structure when recording . Here are two ways to get the data structure :
3.1.1 Use rviz get
As we mentioned earlier ,rviz It is the lidar reflectivity that can normally display point clouds intensity Of , That is to say rviz This type of point cloud can be accepted normally , have access to rviz adopt “by topic” Get the selected topic Point cloud , And then from Channel Name Click the drop-down list on the right , You can see all members . But this method cannot get the actual sorting , But the general sorting is XYZIRT.
3.1.2 sensor_msgs::PointCloud2 Data structure acquisition
manual Should be msg The data structure is as follows , among sensor_msgs/PointField[] fields Contains the data part of the point cloud .
std_msgs/Header header
uint32 height
uint32 width
sensor_msgs/PointField[] fields
bool is_bigendian
uint32 point_step
uint32 row_step
uint8[] data
bool is_dense
Here is sensor_msgs/PointField.msg Of Source file , among name Save the member name of the point cloud structure ( Such as :x, y, z, intensity etc. ……),offset Indicates correspondence name The data of is stored in the storage location of this group of data ,datatype Store this name Of offset What is the data type , however datatype It's a uint8 Enumeration , The values defined above for each data type store the corresponding types . That is, we will correspond to name Of datatype You can know its type by printing it .
# This message holds the description of one point entry in the
# PointCloud2 message format.
uint8 INT8 = 1
uint8 UINT8 = 2
uint8 INT16 = 3
uint8 UINT16 = 4
uint8 INT32 = 5
uint8 UINT32 = 6
uint8 FLOAT32 = 7
uint8 FLOAT64 = 8
string name # Name of field
uint32 offset # Offset from start of point struct
uint8 datatype # Datatype enumeration, see above
uint32 count # How many elements in the field
Just refer to the callback of the cloud below to print datatype The enumerated values . If printed as 2, Is due to uint8 UINT8 = 2 The definition of ,intensity Should be uint8_t type .
void MapGenerationNode::lidarCallback(const sensor_msgs::PointCloud2::ConstPtr& lidar)
{
for (int f=0; f<lidar->fields.size(); ++f)
{
if (lidar->fields[f].name == "intensity")
std::cout << "intensity lidar->fields[f].datatype = " << (int)lidar->fields[f].datatype << std::endl;
}
3.2 Manually convert point cloud format
Customize a fromROSMsg_DIY The function of is used to convert point clouds
void fromROSMsg_DIY(const sensor_msgs::PointCloud2::ConstPtr& cloud_msg,
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud)
{
// Get the field structure of this point cloud
int pointBytes = cloud_msg->point_step;
int offset_x;
int offset_y;
int offset_z;
int offset_int;
for (int f=0; f<cloud_msg->fields.size(); ++f)
{
if (cloud_msg->fields[f].name == "x")
offset_x = cloud_msg->fields[f].offset;
if (cloud_msg->fields[f].name == "y")
offset_y = cloud_msg->fields[f].offset;
if (cloud_msg->fields[f].name == "z")
offset_z = cloud_msg->fields[f].offset;
if (cloud_msg->fields[f].name == "intensity")
offset_int = cloud_msg->fields[f].offset;
}
// populate point cloud object
for (int p=0; p<cloud_msg->width*cloud_msg->height; ++p)
{
pcl::PointXYZI newPoint;
newPoint.x = *(float*)(&cloud_msg->data[0] + (pointBytes*p) + offset_x);
newPoint.y = *(float*)(&cloud_msg->data[0] + (pointBytes*p) + offset_y);
newPoint.z = *(float*)(&cloud_msg->data[0] + (pointBytes*p) + offset_z);
newPoint.intensity = *(unsigned char*)(&cloud_msg->data[0] + (pointBytes*p) + offset_int);
cloud->points.push_back(newPoint);
}
cloud->height = cloud_msg->height;
cloud->width = cloud_msg->width;
}
The callback function can be written like this
void MapNode::lidarCallback(const sensor_msgs::PointCloud2::ConstPtr& lidar)
{
pcl::PointCloud<pcl::PointXYZI>::Ptr lidar_cloud3(new pcl::PointCloud<pcl::PointXYZI>);
fromROSMsg_DIY(lidar, lidar_cloud3);
//...
}
You can also refer to a complete routine 【 Quote from here 】, But note that there is no point cloud in this routine hight and width assignment , Doing something else ( Such as :pcl::io::savePCDFileASCII ()) There may be problems when .
#include <iostream>
#include <pcl/common/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/conversions.h>
using namespace std;
/* ---[ */
int main (int argc, char** argv)
{
if (argc < 4)
{
std::cerr << "Syntax is: " << argv[0] << " <file_in.pcd> <file_out.pcd> 0/1/2 (ascii/binary/binary_compressed) [precision (ASCII)]" << std::endl;
return (-1);
}
pcl::PCLPointCloud2 cloud_msg;
Eigen::Vector4f origin; Eigen::Quaternionf orientation;
pcl::PointCloud<pcl::PointXYZI> cloud_xyzi;
if (pcl::io::loadPCDFile (string (argv[1]), cloud_msg, origin, orientation) < 0)
{
std::cerr << "Unable to load " << argv[1] << std::endl;
return (-1);
}
// pcl::fromPCLPointCloud2(cloud,*cloud_xyzi);
int pointBytes = cloud_msg.point_step;
int offset_x;
int offset_y;
int offset_z;
int offset_int;
for (int f=0; f<cloud_msg.fields.size(); ++f)
{
if (cloud_msg.fields[f].name == "x")
offset_x = cloud_msg.fields[f].offset;
if (cloud_msg.fields[f].name == "y")
offset_y = cloud_msg.fields[f].offset;
if (cloud_msg.fields[f].name == "z")
offset_z = cloud_msg.fields[f].offset;
if (cloud_msg.fields[f].name == "intensity")
offset_int = cloud_msg.fields[f].offset;
}
std::cout << offset_x << offset_y << offset_z << offset_int << std::endl;
// populate point cloud object
for (int p=0; p<cloud_msg.width*cloud_msg.height; ++p)
{
pcl::PointXYZI newPoint;
newPoint.x = *(float*)(&cloud_msg.data[0] + (pointBytes*p) + offset_x);
newPoint.y = *(float*)(&cloud_msg.data[0] + (pointBytes*p) + offset_y);
newPoint.z = *(float*)(&cloud_msg.data[0] + (pointBytes*p) + offset_z);
newPoint.intensity = *(unsigned char*)(&cloud_msg.data[0] + (pointBytes*p) + offset_int);
//std::cout << p << " [" << newPoint.x << "," << newPoint.y << "," << newPoint.z << "," << newPoint.intensity << "]" << std::endl;
cloud_xyzi.points.push_back(newPoint);
}
cloud_xyzi.height = 1;
cloud_xyzi.width = cloud_msg.width*cloud_msg.height
int type = atoi (argv[3]);
// std::cerr << "Loaded a point cloud with " << cloud_msg.width * cloud_msg.height <<
// " points (total size is " << cloud_msg.data.size () <<
// ") and the following channels: " << pcl::getFieldsList (cloud_msg) << std::endl;
pcl::PCDWriter w;
if (type == 0)
{
std::cerr << "Saving file " << argv[2] << " as ASCII." << std::endl;
w.writeASCII (string (argv[2]), cloud_xyzi, (argc == 5) ? atoi (argv[4]) : 7);
}
else if (type == 1)
{
std::cerr << "Saving file " << argv[2] << " as binary." << std::endl;
w.writeBinary (string (argv[2]), cloud_xyzi);
}
else if (type == 2)
{
std::cerr << "Saving file " << argv[2] << " as binary_compressed." << std::endl;
w.writeBinaryCompressed (string (argv[2]), cloud_xyzi);
}
}
Its CMakeLists.txt That's how it's written
cmake_minimum_required(VERSION 2.6)
project(pcl_test)
find_package(PCL 1.8 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(save_pcd save_pcd2.cpp)
add_library(save_pcd_lib SHARED save_pcd.cpp)
target_link_libraries (save_pcd ${PCL_LIBRARIES})
https://blog.csdn.net/yuteng12138/article/details/124794822 ︎
边栏推荐
- Fabric of kubernetes CNI plug-in
- Fatal error in golang: concurrent map writes
- 【leetcode】540. A single element in an ordered array
- Get the source code in the mask with the help of shims
- HMS core helps baby bus show high-quality children's digital content to global developers
- xxl-job惊艳的设计,怎能叫人不爱
- [on February 11, 2022, the latest and most fully available script library collection of the whole network, a total of 23]
- Write a jison parser from scratch (6/10): parse, not define syntax
- How should PMP learning ideas be realized?
- Analysis report on the production and marketing demand and investment forecast of tellurium dioxide in the world and China Ⓣ 2022 ~ 2027
猜你喜欢

QTreeView+自定义Model实现示例

Four common methods of copying object attributes (summarize the highest efficiency)

IIS configure FTP website

MySQL foundation 02 - installing MySQL in non docker version

mmclassification 标注文件生成

Markdown syntax

C # use gdi+ to add text to the picture and make the text adaptive to the rectangular area

How do microservices aggregate API documents? This wave of show~

回复评论的sql

2022-2028 global tensile strain sensor industry research and trend analysis report
随机推荐
品牌连锁店5G/4G无线组网方案
Luogu deep foundation part 1 Introduction to language Chapter 4 loop structure programming (2022.02.14)
Reading notes on how to connect the network - hubs, routers and routers (III)
AMLOGIC gsensor debugging
Write a jison parser from scratch (5/10): a brief introduction to the working principle of jison parser syntax
On Multus CNI
QTreeView+自定义Model实现示例
After unplugging the network cable, does the original TCP connection still exist?
PHP personal album management system source code, realizes album classification and album grouping, as well as album image management. The database adopts Mysql to realize the login and registration f
Global and Chinese markets of thrombography hemostasis analyzer (TEG) 2022-2028: Research Report on technology, participants, trends, market size and share
Hands on deep learning (36) -- language model and data set
2022-2028 global special starch industry research and trend analysis report
Tkinter Huarong Road 4x4 tutorial II
C # use ffmpeg for audio transcoding
Investment analysis and future production and marketing demand forecast report of China's paper industry Ⓥ 2022 ~ 2028
2022-2028 global elastic strain sensor industry research and trend analysis report
Reload CUDA and cudnn (for tensorflow and pytorch) [personal sorting summary]
SSM online examination system source code, database using mysql, online examination system, fully functional, randomly generated question bank, supporting a variety of question types, students, teache
Global and Chinese trisodium bicarbonate operation mode and future development forecast report Ⓢ 2022 ~ 2027
Trees and graphs (traversal)