Apollo 11.0
自动驾驶开放平台
object_builder.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 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
25
26namespace apollo {
27namespace perception {
28namespace lidar {
29
31 return true;
32}
33
35 LidarFrame* frame) {
36 if (frame == nullptr) {
37 return false;
38 }
39 std::vector<ObjectPtr>* objects = &(frame->segmented_objects);
40 for (size_t i = 0; i < objects->size(); ++i) {
41 if (objects->at(i)) {
42 objects->at(i)->id = static_cast<int>(i);
43 ComputePolygon2D(objects->at(i));
44 ComputePolygonSizeCenter(objects->at(i));
45 ComputeOtherObjectInformation(objects->at(i));
46 ComputeHeightAboveGround(objects->at(i));
47 // Not necessary
48 // if (FLAGS_need_judge_front_critical) {
49 // JudgeFrontCritical(objects->at(i), frame->lidar2novatel_extrinsics);
50 // }
51 }
52 }
53 return true;
54}
55
57 Eigen::Vector3f min_pt;
58 Eigen::Vector3f max_pt;
59 PointFCloud& cloud = object->lidar_supplement.cloud;
60 GetMinMax3D(cloud, &min_pt, &max_pt);
61 if (cloud.size() < 4u) {
62 SetDefaultValue(min_pt, max_pt, object);
63 return;
64 }
65 LinePerturbation(&cloud);
67 hull.GetConvexHull(cloud, &(object->polygon));
68}
69
71 object->anchor_point = object->center;
72 double timestamp = 0.0;
73 size_t num_point = object->lidar_supplement.cloud.size();
74 for (size_t i = 0; i < num_point; ++i) {
75 timestamp += object->lidar_supplement.cloud.points_timestamp(i);
76 }
77 if (num_point > 0) {
78 timestamp /= static_cast<double>(num_point);
79 }
80 object->latest_tracked_time = timestamp;
81}
82
84 if (object->lidar_supplement.cloud.size() < 4u) {
85 return;
86 }
87 Eigen::Vector3f dir = object->direction;
88 algorithm::CalculateBBoxSizeCenter2DXY(object->lidar_supplement.cloud, dir,
89 &(object->size), &(object->center));
90 if (object->lidar_supplement.is_background) {
91 float length = object->size(0);
92 float width = object->size(1);
93 Eigen::Matrix<float, 3, 1> ortho_dir(-object->direction(1),
94 object->direction(0), 0.0);
95 if (length < width) {
96 object->direction = ortho_dir;
97 object->size(0) = width;
98 object->size(1) = length;
99 }
100 }
101 for (size_t i = 0; i < 3; ++i) {
102 if (object->size(i) < kEpsilonForSize) {
103 object->size(i) = kEpsilonForSize;
104 }
105 }
106 object->theta =
107 static_cast<float>(atan2(object->direction(1), object->direction(0)));
108}
109
111 const float invalid_ground = std::numeric_limits<float>::max();
112 float above_min = std::numeric_limits<float>::max();
113 for (int j = 0; j < object->lidar_supplement.cloud.size(); j++) {
114 auto height = object->lidar_supplement.cloud.points_height(j);
115 if (height == invalid_ground) {
116 continue;
117 }
118 above_min = std::min(above_min, height);
119 }
120 object->lidar_supplement.height_above_ground = above_min;
121}
122
123void ObjectBuilder::SetDefaultValue(const Eigen::Vector3f& min_pt_in,
124 const Eigen::Vector3f& max_pt_in,
125 ObjectPtr object) {
126 Eigen::Vector3f min_pt = min_pt_in;
127 Eigen::Vector3f max_pt = max_pt_in;
128 // handle degeneration case
129 for (int i = 0; i < 3; i++) {
130 if (max_pt[i] - min_pt[i] < kEpsilonForSize) {
131 max_pt[i] = max_pt[i] + kEpsilonForSize / 2;
132 min_pt[i] = min_pt[i] - kEpsilonForSize / 2;
133 }
134 }
135 Eigen::Vector3f center((min_pt[0] + max_pt[0]) / 2,
136 (min_pt[1] + max_pt[1]) / 2,
137 (min_pt[2] + max_pt[2]) / 2);
138 object->center = Eigen::Vector3d(static_cast<double>(center(0)),
139 static_cast<double>(center(1)),
140 static_cast<double>(center(2)));
141 float length = max_pt[0] - min_pt[0];
142 float width = max_pt[1] - min_pt[1];
143 float height = max_pt[2] - min_pt[2];
144 if (length < width) {
145 object->size = Eigen::Vector3f(width, length, height);
146 object->direction = Eigen::Vector3f(0.0, 1.0, 0.0);
147 } else {
148 object->size = Eigen::Vector3f(length, width, height);
149 object->direction = Eigen::Vector3f(1.0, 0.0, 0.0);
150 }
151 // polygon
152 if (object->lidar_supplement.cloud.size() < 4) {
153 object->polygon.resize(4);
154 object->polygon[0].x = static_cast<double>(min_pt[0]);
155 object->polygon[0].y = static_cast<double>(min_pt[1]);
156 object->polygon[0].z = static_cast<double>(min_pt[2]);
157
158 object->polygon[1].x = static_cast<double>(max_pt[0]);
159 object->polygon[1].y = static_cast<double>(min_pt[1]);
160 object->polygon[1].z = static_cast<double>(min_pt[2]);
161
162 object->polygon[2].x = static_cast<double>(max_pt[0]);
163 object->polygon[2].y = static_cast<double>(max_pt[1]);
164 object->polygon[2].z = static_cast<double>(min_pt[2]);
165
166 object->polygon[3].x = static_cast<double>(min_pt[0]);
167 object->polygon[3].y = static_cast<double>(max_pt[1]);
168 object->polygon[3].z = static_cast<double>(min_pt[2]);
169 }
170}
171
173 if (cloud->size() >= 3) {
174 int start_point = 0;
175 int end_point = 1;
176 float diff_x = cloud->at(start_point).x - cloud->at(end_point).x;
177 float diff_y = cloud->at(start_point).y - cloud->at(end_point).y;
178 size_t idx = 0;
179 for (idx = 2; idx < cloud->size(); ++idx) {
180 float tdiff_x = cloud->at(idx).x - cloud->at(start_point).x;
181 float tdiff_y = cloud->at(idx).y - cloud->at(start_point).y;
182 if (fabs(diff_x * tdiff_y - tdiff_x * diff_y) > kEpsilonForLine) {
183 return false;
184 }
185 }
186 cloud->at(0).x += kEpsilonForLine;
187 cloud->at(1).y += kEpsilonForLine;
188 return true;
189 }
190 return true;
191}
192
194 Eigen::Vector3f* min_pt,
195 Eigen::Vector3f* max_pt) {
196 (*min_pt)[0] = (*min_pt)[1] = (*min_pt)[2] =
197 std::numeric_limits<float>::max();
198 (*max_pt)[0] = (*max_pt)[1] = (*max_pt)[2] =
199 -std::numeric_limits<float>::max();
200 for (size_t i = 0; i < cloud.size(); ++i) {
201 if (std::isnan(cloud[i].x) || std::isnan(cloud[i].y) ||
202 std::isnan(cloud[i].z)) {
203 continue;
204 }
205 (*min_pt)[0] = std::min((*min_pt)[0], cloud[i].x);
206 (*max_pt)[0] = std::max((*max_pt)[0], cloud[i].x);
207 (*min_pt)[1] = std::min((*min_pt)[1], cloud[i].y);
208 (*max_pt)[1] = std::max((*max_pt)[1], cloud[i].y);
209 (*min_pt)[2] = std::min((*min_pt)[2], cloud[i].z);
210 (*max_pt)[2] = std::max((*max_pt)[2], cloud[i].z);
211 }
212}
213
215 ObjectPtr object, Eigen::Affine3d& lidar2novatel_pose) {
216 Eigen::Vector3d obj_center = object->center;
217 obj_center = lidar2novatel_pose * obj_center;
218 auto x_in_novatel = obj_center(0);
219 auto y_in_novatel = obj_center(1);
220 const float invalid_ground = std::numeric_limits<float>::max();
221 if (y_in_novatel > FLAGS_y_back && y_in_novatel < FLAGS_y_front &&
222 x_in_novatel > FLAGS_x_back && x_in_novatel < FLAGS_x_front &&
223 object->lidar_supplement.is_clustered) {
224 float above_max = -100.0f;
225 for (size_t j = 0; j < object->lidar_supplement.cloud.size(); j++) {
226 auto height = object->lidar_supplement.cloud.points_height(j);
227 if (height == invalid_ground) {
228 continue;
229 }
230 above_max = std::max(above_max, height);
231 }
232 if (above_max <= FLAGS_max_points_height) {
233 object->is_front_critical = true;
234 AINFO << "Object lidar_x: " << object->center(0) << ", lidar_y: "
235 << object->center(1) << ", max_point_height: " << above_max
236 << " is FRONT-CRITICAL";
237 }
238 }
239}
240
241} // namespace lidar
242} // namespace perception
243} // namespace apollo
bool GetConvexHull(const CLOUD_IN_TYPE &in_cloud, CLOUD_OUT_TYPE *out_polygon)
void ComputeHeightAboveGround(std::shared_ptr< apollo::perception::base::Object > object)
bool LinePerturbation(apollo::perception::base::PointCloud< apollo::perception::base::PointF > *cloud)
void ComputeOtherObjectInformation(std::shared_ptr< apollo::perception::base::Object > object)
void GetMinMax3D(const apollo::perception::base::PointCloud< apollo::perception::base::PointF > &cloud, Eigen::Vector3f *min_pt, Eigen::Vector3f *max_pt)
void ComputePolygon2D(std::shared_ptr< apollo::perception::base::Object > object)
bool Init(const ObjectBuilderInitOptions &options=ObjectBuilderInitOptions())
Init the Object Builder object with initialization options
void SetDefaultValue(const Eigen::Vector3f &min_pt, const Eigen::Vector3f &max_pt, std::shared_ptr< apollo::perception::base::Object > object)
bool Build(const ObjectBuilderOptions &options, LidarFrame *frame)
Calculate and fill object size, center, directions.
void JudgeFrontCritical(std::shared_ptr< apollo::perception::base::Object > object, Eigen::Affine3d &lidar2novatel_pose)
void ComputePolygonSizeCenter(std::shared_ptr< apollo::perception::base::Object > object)
#define AINFO
Definition log.h:42
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
std::shared_ptr< apollo::perception::base::Object > ObjectPtr
apollo::perception::base::PointCloud< PointF > PointFCloud
class register implement
Definition arena_queue.h:37
std::vector< std::shared_ptr< base::Object > > segmented_objects
Definition lidar_frame.h:53