Apollo 11.0
自动驾驶开放平台
apollo::perception::algorithm::PlaneFitGroundDetector类 参考

#include <i_ground.h>

类 apollo::perception::algorithm::PlaneFitGroundDetector 继承关系图:
apollo::perception::algorithm::PlaneFitGroundDetector 的协作图:

Public 成员函数

 PlaneFitGroundDetector (PlaneFitGroundDetectorParam &param)
 
 ~PlaneFitGroundDetector ()
 
bool Init ()
 
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 UpdateParams (float parsing_ground_z, float buffer, double timestamp)
 
const char * GetLabel () const
 
const VoxelGridXY< float > * GetGrid () const
 
const GroundPlaneLiDAR * GetGroundPlane (int r, int c) const
 
unsigned int GetGridDimX () const
 
unsigned int GetGridDimY () const
 
float GetUnknownHeight ()
 
void Pc2Voxel (float x, float y, float z, int *row, int *col)
 
PlaneFitPointCandIndices ** GetCandis () const
 
- Public 成员函数 继承自 apollo::perception::algorithm::BaseGroundDetector
 BaseGroundDetector (PlaneFitGroundDetectorParam &param)
 
virtual ~BaseGroundDetector ()
 

Protected 成员函数

void CleanUp ()
 
void InitOrderTable (const VoxelGridXY< float > *vg, std::pair< int, int > *order)
 
int Fit ()
 
int FitLine (unsigned int r)
 
int FitGrid (const float *point_cloud, PlaneFitPointCandIndices *candi, GroundPlaneLiDAR *groundplane, unsigned int nr_points, unsigned int nr_point_element, float dist_thre)
 
int FitInOrder ()
 
int FilterCandidates (int r, int c, const float *point_cloud, PlaneFitPointCandIndices *candi, std::vector< std::pair< int, int > > *neighbors, unsigned int nr_point_element)
 
int FitGridWithNeighbors (int r, int c, const float *point_cloud, GroundPlaneLiDAR *groundplane, unsigned int nr_points, unsigned int nr_point_element, float dist_thre)
 
void GetNeighbors (int r, int c, int rows, int cols, std::vector< std::pair< int, int > > *neighbors)
 
float CalculateAngleDist (const GroundPlaneLiDAR &plane, const std::vector< std::pair< int, int > > &neighbors)
 
void SelectGroundCandidate (const float *point_cloud, const int *semantic_list, const std::vector< int > &indices, PlaneFitPointCandIndices *candi, GroundCandidateIndices *ground_candi, unsigned int nr_point_element)
 
int NeighborGroundCandidate (int row, int col, const float *point_cloud, const int *semantic_list, const std::vector< int > &indices, PlaneFitPointCandIndices *candi, unsigned int nr_point_element)
 
void SelectCandidates ()
 
int Filter ()
 
int FilterLine (unsigned int r)
 
int FilterGrid (const Voxel< float > &vg, const float *point_cloud, PlaneFitPointCandIndices *candi, unsigned int nr_points, unsigned int nr_point_element)
 
int Smooth ()
 
int SmoothInOrder ()
 
void GetInliers (int *inliers)
 
void Optimization ()
 
void PlaneRefine ()
 
void SetGroundPlaneSpherParams (float *params)
 
void GetGroundPlaneSpherParams (float *params)
 
void SmoothInMath ()
 
int SmoothLine (unsigned int up, unsigned int r, unsigned int dn)
 
int CompleteGrid (const GroundPlaneSpherical &lt, const GroundPlaneSpherical &rt, const GroundPlaneSpherical &up, const GroundPlaneSpherical &dn, GroundPlaneSpherical *gp)
 
int SmoothGrid (const GroundPlaneSpherical &g, const GroundPlaneSpherical &lt, const GroundPlaneSpherical &rt, const GroundPlaneSpherical &up, const GroundPlaneSpherical &dn, GroundPlaneSpherical *gp)
 
int CompareZ (const float *point_cloud, const std::vector< int > &point_indices, const float *z_values, PlaneFitPointCandIndices *candi, unsigned int nr_points, unsigned int nr_point_element, unsigned int nr_compares)
 
void ComputeAdaptiveThreshold ()
 
void ComputeSignedGroundHeight (const float *point_cloud, float *height_above_ground, unsigned int nr_points, unsigned int nr_point_elements)
 
void ComputeSignedGroundHeightLine (const float *point_cloud, const GroundPlaneLiDAR *up, const GroundPlaneLiDAR *cn, const GroundPlaneLiDAR *dn, float *height_above_ground, unsigned int r, unsigned int nr_points, unsigned int nr_point_elements)
 

Protected 属性

VoxelGridXY< float > * vg_fine_
 
VoxelGridXY< float > * vg_coarse_
 
GroundPlaneLiDAR ** ground_planes_
 
GroundPlaneSpherical ** ground_planes_sphe_
 
PlaneFitPointCandIndices ** local_candis_
 
GroundCandidateIndices ** ground_candidates_
 
std::pair< float, bool > ** ground_z_
 
float ** pf_thresholds_
 
unsigned int * map_fine_to_coarse_
 
char * labels_
 
float * sampled_z_values_
 
float * pf_threeds_
 
float * spher_params_
 
int * sampled_indices_
 
int age_ = 0
 
std::pair< int, int > * order_table_
 
double frame_timestamp_ = 0.0
 
float ** weight_buffer_ = nullptr
 
int * inliers_ = nullptr
 
float * sphe_params_ = nullptr
 
std::vector< std::vector< unsigned int > > neighbors_
 
Eigen::SparseMatrix< float > a_array_
 
Eigen::SparseMatrix< float > b_array_
 
Eigen::SimplicialLDLT< Eigen::SparseMatrix< float > > solver_
 
- Protected 属性 继承自 apollo::perception::algorithm::BaseGroundDetector
PlaneFitGroundDetectorParam & param_
 

详细描述

在文件 i_ground.h 第 339 行定义.

构造及析构函数说明

◆ PlaneFitGroundDetector()

apollo::perception::algorithm::PlaneFitGroundDetector::PlaneFitGroundDetector ( PlaneFitGroundDetectorParam &  param)
explicit

在文件 i_ground.cc 第 106 行定义.

107 : BaseGroundDetector(param) {
108 assert(Init());
109}
BaseGroundDetector(PlaneFitGroundDetectorParam &param)
Definition i_ground.h:327

◆ ~PlaneFitGroundDetector()

apollo::perception::algorithm::PlaneFitGroundDetector::~PlaneFitGroundDetector ( )

在文件 i_ground.cc 第 111 行定义.

111 {
112 CleanUp();
113 if (weight_buffer_ != nullptr) {
114 IFree2<float>(&weight_buffer_);
115 }
116 if (inliers_ != nullptr) {
117 IFreeAligned<int>(&inliers_);
118 }
119 if (sphe_params_ != nullptr) {
120 IFreeAligned<float>(&sphe_params_);
121 }
122}

成员函数说明

◆ CalculateAngleDist()

float apollo::perception::algorithm::PlaneFitGroundDetector::CalculateAngleDist ( const GroundPlaneLiDAR &  plane,
const std::vector< std::pair< int, int > > &  neighbors 
)
protected

在文件 i_ground.cc 第 1367 行定义.

1369 {
1370 float angle_dist = 0.0f;
1371 int count = 0;
1372 unsigned int j = 0;
1373 int r_n = 0;
1374 int c_n = 0;
1375 for (j = 0; j < neighbors.size(); ++j) {
1376 r_n = neighbors[j].first;
1377 c_n = neighbors[j].second;
1378 if (ground_planes_[r_n][c_n].IsValid()) {
1379 angle_dist += calculate_two_angles(ground_planes_[r_n][c_n], plane);
1380 count++;
1381 }
1382 }
1383 if (count == 0) {
1384 return -1;
1385 }
1386 return angle_dist / static_cast<float>(count);
1387}
float calculate_two_angles(const GroundPlaneLiDAR &p1, const GroundPlaneLiDAR &p2)
Definition i_ground.cc:1176

◆ CleanUp()

void apollo::perception::algorithm::PlaneFitGroundDetector::CleanUp ( )
protected

在文件 i_ground.cc 第 344 行定义.

344 {
345 if (vg_fine_) {
346 delete vg_fine_;
347 }
348 if (vg_coarse_) {
349 delete vg_coarse_;
350 }
351 IFree2<GroundPlaneLiDAR>(&ground_planes_);
352 IFree2<GroundPlaneSpherical>(&ground_planes_sphe_);
353 IFree2<std::pair<float, bool>>(&ground_z_);
354 IFree2<PlaneFitPointCandIndices>(&local_candis_);
355 IFree2<GroundCandidateIndices>(&ground_candidates_);
356 IFreeAligned<float>(&pf_threeds_);
357 IFreeAligned<char>(&labels_);
358 IFreeAligned<unsigned int>(&map_fine_to_coarse_);
359 IFreeAligned<float>(&sampled_z_values_);
360 IFreeAligned<int>(&sampled_indices_);
361 IFree2<float>(&pf_thresholds_);
362 IFree<std::pair<int, int>>(&order_table_);
363}

◆ CompareZ()

int apollo::perception::algorithm::PlaneFitGroundDetector::CompareZ ( const float *  point_cloud,
const std::vector< int > &  point_indices,
const float *  z_values,
PlaneFitPointCandIndices *  candi,
unsigned int  nr_points,
unsigned int  nr_point_element,
unsigned int  nr_compares 
)
protected

在文件 i_ground.cc 第 365 行定义.

371 {
372 int pos = 0;
373 int nr_candis = 0;
374 unsigned int i = 0;
375 unsigned int nr_contradi = 0;
376 unsigned int nr_z_comp_fail_threshold =
377 IMin(param_.nr_z_comp_fail_threshold, (unsigned int)(nr_compares >> 1));
378 const float *ptr = nullptr;
379 float z = 0.0f;
380 float delta_z = 0.0f;
381 std::vector<int>::const_iterator iter = indices.cbegin();
382 while (iter < indices.cend()) {
383 nr_contradi = 0;
384 pos = *iter++;
385 assert(pos < static_cast<int>(nr_points));
386 nr_contradi = 0;
387 // requires the Z element to be in the third position, i.e., after X, Y
388 ptr = point_cloud + (pos * nr_point_element);
389 z = ptr[2];
390 // for near range check valid height
391 if (IAbs(ptr[0]) < param_.roi_near_rad &&
392 IAbs(ptr[1]) < param_.roi_near_rad) {
395 continue;
396 }
397 }
398 if (nr_compares > nr_z_comp_fail_threshold) {
399 for (i = 0; i < nr_compares; ++i) {
400 delta_z = IAbs(z_values[i] - z);
401 if (delta_z > param_.planefit_filter_threshold) {
402 nr_contradi++;
403 if (nr_contradi > nr_z_comp_fail_threshold) {
404 break;
405 }
406 }
407 }
408 }
409 if (nr_contradi <= nr_z_comp_fail_threshold) {
410 labels_[pos] = 1;
411 candi->PushIndex(pos);
412 nr_candis++;
413 }
414 }
415 return nr_candis;
416}

◆ CompleteGrid()

int apollo::perception::algorithm::PlaneFitGroundDetector::CompleteGrid ( const GroundPlaneSpherical &  lt,
const GroundPlaneSpherical &  rt,
const GroundPlaneSpherical &  up,
const GroundPlaneSpherical &  dn,
GroundPlaneSpherical *  gp 
)
protected

在文件 i_ground.cc 第 1551 行定义.

1555 {
1556 int supports[] = {0, 0, 0, 0};
1557 float weights[] = {0.f, 0.f, 0.f, 0.f};
1558 gp->ForceInvalid();
1559 supports[0] = lt.GetNrSupport();
1560 supports[1] = rt.GetNrSupport();
1561 supports[2] = up.GetNrSupport();
1562 supports[3] = dn.GetNrSupport();
1563 int support_sum = 0;
1564 support_sum = ISum4(supports);
1565 if (!support_sum) {
1566 return 0;
1567 }
1568 weights[0] =
1569 static_cast<float>(supports[0]) / static_cast<float>(support_sum);
1570 weights[1] =
1571 static_cast<float>(supports[1]) / static_cast<float>(support_sum);
1572 weights[2] =
1573 static_cast<float>(supports[2]) / static_cast<float>(support_sum);
1574 weights[3] =
1575 static_cast<float>(supports[3]) / static_cast<float>(support_sum);
1576 // weighted average:
1577 gp->theta = weights[0] * lt.theta + weights[1] * rt.theta +
1578 weights[2] * up.theta + weights[3] * dn.theta;
1579 gp->phi = weights[0] * lt.phi + weights[1] * rt.phi + weights[2] * up.phi +
1580 weights[3] * dn.phi;
1581 gp->d = weights[0] * lt.d + weights[1] * rt.d + weights[2] * up.d +
1582 weights[3] * dn.d;
1583 // compute average - diveided by 4, round to nearest int
1584 support_sum = IMax(((support_sum + 2) >> 2), 1);
1585 gp->SetNrSupport(support_sum);
1586 return 1;
1587}

