Apollo  6.0
Open source self driving car software
ndt_map_matrix.h
Go to the documentation of this file.
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 
29 namespace apollo {
30 namespace localization {
31 namespace 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 
91  unsigned char is_icov_available_ = 0;
93  const unsigned int minimum_points_threshold_ = 6;
94 };
95 
97 class NdtMapCells {
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 
141 class NdtMapMatrix : public BaseMapMatrix {
142  public:
144  NdtMapMatrix();
146  ~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 
204 inline void NdtMapSingleCell::Reset() {
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 
215 inline 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) {
227  ++road_pt_count_;
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 
237 inline 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 
260 inline 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) {
278  is_icov_available_ = 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()) {
294  is_icov_available_ = 0;
295  return;
296  }
297  // Set icov available
298  is_icov_available_ = 1;
299  }
300 }
301 
302 } // namespace msf
303 } // namespace localization
304 } // namespace apollo
NdtMapCells & GetMapCell(unsigned int row, unsigned int col)
Get a map cell.
Definition: ndt_map_matrix.h:182
float intensity_var_
The variance intensity value.
Definition: ndt_map_matrix.h:78
NdtMapSingleCell & operator=(const NdtMapSingleCell &ref)
Overloading the assign operator.
unsigned char is_icov_available_
the inverse covariance available flag.
Definition: ndt_map_matrix.h:91
const unsigned int minimum_points_threshold_
minimum number of points needed.
Definition: ndt_map_matrix.h:93
void Reset()
Reset to default value.
Definition: ndt_map_matrix.h:204
The data structure of ndt Map matrix.
Definition: ndt_map_matrix.h:141
unsigned int GetRows() const
Get the size of row.
Definition: ndt_map_matrix.h:188
The options of the reflectance map.
Definition: base_map_config.h:32
Eigen::Vector3f Vector3f
Definition: base_map_fwd.h:29
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
Eigen::Matrix3f centroid_average_cov_
the pose covariance of the cell.
Definition: ndt_map_matrix.h:87
apollo::localization::msf::pyramid_map::NdtMapMatrix NdtMapMatrix
Definition: lidar_locator_ndt.h:71
int max_altitude_index_
The index of biggest altitude.
Definition: ndt_map_matrix.h:133
Eigen::Matrix3f Matrix3f
Definition: base_map_fwd.h:27
void CentroidEigenSolver(const Eigen::Matrix3f &centroid_cov)
Definition: ndt_map_matrix.h:266
std::unordered_map< int, NdtMapSingleCell > cells_
The multiple altitudes of the cell.
Definition: ndt_map_matrix.h:131
unsigned int GetBinarySize() const
Get the binary size of the object.
unsigned int count_
The number of samples in the cell.
Definition: ndt_map_matrix.h:82
The data structure of the map cells in a map node.
Definition: base_map_matrix.h:28
std::vector< int > road_cell_indices_
The indices of road surface.
Definition: ndt_map_matrix.h:137
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.
Definition: ndt_map_matrix.h:237
unsigned int road_pt_count_
The number of samples belonging to road surface.
Definition: ndt_map_matrix.h:80
bool Init(const char *binary_name)
Eigen::Vector3f centroid_
the centroid of the cell.
Definition: ndt_map_matrix.h:85
Eigen::Matrix3f centroid_icov_
the pose inverse covariance of the cell.
Definition: ndt_map_matrix.h:89
NdtMapSingleCell()
The default constructor.
The data structure of ndt Map cell.
Definition: ndt_map_matrix.h:97
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.
Definition: ndt_map_matrix.h:215
unsigned int LoadBinary(unsigned char *buf)
Load the map cell from a binary chunk.
static void Reduce(NdtMapSingleCell *cell, const NdtMapSingleCell &cell_new)
Combine two NdtMapSingleCell instances (Reduce).
unsigned int CreateBinary(unsigned char *buf, unsigned int buf_size) const
Create the binary. Serialization of the object.
The data structure of a single ndt map cell.
Definition: ndt_map_matrix.h:34
const NdtMapCells & GetMapCell(unsigned int row, unsigned int col) const
Get a const map cell.
Definition: ndt_map_matrix.h:175
int min_altitude_index_
The index of smallest altitude.
Definition: ndt_map_matrix.h:135
unsigned int GetCols() const
Get the size of cols.
Definition: ndt_map_matrix.h:190
float intensity_
The average intensity value.
Definition: ndt_map_matrix.h:76
apollo::localization::msf::pyramid_map::NdtMapCells NdtMapCells
Definition: lidar_locator_ndt.h:69