Apollo 11.0
自动驾驶开放平台
ndt_map_matrix.h
浏览该文件的文档.
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
17#pragma once
18
19#include <limits>
20#include <memory>
21#include <unordered_map>
22#include <vector>
23
24#include "Eigen/Eigenvalues"
25
28
29namespace apollo {
30namespace localization {
31namespace msf {
32
35 public:
39 inline void Reset();
43 unsigned int LoadBinary(unsigned char* buf);
48 unsigned int CreateBinary(unsigned char* buf, unsigned int buf_size) const;
50 unsigned int GetBinarySize() const;
53
55 static void Reduce(NdtMapSingleCell* cell, const NdtMapSingleCell& cell_new);
56
58 inline void AddSample(const float intensity, const float altitude,
59 const Eigen::Vector3f centroid, bool is_road = false);
60
62 inline void MergeCell(const float intensity, const float intensity_var,
63 const unsigned int road_pt_count,
64 const unsigned int count,
65 const Eigen::Vector3f& centroid,
66 const Eigen::Matrix3f& centroid_cov);
67
68 inline void MergeCell(const NdtMapSingleCell& cell_new);
69
70 inline void CentroidEigenSolver(const Eigen::Matrix3f& centroid_cov);
71
72 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
73
74 public:
76 float intensity_ = 0;
78 float intensity_var_ = 0;
80 unsigned int road_pt_count_ = 0;
82 unsigned int count_ = 0;
83
85 Eigen::Vector3f centroid_;
87 Eigen::Matrix3f centroid_average_cov_;
89 Eigen::Matrix3f centroid_icov_;
91 unsigned char is_icov_available_ = 0;
93 const unsigned int minimum_points_threshold_ = 6;
94};
95
98 public:
100 NdtMapCells();
102 void Reset();
104 int AddSample(const float intensity, const float altitude,
105 const float resolution, const Eigen::Vector3f centroid,
106 bool is_road = false);
107
111 unsigned int LoadBinary(unsigned char* buf);
116 unsigned int CreateBinary(unsigned char* buf, unsigned int buf_size) const;
118 unsigned int GetBinarySize() const;
119
121 static int CalAltitudeIndex(const float resolution, const float altitude);
122
124 static float CalAltitude(const float resolution, const int altitude_index);
125
127 static void Reduce(NdtMapCells* cell, const NdtMapCells& cell_new);
128
129 public:
131 std::unordered_map<int, NdtMapSingleCell> cells_;
137 std::vector<int> road_cell_indices_;
138};
139
142 public:
144 NdtMapMatrix();
148 NdtMapMatrix(const NdtMapMatrix& cells);
149
151 virtual void Init(const BaseMapConfig* config);
153 virtual void Reset(const BaseMapConfig* config);
154
156 void Init(unsigned int rows, unsigned int cols);
158 void Reset(unsigned int rows, unsigned int cols);
162 virtual unsigned int LoadBinary(unsigned char* buf);
167 virtual unsigned int CreateBinary(unsigned char* buf,
168 unsigned int buf_size) const;
170 virtual unsigned int GetBinarySize() const;
171
172 virtual void GetIntensityImg(cv::Mat* intensity_img) const;
173
175 inline const NdtMapCells& GetMapCell(unsigned int row,
176 unsigned int col) const {
177 assert(row < rows_);
178 assert(col < cols_);
179 return map3d_cells_[row * cols_ + col];
180 }
182 inline NdtMapCells& GetMapCell(unsigned int row, unsigned int col) {
183 assert(row < rows_);
184 assert(col < cols_);
185 return map3d_cells_[row * cols_ + col];
186 }
188 unsigned int GetRows() const { return rows_; }
190 unsigned int GetCols() const { return cols_; }
191
193 static void Reduce(NdtMapMatrix* cells, const NdtMapMatrix& cells_new);
194
195 private:
197 unsigned int rows_;
199 unsigned int cols_;
201 std::unique_ptr<NdtMapCells[]> map3d_cells_;
202};
203
205 intensity_ = 0.0;
206 intensity_var_ = 0.0;
207 road_pt_count_ = 0;
208 count_ = 0;
209 centroid_ = Eigen::Vector3f::Zero();
210 centroid_average_cov_ = Eigen::Matrix3f::Zero();
211 centroid_icov_ = Eigen::Matrix3f::Identity();
212 is_icov_available_ = false;
213}
214
215inline void NdtMapSingleCell::AddSample(const float intensity,
216 const float altitude,
217 const Eigen::Vector3f centroid,
218 bool is_road) {
219 ++count_;
220 float v1 = intensity - intensity_;
221 intensity_ += v1 / static_cast<float>(count_);
222 float v2 = intensity - intensity_;
223 intensity_var_ = (static_cast<float>(count_ - 1) * intensity_var_ + v1 * v2) /
224 static_cast<float>(count_);
225
226 if (is_road) {
228 }
229
230 Eigen::Vector3f v3 = centroid - centroid_;
231 centroid_ += v3 / static_cast<float>(count_);
232 Eigen::Matrix3f v4 = centroid * centroid.transpose() - centroid_average_cov_;
233 centroid_average_cov_ += v4 / static_cast<float>(count_);
235}
236
237inline void NdtMapSingleCell::MergeCell(const float intensity,
238 const float intensity_var,
239 const unsigned int road_pt_count,
240 const unsigned int count,
241 const Eigen::Vector3f& centroid,
242 const Eigen::Matrix3f& centroid_cov) {
243 unsigned int new_count = count_ + count;
244 float p0 = static_cast<float>(count_) / static_cast<float>(new_count);
245 float p1 = static_cast<float>(count) / static_cast<float>(new_count);
246 float intensity_diff = intensity_ - intensity;
247
248 intensity_ = intensity_ * p0 + intensity * p1;
249 intensity_var_ = intensity_var_ * p0 + intensity_var * p1 +
250 intensity_diff * intensity_diff * p0 * p1;
251
252 centroid_[0] = centroid_[0] * p0 + centroid[0] * p1;
253 centroid_[1] = centroid_[1] * p0 + centroid[1] * p1;
254 centroid_[2] = centroid_[2] * p0 + centroid[2] * p1;
255
256 count_ = new_count;
257 road_pt_count_ += road_pt_count;
258}
259
260inline void NdtMapSingleCell::MergeCell(const NdtMapSingleCell& cell_new) {
261 MergeCell(cell_new.intensity_, cell_new.intensity_var_,
262 cell_new.road_pt_count_, cell_new.count_, cell_new.centroid_,
263 cell_new.centroid_average_cov_);
264}
265
267 const Eigen::Matrix3f& centroid_cov) {
268 // Contain more than five points, we calculate the eigen vector/value of cov.
269 // [Magnusson 2009]
271 Eigen::Matrix3f cov = centroid_cov - centroid_ * centroid_.transpose();
272 cov *= static_cast<float>((count_ - 1.0) / count_);
273 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigen_solver;
274 eigen_solver.compute(cov);
275 Eigen::Matrix3f eigen_val = eigen_solver.eigenvalues().asDiagonal();
276 Eigen::Matrix3f centroid_evecs = eigen_solver.eigenvectors();
277 if (eigen_val(0, 0) < 0 || eigen_val(1, 1) < 0 || eigen_val(2, 2) <= 0) {
279 return;
280 }
281 // Avoid matrices near singularities (eq 6.11) [Magnusson 2009].
282 float min_covar_eigvalue = 0.01f * eigen_val(2, 2);
283 if (eigen_val(0, 0) < min_covar_eigvalue) {
284 eigen_val(0, 0) = min_covar_eigvalue;
285 if (eigen_val(1, 1) < min_covar_eigvalue) {
286 eigen_val(1, 1) = min_covar_eigvalue;
287 }
288 }
289 // Calculate inverse covariance
291 (centroid_evecs * eigen_val * centroid_evecs.inverse()).inverse();
292 if (centroid_icov_.maxCoeff() == std::numeric_limits<float>::infinity() ||
293 centroid_icov_.minCoeff() == -std::numeric_limits<float>::infinity()) {
295 return;
296 }
297 // Set icov available
299 }
300}
301
302} // namespace msf
303} // namespace localization
304} // namespace apollo
The options of the reflectance map.
The data structure of the map cells in a map node.
The data structure of ndt Map cell.
void Reset()
Reset to default value.
int AddSample(const float intensity, const float altitude, const float resolution, const Eigen::Vector3f centroid, bool is_road=false)
Add an sample.
unsigned int GetBinarySize() const
Get the binary size of the object.
std::vector< int > road_cell_indices_
The indices of road surface.
static float CalAltitude(const float resolution, const int altitude_index)
Calculate altitude from altitude index.
unsigned int CreateBinary(unsigned char *buf, unsigned int buf_size) const
Create the binary.
int max_altitude_index_
The index of biggest altitude.
unsigned int LoadBinary(unsigned char *buf)
Load the map cell from a binary chunk.
static int CalAltitudeIndex(const float resolution, const float altitude)
Calculate altitude index from altitude.
static void Reduce(NdtMapCells *cell, const NdtMapCells &cell_new)
Combine two MapCell instances (Reduce).
std::unordered_map< int, NdtMapSingleCell > cells_
The multiple altitudes of the cell.
NdtMapCells()
The default constructor.
int min_altitude_index_
The index of smallest altitude.
The data structure of ndt Map matrix.
const NdtMapCells & GetMapCell(unsigned int row, unsigned int col) const
Get a const map cell.
unsigned int GetRows() const
Get the size of row.
virtual void Reset(const BaseMapConfig *config)
Reset the matrix item to default value.
virtual void GetIntensityImg(cv::Mat *intensity_img) const
get intensity image of node.
static void Reduce(NdtMapMatrix *cells, const NdtMapMatrix &cells_new)
Combine two NdtMapMatrix instances (Reduce).
virtual unsigned int LoadBinary(unsigned char *buf)
Load the map cell from a binary chunk.
virtual unsigned int GetBinarySize() const
Get the binary size of the object.
NdtMapCells & GetMapCell(unsigned int row, unsigned int col)
Get a map cell.
virtual void Init(const BaseMapConfig *config)
Initialize the matrix with the config.
unsigned int GetCols() const
Get the size of cols.
virtual unsigned int CreateBinary(unsigned char *buf, unsigned int buf_size) const
Create the binary.
The data structure of a single ndt map cell.
float intensity_var_
The variance intensity value.
NdtMapSingleCell & operator=(const NdtMapSingleCell &ref)
Overloading the assign operator.
unsigned int GetBinarySize() const
Get the binary size of the object.
void AddSample(const float intensity, const float altitude, const Eigen::Vector3f centroid, bool is_road=false)
Add an sample to the single 3d map cell.
unsigned char is_icov_available_
the inverse covariance available flag.
const unsigned int minimum_points_threshold_
minimum number of points needed.
Eigen::Vector3f centroid_
the centroid of the cell.
Eigen::Matrix3f centroid_icov_
the pose inverse covariance of the cell.
Eigen::Matrix3f centroid_average_cov_
the pose covariance of the cell.
unsigned int road_pt_count_
The number of samples belonging to road surface.
unsigned int CreateBinary(unsigned char *buf, unsigned int buf_size) const
Create the binary.
unsigned int LoadBinary(unsigned char *buf)
Load the map cell from a binary chunk.
unsigned int count_
The number of samples in the cell.
float intensity_
The average intensity value.
void CentroidEigenSolver(const Eigen::Matrix3f &centroid_cov)
static void Reduce(NdtMapSingleCell *cell, const NdtMapSingleCell &cell_new)
Combine two NdtMapSingleCell instances (Reduce).
void MergeCell(const float intensity, const float intensity_var, const unsigned int road_pt_count, const unsigned int count, const Eigen::Vector3f &centroid, const Eigen::Matrix3f &centroid_cov)
Merge two cells.
class register implement
Definition arena_queue.h:37