◆ ComputeAdaptiveThreshold()

void apollo::perception::algorithm::PlaneFitGroundDetector::ComputeAdaptiveThreshold ( )
protected

在文件 i_ground.cc 第 418 行定义.

418 {
419 unsigned int r = 0;
420 unsigned int c = 0;
421 float dr = 0.0f;
422 float dc = 0.0f;
423 float k = 0.0f;
424 float b = 0.0f;
425 float min_dist = 0.0f;
426 float max_dist = 0.0f;
427 float thre = 0.0f;
428 float grid_rad = static_cast<float>(param_.nr_grids_coarse - 1) / 2;
429 assert(pf_thresholds_ != nullptr);
430 for (r = 0; r < param_.nr_grids_coarse; ++r) {
431 dr = static_cast<float>(r) - grid_rad;
432 dr *= dr;
433 for (c = 0; c < param_.nr_grids_coarse; ++c) {
434 dc = static_cast<float>(c) - grid_rad;
435 dc *= dc;
436 // store to center distance:
437 pf_thresholds_[r][c] = ISqrt(dr + dc);
438 }
439 }
442 &max_dist);
443 if (max_dist - min_dist < Constant<float>::EPSILON()) {
446 2;
447 for (r = 0; r < param_.nr_grids_coarse; ++r) {
448 for (c = 0; c < param_.nr_grids_coarse; ++c) {
449 pf_thresholds_[r][c] = thre;
450 }
451 }
452 } else {
455 k = k / (max_dist - min_dist);
458 b = (b - k * (min_dist + max_dist)) / 2;
459 for (r = 0; r < param_.nr_grids_coarse; ++r) {
460 for (c = 0; c < param_.nr_grids_coarse; ++c) {
461 thre = k * pf_thresholds_[r][c] + b;
462 pf_thresholds_[r][c] = thre;
463 }
464 }
465 }
466}
void IMinMaxElements(const T *a, int n, T *min_val, T *max_val)
Definition i_blas.h:3638

◆ ComputeSignedGroundHeight()

void apollo::perception::algorithm::PlaneFitGroundDetector::ComputeSignedGroundHeight ( const float *  point_cloud,
float *  height_above_ground,
unsigned int  nr_points,
unsigned int  nr_point_elements 
)
protected

在文件 i_ground.cc 第 468 行定义.

470 {
471 unsigned int r = 0;
472 unsigned int nm1 = param_.nr_grids_coarse - 1;
473 for (r = 0; r < nr_points; ++r) {
474 height_above_ground[r] = std::numeric_limits<float>::max();
475 }
477 point_cloud, ground_planes_[0], ground_planes_[0], ground_planes_[1],
478 height_above_ground, 0, nr_points, nr_point_elements);
479 for (r = 1; r < nm1; ++r) {
482 height_above_ground, r, nr_points,
483 nr_point_elements);
484 }
485 ComputeSignedGroundHeightLine(point_cloud, ground_planes_[nm1 - 1],
487 height_above_ground, nm1, nr_points,
488 nr_point_elements);
489}
void ComputeSignedGroundHeightLine(const float *point_cloud, const GroundPlaneLiDAR *up, const GroundPlaneLiDAR *cn, const GroundPlaneLiDAR *dn, float *height_above_ground, unsigned int r, unsigned int nr_points, unsigned int nr_point_elements)
Definition i_ground.cc:491

◆ ComputeSignedGroundHeightLine()

void apollo::perception::algorithm::PlaneFitGroundDetector::ComputeSignedGroundHeightLine ( const float *  point_cloud,
const GroundPlaneLiDAR *  up,
const GroundPlaneLiDAR *  cn,
const GroundPlaneLiDAR *  dn,
float *  height_above_ground,
unsigned int  r,
unsigned int  nr_points,
unsigned int  nr_point_elements 
)
protected

在文件 i_ground.cc 第 491 行定义.

495 {
496 unsigned int i = 0;
497 unsigned int c = 0;
498 unsigned int id = 0;
499 int pos = 0;
500 char label = 0;
501 const float *cptr = nullptr;
502 float dist[] = {0, 0, 0, 0, 0};
503 const float *plane[] = {nullptr, nullptr, nullptr, nullptr, nullptr};
504 float min_abs_dist = 0.0f;
505 unsigned int nm1 = param_.nr_grids_coarse - 1;
506 assert(param_.nr_grids_coarse >= 2);
507 plane[0] = cn[0].IsValid() ? cn[0].params : nullptr;
508 plane[1] = cn[1].IsValid() ? cn[1].params : nullptr;
509 plane[2] = up[0].IsValid() ? up[0].params : nullptr;
510 plane[3] = dn[0].IsValid() ? dn[0].params : nullptr;
511 std::vector<int>::const_iterator iter = (*vg_coarse_)(r, 0).indices_.cbegin();
512 while (iter < (*vg_coarse_)(r, 0).indices_.cend()) {
513 pos = *iter;
514 assert(pos < static_cast<int>(nr_points));
515 label = labels_[pos];
516 cptr = point_cloud + (nr_point_elements * pos);
517 dist[0] = plane[0] != nullptr
519 : std::numeric_limits<float>::max();
520 min_abs_dist = IAbs(dist[0]);
521 id = 0;
522 // for candidates we take min dist:
523 if (label) {
524 dist[1] = plane[1] != nullptr
526 : std::numeric_limits<float>::max();
527 dist[2] = plane[2] != nullptr
529 : std::numeric_limits<float>::max();
530 dist[3] = plane[3] != nullptr
532 : std::numeric_limits<float>::max();
533 for (i = 1; i < 4; ++i) {
534 if (min_abs_dist > IAbs(dist[i])) {
535 min_abs_dist = IAbs(dist[i]);
536 id = i;
537 }
538 }
539 }
540 height_above_ground[pos] = dist[id];
541 ++iter;
542 }
543
544 for (c = 1; c < nm1; ++c) {
545 plane[0] = cn[c].IsValid() ? cn[c].params : nullptr;
546 plane[1] = cn[c - 1].IsValid() ? cn[c - 1].params : nullptr;
547 plane[2] = cn[c + 1].IsValid() ? cn[c + 1].params : nullptr;
548 plane[3] = up[c].IsValid() ? up[c].params : nullptr;
549 plane[4] = dn[c].IsValid() ? dn[c].params : nullptr;
550 iter = (*vg_coarse_)(r, c).indices_.cbegin();
551 while (iter < (*vg_coarse_)(r, c).indices_.cend()) {
552 pos = *iter;
553 assert(pos < static_cast<int>(nr_points));
554 label = labels_[pos];
555 cptr = point_cloud + (nr_point_elements * pos);
556 dist[0] = plane[0] != nullptr
558 : std::numeric_limits<float>::max();
559 min_abs_dist = IAbs(dist[0]);
560 id = 0;
561 if (label) {
562 dist[1] = plane[1] != nullptr
564 : std::numeric_limits<float>::max();
565 dist[2] = plane[2] != nullptr
567 : std::numeric_limits<float>::max();
568 dist[3] = plane[3] != nullptr
570 : std::numeric_limits<float>::max();
571 dist[4] = plane[4] != nullptr
573 : std::numeric_limits<float>::max();
574 for (i = 1; i < 5; ++i) {
575 if (min_abs_dist > IAbs(dist[i])) {
576 min_abs_dist = IAbs(dist[i]);
577 id = i;
578 }
579 }
580 }
581 height_above_ground[pos] = dist[id];
582 ++iter;
583 }
584 }
585 plane[0] = cn[nm1].IsValid() ? cn[nm1].params : nullptr;
586 plane[1] = cn[nm1 - 1].IsValid() ? cn[nm1 - 1].params : nullptr;
587 plane[2] = up[nm1].IsValid() ? up[nm1].params : nullptr;
588 plane[3] = dn[nm1].IsValid() ? dn[nm1].params : nullptr;
589 iter = (*vg_coarse_)(r, nm1).indices_.cbegin();
590 while (iter < (*vg_coarse_)(r, nm1).indices_.cend()) {
591 pos = *iter;
592 assert(pos < static_cast<int>(nr_points));
593 label = labels_[pos];
594 cptr = point_cloud + (nr_point_elements * pos);
595 dist[0] = plane[0] != nullptr
597 : std::numeric_limits<float>::max();
598 min_abs_dist = IAbs(dist[0]);
599 id = 0;
600 // for candidates we take min dist:
601 if (label) {
602 dist[1] = plane[1] != nullptr
604 : std::numeric_limits<float>::max();
605 dist[2] = plane[2] != nullptr
607 : std::numeric_limits<float>::max();
608 dist[3] = plane[3] != nullptr
610 : std::numeric_limits<float>::max();
611 for (i = 1; i < 4; ++i) {
612 if (min_abs_dist > IAbs(dist[i])) {
613 min_abs_dist = IAbs(dist[i]);
614 id = i;
615 }
616 }
617 }
618 height_above_ground[pos] = dist[id];
619 ++iter;
620 }
621}
T IPlaneToPointSignedDistanceWUnitNorm(const T *pi, const T *p)
Definition i_plane.h:102
Definition future.h:29

◆ Detect()

bool apollo::perception::algorithm::PlaneFitGroundDetector::Detect ( const float *  point_cloud,
const int *  semantic_value,
float *  height_above_ground,
unsigned int  nr_points,
unsigned int  nr_point_elements 
)
virtual

实现了 apollo::perception::algorithm::BaseGroundDetector.

在文件 i_ground.cc 第 1899 行定义.

1901 {
1902 assert(point_cloud != nullptr);
1903 assert(semantic_value != nullptr);
1904 assert(height_above_ground != nullptr);
1905 assert(nr_points <= param_.nr_points_max);
1906 assert(nr_point_elements >= 3);
1907 // setup the fine voxel grid
1908 if (!vg_fine_->SetS(point_cloud, semantic_value,
1909 nr_points, nr_point_elements)) {
1910 return false;
1911 }
1912 // setup the coarse voxel grid
1913 if (!vg_coarse_->SetS(point_cloud, semantic_value,
1914 nr_points, nr_point_elements)) {
1915 return false;
1916 }
1917
1918 // when single-frame-detect, should empty ground_planes_
1920 for (size_t row = 0; row < param_.nr_grids_coarse; ++row) {
1921 for (size_t col = 0; col < param_.nr_grids_coarse; ++col) {
1922 ground_planes_[row][col].ForceInvalid();
1924 }
1925 }
1926 }
1927 // int nr_candis = 0;
1928 // int nr_valid_grid = 0;
1929 unsigned int r = 0;
1930 unsigned int c = 0;
1931 // Filter to generate plane fitting candidates
1932 // int nr_candis =
1935 } else {
1936 Filter();
1937 }
1938 // std::cout << "# of plane candidates: " << nr_candis << std::endl;
1939 // Fit local plane using ransac
1940 // nr_valid_grid = Fit();
1941 // int nr_valid_grid =
1942 FitInOrder();
1943 // std::cout << "# of valid plane geometry (fitting): " << nr_valid_grid <<
1944 // std::endl;
1945 // Smooth plane using neighborhood information:
1947 SmoothInMath();
1948 } else {
1949 for (int iter = 0; iter < param_.nr_smooth_iter; ++iter) {
1950 // Smooth();
1951 SmoothInOrder();
1952 }
1953 }
1954
1955 for (r = 0; r < param_.nr_grids_coarse; ++r) {
1956 for (c = 0; c < param_.nr_grids_coarse; ++c) {
1957 if ((*vg_coarse_)(r, c).Empty()) {
1959 }
1960 }
1961 }
1962
1963 // std::cout << "# of valid plane geometry (Smooth): " << nr_valid_grid <<
1964 // std::endl;
1965 // compute point to ground distance
1966 ComputeSignedGroundHeight(point_cloud, height_above_ground, nr_points,
1967 nr_point_elements);
1968 return true;
1969}
void ComputeSignedGroundHeight(const float *point_cloud, float *height_above_ground, unsigned int nr_points, unsigned int nr_point_elements)
Definition i_ground.cc:468
bool SetS(const float *data, const int *semantic_data, unsigned int nr_points, unsigned int nr_point_element)
Definition i_struct_s.h:759

