lego-loam imageProjection.cpp源码注释(三)
马上就注释完啦!!加油!!
void cloudHandler(const sensor_msgs::PointCloud2ConstPtr& laserCloudMsg){
// 1. Convert ros message to pcl point cloud
copyPointCloud(laserCloudMsg);
// 2. Start and end angle of a scan
findStartEndAngle();
// 3. Range image projection
projectPointCloud();
// 4. Mark ground points
groundRemoval();
// 5. Point cloud segmentation
cloudSegmentation();
// 6. Publish all clouds
publishCloud();
// 7. Reset parameters for next iteration
resetParameters();
}
我们继续看回调函数 publishCloud()
一、publishCloud()
void publishCloud(){
// 1. Publish Seg Cloud Info
segMsg.header = cloudHeader;
pubSegmentedCloudInfo.publish(segMsg);
// 2. Publish clouds
sensor_msgs::PointCloud2 laserCloudTemp;
pcl::toROSMsg(*outlierCloud, laserCloudTemp);
laserCloudTemp.header.stamp = cloudHeader.stamp;
laserCloudTemp.header.frame_id = "base_link";
pubOutlierCloud.publish(laserCloudTemp);
// segmented cloud with ground
pcl::toROSMsg(*segmentedCloud, laserCloudTemp);
laserCloudTemp.header.stamp = cloudHeader.stamp;
laserCloudTemp.header.frame_id = "base_link";
pubSegmentedCloud.publish(laserCloudTemp);
// projected full cloud
if (pubFullCloud.getNumSubscribers() != 0){
pcl::toROSMsg(*fullCloud, laserCloudTemp);
laserCloudTemp.header.stamp = cloudHeader.stamp;
laserCloudTemp.header.frame_id = "base_link";
pubFullCloud.publish(laserCloudTemp);
}
// original dense ground cloud
if (pubGroundCloud.getNumSubscribers() != 0){
pcl::toROSMsg(*groundCloud, laserCloudTemp);
laserCloudTemp.header.stamp = cloudHeader.stamp;
laserCloudTemp.header.frame_id = "base_link";
pubGroundCloud.publish(laserCloudTemp);
}
// segmented cloud without ground
if (pubSegmentedCloudPure.getNumSubscribers() != 0){
pcl::toROSMsg(*segmentedCloudPure, laserCloudTemp);
laserCloudTemp.header.stamp = cloudHeader.stamp;
laserCloudTemp.header.frame_id = "base_link";
pubSegmentedCloudPure.publish(laserCloudTemp);
}
// projected full cloud info
if (pubFullInfoCloud.getNumSubscribers() != 0){
pcl::toROSMsg(*fullInfoCloud, laserCloudTemp);
laserCloudTemp.header.stamp = cloudHeader.stamp;
laserCloudTemp.header.frame_id = "base_link";
pubFullInfoCloud.publish(laserCloudTemp);
}
}
};
publishCloud()主要是用来发布数据的代码,需要注释的地方不多,我们可以注意一下发布了哪些数据,outlierCloud离群点,segmentedCloud(包含少量地面点的分割后点云),fullCloud全部点云,groundCloud地面点,segmentedCloudPure不包括地面点的分割后点云,fullInfoCloud点云信息。
二、resetParameters()
void resetParameters(){
laserCloudIn->clear();
groundCloud->clear();
segmentedCloud->clear();
segmentedCloudPure->clear();
outlierCloud->clear();
rangeMat = cv::Mat(N_SCAN, Horizon_SCAN, CV_32F, cv::Scalar::all(FLT_MAX));
groundMat = cv::Mat(N_SCAN, Horizon_SCAN, CV_8S, cv::Scalar::all(0));
labelMat = cv::Mat(N_SCAN, Horizon_SCAN, CV_32S, cv::Scalar::all(0));
labelCount = 1;
std::fill(fullCloud->points.begin(), fullCloud->points.end(), nanPoint);
std::fill(fullInfoCloud->points.begin(), fullInfoCloud->points.end(), nanPoint);
}
其实应该先看resetParameters(),里面为清空了之前的点云数据,为新数据分配空间。
而且初始化了rangeMat等的初始值!!
CV_32F
,表示单精度浮点数。CV_8S
,表示带符号的 8 位整数。CV_32S
,表示 32 位整数。
-
std::fill(fullCloud->points.begin(), fullCloud->points.end(), nanPoint);
:- 这行代码使用
std::fill
函数将fullCloud
点云中的所有点设置为nanPoint
。 nanPoint
可能表示一个特殊的点,其所有坐标都是 NaN 值,用于标记无效点或需要被忽略的点。
- 这行代码使用
-
std::fill(fullInfoCloud->points.begin(), fullInfoCloud->points.end(), nanPoint);
:- 类似于上一行,这行代码将
fullInfoCloud
点云中的所有点设置为nanPoint
。
- 类似于上一行,这行代码将
到这里回调函数就都注释完啦!!
最后补充一下allocateMemory()
三、allocateMemory()
void allocateMemory(){
laserCloudIn.reset(new pcl::PointCloud<PointType>());
laserCloudInRing.reset(new pcl::PointCloud<PointXYZIR>());
fullCloud.reset(new pcl::PointCloud<PointType>());
fullInfoCloud.reset(new pcl::PointCloud<PointType>());
groundCloud.reset(new pcl::PointCloud<PointType>());
segmentedCloud.reset(new pcl::PointCloud<PointType>());
segmentedCloudPure.reset(new pcl::PointCloud<PointType>());
outlierCloud.reset(new pcl::PointCloud<PointType>());
fullCloud->points.resize(N_SCAN*Horizon_SCAN);
fullInfoCloud->points.resize(N_SCAN*Horizon_SCAN);
segMsg.startRingIndex.assign(N_SCAN, 0);
segMsg.endRingIndex.assign(N_SCAN, 0);
segMsg.segmentedCloudGroundFlag.assign(N_SCAN*Horizon_SCAN, false);
segMsg.segmentedCloudColInd.assign(N_SCAN*Horizon_SCAN, 0);
segMsg.segmentedCloudRange.assign(N_SCAN*Horizon_SCAN, 0);
std::pair<int8_t, int8_t> neighbor;
neighbor.first = -1; neighbor.second = 0; neighborIterator.push_back(neighbor);
neighbor.first = 0; neighbor.second = 1; neighborIterator.push_back(neighbor);
neighbor.first = 0; neighbor.second = -1; neighborIterator.push_back(neighbor);
neighbor.first = 1; neighbor.second = 0; neighborIterator.push_back(neighbor);
allPushedIndX = new uint16_t[N_SCAN*Horizon_SCAN];
allPushedIndY = new uint16_t[N_SCAN*Horizon_SCAN];
queueIndX = new uint16_t[N_SCAN*Horizon_SCAN];
queueIndY = new uint16_t[N_SCAN*Horizon_SCAN];
}
这个函数主要用于定义不同的点云。
reset
方法用于重置智能指针,使其指向一个新的 pcl::PointCloud
对象。
比较需要关注的是neighbor!!这个之前看漏了!!
确实是使用的四邻域的广度搜索算法!!
到这里imageProjection.cpp源码注释就结束啦!!感谢观看!!有不对的地方请指出!!
原文地址:https://blog.csdn.net/Joeybee/article/details/143027626
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!