Apollo 10.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 if (FLAGS_need_judge_front_critical) {
48 JudgeFrontCritical(objects->at(i), frame->lidar2novatel_extrinsics);
49 }
50 }
51 }
52 return true;
53}
54
56 Eigen::Vector3f min_pt;
57 Eigen::Vector3f max_pt;
58 PointFCloud& cloud = object->lidar_supplement.cloud;
59 GetMinMax3D(cloud, &min_pt, &max_pt);
60 if (cloud.size() < 4u) {
61 SetDefaultValue(min_pt, max_pt, object);
62 return;
63 }
64 LinePerturbation(&cloud);
66 hull.GetConvexHull(cloud, &(object->polygon));
67}
68
70 object->anchor_point = object->center;
71 double timestamp = 0.0;
72 size_t num_point = object->lidar_supplement.cloud.size();
73 for (size_t i = 0; i < num_point; ++i) {
74 timestamp += object->lidar_supplement.cloud.points_timestamp(i);
75 }
76 if (num_point > 0) {
77 timestamp /= static_cast<double>(num_point);
78 }
79 object->latest_tracked_time = timestamp;
80}
81
83 if (object->lidar_supplement.cloud.size() < 4u) {
84 return;
85 }
86 Eigen::Vector3f dir = object->direction;
87 algorithm::CalculateBBoxSizeCenter2DXY(object->lidar_supplement.cloud, dir,
88 &(object->size), &(object->center));
89 if (object->lidar_supplement.is_background) {
90 float length = object->size(0);
91 float width = object->size(1);
92 Eigen::Matrix<float, 3, 1> ortho_dir(-object->direction(1),
93 object->direction(0), 0.0);
94 if (length < width) {
95 object->direction = ortho_dir;
96 object->size(0) = width;
97 object->size(1) = length;
98 }
99 }
100 for (size_t i = 0; i < 3; ++i) {
101 if (object->size(i) < kEpsilonForSize) {
102 object->size(i) = kEpsilonForSize;
103 }
104 }
105 object->theta =
106 static_cast<float>(atan2(object->direction(1), object->direction(0)));
107}
108
110 const float invalid_ground = std::numeric_limits<float>::max();
111 float above_min = std::numeric_limits<float>::max();
112 for (int j = 0; j < object->lidar_supplement.cloud.size(); j++) {
113 auto height = object->lidar_supplement.cloud.points_height(j);
114 if (height == invalid_ground) {
115 continue;
116 }
117 above_min = std::min(above_min, height);
118 }
119 object->lidar_supplement.height_above_ground = above_min;
120}
121
122void ObjectBuilder::SetDefaultValue(const Eigen::Vector3f& min_pt_in,
123 const Eigen::Vector3f& max_pt_in,
124 ObjectPtr object) {
125 Eigen::Vector3f min_pt = min_pt_in;
126 Eigen::Vector3f max_pt = max_pt_in;
127 // handle degeneration case
128 for (int i = 0; i < 3; i++) {
129 if (max_pt[i] - min_pt[i] < kEpsilonForSize) {
130 max_pt[i] = max_pt[i] + kEpsilonForSize / 2;
131 min_pt[i] = min_pt[i] - kEpsilonForSize / 2;
132 }
133 }
134 Eigen::Vector3f center((min_pt[0] + max_pt[0]) / 2,
135 (min_pt[1] + max_pt[1]) / 2,
136 (min_pt[2] + max_pt[2]) / 2);
137 object->center = Eigen::Vector3d(static_cast<double>(center(0)),
138 static_cast<double>(center(1)),
139 static_cast<double>(center(2)));
140 float length = max_pt[0] - min_pt[0];
141 float width = max_pt[1] - min_pt[1];
142 float height = max_pt[2] - min_pt[2];
143 if (length < width) {
144 object->size = Eigen::Vector3f(width, length, height);
145 object->direction = Eigen::Vector3f(0.0, 1.0, 0.0);
146 } else {
147 object->size = Eigen::Vector3f(length, width, height);
148 object->direction = Eigen::Vector3f(1.0, 0.0, 0.0);
149 }
150 // polygon
151 if (object->lidar_supplement.cloud.size() < 4) {
152 object->polygon.resize(4);
153 object->polygon[0].x = static_cast<double>(min_pt[0]);
154 object->polygon[0].y = static_cast<double>(min_pt[1]);
155 object->polygon[0].z = static_cast<double>(min_pt[2]);
156
157 object->polygon[1].x = static_cast<double>(max_pt[0]);
158 object->polygon[1].y = static_cast<double>(min_pt[1]);
159 object->polygon[1].z = static_cast<double>(min_pt[2]);
160
161 object->polygon[2].x = static_cast<double>(max_pt[0]);
162 object->polygon[2].y = static_cast<double>(max_pt[1]);
163 object->polygon[2].z = static_cast<double>(min_pt[2]);
164
165 object->polygon[3].x = static_cast<double>(min_pt[0]);
166 object->polygon[3].y = static_cast<double>(max_pt[1]);
167 object->polygon[3].z = static_cast<double>(min_pt[2]);
168 }
169}
170
172 if (cloud->size() >= 3) {
173 int start_point = 0;
174 int end_point = 1;
175 float diff_x = cloud->at(start_point).x - cloud->at(end_point).x;
176 float diff_y = cloud->at(start_point).y - cloud->at(end_point).y;
177 size_t idx = 0;
178 for (idx = 2; idx < cloud->size(); ++idx) {
179 float tdiff_x = cloud->at(idx).x - cloud->at(start_point).x;
180 float tdiff_y = cloud->at(idx).y - cloud->at(start_point).y;
181 if (fabs(diff_x * tdiff_y - tdiff_x * diff_y) > kEpsilonForLine) {
182 return false;
183 }
184 }
185 cloud->at(0).x += kEpsilonForLine;
186 cloud->at(1).y += kEpsilonForLine;
187 return true;
188 }
189 return true;
190}
191
193 Eigen::Vector3f* min_pt,
194 Eigen::Vector3f* max_pt) {
195 (*min_pt)[0] = (*min_pt)[1] = (*min_pt)[2] =
196 std::numeric_limits<float>::max();
197 (*max_pt)[0] = (*max_pt)[1] = (*max_pt)[2] =
198 -std::numeric_limits<float>::max();
199 for (size_t i = 0; i < cloud.size(); ++i) {
200 if (std::isnan(cloud[i].x) || std::isnan(cloud[i].y) ||
201 std::isnan(cloud[i].z)) {
202 continue;
203 }
204 (*min_pt)[0] = std::min((*min_pt)[0], cloud[i].x);
205 (*max_pt)[0] = std::max((*max_pt)[0], cloud[i].x);
206 (*min_pt)[1] = std::min((*min_pt)[1], cloud[i].y);
207 (*max_pt)[1] = std::max((*max_pt)[1], cloud[i].y);
208 (*min_pt)[2] = std::min((*min_pt)[2], cloud[i].z);
209 (*max_pt)[2] = std::max((*max_pt)[2], cloud[i].z);
210 }
211}
212
214 ObjectPtr object, Eigen::Affine3d& lidar2novatel_pose) {
215 Eigen::Vector3d obj_center = object->center;
216 obj_center = lidar2novatel_pose * obj_center;
217 auto x_in_novatel = obj_center(0);
218 auto y_in_novatel = obj_center(1);
219 if (y_in_novatel > FLAGS_y_back && y_in_novatel < FLAGS_y_front &&
220 x_in_novatel > FLAGS_x_back && x_in_novatel < FLAGS_x_front &&
221 object->lidar_supplement.is_clustered) {
222 object->is_front_critical = true;
223 AINFO << "Object " << object->id << " is FRONT-CRITICAL";
224 }
225}
226
227} // namespace lidar
228} // namespace perception
229} // 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:112
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