◆ Filter()

int apollo::perception::algorithm::PlaneFitGroundDetector::Filter ( )
protected

在文件 i_ground.cc 第 678 行定义.

678 {
679 int nr_candis = 0;
680 unsigned int i = 0;
681 unsigned int r = 0;
682 memset(reinterpret_cast<void *>(labels_), 0,
683 vg_fine_->NrPoints() * sizeof(char));
684 // Clear candidate list
685 for (i = 0; i < vg_coarse_->NrVoxel(); ++i) {
686 local_candis_[0][i].Clear();
687 }
688 // Filter plane fitting candidates
689 for (r = 0; r < param_.nr_grids_fine; ++r) {
690 nr_candis += FilterLine(r);
691 }
692 return nr_candis;
693}

◆ FilterCandidates()

int apollo::perception::algorithm::PlaneFitGroundDetector::FilterCandidates ( int  r,
int  c,
const float *  point_cloud,
PlaneFitPointCandIndices *  candi,
std::vector< std::pair< int, int > > *  neighbors,
unsigned int  nr_point_element 
)
protected

在文件 i_ground.cc 第 1136 行定义.

1139 {
1140 float avg_z = 0.f;
1141 int count = 0;
1142 unsigned int i = 0;
1143 int r_n = 0;
1144 int c_n = 0;
1145 float z = 0.f;
1146 std::vector<int> filtered_indices;
1147 filtered_indices.reserve(candi->Size());
1148 for (i = 0; i < neighbors->size(); ++i) {
1149 r_n = (*neighbors)[i].first;
1150 c_n = (*neighbors)[i].second;
1151 if (ground_z_[r_n][c_n].second) {
1152 avg_z += ground_z_[r_n][c_n].first;
1153 count++;
1154 }
1155 }
1156 if (count > 0) {
1157 avg_z /= static_cast<float>(count);
1158 ground_z_[r][c].first = avg_z;
1159 ground_z_[r][c].second = true;
1160 for (i = 0; i < candi->Size(); ++i) {
1161 z = (point_cloud + (nr_point_element * (*candi)[i]))[2];
1162 if (z > avg_z - param_.candidate_filter_threshold &&
1163 z < avg_z + param_.candidate_filter_threshold) {
1164 filtered_indices.push_back((*candi)[i]);
1165 } else {
1166 labels_[(*candi)[i]] = 0;
1167 }
1168 }
1169 if (filtered_indices.size() != candi->Size()) {
1170 candi->indices.assign(filtered_indices.begin(), filtered_indices.end());
1171 }
1172 }
1173 return count;
1174}

◆ FilterGrid()

int apollo::perception::algorithm::PlaneFitGroundDetector::FilterGrid ( const Voxel< float > &  vg,
const float *  point_cloud,
PlaneFitPointCandIndices *  candi,
unsigned int  nr_points,
unsigned int  nr_point_element 
)
protected

在文件 i_ground.cc 第 623 行定义.

627 {
628 int pos = 0;
629 int rseed = I_DEFAULT_SEED;
630 int nr_candis = 0;
631 unsigned int i = 0;
632 unsigned int nr_samples = IMin(param_.nr_z_comp_candis, vx.NrPoints());
633 if (vx.Empty()) {
634 return 0;
635 }
636 // generate sampled indices
637 if (vx.NrPoints() <= param_.nr_z_comp_candis) {
638 // IRamp(sampled_indices_, vx.NrPoints());
639 // sampled z values
640 for (i = 0; i < vx.NrPoints(); ++i) {
641 pos = vx.indices_[i] * nr_point_element;
642 // requires the Z element to be in the third position, i.e., after X, Y
643 sampled_z_values_[i] = (point_cloud + pos)[2];
644 }
645 } else {
647 static_cast<int>(vx.NrPoints()), &rseed);
648 // sampled z values
649 for (i = 0; i < nr_samples; ++i) {
650 pos = vx.indices_[sampled_indices_[i]] * nr_point_element;
651 // requires the Z element to be in the third position, i.e., after X, Y
652 sampled_z_values_[i] = (point_cloud + pos)[2];
653 }
654 }
655 // Filter points and get plane fitting candidates
656 nr_candis = CompareZ(point_cloud, vx.indices_, sampled_z_values_, candi,
657 nr_points, nr_point_element, nr_samples);
658 return nr_candis;
659}
int CompareZ(const float *point_cloud, const std::vector< int > &point_indices, const float *z_values, PlaneFitPointCandIndices *candi, unsigned int nr_points, unsigned int nr_point_element, unsigned int nr_compares)
Definition i_ground.cc:365
void IRandomSample(int *sample, int n, int pool_size, int *s)
Definition i_rand.h:47

◆ FilterLine()

int apollo::perception::algorithm::PlaneFitGroundDetector::FilterLine ( unsigned int  r)
protected

在文件 i_ground.cc 第 661 行定义.

661 {
662 int nr_candis = 0;
663 unsigned int c = 0;
664 const float *point_cloud = vg_fine_->const_data();
665 unsigned int nr_points = vg_fine_->NrPoints();
666 unsigned int nr_point_element = vg_fine_->NrPointElement();
667 unsigned int begin = (r * param_.nr_grids_fine);
668 int parent = 0;
669 for (c = 0; c < param_.nr_grids_fine; c++) {
670 parent = map_fine_to_coarse_[begin + c];
671 nr_candis +=
672 FilterGrid((*vg_fine_)(r, c), point_cloud, &local_candis_[0][parent],
673 nr_points, nr_point_element);
674 }
675 return nr_candis;
676}
int FilterGrid(const Voxel< float > &vg, const float *point_cloud, PlaneFitPointCandIndices *candi, unsigned int nr_points, unsigned int nr_point_element)
Definition i_ground.cc:623

◆ Fit()

int apollo::perception::algorithm::PlaneFitGroundDetector::Fit ( )
protected

在文件 i_ground.cc 第 1127 行定义.

1127 {
1128 int nr_grids = 0;
1129 for (unsigned int r = 0; r < param_.nr_grids_coarse; ++r) {
1130 nr_grids += FitLine(r);
1131 }
1132 return nr_grids;
1133}

◆ FitGrid()

int apollo::perception::algorithm::PlaneFitGroundDetector::FitGrid ( const float *  point_cloud,
PlaneFitPointCandIndices *  candi,
GroundPlaneLiDAR *  groundplane,
unsigned int  nr_points,
unsigned int  nr_point_element,
float  dist_thre 
)
protected

在文件 i_ground.cc 第 986 行定义.

