Skip to content

Commit 4a53e1e

Browse files
committed
add RBF-kernel-based covariance estimation
1 parent b0b09a5 commit 4a53e1e

12 files changed

+364
-71
lines changed

.clang-format

+73-18
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,30 @@
22
Language: Cpp
33
# BasedOnStyle: Google
44
AccessModifierOffset: -2
5-
AlignAfterOpenBracket: Align
5+
AlignAfterOpenBracket: AlwaysBreak
6+
AlignConsecutiveMacros: false
67
AlignConsecutiveAssignments: false
78
AlignConsecutiveDeclarations: false
89
AlignEscapedNewlines: Left
910
AlignOperands: true
1011
AlignTrailingComments: true
11-
AllowAllParametersOfDeclarationOnNextLine: true
12-
AllowShortBlocksOnASingleLine: false
12+
AllowAllArgumentsOnNextLine: false
13+
AllowAllConstructorInitializersOnNextLine: false
14+
AllowAllParametersOfDeclarationOnNextLine: false
15+
AllowShortBlocksOnASingleLine: Never
1316
AllowShortCaseLabelsOnASingleLine: false
14-
AllowShortFunctionsOnASingleLine: Empty
15-
AllowShortIfStatementsOnASingleLine: true
17+
AllowShortFunctionsOnASingleLine: Inline
18+
AllowShortLambdasOnASingleLine: All
19+
AllowShortIfStatementsOnASingleLine: WithoutElse
1620
AllowShortLoopsOnASingleLine: true
1721
AlwaysBreakAfterDefinitionReturnType: None
1822
AlwaysBreakAfterReturnType: None
1923
AlwaysBreakBeforeMultilineStrings: true
20-
AlwaysBreakTemplateDeclarations: true
21-
BinPackArguments: true
24+
AlwaysBreakTemplateDeclarations: Yes
25+
BinPackArguments: false
2226
BinPackParameters: false
2327
BraceWrapping:
28+
AfterCaseLabel: false
2429
AfterClass: false
2530
AfterControlStatement: false
2631
AfterEnum: false
@@ -39,38 +44,46 @@ BraceWrapping:
3944
BreakBeforeBinaryOperators: None
4045
BreakBeforeBraces: Attach
4146
BreakBeforeInheritanceComma: false
47+
BreakInheritanceList: BeforeColon
4248
BreakBeforeTernaryOperators: true
4349
BreakConstructorInitializersBeforeComma: false
4450
BreakConstructorInitializers: BeforeColon
4551
BreakAfterJavaFieldAnnotations: false
46-
BreakStringLiterals: false
47-
ColumnLimit: 256
52+
BreakStringLiterals: true
53+
ColumnLimit: 180
4854
CommentPragmas: '^ IWYU pragma:'
4955
CompactNamespaces: false
5056
ConstructorInitializerAllOnOneLineOrOnePerLine: true
51-
ConstructorInitializerIndentWidth: 4
52-
ContinuationIndentWidth: 4
57+
ConstructorInitializerIndentWidth: 0
58+
ContinuationIndentWidth: 2
5359
Cpp11BracedListStyle: true
54-
DerivePointerAlignment: true
60+
DeriveLineEnding: true
61+
DerivePointerAlignment: false
5562
DisableFormat: false
5663
ExperimentalAutoDetectBinPacking: false
5764
FixNamespaceComments: true
5865
ForEachMacros:
5966
- foreach
6067
- Q_FOREACH
6168
- BOOST_FOREACH
62-
IncludeBlocks: Preserve
69+
IncludeBlocks: Regroup
6370
IncludeCategories:
6471
- Regex: '^<ext/.*\.h>'
6572
Priority: 2
73+
SortPriority: 0
6674
- Regex: '^<.*\.h>'
6775
Priority: 1
76+
SortPriority: 0
6877
- Regex: '^<.*'
6978
Priority: 2
79+
SortPriority: 0
7080
- Regex: '.*'
7181
Priority: 3
82+
SortPriority: 0
7283
IncludeIsMainRegex: '([-_](test|unittest))?$'
84+
IncludeIsMainSourceRegex: ''
7385
IndentCaseLabels: true
86+
IndentGotoLabels: true
7487
IndentPPDirectives: None
7588
IndentWidth: 2
7689
IndentWrappedFunctionNames: false
@@ -81,33 +94,75 @@ MacroBlockBegin: ''
8194
MacroBlockEnd: ''
8295
MaxEmptyLinesToKeep: 1
8396
NamespaceIndentation: None
97+
ObjCBinPackProtocolList: Never
8498
ObjCBlockIndentWidth: 2
8599
ObjCSpaceAfterProperty: false
86-
ObjCSpaceBeforeProtocolList: false
100+
ObjCSpaceBeforeProtocolList: true
87101
PenaltyBreakAssignment: 2
88102
PenaltyBreakBeforeFirstCallParameter: 1
89103
PenaltyBreakComment: 300
90104
PenaltyBreakFirstLessLess: 120
91105
PenaltyBreakString: 1000
92-
PenaltyExcessCharacter: 0
106+
PenaltyBreakTemplateDeclaration: 10
107+
PenaltyExcessCharacter: 1000000
93108
PenaltyReturnTypeOnItsOwnLine: 200
94109
PointerAlignment: Left
110+
RawStringFormats:
111+
- Language: Cpp
112+
Delimiters:
113+
- cc
114+
- CC
115+
- cpp
116+
- Cpp
117+
- CPP
118+
- 'c++'
119+
- 'C++'
120+
CanonicalDelimiter: ''
121+
BasedOnStyle: google
122+
- Language: TextProto
123+
Delimiters:
124+
- pb
125+
- PB
126+
- proto
127+
- PROTO
128+
EnclosingFunctions:
129+
- EqualsProto
130+
- EquivToProto
131+
- PARSE_PARTIAL_TEXT_PROTO
132+
- PARSE_TEST_PROTO
133+
- PARSE_TEXT_PROTO
134+
- ParseTextOrDie
135+
- ParseTextProtoOrDie
136+
CanonicalDelimiter: ''
137+
BasedOnStyle: google
95138
ReflowComments: true
96139
SortIncludes: false
97-
SortUsingDeclarations: false
140+
SortUsingDeclarations: true
98141
SpaceAfterCStyleCast: false
99-
SpaceAfterTemplateKeyword: false
142+
SpaceAfterLogicalNot: false
143+
SpaceAfterTemplateKeyword: true
100144
SpaceBeforeAssignmentOperators: true
101-
SpaceBeforeParens: Never
145+
SpaceBeforeCpp11BracedList: false
146+
SpaceBeforeCtorInitializerColon: true
147+
SpaceBeforeInheritanceColon: true
148+
SpaceBeforeParens: ControlStatements
149+
SpaceBeforeRangeBasedForLoopColon: true
150+
SpaceInEmptyBlock: false
102151
SpaceInEmptyParentheses: false
103152
SpacesBeforeTrailingComments: 2
104153
SpacesInAngles: false
154+
SpacesInConditionalStatement: false
105155
SpacesInContainerLiterals: true
106156
SpacesInCStyleCastParentheses: false
107157
SpacesInParentheses: false
108158
SpacesInSquareBrackets: false
159+
SpaceBeforeSquareBrackets: false
109160
Standard: Auto
161+
StatementMacros:
162+
- Q_UNUSED
163+
- QT_REQUIRE_VERSION
110164
TabWidth: 8
165+
UseCRLF: false
111166
UseTab: Never
112167
...
113168

CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ if(BUILD_VGICP_CUDA)
8282
src/fast_gicp/cuda/fast_vgicp_cuda.cu
8383
src/fast_gicp/cuda/brute_force_knn.cu
8484
src/fast_gicp/cuda/covariance_estimation.cu
85+
src/fast_gicp/cuda/covariance_estimation_rbf.cu
86+
src/fast_gicp/cuda/covariance_regularization.cu
8587
src/fast_gicp/cuda/gaussian_voxelmap.cu
8688
src/fast_gicp/cuda/find_voxel_correspondences.cu
8789
src/fast_gicp/cuda/compute_derivatives.cu

include/fast_gicp/cuda/covariance_estimation.cuh

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
namespace fast_gicp {
99
namespace cuda {
1010

11-
void covariance_estimation(const thrust::device_vector<Eigen::Vector3f>& points, int k, const thrust::device_vector<int>& k_neighbors, thrust::device_vector<Eigen::Matrix3f>& covariances, RegularizationMethod method);
11+
void covariance_estimation(const thrust::device_vector<Eigen::Vector3f>& points, int k, const thrust::device_vector<int>& k_neighbors, thrust::device_vector<Eigen::Matrix3f>& covariances);
1212

13+
void covariance_estimation_rbf(const thrust::device_vector<Eigen::Vector3f>& points, double kernel_width, double max_dist, thrust::device_vector<Eigen::Matrix3f>& covariances);
1314
}
1415
} // namespace fast_gicp
1516

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef FAST_GICP_CUDA_COVARIANCE_REGULARIZATION_CUH
2+
#define FAST_GICP_CUDA_COVARIANCE_REGULARIZATION_CUH
3+
4+
#include <Eigen/Core>
5+
#include <thrust/device_vector.h>
6+
#include <fast_gicp/gicp/gicp_settings.hpp>
7+
8+
namespace fast_gicp {
9+
namespace cuda {
10+
11+
void covariance_regularization(thrust::device_vector<Eigen::Matrix3f>& covs, RegularizationMethod method);
12+
13+
} // namespace cuda
14+
} // namespace fast_gicp
15+
16+
#endif

