当前位置:网站首页>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::fromROSMsg
Function can still convert the previous consistent part , At least x, y, z, i It can be received normally . But in the example above PointXYZI Ofintensity
yes float, Self defined PointXYZIRTintensity
nevertheless uint8_t, suchpcl::fromROSMsg
Function 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 ︎
边栏推荐
- 智能网关助力提高工业数据采集和利用
- Global and Chinese markets of hemoglobin analyzers in care points 2022-2028: Research Report on technology, participants, trends, market size and share
- Write a jison parser from scratch (1/10):jison, not JSON
- Latex download installation record
- Hands on deep learning (34) -- sequence model
- Report on the development trend and prospect trend of high purity zinc antimonide market in the world and China Ⓕ 2022 ~ 2027
- Svg image quoted from CodeChina
- PHP book borrowing management system, with complete functions, supports user foreground management and background management, and supports the latest version of PHP 7 x. Database mysql
- 2022-2028 global small batch batch batch furnace industry research and trend analysis report
- Reading notes on how to connect the network - tcp/ip connection (II)
猜你喜欢
165 webmaster online toolbox website source code / hare online tool system v2.2.7 Chinese version
2022-2028 global seeder industry research and trend analysis report
At the age of 30, I changed to Hongmeng with a high salary because I did these three things
品牌连锁店5G/4G无线组网方案
2022-2028 global gasket metal plate heat exchanger industry research and trend analysis report
libmysqlclient.so.20: cannot open shared object file: No such file or directory
Hands on deep learning (35) -- text preprocessing (NLP)
2022-2028 global industry research and trend analysis report on anterior segment and fundus OTC detectors
华为联机对战如何提升玩家匹配成功几率
Log cannot be recorded after log4net is deployed to the server
随机推荐
QTreeView+自定义Model实现示例
Solution to null JSON after serialization in golang
Global and Chinese markets of water heaters in Saudi Arabia 2022-2028: Research Report on technology, participants, trends, market size and share
Golang Modules
Upgrading Xcode 12 caused Carthage to build cartfile containing only rxswift to fail
Report on investment analysis and prospect trend prediction of China's MOCVD industry Ⓤ 2022 ~ 2028
Investment analysis and prospect prediction report of global and Chinese high purity tin oxide Market Ⓞ 2022 ~ 2027
Reading notes on how to connect the network - hubs, routers and routers (III)
Some points needing attention in PMP learning
2022-2028 global industry research and trend analysis report on anterior segment and fundus OTC detectors
2022-2028 global gasket metal plate heat exchanger industry research and trend analysis report
How do microservices aggregate API documents? This wave of show~
2022-2028 global optical transparency industry research and trend analysis report
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
How to ensure the uniqueness of ID in distributed environment
品牌连锁店5G/4G无线组网方案
2022-2028 research and trend analysis report on the global edible essence industry
C # use gdi+ to add text to the picture and make the text adaptive to the rectangular area
Markdown syntax
"How to connect the Internet" reading notes - FTTH