991 {
992 // initialize the best plane
993 groundplane->ForceInvalid();
994 // not enough samples, failed and return
995 if (candi->Size() < param_.nr_inliers_min_threshold) {
996 return 0;
997 }
998 GroundPlaneLiDAR plane;
999 float ptp_dist = 0.0f;
1000 float fit_cost = 0.0f;
1001 float fit_cost_best = dist_thre;
1002 int nr_inliers = 0;
1003 int nr_inliers_best = -1;
1004 int i = 0;
1005 int j = 0;
1006 int rseed = I_DEFAULT_SEED;
1007 int indices_trial[] = {0, 0, 0};
1008 int nr_samples = candi->Prune(param_.nr_samples_min_threshold,
1010 int nr_inliers_termi = IRound(static_cast<float>(nr_samples) *
1012 // 3x3 matrix stores: x, y, z; x, y, z; x, y, z;
1013 float samples[9];
1014 // copy 3D points
1015 float *psrc = nullptr;
1016 float *pdst = pf_threeds_;
1017 for (i = 0; i < nr_samples; ++i) {
1018 assert((*candi)[i] < static_cast<int>(nr_points));
1019 ICopy3(point_cloud + (nr_point_element * (*candi)[i]), pdst);
1020 pdst += dim_point_;
1021 }
1022 // generate plane hypothesis and vote
1023 for (i = 0; i < param_.nr_ransac_iter_threshold; ++i) {
1024 IRandomSample(indices_trial, 3, nr_samples, &rseed);
1025 IScale3(indices_trial, dim_point_);
1026 ICopy3(pf_threeds_ + indices_trial[0], samples);
1027 ICopy3(pf_threeds_ + indices_trial[1], samples + 3);
1028 ICopy3(pf_threeds_ + indices_trial[2], samples + 6);
1029 IPlaneFitDestroyed(samples, plane.params);
1030 // check if the plane hypothesis has valid geometry
1031 if (plane.GetDegreeNormalToZ() > param_.planefit_orien_threshold) {
1032 continue;
1033 }
1034 // iterate samples and check if the point to plane distance is below
1035 // threshold
1036 psrc = pf_threeds_;
1037 nr_inliers = 0;
1038 fit_cost = 0;
1039 for (j = 0; j < nr_samples; ++j) {
1040 ptp_dist = IPlaneToPointDistanceWUnitNorm(plane.params, psrc);
1041 if (ptp_dist < dist_thre) {
1042 nr_inliers++;
1043 fit_cost += ptp_dist;
1044 }
1045 psrc += dim_point_;
1046 }
1047 // Assign number of supports
1048 plane.SetNrSupport(nr_inliers);
1049
1050 fit_cost = nr_inliers > 0 ? (fit_cost / static_cast<float>(nr_inliers))
1051 : dist_thre;
1052 // record the best plane
1053 if (nr_inliers >= nr_inliers_best) {
1054 if (nr_inliers == nr_inliers_best) {
1055 if (fit_cost < fit_cost_best) {
1056 nr_inliers_best = nr_inliers;
1057 fit_cost_best = fit_cost;
1058 *groundplane = plane;
1059 }
1060 } else {
1061 nr_inliers_best = nr_inliers;
1062 fit_cost_best = fit_cost;
1063 *groundplane = plane;
1064 }
1065 // found enough inliers - terminate the ransac
1066 if (nr_inliers_best > nr_inliers_termi) {
1067 break;
1068 }
1069 }
1070 }
1071 // check if meet the inlier number requirement
1072 if (!groundplane->IsValid()) {
1073 return 0;
1074 }
1075 if (groundplane->GetNrSupport() <
1076 static_cast<int>(param_.nr_inliers_min_threshold)) {
1077 groundplane->ForceInvalid();
1078 return 0;
1079 }
1080 // iterate samples and check if the point to plane distance is within
1081 // threshold
1082 nr_inliers = 0;
1083 psrc = pf_threeds_;
1084 pdst = pf_threeds_;
1085 for (i = 0; i < nr_samples; ++i) {
1086 ptp_dist = IPlaneToPointDistanceWUnitNorm(groundplane->params, psrc);
1087 if (ptp_dist < dist_thre) {
1088 ICopy3(psrc, pdst);
1089 pdst += 3;
1090 nr_inliers++;
1091 }
1092 psrc += dim_point_;
1093 }
1094 groundplane->SetNrSupport(nr_inliers);
1095 // note that pf_threeds_ will be destroyed after calling this routine
1096 IPlaneFitTotalLeastSquare(pf_threeds_, groundplane->params, nr_inliers);
1097 // filtering: the best plane orientation is not valid*/
1098 // std::cout << groundplane->GetDegreeNormalToZ() << std::endl;
1099 if (groundplane->GetDegreeNormalToZ() > param_.planefit_orien_threshold) {
1100 groundplane->ForceInvalid();
1101 return 0;
1102 }
1103 return nr_inliers;
1104}
void IPlaneFitDestroyed(T *Xs, T *pi)
Definition i_plane.h:447
void ICopy3(const T src[3], T dst[3])
Definition i_blas.h:40
T IPlaneToPointDistanceWUnitNorm(const T *pi, const T *p)
Definition i_plane.h:93
void IPlaneFitTotalLeastSquare(T *X, T *pi, int n)
Definition i_plane.h:140
void IScale3(T x[3], T sf)
Definition i_blas.h:1868

◆ FitGridWithNeighbors()

int apollo::perception::algorithm::PlaneFitGroundDetector::FitGridWithNeighbors ( int  r,
int  c,
const float *  point_cloud,
GroundPlaneLiDAR *  groundplane,
unsigned int  nr_points,
unsigned int  nr_point_element,
float  dist_thre 
)
protected

在文件 i_ground.cc 第 1183 行定义.

1185 {
1186 // initialize the best plane
1187 groundplane->ForceInvalid();
1188 // not enough samples, failed and return
1189
1190 PlaneFitPointCandIndices &candi = local_candis_[r][c];
1191 std::vector<std::pair<int, int>> neighbors;
1193 &neighbors);
1194 FilterCandidates(r, c, point_cloud, &candi, &neighbors, nr_point_element);
1195
1196 if (candi.Size() < param_.nr_inliers_min_threshold) {
1197 return 0;
1198 }
1199
1200 GroundPlaneLiDAR plane;
1201 int kNr_iter =
1202 param_.nr_ransac_iter_threshold + static_cast<int>(neighbors.size());
1203 // check hypothesis initialized correct or not
1204 if (kNr_iter < 1) {
1205 return 0;
1206 }
1207 GroundPlaneLiDAR hypothesis[kNr_iter];
1208
1209 float ptp_dist = 0.0f;
1210 int best = 0;
1211 int nr_inliers = 0;
1212 int nr_inliers_best = -1;
1213 float angle_best = std::numeric_limits<float>::max();
1214
1215 int rseed = I_DEFAULT_SEED;
1216 int indices_trial[] = {0, 0, 0};
1217 int nr_samples = candi.Prune(param_.nr_samples_min_threshold,
1219 int nr_inliers_termi = IRound(static_cast<float>(nr_samples) *
1221 // 3x3 matrix stores: x, y, z; x, y, z; x, y, z;
1222 float samples[9];
1223 // copy 3D points
1224 float *psrc = nullptr;
1225 float *pdst = pf_threeds_;
1226 int r_n = 0;
1227 int c_n = 0;
1228 float angle = -1.f;
1229 for (int i = 0; i < nr_samples; ++i) {
1230 assert(candi[i] < static_cast<int>(nr_points));
1231 ICopy3(point_cloud + (nr_point_element * candi[i]), pdst);
1232 pdst += dim_point_;
1233 }
1234 // generate plane hypothesis and vote
1235 for (int i = 0; i < param_.nr_ransac_iter_threshold; ++i) {
1236 IRandomSample(indices_trial, 3, nr_samples, &rseed);
1237 IScale3(indices_trial, dim_point_);
1238 ICopy3(pf_threeds_ + indices_trial[0], samples);
1239 ICopy3(pf_threeds_ + indices_trial[1], samples + 3);
1240 ICopy3(pf_threeds_ + indices_trial[2], samples + 6);
1241 IPlaneFitDestroyed(samples, hypothesis[i].params);
1242 // check if the plane hypothesis has valid geometry
1243 if (hypothesis[i].GetDegreeNormalToZ() > param_.planefit_orien_threshold) {
1244 continue;
1245 }
1246 // iterate samples and check if the point to plane distance is below
1247 // threshold
1248 psrc = pf_threeds_;
1249 nr_inliers = 0;
1250 for (int j = 0; j < nr_samples; ++j) {
1251 ptp_dist = IPlaneToPointDistanceWUnitNorm(hypothesis[i].params, psrc);
1252 if (ptp_dist < dist_thre) {
1253 nr_inliers++;
1254 }
1255 psrc += dim_point_;
1256 }
1257 // Assign number of supports
1258 hypothesis[i].SetNrSupport(nr_inliers);
1259 hypothesis[i].SetOrigin("self");
1260
1261 if (nr_inliers > nr_inliers_termi) {
1262 break;
1263 }
1264 }
1265
1266 for (size_t i = 0; i < neighbors.size(); ++i) {
1267 r_n = neighbors[i].first;
1268 c_n = neighbors[i].second;
1269 if (ground_planes_[r_n][c_n].IsValid()) {
1270 hypothesis[i + param_.nr_ransac_iter_threshold] =
1271 ground_planes_[r_n][c_n];
1272 psrc = pf_threeds_;
1273 nr_inliers = 0;
1274 for (int j = 0; j < nr_samples; ++j) {
1276 hypothesis[i + param_.nr_ransac_iter_threshold].params, psrc);
1277 if (ptp_dist < dist_thre) {
1278 nr_inliers++;
1279 }
1280 psrc += dim_point_;
1281 }
1282 if (nr_inliers < static_cast<int>(param_.nr_inliers_min_threshold)) {
1283 hypothesis[i + param_.nr_ransac_iter_threshold].ForceInvalid();
1284 continue;
1285 }
1286 hypothesis[i + param_.nr_ransac_iter_threshold].SetNrSupport(nr_inliers);
1287 hypothesis[i + param_.nr_ransac_iter_threshold].SetOrigin("neighbor");
1288 }
1289 }
1290
1291 nr_inliers_best = -1;
1292 for (int i = 0; i < kNr_iter; ++i) {
1293 if (!(hypothesis[i].IsValid())) {
1294 continue;
1295 }
1296 nr_inliers = hypothesis[i].GetNrSupport();
1297 if (nr_inliers >= nr_inliers_best) {
1298 if (nr_inliers == nr_inliers_best) {
1299 angle = CalculateAngleDist(hypothesis[i], neighbors);
1300 if (angle < angle_best && angle > 0) {
1301 angle_best = angle;
1302 best = i;
1303 }
1304 } else {
1305 nr_inliers_best = nr_inliers;
1306 angle_best = CalculateAngleDist(hypothesis[i], neighbors);
1307 best = i;
1308 }
1309 }
1310 }
1311
1312 *groundplane = hypothesis[best];
1313
1314 // check if meet the inlier number requirement
1315 if (!groundplane->IsValid()) {
1316 groundplane->SetInvalidStatus("groundplane Invalid");
1317 return 0;
1318 }
1319 if (groundplane->GetNrSupport() <
1320 static_cast<int>(param_.nr_inliers_min_threshold)) {
1321 groundplane->ForceInvalid();
1322 groundplane->SetInvalidStatus("inliers Small");
1323 return 0;
1324 }
1325 // iterate samples and check if the point to plane distance is within
1326 // threshold
1327 nr_inliers = 0;
1328 psrc = pf_threeds_;
1329 pdst = pf_threeds_;
1330 for (int i = 0; i < nr_samples; ++i) {
1331 ptp_dist = IPlaneToPointDistanceWUnitNorm(groundplane->params, psrc);
1332 if (ptp_dist < dist_thre) {
1333 ICopy3(psrc, pdst);
1334 pdst += 3;
1335 nr_inliers++;
1336 }
1337 psrc += dim_point_;
1338 }
1339 groundplane->SetNrSupport(nr_inliers);
1340
1341 // note that pf_threeds_ will be destroyed after calling this routine
1342 IPlaneFitTotalLeastSquare(pf_threeds_, groundplane->params, nr_inliers);
1343 if (angle_best <= CalculateAngleDist(*groundplane, neighbors)) {
1344 *groundplane = hypothesis[best];
1345 groundplane->SetStatus(true);
1346 }
1347
1348 if (groundplane->GetDegreeNormalToZ() > param_.planefit_orien_threshold) {
1349 groundplane->ForceInvalid();
1350 groundplane->SetInvalidStatus("Z Bigger");
1351 return 0;
1352 }
1353
1354 const auto &voxel_cur = (*vg_coarse_)(r, c);
1355 float radius = voxel_cur.dim_x_ * 0.5f;
1356 float cx = voxel_cur.v_[0] + radius;
1357 float cy = voxel_cur.v_[1] + radius;
1358 float cz = -(groundplane->params[0] * cx + groundplane->params[1] * cy +
1359 groundplane->params[3]) /
1360 groundplane->params[2];
1361 ground_z_[r][c].first = cz;
1362 ground_z_[r][c].second = true;
1363
1364 return nr_inliers;
1365}
float CalculateAngleDist(const GroundPlaneLiDAR &plane, const std::vector< std::pair< int, int > > &neighbors)
Definition i_ground.cc:1367
void GetNeighbors(int r, int c, int rows, int cols, std::vector< std::pair< int, int > > *neighbors)
Definition i_ground.cc:1476
int FilterCandidates(int r, int c, const float *point_cloud, PlaneFitPointCandIndices *candi, std::vector< std::pair< int, int > > *neighbors, unsigned int nr_point_element)
Definition i_ground.cc:1136

◆ FitInOrder()

int apollo::perception::algorithm::PlaneFitGroundDetector::FitInOrder ( )
protected

在文件 i_ground.cc 第 1389 行定义.

1389 {
1390 int nr_grids = 0;
1391 unsigned int i = 0;
1392 unsigned int j = 0;
1393 int r = 0;
1394 int c = 0;
1395 GroundPlaneLiDAR gp;
1396 for (i = 0; i < param_.nr_grids_coarse; ++i) {
1397 for (j = 0; j < param_.nr_grids_coarse; ++j) {
1398 ground_z_[i][j].first = 0.f;
1399 ground_z_[i][j].second = false;
1400 }
1401 }
1402 std::stringstream sstr;
1403 sstr << "[GroundFitInfo] " << std::to_string(frame_timestamp_) << std::endl;
1404 size_t count = 0;
1405 for (i = 0; i < vg_coarse_->NrVoxel(); ++i) {
1406 r = order_table_[i].first;
1407 c = order_table_[i].second;
1408
1409 if (param_.debug_output) {
1410 sstr << "[FitInOrder] row = " << r << " col = " << c
1411 << " center_x = "
1412 << (*vg_coarse_)(r, c).v_[0] + (*vg_coarse_)(r, c).dim_x_ * 0.5f
1413 << " center_y = "
1414 << (*vg_coarse_)(r, c).v_[1] + (*vg_coarse_)(r, c).dim_y_ * 0.5f
1415 << " inliers_thres = " << pf_thresholds_[r][c]
1416 << " [AfterFilterCandidates] count = " << local_candis_[r][c].Size();
1417
1418 float max_z = -5.0, min_z = 5.0;
1419 for (unsigned int p = 0; p < local_candis_[r][c].Size(); ++p) {
1420 float x = (vg_coarse_->const_data() +
1421 (vg_coarse_->NrPointElement() * (local_candis_[r][c])[p]))[0];
1422 float y = (vg_coarse_->const_data() +
1423 (vg_coarse_->NrPointElement() * (local_candis_[r][c])[p]))[1];
1424 float z = (vg_coarse_->const_data() +
1425 (vg_coarse_->NrPointElement() * (local_candis_[r][c])[p]))[2];
1426 if (z > max_z) {
1427 max_z = z;
1428 }
1429 if (z < min_z) {
1430 min_z = z;
1431 }
1432 if (p == 0) {
1433 sstr << " sample_point_cooridinate = (" << x << ", " << y
1434 << ", " << z << ")";
1435 }
1436 }
1437 sstr << " min_z = " << min_z << " max_z= " << max_z;
1438 }
1439 count += local_candis_[r][c].Size();
1441 r, c, vg_coarse_->const_data(), &gp, vg_coarse_->NrPoints(),
1443 static_cast<int>(param_.nr_inliers_min_threshold)) {
1445 ground_planes_[r][c] = gp;
1446 nr_grids++;
1447 } else {
1450 }
1451
1452 if (param_.debug_output) {
1453 sstr << " [AfterNeighborFilter] count = " << local_candis_[r][c].Size()
1454 << " [AfterGridPlaneFit] ground_z_valid = " << ground_z_[r][c].second
1455 << " ground_z_value = " << ground_z_[r][c].first
1456 << " plane_valid = " << ground_planes_[r][c].IsValid()
1457 << " plane_invalid_status = "
1459 << " plane_origin = " << ground_planes_[r][c].GetOrigin()
1460 << " support_number = " << ground_planes_[r][c].GetNrSupport()
1461 << " plane_params = " << ground_planes_[r][c].params[0] << ", "
1462 << ground_planes_[r][c].params[1] << ", "
1463 << ground_planes_[r][c].params[2]
1464 << ", " << ground_planes_[r][c].params[3] << std::endl;
1465 }
1466 }
1467 if (param_.debug_output) {
1468 AINFO << sstr.str();
1469 AINFO << "This Frame " << std::to_string(frame_timestamp_)
1470 << " ground_count is " << count;
1471 }
1472 sstr.clear();
1473 return nr_grids;
1474}
int FitGridWithNeighbors(int r, int c, const float *point_cloud, GroundPlaneLiDAR *groundplane, unsigned int nr_points, unsigned int nr_point_element, float dist_thre)
Definition i_ground.cc:1183
#define AINFO
Definition log.h:42
void IPlaneEucliToSpher(const GroundPlaneLiDAR &src, GroundPlaneSpherical *dst)
Definition i_ground.cc:2023

◆ FitLine()

int apollo::perception::algorithm::PlaneFitGroundDetector::FitLine ( unsigned int  r)
protected

在文件 i_ground.cc 第 1106 行定义.

1106 {
1107 int nr_grids = 0;
1108 unsigned int c = 0;
1109 GroundPlaneLiDAR gp;
1110 for (c = 0; c < param_.nr_grids_coarse; c++) {
1111 if (FitGrid(vg_coarse_->const_data(), &local_candis_[r][c], &gp,
1113 pf_thresholds_[r][c]) >=
1114 static_cast<int>(param_.nr_inliers_min_threshold)) {
1115 // transform to polar coordinates and store:
1117 ground_planes_[r][c] = gp;
1118 nr_grids++;
1119 } else {
1122 }
1123 }
1124 return nr_grids;
1125}
int FitGrid(const float *point_cloud, PlaneFitPointCandIndices *candi, GroundPlaneLiDAR *groundplane, unsigned int nr_points, unsigned int nr_point_element, float dist_thre)
Definition i_ground.cc:986

◆ GetCandis()

PlaneFitPointCandIndices ** apollo::perception::algorithm::PlaneFitGroundDetector::GetCandis ( ) const

在文件 i_ground.cc 第 2019 行定义.

2019 {
2020 return local_candis_;
2021}

◆ GetGrid()

const VoxelGridXY< float > * apollo::perception::algorithm::PlaneFitGroundDetector::GetGrid ( ) const

在文件 i_ground.cc 第 1996 行定义.

1996 {
1997 return vg_coarse_;
1998}

◆ GetGridDimX()

unsigned int apollo::perception::algorithm::PlaneFitGroundDetector::GetGridDimX ( ) const

在文件 i_ground.cc 第 2007 行定义.

2007 {
2008 return vg_coarse_->NrVoxelX();
2009}

◆ GetGridDimY()

unsigned int apollo::perception::algorithm::PlaneFitGroundDetector::GetGridDimY ( ) const

在文件 i_ground.cc 第 2011 行定义.

2011 {
2012 return vg_coarse_->NrVoxelY();
2013}

◆ GetGroundPlane()

const GroundPlaneLiDAR * apollo::perception::algorithm::PlaneFitGroundDetector::GetGroundPlane ( int  r,
int  c 
) const

在文件 i_ground.cc 第 2000 行定义.

2001 {
2002 assert(r >= 0 && r < static_cast<int>(param_.nr_grids_coarse));
2003 assert(c >= 0 && c < static_cast<int>(param_.nr_grids_coarse));
2004 return ground_planes_ != nullptr ? ground_planes_[r] + c : nullptr;
2005}

◆ GetGroundPlaneSpherParams()

void apollo::perception::algorithm::PlaneFitGroundDetector::GetGroundPlaneSpherParams ( float *  params)
protected

在文件 i_ground.cc 第 1812 行定义.

1812 {
1813 unsigned int lap_size = param_.nr_grids_coarse * param_.nr_grids_coarse;
1814 unsigned int offset = 0;
1815 // for (unsigned int r = 0; r < param_.nr_grids_coarse; ++r) {
1816 // for (unsigned int c = 0; c < param_.nr_grids_coarse; ++c) {
1817 // if ((*vg_coarse_)(r, c).Empty()) {
1818 // ground_planes_sphe_[r][c].ForceInvalid();
1819 // } else {
1820 // IPlaneEucliToSpher(ground_planes_[r][c],
1821 // &ground_planes_sphe_[r][c]);
1822 // }
1823 // }
1824 // }
1825 for (unsigned int i = 0; i < lap_size; ++i) {
1826 params[i + offset] = ground_planes_sphe_[0][i].theta;
1827 }
1828 offset += lap_size;
1829 for (unsigned int i = 0; i < lap_size; ++i) {
1830 params[i + offset] = ground_planes_sphe_[0][i].phi;
1831 }
1832 offset += lap_size;
1833 for (unsigned int i = 0; i < lap_size; ++i) {
1834 params[i + offset] = ground_planes_sphe_[0][i].d;
1835 }
1836}

◆ GetInliers()

void apollo::perception::algorithm::PlaneFitGroundDetector::GetInliers ( int *  inliers)
protected

在文件 i_ground.cc 第 1696 行定义.

1696 {
1697 unsigned int lap_size = param_.nr_grids_coarse * param_.nr_grids_coarse;
1698 for (unsigned int i = 0; i < lap_size; ++i) {
1699 inliers[i] = ground_planes_sphe_[0][i].GetNrSupport();
1700 }
1701}

◆ GetLabel()

const char * apollo::perception::algorithm::PlaneFitGroundDetector::GetLabel ( ) const

在文件 i_ground.cc 第 1971 行定义.

1971{ return labels_; }

◆ GetNeighbors()

void apollo::perception::algorithm::PlaneFitGroundDetector::GetNeighbors ( int  r,
int  c,
int  rows,
int  cols,
std::vector< std::pair< int, int > > *  neighbors 
)
protected

在文件 i_ground.cc 第 1476 行定义.

1478 {
1479 int left = IMax(0, c - 1);
1480 int right = IMin(cols - 1, c + 1);
1481 int up = IMax(0, r - 1);
1482 int down = IMin(rows - 1, r + 1);
1483 int x = 0;
1484 int y = 0;
1485 neighbors->reserve(8);
1486 for (x = left; x <= right; ++x) {
1487 for (y = up; y <= down; ++y) {
1488 if (x == c && y == r) {
1489 continue;
1490 }
1491 neighbors->push_back(std::pair<int, int>(y, x));
1492 }
1493 }
1494}

◆ GetUnknownHeight()

float apollo::perception::algorithm::PlaneFitGroundDetector::GetUnknownHeight ( )

在文件 i_ground.cc 第 2015 行定义.

2015 {
2016 return std::numeric_limits<float>::max();
2017}

◆ Init()

bool apollo::perception::algorithm::PlaneFitGroundDetector::Init ( )

在文件 i_ground.cc 第 154 行定义.

154 {
155 unsigned int r = 0;
156 unsigned int c = 0;
157 unsigned int pr = 0;
158 unsigned int pc = 0;
159 unsigned int index = 0;
160 unsigned int capacity = 0;
161 unsigned int sf = param_.nr_grids_fine / param_.nr_grids_coarse;
162 if (!param_.Validate()) {
163 return false;
164 }
165 // fine grid:
166 vg_fine_ = new VoxelGridXY<float>();
167 if (vg_fine_ == nullptr) {
168 return false;
169 }
174 return false;
175 }
176 // coarse grid:
177 vg_coarse_ = new VoxelGridXY<float>();
178 if (vg_coarse_ == nullptr) {
179 return false;
180 }
185 return false;
186 }
187
188 // Init order lookup table
189 order_table_ = IAlloc<std::pair<int, int>>(vg_fine_->NrVoxel());
191
192 // ground plane:
194 IAlloc2<GroundPlaneLiDAR>(param_.nr_grids_coarse, param_.nr_grids_coarse);
195 if (!ground_planes_) {
196 return false;
197 }
198 ground_planes_sphe_ = IAlloc2<GroundPlaneSpherical>(param_.nr_grids_coarse,
200 if (!ground_planes_sphe_) {
201 return false;
202 }
203 ground_z_ = IAlloc2<std::pair<float, bool>>(param_.nr_grids_coarse,
205 if (!ground_z_) {
206 return false;
207 }
208 // sample candis:
209 local_candis_ = IAlloc2<PlaneFitPointCandIndices>(param_.nr_grids_coarse,
211 if (!local_candis_) {
212 return false;
213 }
214 // Reserve space to avoid runtime memory re-allocation
215 for (r = 0; r < param_.nr_grids_coarse; ++r) {
216 for (c = 0; c < param_.nr_grids_coarse; ++c) {
217 if (r < (param_.nr_grids_coarse << 3) &&
218 c < (param_.nr_grids_coarse << 3)) {
219 capacity = 16384;
220 } else if (r < (param_.nr_grids_coarse << 2) &&
221 c < (param_.nr_grids_coarse << 2)) {
222 capacity = 8192;
223 } else if (r < (param_.nr_grids_coarse << 1) &&
224 c < (param_.nr_grids_coarse << 1)) {
225 capacity = 4096;
226 } else {
227 capacity = 512;
228 }
229 local_candis_[r][c].Reserve(capacity);
230 }
231 }
232 // ground candidate
233 ground_candidates_ = IAlloc2<GroundCandidateIndices>(param_.nr_grids_fine,
235 if (!ground_candidates_) {
236 return false;
237 }
238 // threeds in ransac, in inhomogeneous coordinates:
240 IAllocAligned<float>(param_.nr_samples_max_threshold * dim_point_, 4);
241 if (!pf_threeds_) {
242 return false;
243 }
244 memset(reinterpret_cast<void *>(pf_threeds_), 0,
245 param_.nr_samples_max_threshold * dim_point_ * sizeof(float));
246 // labels:
247 labels_ = IAllocAligned<char>(param_.nr_points_max, 4);
248 if (!labels_) {
249 return false;
250 }
251 memset(reinterpret_cast<void *>(labels_), 0,
252 param_.nr_points_max * sizeof(char));
253 // map of fine grid id to coarse id:
254 map_fine_to_coarse_ = IAllocAligned<unsigned int>(
256 if (!map_fine_to_coarse_) {
257 return false;
258 }
259 for (r = 0; r < param_.nr_grids_fine; ++r) {
260 pr = r / sf;
261 index = r * param_.nr_grids_fine;
262 for (c = 0; c < param_.nr_grids_fine; ++c) {
263 pc = c / sf;
264 map_fine_to_coarse_[index + c] = pr * param_.nr_grids_coarse + pc;
265 }
266 }
267 // ransac memory:
268 sampled_z_values_ = IAllocAligned<float>(param_.nr_z_comp_candis, 4);
269 if (!sampled_z_values_) {
270 return false;
271 }
272 memset(reinterpret_cast<void *>(sampled_z_values_), 0,
273 param_.nr_z_comp_candis * sizeof(float));
274 // ransac memory:
275 sampled_indices_ = IAllocAligned<int>(param_.nr_z_comp_candis, 4);
276 if (!sampled_indices_) {
277 return false;
278 }
279 memset(reinterpret_cast<void *>(sampled_indices_), 0,
280 param_.nr_z_comp_candis * sizeof(int));
281 // ransac thresholds:
284 if (!pf_thresholds_) {
285 return false;
286 }
287 // compute thresholds
289
290 //global optimization
291 unsigned int lap_size = param_.nr_grids_coarse * param_.nr_grids_coarse;
292 neighbors_.resize(lap_size);
293 for (unsigned int r = 0; r < param_.nr_grids_coarse; ++r) {
294 for (unsigned int c = 0; c < param_.nr_grids_coarse; ++c) {
295 unsigned int index_cur = r * param_.nr_grids_coarse + c;
296 neighbors_[index_cur].clear();
297 if (r > 0) {
298 neighbors_[index_cur].push_back((r - 1)* param_.nr_grids_coarse + c);
299 }
300 if (r + 1 < param_.nr_grids_coarse) {
301 neighbors_[index_cur].push_back((r + 1)* param_.nr_grids_coarse + c);
302 }
303 if (c > 0) {
304 neighbors_[index_cur].push_back(r * param_.nr_grids_coarse + c - 1);
305 }
306 if (c + 1 < param_.nr_grids_coarse) {
307 neighbors_[index_cur].push_back(r * param_.nr_grids_coarse + c + 1);
308 }
309 if (c + 1 < param_.nr_grids_coarse && r + 1 < param_.nr_grids_coarse) {
310 neighbors_[index_cur].push_back(
311 (r + 1)* param_.nr_grids_coarse + c + 1);
312 }
313 if (c > 0 && r + 1 < param_.nr_grids_coarse) {
314 neighbors_[index_cur].push_back(
315 (r + 1)* param_.nr_grids_coarse + c - 1);
316 }
317 if (c + 1 < param_.nr_grids_coarse && r > 0) {
318 neighbors_[index_cur].push_back(
319 (r - 1)* param_.nr_grids_coarse + c + 1);
320 }
321 if (c > 0 && r > 0) {
322 neighbors_[index_cur].push_back(
323 (r - 1)* param_.nr_grids_coarse + c - 1);
324 }
325 }
326 }
327 weight_buffer_ = IAlloc2<float>(2, lap_size);
328 inliers_ = IAllocAligned<int>(lap_size, 4);
329 sphe_params_ = IAllocAligned<float>(lap_size * 3, 4);
330 a_array_.resize(lap_size * 2, lap_size);
331 b_array_.resize(lap_size * 2, 3);
332
333 for (unsigned int i = 0; i < lap_size; ++i) {
334 a_array_.coeffRef(i, i) = 1.0;
335 float w = -1.0 / neighbors_[i].size();
336 for (const auto& j : neighbors_[i]) {
337 a_array_.coeffRef(i, j) = w;
338 }
339 }
340
341 return true;
342}
void InitOrderTable(const VoxelGridXY< float > *vg, std::pair< int, int > *order)
Definition i_ground.cc:125
std::vector< std::vector< unsigned int > > neighbors_
Definition i_ground.h:453
bool Alloc(unsigned int nr_voxel_x, unsigned int nr_voxel_y, T spatial_bound_x_min, T spatial_bound_x_max, T spatial_bound_y_min, T spatial_bound_y_max, T spatial_bound_z_min, T spatial_bound_z_max)
Definition i_struct_s.h:645

◆ InitOrderTable()

void apollo::perception::algorithm::PlaneFitGroundDetector::InitOrderTable ( const VoxelGridXY< float > *  vg,
std::pair< int, int > *  order 
)
protected

在文件 i_ground.cc 第 125 行定义.

126 {
127 std::vector<std::pair<float, int>> map_dist;
128 float cx = 0.f;
129 float cy = 0.f;
130 float dist2 = 0.f;
131 float radius = 0.f;
132 unsigned int i = 0;
133 int id = 0;
134 for (i = 0; i < vg->NrVoxel(); ++i) {
135 const auto &voxel = vg->GetConstVoxels()[i];
136 radius = voxel.dim_x_ * 0.5f;
137 cx = voxel.v_[0] + radius;
138 cy = voxel.v_[1] + radius;
139 dist2 = cx * cx + cy * cy;
140 map_dist.push_back(std::pair<float, int>(dist2, i));
141 }
142 sort(map_dist.begin(), map_dist.end(),
143 [](const std::pair<float, int> &a, const std::pair<float, int> &b) {
144 return a.first < b.first;
145 });
146 for (i = 0; i < map_dist.size(); ++i) {
147 id = map_dist[i].second;
148 const auto &voxel = vg->GetConstVoxels()[id];
149 order[i].first = voxel.iy_;
150 order[i].second = voxel.ix_;
151 }
152}
const std::vector< Voxel< T > > & GetConstVoxels() const
Definition i_struct_s.h:372

◆ NeighborGroundCandidate()

int apollo::perception::algorithm::PlaneFitGroundDetector::NeighborGroundCandidate ( int  row,
int  col,
const float *  point_cloud,
const int *  semantic_list,
const std::vector< int > &  indices,
PlaneFitPointCandIndices *  candi,
unsigned int  nr_point_element 
)
protected

在文件 i_ground.cc 第 764 行定义.

767 {
768 const float pi = 3.1415926535898;
769 unsigned int nr_contradi = 0;
770 const float *pt_ptr = nullptr;
771 const int *semantic_value = nullptr;
772 auto voxel = (*vg_fine_)(row, col);
773 // default delta = 0.022
774 float res = param_.roi_region_rad_x * 2 * 1.0f / param_.nr_grids_fine;
775 float delta = tan(param_.planefit_orien_threshold * pi / 180.0) * res;
776 delta /= 2.0;
777
778 // get neighbors
779 std::vector<std::pair<int, int>> neigh;
781 // find around-ground-ave and original candidate methods
782 size_t count = 0;
783 for (size_t i = 0; i < indices.size(); i++) {
784 if (ground_candidates_[row][col].GetIndicesVisitedFlag(i)) {
785 continue;
786 }
787 int pos = indices[i];
788 pt_ptr = point_cloud + (pos * nr_point_element);
789 float z = pt_ptr[2];
790 float candidata_z = 0.0;
791 // condition 3: near around-ground-value
792 if (ground_candidates_[row][col].GetValidFlag()) {
793 candidata_z = ground_candidates_[row][col].GetValidHeight();
794 if (fabs(z - candidata_z) < 2 * delta) {
795 labels_[pos] = 1;
796 candi->PushIndex(pos);
798 count++;
799 continue;
800 }
801 }
802 for (size_t jj = 0; jj < neigh.size(); jj++) {
803 int rr = neigh[jj].first;
804 int cc = neigh[jj].second;
805 if (ground_candidates_[rr][cc].GetValidFlag()) {
806 candidata_z = ground_candidates_[rr][cc].GetValidHeight();
807 if (fabs(z - candidata_z) < 2 * delta) {
808 labels_[pos] = 1;
809 candi->PushIndex(pos);
811 count++;
812 }
813 }
814 }
815 }
816 int valid_count = ground_candidates_[row][col].GetValidCount();
817 if (count + valid_count > param_.nr_z_comp_candis / 2 ||
818 count + valid_count > 0.9 *
820 return count;
821 }
822 // ground info okay. run extreme-scenes
823 if (voxel.Empty()) {
824 return count;
825 }
826 int rseed = I_DEFAULT_SEED;
827 std::vector<float> sample_z;
828 unsigned int voxel_points = voxel.NrPoints();
829 unsigned int nr_samples = IMin(param_.nr_z_comp_candis, voxel_points);
830 unsigned int nr_z_comp_fail_threshold =
831 IMin(param_.nr_z_comp_fail_threshold, (unsigned int)(nr_samples >> 1));
832 sample_z.resize(nr_samples);
833 sample_z.clear();
834 if (voxel_points <= param_.nr_z_comp_candis) {
835 for (size_t ii = 0; ii < voxel_points; ++ii) {
836 int pos = voxel.indices_[ii] * nr_point_element;
837 sample_z[ii] = (point_cloud + pos)[2];
838 }
839 } else {
841 static_cast<int>(param_.nr_z_comp_candis), voxel_points, &rseed);
842 // sampled z values
843 for (size_t ii = 0; ii < nr_samples; ++ii) {
844 int pos = voxel.indices_[sampled_indices_[ii]] * nr_point_element;
845 sample_z[ii] = (point_cloud + pos)[2];
846 }
847 }
848
849 // if semantic is all-wrong, it seems to degarde to original methods
850 for (size_t i = 0; i < indices.size(); i++) {
851 if (ground_candidates_[row][col].GetIndicesVisitedFlag(i)) {
852 continue;
853 }
854 int pos = indices[i];
855 // is ground
856 semantic_value = semantic_list + pos;
857 int value = semantic_value[0];
858 if (value == param_.semantic_ground_value) {
859 labels_[pos] = 1;
860 candi->PushIndex(pos);
861 count++;
862 continue;
863 }
864 if (count + valid_count > param_.nr_z_comp_candis / 2 ||
865 count + valid_count > 0.9 *
867 return count;
868 }
869 pt_ptr = point_cloud + (pos * nr_point_element);
870 float z = pt_ptr[2];
871 // within roi_near_rad
872 if (IAbs(pt_ptr[0]) < param_.roi_near_rad &&
873 IAbs(pt_ptr[1]) < param_.roi_near_rad) {
874 // if (z <= param_.sample_region_z_upper &&
875 // z >= param_.sample_region_z_lower) {
876 // labels_[pos] = 1;
877 // candi->PushIndex(pos);
878 // count++;
879 // continue;
880 // } else {
881 // continue;
882 // }
885 continue;
886 }
887 }
888 // beyond roi_near_rad
889 if (nr_samples > nr_z_comp_fail_threshold) {
890 for (size_t jj = 0; jj < nr_samples; ++jj) {
891 float delta_z = IAbs(sample_z[jj] - z);
892 if (delta_z > param_.planefit_filter_threshold) {
893 nr_contradi++;
894 if (nr_contradi > nr_z_comp_fail_threshold) {
895 break;
896 }
897 }
898 }
899 }
900 if (nr_contradi <= nr_z_comp_fail_threshold) {
901 labels_[pos] = 1;
902 candi->PushIndex(pos);
903 count++;
904 }
905 }
906 return count;
907}
float tan(Angle16 a)
Definition angle.cc:47

◆ Optimization()

void apollo::perception::algorithm::PlaneFitGroundDetector::Optimization ( )
protected

在文件 i_ground.cc 第 1703 行定义.

1703 {
1704 unsigned int lap_size = param_.nr_grids_coarse * param_.nr_grids_coarse;
1705 unsigned int i = 0;
1706 Eigen::SparseMatrix<float> in;
1707 Eigen::SparseMatrix<float> out;
1708 memset((void*)weight_buffer_[0], 0, 2 * lap_size * sizeof(float));
1709
1710 for (i = 0; i < lap_size; ++i) {
1711 weight_buffer_[0][i] = inliers_[i] > 8 ?
1712 std::exp((inliers_[i] - 8) / 20) : 0.1;
1713 }
1714
1715 for (i = 0; i < lap_size; ++i) {
1716 for (const auto& j : neighbors_[i]) {
1717 weight_buffer_[1][i] += weight_buffer_[0][j];
1718 }
1719 }
1720
1721 for (i = 0; i < lap_size; ++i) {
1722 if (inliers_[i] > 0) {
1723 a_array_.coeffRef(i + lap_size, i) = weight_buffer_[0][i];
1724 } else {
1725 a_array_.coeffRef(i + lap_size, i) = 0.0;
1726 }
1727 for (const auto& j : neighbors_[i]) {
1728 // -weight_buffer_[0][j] / weight_buffer_[1][i]
1729 a_array_.coeffRef(i, j) = -1.0 / neighbors_[i].size();
1730 }
1731 }
1732
1733 a_array_.makeCompressed();
1734 solver_.compute(a_array_.transpose() * a_array_);
1735
1736 for (i = 0; i < lap_size; ++i) {
1737 if (inliers_[i] > 0) {
1738 b_array_.coeffRef(i + lap_size, 0) =
1739 sphe_params_[i] * weight_buffer_[0][i];
1740 b_array_.coeffRef(i + lap_size, 1) =
1741 sphe_params_[i + lap_size] * weight_buffer_[0][i];
1742 b_array_.coeffRef(i + lap_size, 2) =
1743 sphe_params_[i + lap_size * 2] * weight_buffer_[0][i];
1744 } else {
1745 b_array_.coeffRef(i + lap_size, 0) = 0.0;
1746 b_array_.coeffRef(i + lap_size, 1) = 0.0;
1747 b_array_.coeffRef(i + lap_size, 2) = 0.0;
1748 }
1749 }
1750 in = a_array_.transpose() * b_array_;
1751 out = solver_.solve(in);
1752 for (i = 0; i < lap_size; ++i) {
1753 sphe_params_[i] = out.coeffRef(i, 0);
1754 sphe_params_[i + lap_size] = out.coeffRef(i, 1);
1755 sphe_params_[i + lap_size * 2] = out.coeffRef(i, 2);
1756 }
1757}
Eigen::SimplicialLDLT< Eigen::SparseMatrix< float > > solver_
Definition i_ground.h:456

◆ Pc2Voxel()

void apollo::perception::algorithm::PlaneFitGroundDetector::Pc2Voxel ( float  x,
float  y,
float  z,
int *  row,
int *  col 
)

在文件 i_ground.cc 第 1973 行定义.

1973 {
1974 *row = -1;
1975 *col = -1;
1976 // points that are outside the defined BBOX are ignored
1977 if (x < -param_.roi_region_rad_x || x > param_.roi_region_rad_x ||
1978 y < -param_.roi_region_rad_y || y > param_.roi_region_rad_y ||
1979 z < -param_.roi_region_rad_z || z > param_.roi_region_rad_z) {
1980 return;
1981 }
1982
1983 float voxel_width_x = IDiv(param_.roi_region_rad_x +
1984 param_.roi_region_rad_x, static_cast<int>(param_.nr_grids_coarse));
1985 float voxel_width_y = IDiv(param_.roi_region_rad_y +
1986 param_.roi_region_rad_y, static_cast<int>(param_.nr_grids_coarse));
1987 float voxel_width_x_rec = IRec(voxel_width_x);
1988 float voxel_width_y_rec = IRec(voxel_width_y);
1989 int grid_size = param_.nr_grids_coarse;
1990 *col = IMin(grid_size - 1, static_cast<int>(
1991 (x + param_.roi_region_rad_x) * voxel_width_x_rec));
1992 *row = IMin(grid_size - 1, static_cast<int>(
1993 (y + param_.roi_region_rad_y) * voxel_width_y_rec));
1994}
float IDiv(float a, float b)
Definition i_basic.h:35

◆ PlaneRefine()

void apollo::perception::algorithm::PlaneFitGroundDetector::PlaneRefine ( )
protected

在文件 i_ground.cc 第 1759 行定义.

1759 {
1760 const float *point_cloud = vg_coarse_->const_data();
1761 unsigned int nr_point_element = vg_coarse_->NrPointElement();
1762 unsigned int nr_points = vg_coarse_->NrPoints();
1763 unsigned int r = 0;
1764 unsigned int c = 0;
1765 float dist_thre = 0.0;
1766 float ptp_dist = 0.0;
1767 int nr_inliers = 0;
1768 unsigned int i = 0;
1769 float threshold_rad = 5.0 * Constant<float>::DEGREE_TO_RADIAN();
1770 for (r = 0; r < param_.nr_grids_coarse; ++r) {
1771 for (c = 0; c < param_.nr_grids_coarse; ++c) {
1772 if ((*vg_coarse_)(r, c).Empty()) {
1773 continue;
1774 }
1775 dist_thre = pf_thresholds_[r][c];
1776 const auto& opt_gd = ground_planes_[r][c];
1777 GroundPlaneLiDAR fit_gd;
1778 PlaneFitPointCandIndices &candi = local_candis_[r][c];
1779 if (candi.Size() < param_.nr_inliers_min_threshold) {
1780 continue;
1781 }
1782 int nr_samples = candi.Prune(param_.nr_samples_min_threshold,
1784
1785 float *psrc = pf_threeds_;
1786 nr_inliers = 0;
1787 for (i = 0; i < nr_samples; ++i) {
1788 assert(candi[i] < (int)nr_points);
1789 ICopy3(point_cloud + (nr_point_element * candi[i]), psrc);
1790 ptp_dist = IPlaneToPointDistanceWUnitNorm(opt_gd.params, psrc);
1791 if (ptp_dist < dist_thre) {
1792 psrc += dim_point_;
1793 nr_inliers++;
1794 }
1795 }
1796 if (nr_inliers < param_.nr_inliers_min_threshold) {
1797 continue;
1798 }
1799 IPlaneFitTotalLeastSquare(pf_threeds_, fit_gd.params, nr_inliers);
1800 float angle = calculate_two_angles(opt_gd, fit_gd);
1801 if (angle > threshold_rad) {
1802 continue;
1803 }
1804 ground_planes_[r][c].params[0] = fit_gd.params[0];
1805 ground_planes_[r][c].params[1] = fit_gd.params[1];
1806 ground_planes_[r][c].params[2] = fit_gd.params[2];
1807 ground_planes_[r][c].params[3] = fit_gd.params[3];
1808 }
1809 }
1810}
int Prune(unsigned int min_nr_samples, unsigned int max_nr_samples)
Definition i_ground.cc:69

◆ ResetParams()

void apollo::perception::algorithm::PlaneFitGroundDetector::ResetParams ( float  ori_z_lower,
float  ori_z_upper 
)

在文件 i_ground.cc 第 1882 行定义.

1882 {
1883 param_.sample_region_z_lower = ori_z_lower;
1884 param_.sample_region_z_upper = ori_z_upper;
1885 AINFO << "[BEFORE]: {} " << param_.sample_region_z_lower << ",{} "
1887}

◆ SelectCandidates()

void apollo::perception::algorithm::PlaneFitGroundDetector::SelectCandidates ( )
protected

在文件 i_ground.cc 第 909 行定义.

909 {
910 memset(reinterpret_cast<void *>(labels_), 0,
911 vg_fine_->NrPoints() * sizeof(char));
912 // Clear candidate list
913 for (size_t i = 0; i < vg_coarse_->NrVoxel(); ++i) {
914 local_candis_[0][i].Clear();
915 }
916 // plane fitting candidates
917 const float *point_cloud = vg_fine_->const_data();
918 const int* semantic_list = vg_fine_->const_semantic_data();
919 unsigned int nr_point_element = vg_fine_->NrPointElement();
920 std::stringstream sstr;
921 sstr << "[GroundCandidateSelect] " << std::to_string(frame_timestamp_)
922 << std::endl;
923 for (size_t r = 0; r < param_.nr_grids_fine; ++r) {
924 unsigned int begin = (r * param_.nr_grids_fine);
925 for (size_t c = 0; c < param_.nr_grids_fine; ++c) {
926 int parent = map_fine_to_coarse_[begin + c];
927 auto voxel = (*vg_fine_)(r, c);
928 // Clear ground_candidate list
930 ground_candidates_[r][c].Resize(voxel.indices_.size(), false);
931 if (voxel.indices_.size() < 1) {
932 continue;
933 }
934 SelectGroundCandidate(point_cloud, semantic_list, voxel.indices_,
935 &local_candis_[0][parent], &ground_candidates_[r][c],
936 nr_point_element);
937 }
938 }
939 // use ground to select again
940 for (size_t r = 0; r < param_.nr_grids_fine; ++r) {
941 unsigned int begin = (r * param_.nr_grids_fine);
942 for (size_t c = 0; c < param_.nr_grids_fine; ++c) {
943 auto voxel = (*vg_fine_)(r, c);
944 if (param_.debug_output && voxel.indices_.size() > 0) {
945 sstr << "row = " << r << " col = " << c
946 << " center_x = " << voxel.v_[0] + voxel.dim_x_ * 0.5f
947 << " center_y = " << voxel.v_[1] + voxel.dim_y_ * 0.5f
948 << " total_indices = " << voxel.indices_.size()
949 << " ground_flag = "
951 << " ground_count = "
953 << " ground_height = "
955 << " valid_flag = "
957 << " valid_count = "
959 << " valid_height = "
961 }
962 // Enough Points -> Do PlaneFit
963 int valid_c = ground_candidates_[r][c].GetValidCount();
964 if (valid_c > param_.nr_z_comp_candis / 2 ||
965 valid_c > 0.8 * ground_candidates_[r][c].GetIndicesSize()) {
966 if (param_.debug_output) {
967 sstr << " no necessary to get neighbor." << std::endl;
968 }
969 continue;
970 }
971 int parent = map_fine_to_coarse_[begin + c];
972 int count = NeighborGroundCandidate(r, c, point_cloud,
973 semantic_list, voxel.indices_, &local_candis_[0][parent],
974 nr_point_element);
975 if (param_.debug_output && voxel.indices_.size() > 0) {
976 sstr << " after neighbor_count = " << count << std::endl;
977 }
978 }
979 }
980 if (param_.debug_output) {
981 AINFO << sstr.str();
982 }
983 sstr.clear();
984}
void SelectGroundCandidate(const float *point_cloud, const int *semantic_list, const std::vector< int > &indices, PlaneFitPointCandIndices *candi, GroundCandidateIndices *ground_candi, unsigned int nr_point_element)
Definition i_ground.cc:695
int NeighborGroundCandidate(int row, int col, const float *point_cloud, const int *semantic_list, const std::vector< int > &indices, PlaneFitPointCandIndices *candi, unsigned int nr_point_element)
Definition i_ground.cc:764

◆ SelectGroundCandidate()

void apollo::perception::algorithm::PlaneFitGroundDetector::SelectGroundCandidate ( const float *  point_cloud,
const int *  semantic_list,
const std::vector< int > &  indices,
PlaneFitPointCandIndices *  candi,
GroundCandidateIndices *  ground_candi,
unsigned int  nr_point_element 
)
protected

在文件 i_ground.cc 第 695 行定义.

698 {
699 const float pi = 3.1415926535898;
700 const float *pt_ptr = nullptr;
701 const int *semantic_value = nullptr;
702 // default delta = 0.022
703 float res = param_.roi_region_rad_x * 2 * 1.0f / param_.nr_grids_fine;
704 float delta = tan(param_.planefit_orien_threshold * pi / 180.0) * res;
705 delta /= 2.0;
706 size_t ground_count = 0, valid_count = 0;
707 float ground_hei = 0.0, valid_hei = 0.0;
708 ground_candi->SetGroundFlag(false);
709 ground_candi->SetValidFlag(false);
710 // calculate semantic-ground value
711 for (size_t i = 0; i < indices.size(); i++) {
712 int pos = indices[i];
713 pt_ptr = point_cloud + (pos * nr_point_element);
714 float z = pt_ptr[2];
715 semantic_value = semantic_list + pos;
716 int value = semantic_value[0];
717 if (value == param_.semantic_ground_value) {
718 ground_count++;
719 ground_hei += z;
720 }
721 }
722 if (ground_count > 0.3 * indices.size() && ground_count > 0) {
723 ground_hei = (ground_hei * 1.0f / ground_count);
724 ground_candi->SetGroundFlag(true);
725 ground_candi->SetGroundCount(ground_count);
726 ground_candi->SetGroundHeight(ground_hei);
727 for (size_t i = 0; i < indices.size(); i++) {
728 int pos = indices[i];
729 pt_ptr = point_cloud + (pos * nr_point_element);
730 float z = pt_ptr[2];
731 semantic_value = semantic_list + pos;
732 int value = semantic_value[0];
733 // ground: range is 3 * delta
734 // other-semantic: range is 2 * delta
735 if (value == param_.semantic_ground_value) {
736 if (z > ground_hei - 3 * delta && z < ground_hei + 3 * delta) {
737 labels_[pos] = 1;
738 candi->PushIndex(pos);
739 ground_candi->SetVisitedTrue(i);
740 valid_count++;
741 valid_hei += z;
742 continue;
743 }
744 } else {
745 if (z > ground_hei - 2 * delta && z < ground_hei + 2 * delta) {
746 labels_[pos] = 1;
747 candi->PushIndex(pos);
748 ground_candi->SetVisitedTrue(i);
749 valid_count++;
750 valid_hei += z;
751 continue;
752 }
753 }
754 }
755 }
756 if (valid_count > 0) {
757 valid_hei = (valid_hei * 1.0f / valid_count);
758 ground_candi->SetValidFlag(true);
759 ground_candi->SetValidCount(valid_count);
760 ground_candi->SetValidHeight(valid_hei);
761 }
762}

◆ SetGroundPlaneSpherParams()

void apollo::perception::algorithm::PlaneFitGroundDetector::SetGroundPlaneSpherParams ( float *  params)
protected

在文件 i_ground.cc 第 1668 行定义.

1668 {
1669 unsigned int lap_size = param_.nr_grids_coarse * param_.nr_grids_coarse;
1670 unsigned int offset = 0;
1671 for (unsigned int i = 0; i < lap_size; ++i) {
1672 ground_planes_sphe_[0][i].theta = params[i + offset];
1673 }
1674 offset += lap_size;
1675 for (unsigned int i = 0; i < lap_size; ++i) {
1676 ground_planes_sphe_[0][i].phi = params[i + offset];
1677 }
1678 offset += lap_size;
1679 for (unsigned int i = 0; i < lap_size; ++i) {
1680 ground_planes_sphe_[0][i].d = params[i + offset];
1681 }
1682 for (unsigned int r = 0; r < param_.nr_grids_coarse; ++r) {
1683 for (unsigned int c = 0; c < param_.nr_grids_coarse; ++c) {
1684 // if ((*vg_coarse_)(r, c).Empty()) {
1685 // ground_planes_[r][c].ForceInvalid();
1686 // } else {
1687 // ground_planes_sphe_[r][c].SetNrSupport(1);
1688 // IPlaneSpherToEucli(ground_planes_sphe_[r][c],
1689 // &ground_planes_[r][c]);
1690 // }
1692 }
1693 }
1694}
void IPlaneSpherToEucli(const GroundPlaneSpherical &src, GroundPlaneLiDAR *dst)
Definition i_ground.cc:2040

◆ Smooth()

int apollo::perception::algorithm::PlaneFitGroundDetector::Smooth ( )
protected

在文件 i_ground.cc 第 1649 行定义.

1649 {
1650 int nr_grids = 0;
1651 unsigned int r = 0;
1652 unsigned int c = 0;
1653 unsigned int nm1 = param_.nr_grids_coarse - 1;
1654 assert(param_.nr_grids_coarse >= 2);
1655 nr_grids += SmoothLine(0, 0, 1);
1656 for (r = 1; r < nm1; ++r) {
1657 nr_grids += SmoothLine(r - 1, r, r + 1);
1658 }
1659 nr_grids += SmoothLine(nm1 - 1, nm1, nm1);
1660 for (r = 0; r < param_.nr_grids_coarse; ++r) {
1661 for (c = 0; c < param_.nr_grids_coarse; ++c) {
1663 }
1664 }
1665 return nr_grids;
1666}
int SmoothLine(unsigned int up, unsigned int r, unsigned int dn)
Definition i_ground.cc:1496

◆ SmoothGrid()

int apollo::perception::algorithm::PlaneFitGroundDetector::SmoothGrid ( const GroundPlaneSpherical &  g,
const GroundPlaneSpherical &  lt,
const GroundPlaneSpherical &  rt,
const GroundPlaneSpherical &  up,
const GroundPlaneSpherical &  dn,
GroundPlaneSpherical *  gp 
)
protected

在文件 i_ground.cc 第 1589 行定义.

1594 {
1595 int supports[] = {0, 0, 0, 0, 0};
1596 float weights[] = {0.f, 0.f, 0.f, 0.f, 0.f};
1597 gp->ForceInvalid();
1598 if (!g.IsValid()) {
1599 return 0;
1600 }
1601 // geometry weight:
1602 // 1
1603 // 1 4 1
1604 // 1
1605 if (lt.GetStatus()) {
1606 supports[0] = lt.GetNrSupport();
1607 }
1608 if (rt.GetStatus()) {
1609 supports[1] = rt.GetNrSupport();
1610 }
1611 if (up.GetStatus()) {
1612 supports[2] = up.GetNrSupport();
1613 }
1614 if (dn.GetStatus()) {
1615 supports[3] = dn.GetNrSupport();
1616 }
1617 supports[4] = (g.GetNrSupport() << 2);
1618 int support_sum = 0;
1619 support_sum = ISum4(supports);
1620 if (support_sum == 0) {
1621 *gp = g;
1622 return 0;
1623 }
1624 support_sum += supports[4];
1625 weights[0] =
1626 static_cast<float>(supports[0]) / static_cast<float>(support_sum);
1627 weights[1] =
1628 static_cast<float>(supports[1]) / static_cast<float>(support_sum);
1629 weights[2] =
1630 static_cast<float>(supports[2]) / static_cast<float>(support_sum);
1631 weights[3] =
1632 static_cast<float>(supports[3]) / static_cast<float>(support_sum);
1633 weights[4] =
1634 static_cast<float>(supports[4]) / static_cast<float>(support_sum);
1635 // weighted average:
1636 gp->theta = weights[0] * lt.theta + weights[1] * rt.theta +
1637 weights[2] * up.theta + weights[3] * dn.theta +
1638 weights[4] * g.theta;
1639 gp->phi = weights[0] * lt.phi + weights[1] * rt.phi + weights[2] * up.phi +
1640 weights[3] * dn.phi + weights[4] * g.phi;
1641 gp->d = weights[0] * lt.d + weights[1] * rt.d + weights[2] * up.d +
1642 weights[3] * dn.d + weights[4] * g.d;
1643 // compute weighted average - diveided by 8, round to nearest int
1644 support_sum = IMax(((support_sum + 2) >> 3), 1);
1645 gp->SetNrSupport(support_sum);
1646 return 1;
1647}

◆ SmoothInMath()

void apollo::perception::algorithm::PlaneFitGroundDetector::SmoothInMath ( )
protected

◆ SmoothInOrder()

int apollo::perception::algorithm::PlaneFitGroundDetector::SmoothInOrder ( )
protected

在文件 i_ground.cc 第 1846 行定义.

1846 {
1847 int nr_grids = 0;
1848 assert(param_.nr_grids_coarse >= 2);
1849 GroundPlaneSpherical plane;
1850 int cols = param_.nr_grids_coarse;
1851 int rows = param_.nr_grids_coarse;
1852 // from center to edge
1853 for (size_t i = 0; i < vg_coarse_->NrVoxel(); i++) {
1854 int row = order_table_[i].first;
1855 int col = order_table_[i].second;
1856 int last_col = IMax(0, col - 1);
1857 int next_col = IMin(cols - 1, col + 1);
1858 int last_row = IMax(0, row - 1);
1859 int next_row = IMin(rows - 1, row + 1);
1860 if (!ground_planes_sphe_[row][col].IsValid()) {
1861 nr_grids += CompleteGrid(ground_planes_sphe_[row][last_col],
1862 ground_planes_sphe_[row][next_col],
1863 ground_planes_sphe_[last_row][col],
1864 ground_planes_sphe_[next_row][col], &plane);
1865 } else {
1866 nr_grids += SmoothGrid(ground_planes_sphe_[row][col],
1867 ground_planes_sphe_[row][last_col],
1868 ground_planes_sphe_[row][next_col],
1869 ground_planes_sphe_[last_row][col],
1870 ground_planes_sphe_[next_row][col], &plane);
1871 }
1872 IPlaneSpherToEucli(plane, &ground_planes_[row][col]);
1873 }
1874 for (unsigned int r = 0; r < param_.nr_grids_coarse; ++r) {
1875 for (unsigned int c = 0; c < param_.nr_grids_coarse; ++c) {
1877 }
1878 }
1879 return nr_grids;
1880}
int CompleteGrid(const GroundPlaneSpherical &lt, const GroundPlaneSpherical &rt, const GroundPlaneSpherical &up, const GroundPlaneSpherical &dn, GroundPlaneSpherical *gp)
Definition i_ground.cc:1551
int SmoothGrid(const GroundPlaneSpherical &g, const GroundPlaneSpherical &lt, const GroundPlaneSpherical &rt, const GroundPlaneSpherical &up, const GroundPlaneSpherical &dn, GroundPlaneSpherical *gp)
Definition i_ground.cc:1589

◆ SmoothLine()

int apollo::perception::algorithm::PlaneFitGroundDetector::SmoothLine ( unsigned int  up,
unsigned int  r,
unsigned int  dn 
)
protected

(*_vg_coarse)(r, 0).empty()

(*_vg_coarse)(r, c).empty()

(*_vg_coarse)(r, nm1).empty()

在文件 i_ground.cc 第 1496 行定义.

1497 {
1498 int nr_grids = 0;
1499 unsigned int c = 0;
1500 unsigned int nm1 = param_.nr_grids_coarse - 1;
1501 GroundPlaneSpherical plane;
1502 assert(param_.nr_grids_coarse >= 2);
1503 assert(up < param_.nr_grids_coarse);
1504 assert(r < param_.nr_grids_coarse);
1505 assert(dn < param_.nr_grids_coarse);
1506 if ( true) {
1507 if (!ground_planes_sphe_[r][0].IsValid()) {
1508 nr_grids += CompleteGrid(
1510 ground_planes_sphe_[up][0], ground_planes_sphe_[dn][0], &plane);
1511 } else {
1512 nr_grids +=
1515 ground_planes_sphe_[dn][0], &plane);
1516 }
1517 IPlaneSpherToEucli(plane, &ground_planes_[r][0]);
1518 }
1519 for (c = 1; c < nm1; ++c) {
1520 if ( true) {
1521 if (!ground_planes_sphe_[r][c].IsValid()) {
1522 nr_grids += CompleteGrid(
1523 ground_planes_sphe_[r][c - 1], ground_planes_sphe_[r][c + 1],
1524 ground_planes_sphe_[up][c], ground_planes_sphe_[dn][c], &plane);
1525 } else {
1526 nr_grids += SmoothGrid(
1528 ground_planes_sphe_[r][c + 1], ground_planes_sphe_[up][c],
1529 ground_planes_sphe_[dn][c], &plane);
1530 }
1531 IPlaneSpherToEucli(plane, &ground_planes_[r][c]);
1532 }
1533 }
1534 if ( true) {
1535 if (!ground_planes_sphe_[r][nm1].IsValid()) {
1536 nr_grids += CompleteGrid(
1537 ground_planes_sphe_[r][nm1 - 1], ground_planes_sphe_[r][nm1],
1538 ground_planes_sphe_[up][nm1], ground_planes_sphe_[dn][nm1], &plane);
1539 } else {
1540 nr_grids += SmoothGrid(
1541 ground_planes_sphe_[r][nm1], ground_planes_sphe_[r][nm1 - 1],
1542 ground_planes_sphe_[r][nm1], ground_planes_sphe_[up][nm1],
1543 ground_planes_sphe_[dn][nm1], &plane);
1544 }
1545 IPlaneSpherToEucli(plane, &ground_planes_[r][nm1]);
1546 }
1547
1548 return nr_grids;
1549}

◆ UpdateParams()

void apollo::perception::algorithm::PlaneFitGroundDetector::UpdateParams ( float  parsing_ground_z,
float  buffer,
double  timestamp 
)

在文件 i_ground.cc 第 1889 行定义.

1889 {
1891 parsing_ground_z - buffer);
1893 parsing_ground_z + buffer);
1895 AINFO << "[AFTER]: {} " << param_.sample_region_z_lower << ",{} "
1897}

