TixiaoShan/LIO-SAM

Some questions about surface feature extraction

BLB0803 opened this issue · 4 comments

Hello, Shan, I had read the article and watched the LIO-SAM and LVI-SAM demo on YouTube, there are amazing work.

And I'm reading the codes to get further understanding of whole system now.

BUT, I found something really confusing me, at

featureExtraction.cpp, function extractFeatures(), line 202,

I saw that a point belongs to planar feature will be labeled as -1 in the array called cloudLabel.

In which part makes me confused is, at line 227 of featureExtraction.cpp, below the labeling part mentioned before,

if (cloudLabel[k] <= 0){ surfaceCloudScan->push_back(extractedCloud->points[k]); }

It seems like you chosed not only points labeled as -1 but also labeled as 0.

To check out this part, I visualized the surfaceCloud that published by the publisher called pubSurfacePoints at rviz, here's the result:

Screenshot from 2021-09-27 16-07-16

Some points should not belongs to planar feature(like points of trees) had been extracted, cuz of pushing not only -1 but also 0 labeled points into surfaceCloudScan.

So I tryed to change
if (cloudLabel[k] <= 0){ surfaceCloudScan->push_back(extractedCloud->points[k]); }
with
if (cloudLabel[k] < 0){ surfaceCloudScan->push_back(extractedCloud->points[k]); }

to save planar features properly, and the visualize result like below:
Screenshot from 2021-09-27 16-20-11

It seems like extracted some "real" planar features, although are sparse.

But after I changed that, every time when I test with the dataset named campus_large_dataset.bag,

It crashed at the timestamp of[PAUSED ] Bag Time: 1572807852.632124 Duration: 430.792850 / 994.965750 like below:

Screenshot from 2021-09-27 16-35-01

Screenshot from 2021-09-27 16-38-51

Although I had double checked the /config/params.yaml to ensure parameters were configured properly.

And the WARN message is:

[ WARN] [1632731906.350954159]: Large velocity, reset IMU-preintegration!

Maybe it's because of lacking of features after I changed code like that, I guess.

Is this a bug or just I misunderstood the codes of that part? Because I had checked the same part of LVI-SAM at featureExtraction.cpp, it's exactly the same as:

if (cloudLabel[k] <= 0){ surfaceCloudScan->push_back(extractedCloud->points[k]); }

But in my opinion, a points labeled as '0' should not belongs to planar feature, since the value of each points in the label container cloudLabel, would be initialized as 0 by default.

So how could I fix this problem? Expecting for your reply.

Hi,
I do not know the reasoning behind this part of the code but isn't true that if we take the edges of a cloud, everything else would belong in the surface category? I guess this is because it's easier to pinpoint which points belong to the edges (because they are normally singular discontinuities) that which ones belong to surfaces (because we do not have continuous resolution). So I guess classifying points that are definitely edges (1), that are definitely surfaces (-1) and the rest that might belong to surfaces (0) is what is being done here.

In the first half of that function cloudNeighborPicked[ind] values of the neighbors of an edge feature are set to 1, and they won't be considered for surface points if cloudLabel[k] < 0, and there are also two downSizeFilters being applied, at line 234 of featureExtraction.cpp and line 390 of mapOptmization.cpp
all of these are making the surface points too sparse to estimate scan matching when we change to cloudLabel[k] < 0 I think.

Before change:
Screenshot from 2021-10-11 15-31-06

After change:
Screenshot from 2021-10-11 15-26-39

so to get the surface points, it seems like at every iteration in the feature extractor function, all the points other than edges are begin downsampled and accumulated into *surfaceCloud at line 236

fyi:
From my experience the degenerate check can make issues if the amount of points is small:

LIO-SAM/src/mapOptmization.cpp

Lines 1225 to 1247 in 3a3d82f

if (iterCount == 0) {
cv::Mat matE(1, 6, CV_32F, cv::Scalar::all(0));
cv::Mat matV(6, 6, CV_32F, cv::Scalar::all(0));
cv::Mat matV2(6, 6, CV_32F, cv::Scalar::all(0));
cv::eigen(matAtA, matE, matV);
matV.copyTo(matV2);
isDegenerate = false;
float eignThre[6] = {100, 100, 100, 100, 100, 100};
for (int i = 5; i >= 0; i--) {
if (matE.at<float>(0, i) < eignThre[i]) {
for (int j = 0; j < 6; j++) {
matV2.at<float>(i, j) = 0;
}
isDegenerate = true;
} else {
break;
}
}
matP = matV.inv() * matV2;
}

When turning it off, the small campus dataset worked fine even if using cloudLabel[k] < 0.

stale commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.