Apollo 11.0
自动驾驶开放平台
radar_object_util.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 *****************************************************************************/
17
18#include <algorithm>
19#include <limits>
20
23
24namespace apollo {
25namespace perception {
26namespace radar4d {
27
28using base::Object;
29using base::RadarPointCloud;
32using base::PointCloud;
33using base::PointD;
34
35void GetBoundingBox2d(const std::shared_ptr<Object>& object,
36 RadarPointCloud<RadarPointD>* box, double expand) {
37 box->clear();
38 box->resize(4);
39
40 Eigen::Vector3d direction = object->direction.cast<double>();
41 Eigen::Vector3d odirection(-direction(1), direction(0), 0.0);
42 double half_length = object->size(0) * 0.5 + expand;
43 double half_width = object->size(1) * 0.5 + expand;
44
45 box->at(0).x = half_length * direction(0) + half_width * odirection(0) +
46 object->center(0);
47 box->at(0).y = half_length * direction(1) + half_width * odirection(1) +
48 object->center(1);
49 box->at(1).x = -half_length * direction(0) + half_width * odirection(0) +
50 object->center(0);
51 box->at(1).y = -half_length * direction(1) + half_width * odirection(1) +
52 object->center(1);
53 box->at(2).x = -half_length * direction(0) - half_width * odirection(0) +
54 object->center(0);
55 box->at(2).y = -half_length * direction(1) - half_width * odirection(1) +
56 object->center(1);
57 box->at(3).x = half_length * direction(0) - half_width * odirection(0) +
58 object->center(0);
59 box->at(3).y = half_length * direction(1) - half_width * odirection(1) +
60 object->center(1);
61}
62
63void ComputeObjectShapeFromPolygon(std::shared_ptr<Object> object,
64 bool use_world_cloud) {
65 const PointCloud<PointD>& polygon = object->polygon;
66 const RadarPointCloud<RadarPointF>& cloud =
67 object->radar4d_supplement.cloud;
68 const RadarPointCloud<RadarPointD>& world_cloud =
69 object->radar4d_supplement.cloud_world;
70
71 if (polygon.empty() || cloud.empty()) {
72 AINFO << "Failed to compute box, polygon size: " << polygon.size()
73 << " cloud size: " << cloud.size();
74 return;
75 }
76
77 // note here we assume direction is not changed
78 Eigen::Vector2d polygon_xy;
79 Eigen::Vector2d projected_polygon_xy;
80 Eigen::Vector3d raw_direction = object->direction.cast<double>();
81 Eigen::Vector2d direction = raw_direction.head<2>();
82 Eigen::Vector2d odirection(-direction(1), direction(0));
83
84 constexpr double kDoubleMax = std::numeric_limits<double>::max();
85 Eigen::Vector2d min_polygon_xy(kDoubleMax, kDoubleMax);
86 Eigen::Vector2d max_polygon_xy(-kDoubleMax, -kDoubleMax);
87
88 // note we keep this offset to avoid numeric precision issues in world frame
89 Eigen::Vector2d offset(object->polygon[0].x, object->polygon[0].y);
90
91 for (const auto& point : object->polygon.points()) {
92 polygon_xy << point.x, point.y;
93 polygon_xy -= offset;
94 projected_polygon_xy(0) = direction.dot(polygon_xy);
95 projected_polygon_xy(1) = odirection.dot(polygon_xy);
96 min_polygon_xy(0) = std::min(min_polygon_xy(0), projected_polygon_xy(0));
97 min_polygon_xy(1) = std::min(min_polygon_xy(1), projected_polygon_xy(1));
98 max_polygon_xy(0) = std::max(max_polygon_xy(0), projected_polygon_xy(0));
99 max_polygon_xy(1) = std::max(max_polygon_xy(1), projected_polygon_xy(1));
100 }
101
102 double min_z = 0.0;
103 double max_z = 0.0;
104 if (use_world_cloud) {
105 min_z = world_cloud[0].z;
106 max_z = world_cloud[0].z;
107 for (const auto& point : world_cloud.points()) {
108 min_z = std::min(min_z, point.z);
109 max_z = std::max(max_z, point.z);
110 }
111 } else {
112 min_z = cloud[0].z;
113 max_z = cloud[0].z;
114 for (const auto& point : cloud.points()) {
115 min_z = std::min(min_z, static_cast<double>(point.z));
116 max_z = std::max(max_z, static_cast<double>(point.z));
117 }
118 }
119
120 // update size
121 object->size << static_cast<float>(max_polygon_xy(0) - min_polygon_xy(0)),
122 static_cast<float>(max_polygon_xy(1) - min_polygon_xy(1)),
123 static_cast<float>(max_z - min_z);
124 // for safety issues, set a default minmium value
125 object->size(0) = std::max(object->size(0), 0.01f);
126 object->size(1) = std::max(object->size(1), 0.01f);
127 object->size(2) = std::max(object->size(2), 0.01f);
128 // update center
129 projected_polygon_xy << (min_polygon_xy(0) + max_polygon_xy(0)) * 0.5,
130 (min_polygon_xy(1) + max_polygon_xy(1)) * 0.5;
131 polygon_xy = projected_polygon_xy(0) * direction +
132 projected_polygon_xy(1) * odirection;
133 object->center << polygon_xy(0) + offset(0), polygon_xy(1) + offset(1), min_z;
134}
135
136} // namespace radar4d
137} // namespace perception
138} // namespace apollo
const std::vector< RadarPointT > & points() const
const RadarPointT * at(size_t col, size_t row) const
#define AINFO
Definition log.h:42
RadarPoint< double > RadarPointD
Definition point.h:114
RadarPoint< float > RadarPointF
Definition point.h:113
Point< double > PointD
Definition point.h:57
void GetBoundingBox2d(const std::shared_ptr< Object > &object, RadarPointCloud< RadarPointD > *box, double expand)
void ComputeObjectShapeFromPolygon(std::shared_ptr< Object > object, bool use_world_cloud)
class register implement
Definition arena_queue.h:37