类成员变量说明

◆ a_array_

Eigen::SparseMatrix<float> apollo::perception::algorithm::PlaneFitGroundDetector::a_array_
protected

在文件 i_ground.h 第 454 行定义.

◆ age_

int apollo::perception::algorithm::PlaneFitGroundDetector::age_ = 0
protected

在文件 i_ground.h 第 445 行定义.

◆ b_array_

Eigen::SparseMatrix<float> apollo::perception::algorithm::PlaneFitGroundDetector::b_array_
protected

在文件 i_ground.h 第 455 行定义.

◆ frame_timestamp_

double apollo::perception::algorithm::PlaneFitGroundDetector::frame_timestamp_ = 0.0
protected

在文件 i_ground.h 第 447 行定义.

◆ ground_candidates_

GroundCandidateIndices** apollo::perception::algorithm::PlaneFitGroundDetector::ground_candidates_
protected

在文件 i_ground.h 第 436 行定义.

◆ ground_planes_

GroundPlaneLiDAR** apollo::perception::algorithm::PlaneFitGroundDetector::ground_planes_
protected

在文件 i_ground.h 第 433 行定义.

◆ ground_planes_sphe_

GroundPlaneSpherical** apollo::perception::algorithm::PlaneFitGroundDetector::ground_planes_sphe_
protected

