ceres_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/ceres_scan_matcher_2d.h"
00018 
00019 #include <utility>
00020 #include <vector>
00021 
00022 #include "Eigen/Core"
00023 #include "cartographer/common/ceres_solver_options.h"
00024 #include "cartographer/common/lua_parameter_dictionary.h"
00025 #include "cartographer/mapping/2d/grid_2d.h"
00026 #include "cartographer/mapping/internal/2d/scan_matching/occupied_space_cost_function_2d.h"
00027 #include "cartographer/mapping/internal/2d/scan_matching/rotation_delta_cost_functor_2d.h"
00028 #include "cartographer/mapping/internal/2d/scan_matching/translation_delta_cost_functor_2d.h"
00029 #include "cartographer/mapping/internal/2d/scan_matching/tsdf_match_cost_function_2d.h"
00030 #include "cartographer/transform/transform.h"
00031 #include "ceres/ceres.h"
00032 #include "glog/logging.h"
00033 
00034 namespace cartographer {
00035 namespace mapping {
00036 namespace scan_matching {
00037 
00038 proto::CeresScanMatcherOptions2D CreateCeresScanMatcherOptions2D(
00039     common::LuaParameterDictionary* const parameter_dictionary) {
00040   proto::CeresScanMatcherOptions2D options;
00041   options.set_occupied_space_weight(
00042       parameter_dictionary->GetDouble("occupied_space_weight"));
00043   options.set_translation_weight(
00044       parameter_dictionary->GetDouble("translation_weight"));
00045   options.set_rotation_weight(
00046       parameter_dictionary->GetDouble("rotation_weight"));
00047   *options.mutable_ceres_solver_options() =
00048       common::CreateCeresSolverOptionsProto(
00049           parameter_dictionary->GetDictionary("ceres_solver_options").get());
00050   return options;
00051 }
00052 
00053 CeresScanMatcher2D::CeresScanMatcher2D(
00054     const proto::CeresScanMatcherOptions2D& options)
00055     : options_(options),
00056       ceres_solver_options_(
00057           common::CreateCeresSolverOptions(options.ceres_solver_options())) {
00058   ceres_solver_options_.linear_solver_type = ceres::DENSE_QR;
00059 }
00060 
00061 CeresScanMatcher2D::~CeresScanMatcher2D() {}
00062 
00063 void CeresScanMatcher2D::Match(const Eigen::Vector2d& target_translation,
00064                                const transform::Rigid2d& initial_pose_estimate,
00065                                const sensor::PointCloud& point_cloud,
00066                                const Grid2D& grid,
00067                                transform::Rigid2d* const pose_estimate,
00068                                ceres::Solver::Summary* const summary) const {
00069   double ceres_pose_estimate[3] = {initial_pose_estimate.translation().x(),
00070                                    initial_pose_estimate.translation().y(),
00071                                    initial_pose_estimate.rotation().angle()};
00072   ceres::Problem problem;
00073   CHECK_GT(options_.occupied_space_weight(), 0.);
00074   switch (grid.GetGridType()) {
00075     case GridType::PROBABILITY_GRID:
00076       problem.AddResidualBlock(
00077           CreateOccupiedSpaceCostFunction2D(
00078               options_.occupied_space_weight() /
00079                   std::sqrt(static_cast<double>(point_cloud.size())),
00080               point_cloud, grid),
00081           nullptr /* loss function */, ceres_pose_estimate);
00082       break;
00083     case GridType::TSDF:
00084       problem.AddResidualBlock(
00085           CreateTSDFMatchCostFunction2D(
00086               options_.occupied_space_weight() /
00087                   std::sqrt(static_cast<double>(point_cloud.size())),
00088               point_cloud, static_cast<const TSDF2D&>(grid)),
00089           nullptr /* loss function */, ceres_pose_estimate);
00090       break;
00091   }
00092   CHECK_GT(options_.translation_weight(), 0.);
00093   problem.AddResidualBlock(
00094       TranslationDeltaCostFunctor2D::CreateAutoDiffCostFunction(
00095           options_.translation_weight(), target_translation),
00096       nullptr /* loss function */, ceres_pose_estimate);
00097   CHECK_GT(options_.rotation_weight(), 0.);
00098   problem.AddResidualBlock(
00099       RotationDeltaCostFunctor2D::CreateAutoDiffCostFunction(
00100           options_.rotation_weight(), ceres_pose_estimate[2]),
00101       nullptr /* loss function */, ceres_pose_estimate);
00102 
00103   ceres::Solve(ceres_solver_options_, &problem, summary);
00104 
00105   *pose_estimate = transform::Rigid2d(
00106       {ceres_pose_estimate[0], ceres_pose_estimate[1]}, ceres_pose_estimate[2]);
00107 }
00108 
00109 }  // namespace scan_matching
00110 }  // namespace mapping
00111 }  // namespace cartographer


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