include/fast_gicp/cuda/fast_vgicp_cuda.cuh

+6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public:
3333
~FastVGICPCudaCore();
3434

3535
void set_resolution(double resolution);
36+
void set_kernel_params(double kernel_width, double kernel_max_dist);
3637

3738
void swap_source_and_target();
3839
void set_source_cloud(const std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f>>& cloud);
@@ -46,6 +47,9 @@ public:
4647
void calculate_source_covariances(RegularizationMethod method);
4748
void calculate_target_covariances(RegularizationMethod method);
4849

50+
void calculate_source_covariances_rbf(RegularizationMethod method);
51+
void calculate_target_covariances_rbf(RegularizationMethod method);
52+
4953
void get_source_covariances(std::vector<Eigen::Matrix3f, Eigen::aligned_allocator<Eigen::Matrix3f>>& covs) const;
5054
void get_target_covariances(std::vector<Eigen::Matrix3f, Eigen::aligned_allocator<Eigen::Matrix3f>>& covs) const;
5155

@@ -62,6 +66,8 @@ public:
6266

6367
public:
6468
double resolution;
69+
double kernel_width;
70+
double kernel_max_dist;
6571

6672
std::unique_ptr<Points> source_points;
6773
std::unique_ptr<Points> target_points;

include/fast_gicp/gicp/fast_vgicp_cuda.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace cuda {
1818
class FastVGICPCudaCore;
1919
}
2020

21-
enum class NearestNeighborMethod { CPU_PARALLEL_KDTREE, GPU_BRUTEFORCE };
21+
enum class NearestNeighborMethod { CPU_PARALLEL_KDTREE, GPU_BRUTEFORCE, GPU_RBF_KERNEL };
2222