在文件 i_ground.h 第 434 行定义.

◆ ground_z_

std::pair<float, bool>** apollo::perception::algorithm::PlaneFitGroundDetector::ground_z_
protected

在文件 i_ground.h 第 437 行定义.

◆ inliers_

int* apollo::perception::algorithm::PlaneFitGroundDetector::inliers_ = nullptr
protected

在文件 i_ground.h 第 451 行定义.

◆ labels_

char* apollo::perception::algorithm::PlaneFitGroundDetector::labels_
protected

在文件 i_ground.h 第 440 行定义.

◆ local_candis_

PlaneFitPointCandIndices** apollo::perception::algorithm::PlaneFitGroundDetector::local_candis_
protected

在文件 i_ground.h 第 435 行定义.

◆ map_fine_to_coarse_

unsigned int* apollo::perception::algorithm::PlaneFitGroundDetector::map_fine_to_coarse_
protected

在文件 i_ground.h 第 439 行定义.

◆ neighbors_

std::vector<std::vector<unsigned int> > apollo::perception::algorithm::PlaneFitGroundDetector::neighbors_
protected

在文件 i_ground.h 第 453 行定义.

◆ order_table_

std::pair<int, int>* apollo::perception::algorithm::PlaneFitGroundDetector::order_table_
protected

