这篇文章整理了常用PCL函数(用途、参数的意义,必要时也会列出该函数所在的头文件)以及一些其它关于PCL库的知识。
Empirical Observation
sort by alphabet.
pcl::Octree
adoptBoundingBoxToPoint
This function can adjust bounding box even the box has been defined manually.
defineBoundingBox
pcl::Octree::OctreePointCloud::defineBoundingBox
: input bounding box will be used as initial bounding box first. Then the box will be adjusted to a cube. The adjusted bounding box always is different with the initial bounding box.
#####
一、基础知识
1. data()
2
chapter 2 octree
getIntersectedVoxelCenters
pcl::octree::OctreePointCloudSearch::getIntersectedVoxelCenters(Eigen::Vector3f origin,
Eigen::Vector3f direction,
AlignedPointTVector& voxel_center_list,
int max_voxel_count);
whether normalize direction
can influence the result.
- Best Case $𝑂(log(𝑁))$ In the ideal case, the octree is well-balanced, and the ray intersects only a small number of voxels, minimizing traversal.
- Average Case $𝑂(𝑘+log(𝑁))$ Where 𝑘 is the number of voxels intersected by the ray. Traversing the octree to find the ray’s starting position is $𝑂(log(𝑁))$, and processing intersected voxels depends on 𝑘.
- Worst Case $𝑂(𝑘)$ If the ray intersects a large number of voxels (e.g., when the ray passes through the entire octree), the complexity is proportional to the number of intersected voxels.
三、位姿变换
#include <pcl/common/transforms.h> //主要内容为:表示位姿的几种方法之间的转换
//cloud_in和cloud_out为::Ptr点云指针; Matrix4f=Affine3f
void pcl::transformPointCloud(const *cloud_in, *cloud_out, const Eigen::Matrix4f & transform)
2. pcl/common/eigen.h
4×4变换矩阵 transformation Eigen::Affine3f 仿射矩阵 –> pos和rpy 位置和角度 6D位姿 ;输入和输出参数为float
#include <pcl/common/eigen.h>
// 精度可能存在问题
pcl::getTranslationAndEulerAngles(imuOdomAffineLast, x, y, z, roll, pitch, yaw);
// 输入和输出参数为float
Eigen::Affine3f lastPoseInMapAff = pcl::getTransformation(x, y, z, roll, pitch, yaw);
四、匹配和配准
1. ndt.h
setTransformationEpsilon(ndt_epsilon_); // the transformation epsilon in order for an optimization to be considered as having converged to the final solution.
setStepSize(ndt_step_size_); // Set the newton line search maximum step length.
setResolution(ndt_resolution_); // Set the voxel grid resolution.
getFitnessScore ( double max_range = std::numeric_limits<double>::max() ); // Obtain the Euclidean fitness score (e.g., mean of squared distances from the source to the target)
2. pcl/kdtree/kdtree_flann.h
#include <pcl/kdtree/kdtree_flann.h>
// max_nn: num of returned points, if max_nn==0, return all.
kdtreeSurroundingKeyPoses->radiusSearch(point, radius, k_indices, k_sqr_distances, max_nn);
pcl::moveFromROSMsg(currentCloudMsg, *laserCloudIn);
3. pcl/registration/icp.h
#include <pcl/registration/icp.h>
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
pcl::PointCloud<pcl::PointXYZ>::Ptr loopSourceCorner;
icp.setInputSource(loopSourceCorner); //注意输入的点云的数据类型为Ptr
五、文件处理
1. 加载文件
#include <pcl/io/pcd_io.h>
//temFilePath包含文件名和后缀;thisCornerCloud为::Ptr点云指针;
pcl::io::loadPCDFile(temFilePath, *thisCornerCloud);
2
other
1.
You can use the following code to print out the fields of your registered point type and verify the order:
template <typename PointT>
void printPointTypeFields() {
std::cout << "Fields in the point type:\n";
for (const auto& field : pcl::traits::fieldList<PointT>::type::fields) {
std::cout << " " << field.name << "\n";
}
}
2. pcl::octree
the returned value of pcl::Octree::getIntersectedVoxels
is not guaranteed to be sorted by default.
3.
leaf_begin(): breadth-first leaf_depth_begin(): depth-first manner
末、Q&A
1.
运行pcl_viewer
时提示错误segment fault(core dump)
。可能是因为驱动安装有问题,或者pcl的版本不适配。
2.
code below is used to define and register a point type to PCL.
#include <pcl/point_types.h>
namespace custom_pcl
{
struct MyCustomPoint
{
PCL_ADD_POINT4D; // This macro adds padding for alignment and the XYZ fields
int id; // Add the custom field `id`
EIGEN_MAKE_ALIGNED_OPERATOR_NEW // Ensure proper alignment
};
}
POINT_CLOUD_REGISTER_POINT_STRUCT(
custom_pcl::MyCustomPoint, // Fully qualified name of the struct
(float, x, x) // Mapping: type, field name in struct, field name in PCL
(float, y, y)
(float, z, z)
(int, id, id) // Include the new `id` field
)
Note that the POINT_CLOUD_REGISTER_POINT_STRUCT
macro must be placed in the global namespace. You cannot place it inside a namespace because the macro relies on global templates and compile-time mechanisms that PCL expects in the global scope. However, you can still define your custom point type within a namespace. Only the macro itself has to remain in the global scope.
3.
Define a point type from existing point type in PCL
namespace custom_pcl
{
struct EIGEN_ALIGN16 MyCustomPoint : public pcl::PointXYZINormal
{
int id; // Additional field
EIGEN_MAKE_ALIGNED_OPERATOR_NEW // Ensure proper memory alignment
};
}
POINT_CLOUD_REGISTER_POINT_STRUCT(
custom_pcl::MyCustomPoint,
(float, x, x)
(float, y, y)
(float, z, z)
(float, intensity, intensity)
(float, normal_x, normal_x)
(float, normal_y, normal_y)
(float, normal_z, normal_z)
(float, curvature, curvature)
(int, id, id)
)
Then I got a warning.
warning: offsetof within non-standard-layout type 'sinoslam::Pointid' is conditionally-supported [-Winvalid-offsetof]
Standard Layout Requirements:
- A standard-layout type is one where all non-static data members are laid out in a well-defined order in memory, and there is no ambiguity due to inheritance.
- Adding new fields to a derived class makes the layout non-standard because the base class may already contain its own fields, making offsets potentially ambiguous.
4.
code below
template <class PointT>
bool calculateNormal(const pcl::PointCloud<PointT>::Ptr &cloud, Eigen::Vector3f &normal) {}
I got an error during compilation:
error : need 'typename' before 'pcl::PointCloud<PointT>::Ptr' because 'pcl::PointCloud<PointT>' is a dependent bool calculateNormal(const pcl::PointCloud<PointT>::Ptr &cloud, Eigen::Vector3f &normal)
The error arises because in a templated function, PointT is a dependent type, and the compiler needs explicit help to identify pcl::PointCloud
template <typename PointT>
bool calculateNormal(const typename pcl::PointCloud<PointT>::Ptr &cloud, Eigen::Vector3f &normal) {}
In fact, the corrected code can’t be compiled successfully. Because
5
octree_search.hpp : 396 : 46 : error : 'const struct custom::Pointid' has no member named 'getVector3fMap' return (point_a.getVector3fMap() - point_b.getVector3fMap()).squaredNorm();
The error indicates that the structure custom::Pointid does not have a member function or attribute named getVector3fMap. This function is a part of the PCL library for points that are derived from pcl::PointXYZ or similar types. Your custom Pointid struct likely does not inherit from a pcl::PointXYZ-like structure or does not implement this function.