102 {
103
104 if (frame == nullptr) {
105 AERROR <<
"Input null frame ptr.";
106 return false;
107 }
108 if (frame->cloud.get() == nullptr || frame->world_cloud.get() == nullptr) {
109 AERROR <<
"Input null frame cloud.";
110 return false;
111 }
112 if (frame->cloud->empty() || frame->world_cloud->empty()) {
113 AERROR <<
"Input none points.";
114 return false;
115 }
116
117 unsigned int data_id = 0;
118 unsigned int semantic_data_id = 0;
119 unsigned int valid_point_num = 0;
120 unsigned int valid_point_num_cur = 0;
121 size_t i = 0;
122 size_t num_points = 0;
123 size_t num_points_all = 0;
124 int index = 0;
125 unsigned int nr_points_element = 3;
126 float z_dis = 0.0f;
127
128 cloud_center_(0) = frame->lidar2world_pose(0, 3);
129 cloud_center_(1) = frame->lidar2world_pose(1, 3);
130 cloud_center_(2) = frame->lidar2world_pose(2, 3);
131
132
133 frame->non_ground_indices.indices.clear();
134
135 if (frame->roi_indices.indices.empty()) {
136 use_roi_ = false;
137 }
138
139 if (use_roi_) {
140 num_points = frame->roi_indices.indices.size();
141 } else {
142 num_points = frame->world_cloud->size();
143 }
144
145
146 num_points_all = num_points;
147
148 if (num_points_all > default_point_size_) {
149 default_point_size_ = num_points * 2;
150 point_attribute_.resize(default_point_size_);
151 point_indices_temp_.resize(default_point_size_);
152 data_.resize(default_point_size_ * 3);
153 semantic_data_.resize(default_point_size_);
154 ground_height_signed_.resize(default_point_size_);
155 }
156
157
158
159
160 size_t near_ground_count = 0;
161 float near_ground_z = 0.0;
162 if (use_roi_) {
163 for (i = 0; i < num_points; ++i) {
164 index = frame->roi_indices.indices[i];
165
166
167
168
169
170
171 point_attribute_[i] = std::make_pair(index, valid_point_num);
172 point_indices_temp_[valid_point_num++] = index;
174 frame->cloud->points_semantic_label(index));
175 if (single_ground_detect_) {
176 const auto& pt = frame->cloud->at(index);
177 data_[data_id++] = static_cast<float>(pt.x);
178 data_[data_id++] = static_cast<float>(pt.y);
179 data_[data_id++] = static_cast<float>(pt.z);
180 semantic_data_[semantic_data_id++] = static_cast<int>(
182 if (ground_flag &&
183 fabs(pt.x) <= near_range_ && fabs(pt.y) <= near_range_) {
184 near_ground_count++;
185 near_ground_z += pt.z;
186 }
187 } else {
188 const auto& pt = frame->world_cloud->at(index);
189 data_[data_id++] = static_cast<float>(pt.x - cloud_center_(0));
190 data_[data_id++] = static_cast<float>(pt.y - cloud_center_(1));
191 data_[data_id++] = static_cast<float>(pt.z - cloud_center_(2));
192 semantic_data_[semantic_data_id++] = static_cast<int>(
194 if (ground_flag &&
195 fabs(pt.x - cloud_center_(0)) <= near_range_ &&
196 fabs(pt.y - cloud_center_(1)) <= near_range_) {
197 near_ground_count++;
198 near_ground_z += pt.z;
199 }
200 }
201 }
202 } else {
203 for (i = 0; i < num_points; ++i) {
204
205
206
207
208
209
210 point_attribute_[i] = std::make_pair(i, valid_point_num);
211 point_indices_temp_[valid_point_num++] = static_cast<int>(i);
213 frame->cloud->points_semantic_label(i));
214 if (single_ground_detect_) {
215 const auto& pt = frame->cloud->at(i);
216 data_[data_id++] = static_cast<float>(pt.x);
217 data_[data_id++] = static_cast<float>(pt.y);
218 data_[data_id++] = static_cast<float>(pt.z);
219 semantic_data_[semantic_data_id++] = static_cast<int>(
221 if (ground_flag &&
222 fabs(pt.x) <= near_range_ && fabs(pt.y) <= near_range_) {
223 near_ground_count++;
224 near_ground_z += pt.z;
225 }
226 } else {
227 const auto& pt = frame->world_cloud->at(i);
228 data_[data_id++] = static_cast<float>(pt.x - cloud_center_(0));
229 data_[data_id++] = static_cast<float>(pt.y - cloud_center_(1));
230 data_[data_id++] = static_cast<float>(pt.z - cloud_center_(2));
231 semantic_data_[semantic_data_id++] = static_cast<int>(
233 if (ground_flag &&
234 fabs(pt.x - cloud_center_(0)) <= near_range_ &&
235 fabs(pt.y - cloud_center_(1)) <= near_range_) {
236 near_ground_count++;
237 near_ground_z += pt.z;
238 }
239 }
240 }
241 }
242
243 CHECK_GE(num_points, valid_point_num);
244 CHECK_EQ(data_id, valid_point_num * 3);
245 CHECK_EQ(semantic_data_id, valid_point_num);
246 base::PointIndices& non_ground_indices = frame->non_ground_indices;
247
248 AINFO <<
"spatial temporal seg: use roi " << use_roi_ <<
" roi points "
249 << num_points << " and input of ground detector: " << valid_point_num;
250
251 pfdetector_->
ResetParams(ori_sample_z_lower_, ori_sample_z_upper_);
252 if (use_semantic_ground_) {
253 if (near_ground_count > 0) {
254 pfdetector_->
UpdateParams(near_ground_z * 1.0f / near_ground_count,
255 parsing_height_buffer_, frame->timestamp);
256 } else {
258 parsing_height_buffer_, frame->timestamp);
259 }
260 }
261 if (!pfdetector_->
Detect(data_.data(), semantic_data_.data(),
262 ground_height_signed_.data(), valid_point_num, nr_points_element)) {
263 ADEBUG <<
"failed to call ground detector!";
264 non_ground_indices.indices.insert(
265 non_ground_indices.indices.end(), point_indices_temp_.begin(),
266 point_indices_temp_.begin() + valid_point_num);
267 return false;
268 }
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 size_t ground_z_value_count = 0;
287 float ground_z_value = 0.0;
288 if (origin_ground_z_array_.size() >= ground_z_average_frame) {
289 origin_ground_z_array_.pop_front();
290 }
291 auto valid_index = [&](int row, int col) {
292 if (row >= 0 && row < grid_size_ && col >= 0 && col < grid_size_) {
293 return true;
294 }
295 return false;
296 };
297 for (i = 0; i < num_points; ++i) {
298 index = frame->roi_indices.indices[i];
299
300 size_t pc_index = point_attribute_[i].first;
301 size_t count = point_attribute_[i].second;
302
303 float pc[3];
304 if (single_ground_detect_) {
305 const auto& pt = frame->cloud->at(pc_index);
306 pc[0] = pt.x;
307 pc[1] = pt.y;
308 pc[2] = pt.z;
309 } else {
310 const auto& pt = frame->world_cloud->at(pc_index);
311 pc[0] = pt.x - cloud_center_(0);
312 pc[1] = pt.y - cloud_center_(1);
313 pc[2] = pt.z - cloud_center_(2);
314 }
315
316
317 if (count == -1) {
318 int cur_row, cur_col = 0;
319 std::vector<std::pair<int, int>> neighbors;
320 pfdetector_->
Pc2Voxel(pc[0], pc[1], pc[2], &cur_row, &cur_col);
321 neighbors.push_back(std::make_pair(cur_row, cur_col));
322 neighbors.push_back(std::make_pair(cur_row - 1, cur_col));
323 neighbors.push_back(std::make_pair(cur_row + 1, cur_col));
324 neighbors.push_back(std::make_pair(cur_row, cur_col - 1));
325 neighbors.push_back(std::make_pair(cur_row, cur_col + 1));
326 float min_z = std::numeric_limits<float>::max();
327 for (size_t k = 0; k < neighbors.size(); k++) {
328 int row = neighbors[k].first;
329 int col = neighbors[k].second;
330 if (!valid_index(row, col)) {
331 continue;
332 }
333 const algorithm::GroundPlaneLiDAR* plane =
335 if (plane->IsValid()) {
337 plane->params, pc);
338 min_z = std::fabs(z_dis) < min_z ? std::fabs(z_dis) : min_z;
339 }
340 }
341 z_dis = min_z;
342 } else {
343 z_dis = ground_height_signed_.data()[count];
344 }
345 frame->cloud->mutable_points_height()->at(pc_index) = z_dis;
346 frame->world_cloud->mutable_points_height()->at(pc_index) = z_dis;
347
348 const auto& ppp = frame->cloud->at(pc_index);
349 Eigen::Vector3d pc_novatel =
350 frame->lidar2novatel_extrinsics * Eigen::Vector3d(ppp.x, ppp.y, ppp.z);
352 if (pc_novatel(1) > 0 && pc_novatel(1) < near_range_dist_ &&
353 pc_novatel(0) > FLAGS_x_back - 0.1 &&
354 pc_novatel(0) < FLAGS_x_front + 0.1) {
356 }
357 if (pc_novatel(1) >= near_range_dist_ &&
358 pc_novatel(1) < middle_range_dist_ &&
359 pc_novatel(0) > FLAGS_x_back - 0.1 &&
360 pc_novatel(0) < FLAGS_x_front + 0.1) {
362 }
363
364
366 non_ground_indices.indices.push_back(i);
367 } else {
368 frame->cloud->mutable_points_label()->at(pc_index) =
370 frame->world_cloud->mutable_points_label()->at(pc_index) =
372 if (sqrt(ppp.x * ppp.x + ppp.y * ppp.y) < 8 && fabs(z_dis) < 0.1) {
373 ++ground_z_value_count;
374 ground_z_value += ppp.z;
375 }
376 }
377 }
378 AINFO <<
"succeed to call ground detector with non ground points "
379 << non_ground_indices.indices.size();
380
381 float oriHeight = ground_z_value /
382 (static_cast<float>(ground_z_value_count) * 1.0f);
383 origin_ground_z_array_.push_back(oriHeight);
384 float ori_height = 0.0;
385 for (auto value : origin_ground_z_array_) {
386 ori_height += value;
387 }
388 frame->original_ground_z = ori_height /
389 (static_cast<float>(origin_ground_z_array_.size()) * 1.0f);
390 AINFO <<
"This frame " << std::to_string(frame->timestamp)
391 <<" origin ground height is " << frame->original_ground_z;
392
393 if (debug_output_) {
394 std::ofstream out1;
395 out1.open("semantic/" + std::to_string(frame->timestamp) + ".txt");
396 if (out1.is_open()) {
397 for (size_t i = 0; i < frame->cloud->size(); i++) {
399 frame->cloud->points_semantic_label(i)));
401 frame->cloud->points_semantic_label(i)));
402 int label_index = static_cast<uint8_t>(
403 frame->cloud->points_label(i));
404 if (single_ground_detect_) {
405 const auto& pt = frame->cloud->at(i);
406 out1 << pt.x << ", " << pt.y << ", " << pt.z << ", "
407 << pt.intensity << ", " << parsing_index << ", "
408 << sbr_index << ", " << label_index << std::endl;
409 } else {
410 const auto& pt = frame->world_cloud->at(i);
411 out1 << pt.x - cloud_center_(0) << ", "
412 << pt.y - cloud_center_(1) << ", "
413 << pt.z - cloud_center_(2) << ", " << pt.intensity
414 << ", " << parsing_index << ", " << sbr_index << ", "
415 << label_index << std::endl;
416 }
417 }
418 }
419 out1.close();
420 }
421
422 if (use_ground_service_) {
424 if (ground_service != nullptr) {
427 GroundNode* node_ptr = ground_service_content_.
grid_.
DataPtr();
430 unsigned int index = 0;
431 for (unsigned int r = 0; r < rows; ++r) {
432 for (unsigned int c = 0; c < cols; ++c) {
433 const algorithm::GroundPlaneLiDAR* plane =
435 if (plane->IsValid()) {
436 index = r * cols + c;
437 GroundNode* node = node_ptr + index;
438 node->
params(0) = plane->params[0];
439 node->params(1) = plane->params[1];
440 node->params(2) = plane->params[2];
441 node->params(3) = plane->params[3];
442 node->confidence = 1.0;
443 }
444 }
445 }
446 ground_service->UpdateServiceContent(ground_service_content_);
447 } else {
448 AINFO <<
"Failed to find ground service and cannot update.";
449 }
450 }
451 return true;
452}
unsigned int GetGridDimX() const
unsigned int GetGridDimY() const
const GroundPlaneLiDAR * GetGroundPlane(int r, int c) const
void UpdateParams(float parsing_ground_z, float buffer, double timestamp)
bool Detect(const float *point_cloud, const int *semantic_value, float *height_above_ground, unsigned int nr_points, unsigned int nr_point_elements)
void ResetParams(float ori_z_lower, float ori_z_upper)
void Pc2Voxel(float x, float y, float z, int *row, int *col)
Eigen::Vector3d grid_center_
SceneServicePtr Service(const std::string &name)
static SceneManager & Instance()
T IPlaneToPointSignedDistanceWUnitNorm(const T *pi, const T *p)
PointSemanticLabel GetSemanticLabel(uint8_t value)
bool IsSemanticLabelEqual(PointSemanticLabel label, uint8_t value)
Image< uchar > * threshold(Image< T > *src, int t)
Threshold image
PointMotionLabel GetMotionLabel(uint8_t value)