在文件 i_ground.h 第 446 行定义.

◆ pf_threeds_

float* apollo::perception::algorithm::PlaneFitGroundDetector::pf_threeds_
protected

在文件 i_ground.h 第 442 行定义.

◆ pf_thresholds_

float** apollo::perception::algorithm::PlaneFitGroundDetector::pf_thresholds_
protected

在文件 i_ground.h 第 438 行定义.

◆ sampled_indices_

int* apollo::perception::algorithm::PlaneFitGroundDetector::sampled_indices_
protected

在文件 i_ground.h 第 444 行定义.

◆ sampled_z_values_

float* apollo::perception::algorithm::PlaneFitGroundDetector::sampled_z_values_
protected

在文件 i_ground.h 第 441 行定义.

◆ solver_

Eigen::SimplicialLDLT<Eigen::SparseMatrix<float> > apollo::perception::algorithm::PlaneFitGroundDetector::solver_
protected

在文件 i_ground.h 第 456 行定义.

◆ sphe_params_

float* apollo::perception::algorithm::PlaneFitGroundDetector::sphe_params_ = nullptr
protected

在文件 i_ground.h 第 452 行定义.

◆ spher_params_

float* apollo::perception::algorithm::PlaneFitGroundDetector::spher_params_
protected

在文件 i_ground.h 第 443 行定义.

◆ vg_coarse_

VoxelGridXY<float>* apollo::perception::algorithm::PlaneFitGroundDetector::vg_coarse_
protected

在文件 i_ground.h 第 432 行定义.

◆ vg_fine_

VoxelGridXY<float>* apollo::perception::algorithm::PlaneFitGroundDetector::vg_fine_
protected

在文件 i_ground.h 第 431 行定义.

◆ weight_buffer_

float** apollo::perception::algorithm::PlaneFitGroundDetector::weight_buffer_ = nullptr
protected

在文件 i_ground.h 第 450 行定义.


该类的文档由以下文件生成: