-
Notifications
You must be signed in to change notification settings - Fork 0
/
polar_region_gpf.hpp
159 lines (132 loc) · 4.3 KB
/
polar_region_gpf.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
* Copyright (C) 2019 by AutoSense Organization. All rights reserved.
* Gary Chan <[email protected]>
*/
#ifndef POLAR_REGION_GPF_HPP_
#define POLAR_REGION_GPF_HPP_
#define PCL_NO_PRECOMPILE
#include <Eigen/Core>
#include <string>
#include <vector>
#include <deque>
#include <array>
#include <memory>
#include <thread>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/approximate_voxel_grid.h>
// #include "ground_plane_fitting_segmenter.hpp"
#include "utils/cloud_types.hpp"
namespace gicp_mapping{
typedef struct {
Eigen::Vector3f center;
Eigen::MatrixXf normal;
double d = 0.;
} model_t;
typedef std::vector<model_t> model_vector;
template <typename PointType>
double pointDist(PointType p){
return std::sqrt(p.x*p.x + + p.y*p.y + p.z*p.z);
}
template <typename PointType>
bool sortByAxisZAsc(PointType p1, PointType p2) {
return p1.z < p2.z;
}
struct RegionGPFParams {
double sensor_max_fov = 2;
double sensor_min_fov = -24.8;
// Ground Plane Fitting
double gpf_sensor_height = 1.73;
// fitting multiple planes
int gpf_num_bins = 36;
// number of iterations
int gpf_num_iter = 3;
// number of points used to estimate the lowest point representative(LPR)
// double of senser model???
int gpf_num_lpr = 15;
double gpf_th_lprs = 0.15;
// threshold for points to be considered initial seeds
double gpf_th_seeds = 0.2;
// ground points threshold distance from the plane
// <== large to guarantee safe removal
double gpf_th_gnds = 0.23;
// local plane tests.
double deg_thresh_ = 30;
double height_thresh_ = 0.6;
double d_thre_ = 10;
};
/**
* @brief Ground Removal based on Ground Plane Fitting(GPF)
* @refer
* Fast Segmentation of 3D Point Clouds: A Paradigm on LiDAR Data for
* Autonomous Vehicle Applications (ICRA, 2017)
*/
template <typename PointT>
class RegionGPFSegmenter{
public:
RegionGPFSegmenter(){
ground_min_range_ = params_.gpf_sensor_height / std::sin(params_.sensor_min_fov);
ground_min_range_ -= 1.5;
}
~RegionGPFSegmenter(){}
void segment(
const PointCloudType<PointT> &cloud_in,
PointCloudTypePtr<PointT> gnd_out,
PointCloudTypePtr<PointT> obj_out
// PointCloudTypePtr<PointT> obj_out,
// std::vector<model_t> &ground_info
);
// multi-thread version.
void segment_threads(
const PointCloudType<PointT> &cloud_in,
PointCloudTypePtr<PointT> gnd_out,
PointCloudTypePtr<PointT> obj_out
// PointCloudTypePtr<PointT> obj_out,
// std::vector<model_t> &ground_info
);
// for visualization of different segments.
void segment(
const PointCloudType<PointT> &cloud_in,
std::vector<PointCloudType<PointT>> &clouds_out
);
private:
int rangeInd(double dist);
private:
void extractInitialSeeds(const PointCloudType<PointT> &cloud_in,
PointCloudTypePtr<PointT> cloud_seeds);
model_t estimatePlane(const PointCloudType<PointT> &cloud_ground);
void mainLoop(const PointCloudType<PointT> &cloud_in,
PointCloudTypePtr<PointT> cloud_gnds,
PointCloudTypePtr<PointT> cloud_ngnds);
void segmentGPF(const PointCloudType<PointT> &cloud_in,
PointCloudType<PointT> &gnd_pts,
PointCloudType<PointT> &obj_pts);
// PointCloudType<PointT> &obj_pts,
// std::vector<model_t> &gnd_info);
void threadSegGPF(
const PointCloudType<PointT> &cloud_raw,
std::vector<std::vector<int>> &seg_inds,
std::vector<PointCloudType<PointT>> &gnd_pts,
std::vector<PointCloudType<PointT>> &obj_pts,
// std::vector<std::vector<model_t>> &gnd_info,
int thread_num
);
void voxelFiltering(PointCloudTypePtr<PointT> cloud_in,
PointCloudTypePtr<PointT> cloud_out){
pcl::ApproximateVoxelGrid<PointT> vg;
vg.setLeafSize (voxel_, voxel_, voxel_);
vg.setInputCloud(cloud_in);
vg.filter(*cloud_out);
}
private:
RegionGPFParams params_;
static const int segment_nums_ = 36;
float ground_min_range_ = 0;
float voxel_ = 0.75;
std::deque<float> range_list_{
10, 25, 45, 65
};
bool test = false;
};
}
#endif // SEGMENTERS_INCLUDE_SEGMENTERS_GROUND_PLANE_FITTING_SEGMENTER_HPP_