mapping_3d/scan_matching/real_time_correlative_scan_matcher.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2016 The Cartographer Authors
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 <cmath>
20 
21 #include "Eigen/Geometry"
24 #include "glog/logging.h"
25 
26 namespace cartographer {
27 namespace mapping_3d {
28 namespace scan_matching {
29 
31  const mapping_2d::scan_matching::proto::
32  RealTimeCorrelativeScanMatcherOptions& options)
33  : options_(options) {}
34 
36  const transform::Rigid3d& initial_pose_estimate,
37  const sensor::PointCloud& point_cloud, const HybridGrid& hybrid_grid,
38  transform::Rigid3d* pose_estimate) const {
39  CHECK_NOTNULL(pose_estimate);
40  float best_score = -1.f;
42  hybrid_grid.resolution(), point_cloud)) {
43  const transform::Rigid3f candidate =
44  initial_pose_estimate.cast<float>() * transform;
45  const float score = ScoreCandidate(
46  hybrid_grid, sensor::TransformPointCloud(point_cloud, candidate),
47  transform);
48  if (score > best_score) {
49  best_score = score;
50  *pose_estimate = candidate.cast<double>();
51  }
52  }
53  return best_score;
54 }
55 
56 std::vector<transform::Rigid3f>
58  const float resolution, const sensor::PointCloud& point_cloud) const {
59  std::vector<transform::Rigid3f> result;
60  const int linear_window_size =
61  common::RoundToInt(options_.linear_search_window() / resolution);
62  // We set this value to something on the order of resolution to make sure that
63  // the std::acos() below is defined.
64  float max_scan_range = 3.f * resolution;
65  for (const Eigen::Vector3f& point : point_cloud) {
66  const float range = point.norm();
67  max_scan_range = std::max(range, max_scan_range);
68  }
69  const float kSafetyMargin = 1.f - 1e-3f;
70  const float angular_step_size =
71  kSafetyMargin * std::acos(1.f - common::Pow2(resolution) /
72  (2.f * common::Pow2(max_scan_range)));
73  const int angular_window_size =
74  common::RoundToInt(options_.angular_search_window() / angular_step_size);
75  for (int z = -linear_window_size; z <= linear_window_size; ++z) {
76  for (int y = -linear_window_size; y <= linear_window_size; ++y) {
77  for (int x = -linear_window_size; x <= linear_window_size; ++x) {
78  for (int rz = -angular_window_size; rz <= angular_window_size; ++rz) {
79  for (int ry = -angular_window_size; ry <= angular_window_size; ++ry) {
80  for (int rx = -angular_window_size; rx <= angular_window_size;
81  ++rx) {
82  const Eigen::Vector3f angle_axis(rx * angular_step_size,
83  ry * angular_step_size,
84  rz * angular_step_size);
85  result.emplace_back(
86  Eigen::Vector3f(x * resolution, y * resolution,
87  z * resolution),
89  }
90  }
91  }
92  }
93  }
94  }
95  return result;
96 }
97 
99  const HybridGrid& hybrid_grid,
100  const sensor::PointCloud& transformed_point_cloud,
101  const transform::Rigid3f& transform) const {
102  float score = 0.f;
103  for (const Eigen::Vector3f& point : transformed_point_cloud) {
104  score += hybrid_grid.GetProbability(hybrid_grid.GetCellIndex(point));
105  }
106  score /= static_cast<float>(transformed_point_cloud.size());
107  const float angle = transform::GetAngle(transform);
108  score *=
109  std::exp(-common::Pow2(transform.translation().norm() *
110  options_.translation_delta_cost_weight() +
111  angle * options_.rotation_delta_cost_weight()));
112  CHECK_GT(score, 0.f);
113  return score;
114 }
115 
116 } // namespace scan_matching
117 } // namespace mapping_3d
118 } // namespace cartographer
proto::RangeDataInserterOptions options_
PointCloud TransformPointCloud(const PointCloud &point_cloud, const transform::Rigid3f &transform)
Definition: point_cloud.cc:25
Eigen::Quaternion< T > AngleAxisVectorToRotationQuaternion(const Eigen::Matrix< T, 3, 1 > &angle_axis)
Definition: transform.h:86
Eigen::Array3i GetCellIndex(const Eigen::Vector3f &point) const
Definition: hybrid_grid.h:428
constexpr T Pow2(T a)
Definition: math.h:50
float ScoreCandidate(const HybridGrid &hybrid_grid, const sensor::PointCloud &transformed_point_cloud, const transform::Rigid3f &transform) const
float GetProbability(const Eigen::Array3i &index) const
Definition: hybrid_grid.h:518
int RoundToInt(const float x)
Definition: port.h:42
Rigid3< OtherType > cast() const
float angle
const mapping_2d::scan_matching::proto::RealTimeCorrelativeScanMatcherOptions options_
const Vector & translation() const
std::vector< Eigen::Vector3f > PointCloud
Definition: point_cloud.h:30
std::vector< transform::Rigid3f > GenerateExhaustiveSearchTransforms(float resolution, const sensor::PointCloud &point_cloud) const
FloatType GetAngle(const Rigid3< FloatType > &transform)
Definition: transform.h:34
float Match(const transform::Rigid3d &initial_pose_estimate, const sensor::PointCloud &point_cloud, const HybridGrid &hybrid_grid, transform::Rigid3d *pose_estimate) const
RealTimeCorrelativeScanMatcher(const mapping_2d::scan_matching::proto::RealTimeCorrelativeScanMatcherOptions &options)


cartographer
Author(s):
autogenerated on Wed Jun 5 2019 21:57:58