correlative_scan_matcher_2d.cc
Go to the documentation of this file.
00001 /*
00002  * Copyright 2016 The Cartographer Authors
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "cartographer/mapping/internal/2d/scan_matching/correlative_scan_matcher_2d.h"
00018 
00019 #include <cmath>
00020 
00021 #include "cartographer/common/math.h"
00022 
00023 namespace cartographer {
00024 namespace mapping {
00025 namespace scan_matching {
00026 
00027 SearchParameters::SearchParameters(const double linear_search_window,
00028                                    const double angular_search_window,
00029                                    const sensor::PointCloud& point_cloud,
00030                                    const double resolution)
00031     : resolution(resolution) {
00032   // We set this value to something on the order of resolution to make sure that
00033   // the std::acos() below is defined.
00034   float max_scan_range = 3.f * resolution;
00035   for (const sensor::RangefinderPoint& point : point_cloud) {
00036     const float range = point.position.head<2>().norm();
00037     max_scan_range = std::max(range, max_scan_range);
00038   }
00039   const double kSafetyMargin = 1. - 1e-3;
00040   angular_perturbation_step_size =
00041       kSafetyMargin * std::acos(1. - common::Pow2(resolution) /
00042                                          (2. * common::Pow2(max_scan_range)));
00043   num_angular_perturbations =
00044       std::ceil(angular_search_window / angular_perturbation_step_size);
00045   num_scans = 2 * num_angular_perturbations + 1;
00046 
00047   const int num_linear_perturbations =
00048       std::ceil(linear_search_window / resolution);
00049   linear_bounds.reserve(num_scans);
00050   for (int i = 0; i != num_scans; ++i) {
00051     linear_bounds.push_back(
00052         LinearBounds{-num_linear_perturbations, num_linear_perturbations,
00053                      -num_linear_perturbations, num_linear_perturbations});
00054   }
00055 }
00056 
00057 SearchParameters::SearchParameters(const int num_linear_perturbations,
00058                                    const int num_angular_perturbations,
00059                                    const double angular_perturbation_step_size,
00060                                    const double resolution)
00061     : num_angular_perturbations(num_angular_perturbations),
00062       angular_perturbation_step_size(angular_perturbation_step_size),
00063       resolution(resolution),
00064       num_scans(2 * num_angular_perturbations + 1) {
00065   linear_bounds.reserve(num_scans);
00066   for (int i = 0; i != num_scans; ++i) {
00067     linear_bounds.push_back(
00068         LinearBounds{-num_linear_perturbations, num_linear_perturbations,
00069                      -num_linear_perturbations, num_linear_perturbations});
00070   }
00071 }
00072 
00073 void SearchParameters::ShrinkToFit(const std::vector<DiscreteScan2D>& scans,
00074                                    const CellLimits& cell_limits) {
00075   CHECK_EQ(scans.size(), num_scans);
00076   CHECK_EQ(linear_bounds.size(), num_scans);
00077   for (int i = 0; i != num_scans; ++i) {
00078     Eigen::Array2i min_bound = Eigen::Array2i::Zero();
00079     Eigen::Array2i max_bound = Eigen::Array2i::Zero();
00080     for (const Eigen::Array2i& xy_index : scans[i]) {
00081       min_bound = min_bound.min(-xy_index);
00082       max_bound = max_bound.max(Eigen::Array2i(cell_limits.num_x_cells - 1,
00083                                                cell_limits.num_y_cells - 1) -
00084                                 xy_index);
00085     }
00086     linear_bounds[i].min_x = std::max(linear_bounds[i].min_x, min_bound.x());
00087     linear_bounds[i].max_x = std::min(linear_bounds[i].max_x, max_bound.x());
00088     linear_bounds[i].min_y = std::max(linear_bounds[i].min_y, min_bound.y());
00089     linear_bounds[i].max_y = std::min(linear_bounds[i].max_y, max_bound.y());
00090   }
00091 }
00092 
00093 std::vector<sensor::PointCloud> GenerateRotatedScans(
00094     const sensor::PointCloud& point_cloud,
00095     const SearchParameters& search_parameters) {
00096   std::vector<sensor::PointCloud> rotated_scans;
00097   rotated_scans.reserve(search_parameters.num_scans);
00098 
00099   double delta_theta = -search_parameters.num_angular_perturbations *
00100                        search_parameters.angular_perturbation_step_size;
00101   for (int scan_index = 0; scan_index < search_parameters.num_scans;
00102        ++scan_index,
00103            delta_theta += search_parameters.angular_perturbation_step_size) {
00104     rotated_scans.push_back(sensor::TransformPointCloud(
00105         point_cloud, transform::Rigid3f::Rotation(Eigen::AngleAxisf(
00106                          delta_theta, Eigen::Vector3f::UnitZ()))));
00107   }
00108   return rotated_scans;
00109 }
00110 
00111 std::vector<DiscreteScan2D> DiscretizeScans(
00112     const MapLimits& map_limits, const std::vector<sensor::PointCloud>& scans,
00113     const Eigen::Translation2f& initial_translation) {
00114   std::vector<DiscreteScan2D> discrete_scans;
00115   discrete_scans.reserve(scans.size());
00116   for (const sensor::PointCloud& scan : scans) {
00117     discrete_scans.emplace_back();
00118     discrete_scans.back().reserve(scan.size());
00119     for (const sensor::RangefinderPoint& point : scan) {
00120       const Eigen::Vector2f translated_point =
00121           Eigen::Affine2f(initial_translation) * point.position.head<2>();
00122       discrete_scans.back().push_back(
00123           map_limits.GetCellIndex(translated_point));
00124     }
00125   }
00126   return discrete_scans;
00127 }
00128 
00129 }  // namespace scan_matching
00130 }  // namespace mapping
00131 }  // namespace cartographer


cartographer
Author(s): The Cartographer Authors
autogenerated on Thu May 9 2019 02:27:35