2323
/**
2424
* @brief Fast Voxelized GICP algorithm boosted with CUDA
@@ -47,6 +47,7 @@ class FastVGICPCuda : public LsqRegistration<PointSource, PointTarget> {
4747

4848
void setCorrespondenceRandomness(int k);
4949
void setResolution(double resolution);
50+
void setKernelCovarianceEstimationParams(double kernel_width, double max_dist);
5051
void setRegularizationMethod(RegularizationMethod method);
5152
void setNearesetNeighborSearchMethod(NearestNeighborMethod method);
5253

include/fast_gicp/gicp/impl/fast_vgicp_cuda_impl.hpp

+14-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ FastVGICPCuda<PointSource, PointTarget>::FastVGICPCuda() : LsqRegistration<Point
2828

2929
vgicp_cuda_.reset(new cuda::FastVGICPCudaCore());
3030
vgicp_cuda_->set_resolution(voxel_resolution_);
31+
vgicp_cuda_->set_kernel_params(0.5, 3.0);
3132
}
3233

3334
template<typename PointSource, typename PointTarget>
@@ -41,6 +42,9 @@ void FastVGICPCuda<PointSource, PointTarget>::setResolution(double resolution) {
4142
vgicp_cuda_->set_resolution(resolution);
4243
}
4344

45+
template <typename PointSource, typename PointTarget>
46+
void FastVGICPCuda<PointSource, PointTarget>::setKernelCovarianceEstimationParams(double kernel_width, double max_dist) {}
47+
4448
template<typename PointSource, typename PointTarget>
4549
void FastVGICPCuda<PointSource, PointTarget>::setRegularizationMethod(RegularizationMethod method) {
4650
regularization_method_ = method;
@@ -84,12 +88,16 @@ void FastVGICPCuda<PointSource, PointTarget>::setInputSource(const PointCloudSou
8488
case NearestNeighborMethod::CPU_PARALLEL_KDTREE: {
8589
std::vector<int> neighbors = find_neighbors_parallel_kdtree<PointSource>(k_correspondences_, cloud);
8690
vgicp_cuda_->set_source_neighbors(k_correspondences_, neighbors);
91+
vgicp_cuda_->calculate_source_covariances(regularization_method_);
8792
} break;
8893
case NearestNeighborMethod::GPU_BRUTEFORCE:
8994
vgicp_cuda_->find_source_neighbors(k_correspondences_);
95+
vgicp_cuda_->calculate_source_covariances(regularization_method_);
96+
break;
97+
case NearestNeighborMethod::GPU_RBF_KERNEL:
98+
vgicp_cuda_->calculate_source_covariances_rbf(regularization_method_);
9099
break;
91100
}
92-
vgicp_cuda_->calculate_source_covariances(regularization_method_);
93101
}
94102

95103
template<typename PointSource, typename PointTarget>
@@ -109,12 +117,16 @@ void FastVGICPCuda<PointSource, PointTarget>::setInputTarget(const PointCloudTar
109117
case NearestNeighborMethod::CPU_PARALLEL_KDTREE: {
110118
std::vector<int> neighbors = find_neighbors_parallel_kdtree<PointTarget>(k_correspondences_, cloud);
111119
vgicp_cuda_->set_target_neighbors(k_correspondences_, neighbors);
120+
vgicp_cuda_->calculate_target_covariances(regularization_method_);
112121
} break;
113122
case NearestNeighborMethod::GPU_BRUTEFORCE:
114123
vgicp_cuda_->find_target_neighbors(k_correspondences_);
124+
vgicp_cuda_->calculate_target_covariances(regularization_method_);
125+
break;
126+
case NearestNeighborMethod::GPU_RBF_KERNEL:
127+
vgicp_cuda_->calculate_target_covariances_rbf(regularization_method_);
115128
break;
116129
}
117-
vgicp_cuda_->calculate_target_covariances(regularization_method_);
118130
vgicp_cuda_->create_target_voxelmap();
119131
}
120132

src/align.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ int main(int argc, char** argv) {
186186
// this would be a good choice if your PC has a weak CPU and a strong GPU (e.g., NVIDIA Jetson)
187187
vgicp_cuda.setNearesetNeighborSearchMethod(fast_gicp::NearestNeighborMethod::GPU_BRUTEFORCE);
188188
test(vgicp_cuda, target_cloud, source_cloud);
189+
190+
std::cout << "--- vgicp_cuda (gpu_rbf_kernel) ---" << std::endl;
191+
// use RBF-kernel-based covariance estimation
192+
// extremely fast but maybe a bit inaccurate
193+
vgicp_cuda.setNearesetNeighborSearchMethod(fast_gicp::NearestNeighborMethod::GPU_RBF_KERNEL);
194+
test(vgicp_cuda, target_cloud, source_cloud);
189195
#endif
190196

191197
return 0;

src/fast_gicp/cuda/covariance_estimation.cu

+6-47
Original file line numberDiff line numberDiff line change
@@ -40,55 +40,14 @@ namespace {
4040

4141
thrust::device_ptr<Eigen::Matrix3f> covariances_ptr;
4242
};
43+
} // namespace
4344

44-
struct covariance_regularization_svd{
45-
__host__ __device__ void operator()(Eigen::Matrix3f& cov) const {
46-
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eig;
47-
eig.computeDirect(cov);
45+
void covariance_estimation(const thrust::device_vector<Eigen::Vector3f>& points, int k, const thrust::device_vector<int>& k_neighbors, thrust::device_vector<Eigen::Matrix3f>& covariances) {
46+
thrust::device_vector<int> d_indices(points.size());
47+
thrust::sequence(d_indices.begin(), d_indices.end());
4848

49-
// why this doen't work...???
50-
// cov = eig.eigenvectors() * values.asDiagonal() * eig.eigenvectors().inverse();
51-
Eigen::Matrix3f values = Eigen::Vector3f(1e-3, 1, 1).asDiagonal();
52-
Eigen::Matrix3f v_inv = eig.eigenvectors().inverse();
53-
cov = eig.eigenvectors() * values * v_inv;
54-
55-
// JacobiSVD is not supported on CUDA
56-
// Eigen::JacobiSVD(cov, Eigen::ComputeFullU | Eigen::ComputeFullV);
57-
// Eigen::Vector3f values(1, 1, 1e-3);
58-
// cov = svd.matrixU() * values.asDiagonal() * svd.matrixV().transpose();
59-
}
60-
};
61-
62-
struct covariance_regularization_frobenius {
63-
__host__ __device__ void operator()(Eigen::Matrix3f& cov) const {
64-
float lambda = 1e-3;
65-
Eigen::Matrix3f C = cov + lambda * Eigen::Matrix3f::Identity();
66-
Eigen::Matrix3f C_inv = C.inverse();
67-
Eigen::Matrix3f C_norm = (C_inv / C_inv.norm()).inverse();
68-
cov = C_norm;
69-
}
70-
};
71-
}
72-
73-
void covariance_estimation(const thrust::device_vector<Eigen::Vector3f>& points, int k, const thrust::device_vector<int>& k_neighbors, thrust::device_vector<Eigen::Matrix3f>& covariances, RegularizationMethod method) {
74-
thrust::device_vector<int> d_indices(points.size());
75-
thrust::sequence(d_indices.begin(), d_indices.end());
76-
77-
covariances.resize(points.size());
78-
thrust::for_each(d_indices.begin(), d_indices.end(), covariance_estimation_kernel(points, k, k_neighbors, covariances));
79-
80-
switch(method) {
81-
default:
82-
std::cerr << "unimplemented covariance regularization method was selected!!" << std::endl;
83-
abort();
84-
case RegularizationMethod::PLANE:
85-
thrust::for_each(covariances.begin(), covariances.end(), covariance_regularization_svd());
86-
break;
87-
case RegularizationMethod::FROBENIUS:
88-
thrust::for_each(covariances.begin(), covariances.end(), covariance_regularization_frobenius());
89-
break;
49+
covariances.resize(points.size());
50+
thrust::for_each(d_indices.begin(), d_indices.end(), covariance_estimation_kernel(points, k, k_neighbors, covariances));
9051
}
91-
}
92-
9352
}
9453
}

0 commit comments

Comments
 (0)