Apollo 10.0
自动驾驶开放平台
radar_point_cloud.h
浏览该文件的文档.
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
17#pragma once
18
19#include <cstdint>
20#include <limits>
21#include <memory>
22#include <utility>
23#include <vector>
24
25#include "Eigen/Dense"
26
27#include "cyber/common/log.h"
30
31namespace apollo {
32namespace perception {
33namespace base {
34
35template <class RadarPointT>
37 public:
38 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
39
40 public:
41 using PointType = RadarPointT;
42 // @brief default constructor
43 RadarPointCloud() = default;
44
45 // @brief construct from input point cloud and specified indices
47 const PointIndices& indices) {
48 CopyRadarPointCloud(pc, indices);
49 }
51 const std::vector<int>& indices) {
52 CopyRadarPointCloud(pc, indices);
53 }
54 // @brief construct given width and height for organized point cloud
56 size_t width,
57 size_t height,
58 RadarPointT point = RadarPointT())
60 points_.assign(width_ * height_, point);
61 }
62
63 // @brief destructor
64 virtual ~RadarPointCloud() = default;
65
66 // @brief accessor of point via 2d indices for organized cloud,
67 // @return nullptr for non-organized cloud
68 inline const RadarPointT* at(size_t col, size_t row) const {
69 return IsOrganized() ? &(points_[row * width_ + col]) : nullptr;
70 }
71 inline RadarPointT* at(size_t col, size_t row) {
72 return IsOrganized() ? &(points_[row * width_ + col]) : nullptr;
73 }
74 inline const RadarPointT* operator()(size_t col, size_t row) const {
75 return IsOrganized() ? &(points_[row * width_ + col]) : nullptr;
76 }
77 inline RadarPointT* operator()(size_t col, size_t row) {
78 return IsOrganized() ? &(points_[row * width_ + col]) : nullptr;
79 }
80 // @brief whether the cloud is organized
81 inline bool IsOrganized() const { return height_ > 1; }
82 // @brief accessor of point cloud height
83 inline size_t height() const { return height_; }
84 // @brief accessor of point cloud width
85 inline size_t width() const { return width_; }
86 // @brief accessor of point size, wrapper of vector
87 inline size_t size() const { return points_.size(); }
88 // @brief reserve function wrapper of vector
89 inline virtual void reserve(size_t size) { points_.reserve(size); }
90 // @brief empty function wrapper of vector
91 inline bool empty() const { return points_.empty(); }
92 // @brief resize function wrapper of vector
93 inline virtual void resize(size_t size) {
94 points_.resize(size);
95 if (size != width_ * height_) {
96 width_ = size;
97 height_ = 1;
98 }
99 }
100 // @brief accessor of point via 1d index
101 inline const RadarPointT& operator[](size_t n) const { return points_[n]; }
102 inline RadarPointT& operator[](size_t n) { return points_[n]; }
103 inline const RadarPointT& at(size_t n) const { return points_[n]; }
104 inline RadarPointT& at(size_t n) { return points_[n]; }
105 // @brief front accessor wrapper of vector
106 inline const RadarPointT& front() const { return points_.front(); }
107 inline RadarPointT& front() { return points_.front(); }
108 // @brief back accessor wrapper of vector
109 inline const RadarPointT& back() const { return points_.back(); }
110 inline RadarPointT& back() { return points_.back(); }
111 // @brief push_back function wrapper of vector
112 inline virtual void push_back(const RadarPointT& point) {
113 points_.push_back(point);
114 width_ = points_.size();
115 height_ = 1;
116 }
117 // @brief clear function wrapper of vector
118 inline virtual void clear() {
119 points_.clear();
120 width_ = height_ = 0;
121 }
122 // @brief swap point given source and target id
123 inline virtual bool SwapPoint(size_t source_id, size_t target_id) {
124 if (source_id < points_.size() && target_id < points_.size()) {
125 std::swap(points_[source_id], points_[target_id]);
126 width_ = points_.size();
127 height_ = 1;
128 return true;
129 }
130 return false;
131 }
132 // @brief copy point from another point cloud
133 inline bool CopyPoint(size_t id, size_t rhs_id,
134 const RadarPointCloud<RadarPointT>& rhs) {
135 if (id < points_.size() && rhs_id < rhs.points_.size()) {
136 points_[id] = rhs.points_[rhs_id];
137 return true;
138 }
139 return false;
140 }
141 // @brief copy point cloud
143 const PointIndices& indices) {
144 CopyRadarPointCloud(rhs, indices.indices);
145 }
146 template <typename IndexType>
148 const std::vector<IndexType>& indices) {
149 width_ = indices.size();
150 height_ = 1;
151 points_.resize(indices.size());
152 for (size_t i = 0; i < indices.size(); ++i) {
153 points_[i] = rhs.points_[indices[i]];
154 }
155 }
156 template <typename IndexType>
159 const std::vector<IndexType>& indices) {
160 width_ = indices.size();
161 height_ = 1;
162 points_.resize(rhs.size() - indices.size());
163 std::vector<bool> mask(false, rhs.size());
164 for (size_t i = 0; i < indices.size(); ++i) {
165 mask[indices[i]] = true;
166 }
167 for (size_t i = 0; i < rhs.size(); ++i) {
168 if (!mask[i]) {
169 points_.push_back(rhs.points_[i]);
170 }
171 }
172 }
173
174 // @brief swap point cloud
176 points_.swap(rhs->points_);
177 std::swap(width_, rhs->width_);
178 std::swap(height_, rhs->height_);
180 std::swap(timestamp_, rhs->timestamp_);
181 }
182 typedef typename std::vector<RadarPointT>::iterator iterator;
183 typedef typename std::vector<RadarPointT>::const_iterator const_iterator;
184 // @brief vector iterator
185 inline iterator begin() { return points_.begin(); }
186 inline iterator end() { return points_.end(); }
187 inline const_iterator begin() const { return points_.begin(); }
188 inline const_iterator end() const { return points_.end(); }
189 typename std::vector<RadarPointT>* mutable_points() { return &points_; }
190 const typename std::vector<RadarPointT>& points() const { return points_; }
191
192 // @brief cloud timestamp setter
193 void set_timestamp(const double timestamp) { timestamp_ = timestamp; }
194 // @brief cloud timestamp getter
195 double get_timestamp() { return timestamp_; }
196 // @brief sensor to world pose setter
200 // @brief sensor to world pose getter
201 const Eigen::Affine3d& sensor_to_world_pose() {
203 }
204 // @brief rotate the point cloud and set rotation part of pose to identity
205 void RotateRadarPointCloud(bool check_nan = false) {
206 Eigen::Vector3d point3d;
207 Eigen::Matrix3d rotation = sensor_to_world_pose_.linear();
208 for (auto& point : points_) {
209 if (!check_nan || (!std::isnan(point.x) && !std::isnan(point.y) &&
210 !std::isnan(point.z))) {
211 point3d << point.x, point.y, point.z;
212 point3d = rotation * point3d;
213 point.x = static_cast<typename RadarPointT::Type>(point3d(0));
214 point.y = static_cast<typename RadarPointT::Type>(point3d(1));
215 point.z = static_cast<typename RadarPointT::Type>(point3d(2));
216 }
217 }
218 sensor_to_world_pose_.linear().setIdentity();
219 }
220 // @brief transform the point cloud, set the pose to identity
221 void TransformRadarPointCloud(bool check_nan = false) {
222 Eigen::Vector3d point3d;
223 for (auto& point : points_) {
224 if (!check_nan || (!std::isnan(point.x) && !std::isnan(point.y) &&
225 !std::isnan(point.z))) {
226 point3d << point.x, point.y, point.z;
227 point3d = sensor_to_world_pose_ * point3d;
228 point.x = static_cast<typename RadarPointT::Type>(point3d(0));
229 point.y = static_cast<typename RadarPointT::Type>(point3d(1));
230 point.z = static_cast<typename RadarPointT::Type>(point3d(2));
231 }
232 }
233 sensor_to_world_pose_.setIdentity();
234 }
235
236 // @brief transform the point cloud and save to another pc
237 void TransformRadarPointCloud(const Eigen::Affine3f& transform,
239 bool check_nan = false) const {
240 Eigen::Vector3f point3f;
241 RadarPointT pt;
242 for (auto& point : points_) {
243 if (!check_nan || (!std::isnan(point.x) && !std::isnan(point.y) &&
244 !std::isnan(point.z))) {
245 point3f << point.x, point.y, point.z;
246 point3f = transform * point3f;
247 pt.x = static_cast<typename RadarPointT::Type>(point3f(0));
248 pt.y = static_cast<typename RadarPointT::Type>(point3f(1));
249 pt.z = static_cast<typename RadarPointT::Type>(point3f(2));
250 out->push_back(pt);
251 }
252 }
253 }
254 // @brief check data member consistency
255 virtual bool CheckConsistency() const { return true; }
256
257 protected:
258 std::vector<RadarPointT> points_;
259 size_t width_ = 0;
260 size_t height_ = 0;
261
262 Eigen::Affine3d sensor_to_world_pose_ = Eigen::Affine3d::Identity();
263 double timestamp_ = 0.0;
264};
265
266// @brief Point cloud class split points and attributes storage
267// for fast traversing
268template <class RadarPointT>
269class AttributeRadarPointCloud : public RadarPointCloud<RadarPointT> {
270 public:
271 using RadarPointCloud<RadarPointT>::points_;
272 using RadarPointCloud<RadarPointT>::width_;
273 using RadarPointCloud<RadarPointT>::height_;
274 using RadarPointCloud<RadarPointT>::IsOrganized;
276 using RadarPointCloud<RadarPointT>::timestamp_;
277 // @brief default constructor
279
280 // @brief construct from input point cloud and specified indices
286 const std::vector<int>& indices) {
287 CopyRadarPointCloud(pc, indices);
288 }
289 // @brief construct given width and height for organized point cloud
290 AttributeRadarPointCloud(const size_t width, const size_t height,
291 const RadarPointT point = RadarPointT()) {
292 width_ = width;
293 height_ = height;
294 if (width_ > 0 && height_ > SIZE_MAX / width_) {
295 AFATAL << "overflow detected.";
296 exit(1);
297 }
298 size_t size = width_ * height_;
299 points_.assign(size, point);
300 }
301 // @brief destructor
302 virtual ~AttributeRadarPointCloud() = default;
303 // @brief add points of input cloud, return the self cloud
306 points_.insert(points_.end(), rhs.points_.begin(), rhs.points_.end());
307 width_ = width_ * height_ + rhs.width_ * rhs.height_;
308 height_ = 1;
309 return *this;
310 }
311 // @brief overrided reserve function wrapper of vector
312 inline void reserve(const size_t size) override {
313 points_.reserve(size);
314 }
315 // @brief overrided resize function wrapper of vector
316 inline void resize(const size_t size) override {
317 points_.resize(size);
318 if (size != width_ * height_) {
319 width_ = size;
320 height_ = 1;
321 }
322 }
323 // @brief overrided push_back function wrapper of vector
324 inline void push_back(const RadarPointT& point) override {
325 points_.push_back(point);
326 width_ = points_.size();
327 height_ = 1;
328 }
329 inline void push_back(const RadarPointT& point, double timestamp,
330 float height = std::numeric_limits<float>::max(),
331 int32_t beam_id = -1, uint8_t label = 0) {
332 points_.push_back(point);
333 width_ = points_.size();
334 height_ = 1;
335 }
336 // @brief overrided clear function wrapper of vector
337 inline void clear() override {
338 points_.clear();
339 width_ = height_ = 0;
340 }
341 // @brief overrided swap point given source and target id
342 inline bool SwapPoint(const size_t source_id,
343 const size_t target_id) override {
344 if (source_id < points_.size() && target_id < points_.size()) {
345 std::swap(points_[source_id], points_[target_id]);
346 width_ = points_.size();
347 height_ = 1;
348 return true;
349 }
350 return false;
351 }
352 // @brief copy point from another point cloud
353 inline bool CopyPoint(const size_t id, const size_t rhs_id,
355 if (id < points_.size() && rhs_id < rhs.points_.size()) {
356 points_[id] = rhs.points_[rhs_id];
357 return true;
358 }
359 return false;
360 }
361 // @brief copy point cloud
364 const PointIndices& indices) {
365 CopyRadarPointCloud(rhs, indices.indices);
366 }
367 template <typename IndexType>
370 const std::vector<IndexType>& indices) {
371 width_ = indices.size();
372 height_ = 1;
373 points_.resize(indices.size());
374 for (size_t i = 0; i < indices.size(); ++i) {
375 points_[i] = rhs.points_[indices[i]];
376 }
377 }
378
379 // @brief swap point cloud
381 points_.swap(rhs->points_);
382 std::swap(width_, rhs->width_);
383 std::swap(height_, rhs->height_);
385 std::swap(timestamp_, rhs->timestamp_);
386 }
387 // @brief overrided check data member consistency
388 bool CheckConsistency() const override {
389 return true;
390 }
391
392 size_t TransferToIndex(const size_t col, const size_t row) const {
393 return row * width_ + col;
394 }
395};
396
397// typedef of point cloud indices
398typedef std::shared_ptr<PointIndices> PointIndicesPtr;
399typedef std::shared_ptr<const PointIndices> PointIndicesConstPtr;
400
401// typedef of point cloud
404
405typedef std::shared_ptr<RadarPointFCloud> RadarPointFCloudPtr;
406typedef std::shared_ptr<const RadarPointFCloud> RadarPointFCloudConstPtr;
407
408typedef std::shared_ptr<RadarPointDCloud> RadarPointDCloudPtr;
409typedef std::shared_ptr<const RadarPointDCloud> RadarPointDCloudConstPtr;
410
411// typedef of polygon
414
415typedef std::shared_ptr<RadarPolygonFType> RadarPolygonFTypePtr;
416typedef std::shared_ptr<const RadarPolygonFType> RadarPolygonFTypeConstPtr;
417
418typedef std::shared_ptr<RadarPolygonDType> RadarPolygonDTypePtr;
419typedef std::shared_ptr<const RadarPolygonDType> RadarPolygonDTypeConstPtr;
420
421} // namespace base
422} // namespace perception
423} // namespace apollo
void push_back(const RadarPointT &point, double timestamp, float height=std::numeric_limits< float >::max(), int32_t beam_id=-1, uint8_t label=0)
AttributeRadarPointCloud(const size_t width, const size_t height, const RadarPointT point=RadarPointT())
AttributeRadarPointCloud(const AttributeRadarPointCloud< RadarPointT > &pc, const std::vector< int > &indices)
AttributeRadarPointCloud(const AttributeRadarPointCloud< RadarPointT > &pc, const PointIndices &indices)
bool CopyPoint(const size_t id, const size_t rhs_id, const AttributeRadarPointCloud< RadarPointT > &rhs)
void push_back(const RadarPointT &point) override
void SwapRadarPointCloud(AttributeRadarPointCloud< RadarPointT > *rhs)
AttributeRadarPointCloud & operator+=(const AttributeRadarPointCloud< RadarPointT > &rhs)
bool SwapPoint(const size_t source_id, const size_t target_id) override
size_t TransferToIndex(const size_t col, const size_t row) const
void CopyRadarPointCloud(const AttributeRadarPointCloud< RadarPointT > &rhs, const PointIndices &indices)
void CopyRadarPointCloud(const AttributeRadarPointCloud< RadarPointT > &rhs, const std::vector< IndexType > &indices)
virtual bool SwapPoint(size_t source_id, size_t target_id)
void CopyRadarPointCloud(const RadarPointCloud< RadarPointT > &rhs, const PointIndices &indices)
void set_sensor_to_world_pose(const Eigen::Affine3d &sensor_to_world_pose)
bool CopyPoint(size_t id, size_t rhs_id, const RadarPointCloud< RadarPointT > &rhs)
void TransformRadarPointCloud(const Eigen::Affine3f &transform, RadarPointCloud< RadarPointT > *out, bool check_nan=false) const
std::vector< RadarPointT > * mutable_points()
virtual void push_back(const RadarPointT &point)
const std::vector< RadarPointT > & points() const
void set_timestamp(const double timestamp)
const RadarPointT & operator[](size_t n) const
const RadarPointT & at(size_t n) const
std::vector< RadarPointT >::const_iterator const_iterator
const RadarPointT * operator()(size_t col, size_t row) const
RadarPointCloud(const RadarPointCloud< RadarPointT > &pc, const std::vector< int > &indices)
RadarPointT * operator()(size_t col, size_t row)
RadarPointCloud(size_t width, size_t height, RadarPointT point=RadarPointT())
RadarPointCloud(const RadarPointCloud< RadarPointT > &pc, const PointIndices &indices)
void RotateRadarPointCloud(bool check_nan=false)
void TransformRadarPointCloud(bool check_nan=false)
const RadarPointT * at(size_t col, size_t row) const
void SwapRadarPointCloud(RadarPointCloud< RadarPointT > *rhs)
void CopyRadarPointCloudExclude(const RadarPointCloud< RadarPointT > &rhs, const std::vector< IndexType > &indices)
RadarPointT * at(size_t col, size_t row)
std::vector< RadarPointT >::iterator iterator
void CopyRadarPointCloud(const RadarPointCloud< RadarPointT > &rhs, const std::vector< IndexType > &indices)
#define AFATAL
Definition log.h:45
std::shared_ptr< RadarPointFCloud > RadarPointFCloudPtr
std::shared_ptr< RadarPolygonDType > RadarPolygonDTypePtr
AttributeRadarPointCloud< RadarPointF > RadarPointFCloud
AttributeRadarPointCloud< RadarPointD > RadarPointDCloud
std::shared_ptr< RadarPointDCloud > RadarPointDCloudPtr
std::shared_ptr< const RadarPolygonDType > RadarPolygonDTypeConstPtr
RadarPointCloud< PointD > RadarPolygonDType
std::shared_ptr< const RadarPolygonFType > RadarPolygonFTypeConstPtr
RadarPointCloud< PointF > RadarPolygonFType
std::shared_ptr< RadarPolygonFType > RadarPolygonFTypePtr
std::shared_ptr< PointIndices > PointIndicesPtr
std::shared_ptr< const RadarPointFCloud > RadarPointFCloudConstPtr
std::shared_ptr< const RadarPointDCloud > RadarPointDCloudConstPtr
std::shared_ptr< const PointIndices > PointIndicesConstPtr
class register implement
Definition arena_queue.h:37