precomputation_grid_3d.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/3d/scan_matching/precomputation_grid_3d.h"
00018 
00019 #include <algorithm>
00020 
00021 #include "Eigen/Core"
00022 #include "cartographer/common/math.h"
00023 #include "cartographer/mapping/probability_values.h"
00024 #include "glog/logging.h"
00025 
00026 namespace cartographer {
00027 namespace mapping {
00028 namespace scan_matching {
00029 namespace {
00030 
00031 // C++11 defines that integer division rounds towards zero. For index math, we
00032 // actually need it to round towards negative infinity. Luckily bit shifts have
00033 // that property.
00034 inline int DivideByTwoRoundingTowardsNegativeInfinity(const int value) {
00035   return value >> 1;
00036 }
00037 
00038 // Computes the half resolution index corresponding to the full resolution
00039 // 'cell_index'.
00040 Eigen::Array3i CellIndexAtHalfResolution(const Eigen::Array3i& cell_index) {
00041   return Eigen::Array3i(
00042       DivideByTwoRoundingTowardsNegativeInfinity(cell_index[0]),
00043       DivideByTwoRoundingTowardsNegativeInfinity(cell_index[1]),
00044       DivideByTwoRoundingTowardsNegativeInfinity(cell_index[2]));
00045 }
00046 
00047 }  // namespace
00048 
00049 PrecomputationGrid3D ConvertToPrecomputationGrid(
00050     const HybridGrid& hybrid_grid) {
00051   PrecomputationGrid3D result(hybrid_grid.resolution());
00052   for (auto it = HybridGrid::Iterator(hybrid_grid); !it.Done(); it.Next()) {
00053     const int cell_value = common::RoundToInt(
00054         (ValueToProbability(it.GetValue()) - kMinProbability) *
00055         (255.f / (kMaxProbability - kMinProbability)));
00056     CHECK_GE(cell_value, 0);
00057     CHECK_LE(cell_value, 255);
00058     *result.mutable_value(it.GetCellIndex()) = cell_value;
00059   }
00060   return result;
00061 }
00062 
00063 PrecomputationGrid3D PrecomputeGrid(const PrecomputationGrid3D& grid,
00064                                     const bool half_resolution,
00065                                     const Eigen::Array3i& shift) {
00066   PrecomputationGrid3D result(grid.resolution());
00067   for (auto it = PrecomputationGrid3D::Iterator(grid); !it.Done(); it.Next()) {
00068     for (int i = 0; i != 8; ++i) {
00069       // We use this value to update 8 values in the resulting grid, at
00070       // position (x - {0, 'shift'}, y - {0, 'shift'}, z - {0, 'shift'}).
00071       // If 'shift' is 2 ** (depth - 1), where depth 0 is the original grid,
00072       // this results in precomputation grids analogous to the 2D case.
00073       const Eigen::Array3i cell_index =
00074           it.GetCellIndex() - shift * PrecomputationGrid3D::GetOctant(i);
00075       auto* const cell_value = result.mutable_value(
00076           half_resolution ? CellIndexAtHalfResolution(cell_index) : cell_index);
00077       *cell_value = std::max(it.GetValue(), *cell_value);
00078     }
00079   }
00080   return result;
00081 }
00082 
00083 }  // namespace scan_matching
00084 }  // namespace mapping
00085 }  // namespace cartographer


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