Apollo 11.0
自动驾驶开放平台
object_builder.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2023 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include <algorithm>
20#include <limits>
21
24
25namespace apollo {
26namespace perception {
27namespace radar4d {
28
29static const float kEpsilon = 1e-6f;
30static const float kEpsilonForSize = 1e-2f;
31static const float kEpsilonForLine = 1e-3f;
34using ObjectPtr = std::shared_ptr<apollo::perception::base::Object>;
37
39 return true;
40}
41
43 RadarFrame* frame) {
44 if (frame == nullptr) {
45 return false;
46 }
47 std::vector<ObjectPtr>* objects = &(frame->segmented_objects);
48 for (size_t i = 0; i < objects->size(); ++i) {
49 if (objects->at(i)) {
50 objects->at(i)->id = static_cast<int>(i);
51 ComputePolygon2D(objects->at(i));
52 ComputePolygonSizeCenter(objects->at(i));
53 ComputeOtherObjectInformation(objects->at(i));
54 }
55 }
56 return true;
57}
58
59void ObjectBuilder::ComputePolygon2D(ObjectPtr object) {
60 Eigen::Vector3f min_pt;
61 Eigen::Vector3f max_pt;
62 RadarPointFCloud& cloud = object->radar4d_supplement.cloud;
63 GetMinMax3D(cloud, &min_pt, &max_pt);
64 if (cloud.size() < 4u) {
65 SetDefaultValue(min_pt, max_pt, object);
66 return;
67 }
68 LinePerturbation(&cloud);
69 // polygon
71 hull.GetConvexHull(cloud, &(object->polygon));
72}
73
74void ObjectBuilder::ComputeOtherObjectInformation(ObjectPtr object) {
75 object->anchor_point = object->center;
76}
77
78void ObjectBuilder::ComputePolygonSizeCenter(ObjectPtr object) {
79 if (object->radar4d_supplement.cloud.size() < 4u) {
80 return;
81 }
82 Eigen::Vector3f dir = object->direction;
84 object->radar4d_supplement.cloud,
85 dir, &(object->size), &(object->center));
86 if (object->radar4d_supplement.is_background) {
87 float length = object->size(0);
88 float width = object->size(1);
89 Eigen::Matrix<float, 3, 1> ortho_dir(-object->direction(1),
90 object->direction(0), 0.0);
91 if (length < width) {
92 object->direction = ortho_dir;
93 object->size(0) = width;
94 object->size(1) = length;
95 }
96 }
97 for (size_t i = 0; i < 3; ++i) {
98 if (object->size(i) < kEpsilonForSize) {
99 object->size(i) = kEpsilonForSize;
100 }
101 }
102 object->theta =
103 static_cast<float>(atan2(object->direction(1), object->direction(0)));
104}
105
106void ObjectBuilder::SetDefaultValue(const Eigen::Vector3f& min_pt_in,
107 const Eigen::Vector3f& max_pt_in,
108 ObjectPtr object) {
109 Eigen::Vector3f min_pt = min_pt_in;
110 Eigen::Vector3f max_pt = max_pt_in;
111 // handle degeneration case
112 for (int i = 0; i < 3; i++) {
113 if (max_pt[i] - min_pt[i] < kEpsilonForSize) {
114 max_pt[i] = max_pt[i] + kEpsilonForSize / 2;
115 min_pt[i] = min_pt[i] - kEpsilonForSize / 2;
116 }
117 }
118 Eigen::Vector3f center((min_pt[0] + max_pt[0]) / 2,
119 (min_pt[1] + max_pt[1]) / 2,
120 (min_pt[2] + max_pt[2]) / 2);
121 object->center = Eigen::Vector3d(static_cast<double>(center(0)),
122 static_cast<double>(center(1)),
123 static_cast<double>(center(2)));
124 float length = max_pt[0] - min_pt[0];
125 float width = max_pt[1] - min_pt[1];
126 float height = max_pt[2] - min_pt[2];
127 if (length < width) {
128 object->size = Eigen::Vector3f(width, length, height);
129 object->direction = Eigen::Vector3f(0.0, 1.0, 0.0);
130 } else {
131 object->size = Eigen::Vector3f(length, width, height);
132 object->direction = Eigen::Vector3f(1.0, 0.0, 0.0);
133 }
134 // polygon
135 if (object->radar4d_supplement.cloud.size() < 4) {
136 object->polygon.resize(4);
137 object->polygon[0].x = static_cast<double>(min_pt[0]);
138 object->polygon[0].y = static_cast<double>(min_pt[1]);
139 object->polygon[0].z = static_cast<double>(min_pt[2]);
140
141 object->polygon[1].x = static_cast<double>(max_pt[0]);
142 object->polygon[1].y = static_cast<double>(min_pt[1]);
143 object->polygon[1].z = static_cast<double>(min_pt[2]);
144
145 object->polygon[2].x = static_cast<double>(max_pt[0]);
146 object->polygon[2].y = static_cast<double>(max_pt[1]);
147 object->polygon[2].z = static_cast<double>(min_pt[2]);
148
149 object->polygon[3].x = static_cast<double>(min_pt[0]);
150 object->polygon[3].y = static_cast<double>(max_pt[1]);
151 object->polygon[3].z = static_cast<double>(min_pt[2]);
152 }
153}
154
155bool ObjectBuilder::LinePerturbation(RadarPointFCloud* cloud) {
156 if (cloud->size() >= 3) {
157 int start_point = 0;
158 int end_point = 1;
159 float diff_x = cloud->at(start_point).x - cloud->at(end_point).x;
160 float diff_y = cloud->at(start_point).y - cloud->at(end_point).y;
161 size_t idx = 0;
162 for (idx = 2; idx < cloud->size(); ++idx) {
163 float tdiff_x = cloud->at(idx).x - cloud->at(start_point).x;
164 float tdiff_y = cloud->at(idx).y - cloud->at(start_point).y;
165 if (fabs(diff_x * tdiff_y - tdiff_x * diff_y) > kEpsilonForLine) {
166 return false;
167 }
168 }
169 cloud->at(0).x += kEpsilonForLine;
170 cloud->at(1).y += kEpsilonForLine;
171 return true;
172 }
173 return true;
174}
175
176void ObjectBuilder::GetMinMax3D(const RadarPointFCloud& cloud,
177 Eigen::Vector3f* min_pt,
178 Eigen::Vector3f* max_pt) {
179 (*min_pt)[0] = (*min_pt)[1] = (*min_pt)[2] =
180 std::numeric_limits<float>::max();
181 (*max_pt)[0] = (*max_pt)[1] = (*max_pt)[2] =
182 -std::numeric_limits<float>::max();
183 for (size_t i = 0; i < cloud.size(); ++i) {
184 if (std::isnan(cloud[i].x) || std::isnan(cloud[i].y) ||
185 std::isnan(cloud[i].z)) {
186 continue;
187 }
188 (*min_pt)[0] = std::min((*min_pt)[0], cloud[i].x);
189 (*max_pt)[0] = std::max((*max_pt)[0], cloud[i].x);
190 (*min_pt)[1] = std::min((*min_pt)[1], cloud[i].y);
191 (*max_pt)[1] = std::max((*max_pt)[1], cloud[i].y);
192 (*min_pt)[2] = std::min((*min_pt)[2], cloud[i].z);
193 (*max_pt)[2] = std::max((*max_pt)[2], cloud[i].z);
194 }
195}
196
197} // namespace radar4d
198} // namespace perception
199} // namespace apollo
bool GetConvexHull(const CLOUD_IN_TYPE &in_cloud, CLOUD_OUT_TYPE *out_polygon)
const RadarPointT * at(size_t col, size_t row) const
bool Init(const DetectorInitOptions &options=DetectorInitOptions())
Init the Object Builder object with initialization options
bool Build(const DetectorOptions &options, RadarFrame *frame)
Calculate and fill object size, center, directions.
uint32_t height
Height of point cloud
uint32_t width
Width of point cloud
void CalculateBBoxSizeCenter2DXY(const PointCloudT &cloud, const Eigen::Vector3f &dir, Eigen::Vector3f *size, Eigen::Vector3d *center, float minimum_edge_length=std::numeric_limits< float >::epsilon())
Definition common.h:117
RadarPoint< double > RadarPointD
Definition point.h:114
std::shared_ptr< apollo::perception::base::Object > ObjectPtr
apollo::perception::base::RadarPointCloud< RadarPointF > RadarPointFCloud
class register implement
Definition arena_queue.h:37
std::vector< std::shared_ptr< base::Object > > segmented_objects
Definition radar_frame.h:47