grid_2d.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2018 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  */
17 
19 
20 namespace cartographer {
21 namespace mapping {
22 
23 proto::GridOptions2D CreateGridOptions2D(
24  common::LuaParameterDictionary* const parameter_dictionary) {
25  proto::GridOptions2D options;
26  const std::string grid_type_string =
27  parameter_dictionary->GetString("grid_type");
28  proto::GridOptions2D_GridType grid_type;
29  CHECK(proto::GridOptions2D_GridType_Parse(grid_type_string, &grid_type))
30  << "Unknown GridOptions2D_GridType kind: " << grid_type_string;
31  options.set_grid_type(grid_type);
32  options.set_resolution(parameter_dictionary->GetDouble("resolution"));
33  return options;
34 }
35 
36 Grid2D::Grid2D(const MapLimits& limits, float min_correspondence_cost,
37  float max_correspondence_cost)
38  : limits_(limits),
39  correspondence_cost_cells_(
40  limits_.cell_limits().num_x_cells * limits_.cell_limits().num_y_cells,
42  min_correspondence_cost_(min_correspondence_cost),
43  max_correspondence_cost_(max_correspondence_cost) {
45 }
46 
47 Grid2D::Grid2D(const proto::Grid2D& proto)
49  if (proto.has_known_cells_box()) {
50  const auto& box = proto.known_cells_box();
52  Eigen::AlignedBox2i(Eigen::Vector2i(box.min_x(), box.min_y()),
53  Eigen::Vector2i(box.max_x(), box.max_y()));
54  }
55  correspondence_cost_cells_.reserve(proto.cells_size());
56  for (const auto& cell : proto.cells()) {
57  CHECK_LE(cell, std::numeric_limits<uint16>::max());
58  correspondence_cost_cells_.push_back(cell);
59  }
60  if (proto.min_correspondence_cost() == 0.f &&
61  proto.max_correspondence_cost() == 0.f) {
62  LOG(WARNING)
63  << "proto::Grid2D: max_correspondence_cost and min_correspondence_cost "
64  "are initialized with 0 indicating an older version of the "
65  "protobuf format. Loading default values.";
68  } else {
69  min_correspondence_cost_ = proto.min_correspondence_cost();
70  max_correspondence_cost_ = proto.max_correspondence_cost();
71  }
73 }
74 
75 // Finishes the update sequence.
77  while (!update_indices_.empty()) {
81  update_indices_.pop_back();
82  }
83 }
84 
85 // Returns the correspondence cost of the cell with 'cell_index'.
86 float Grid2D::GetCorrespondenceCost(const Eigen::Array2i& cell_index) const {
87  if (!limits().Contains(cell_index)) return kMaxCorrespondenceCost;
89  correspondence_cost_cells()[ToFlatIndex(cell_index)]);
90 }
91 
92 // Returns true if the correspondence cost at the specified index is known.
93 bool Grid2D::IsKnown(const Eigen::Array2i& cell_index) const {
94  return limits_.Contains(cell_index) &&
97 }
98 
99 // Fills in 'offset' and 'limits' to define a subregion of that contains all
100 // known cells.
101 void Grid2D::ComputeCroppedLimits(Eigen::Array2i* const offset,
102  CellLimits* const limits) const {
103  if (known_cells_box_.isEmpty()) {
104  *offset = Eigen::Array2i::Zero();
105  *limits = CellLimits(1, 1);
106  return;
107  }
108  *offset = known_cells_box_.min().array();
109  *limits = CellLimits(known_cells_box_.sizes().x() + 1,
110  known_cells_box_.sizes().y() + 1);
111 }
112 
113 // Grows the map as necessary to include 'point'. This changes the meaning of
114 // these coordinates going forward. This method must be called immediately
115 // after 'FinishUpdate', before any calls to 'ApplyLookupTable'.
116 void Grid2D::GrowLimits(const Eigen::Vector2f& point) {
117  CHECK(update_indices_.empty());
118  while (!limits_.Contains(limits_.GetCellIndex(point))) {
119  const int x_offset = limits_.cell_limits().num_x_cells / 2;
120  const int y_offset = limits_.cell_limits().num_y_cells / 2;
121  const MapLimits new_limits(
123  limits_.max() +
124  limits_.resolution() * Eigen::Vector2d(y_offset, x_offset),
127  const int stride = new_limits.cell_limits().num_x_cells;
128  const int offset = x_offset + stride * y_offset;
129  const int new_size = new_limits.cell_limits().num_x_cells *
130  new_limits.cell_limits().num_y_cells;
131  std::vector<uint16> new_cells(new_size, kUnknownCorrespondenceValue);
132  for (int i = 0; i < limits_.cell_limits().num_y_cells; ++i) {
133  for (int j = 0; j < limits_.cell_limits().num_x_cells; ++j) {
134  new_cells[offset + j + i * stride] =
137  }
138  }
139  correspondence_cost_cells_ = new_cells;
140  limits_ = new_limits;
141  if (!known_cells_box_.isEmpty()) {
142  known_cells_box_.translate(Eigen::Vector2i(x_offset, y_offset));
143  }
144  }
145 }
146 
147 proto::Grid2D Grid2D::ToProto() const {
148  proto::Grid2D result;
149  *result.mutable_limits() = mapping::ToProto(limits_);
150  result.mutable_cells()->Reserve(correspondence_cost_cells_.size());
151  for (const auto& cell : correspondence_cost_cells_) {
152  result.mutable_cells()->Add(cell);
153  }
154  CHECK(update_indices().empty()) << "Serializing a grid during an update is "
155  "not supported. Finish the update first.";
156  if (!known_cells_box().isEmpty()) {
157  auto* const box = result.mutable_known_cells_box();
158  box->set_max_x(known_cells_box().max().x());
159  box->set_max_y(known_cells_box().max().y());
160  box->set_min_x(known_cells_box().min().x());
161  box->set_min_y(known_cells_box().min().y());
162  }
163  result.set_min_correspondence_cost(min_correspondence_cost_);
164  result.set_max_correspondence_cost(max_correspondence_cost_);
165  return result;
166 }
167 
168 int Grid2D::ToFlatIndex(const Eigen::Array2i& cell_index) const {
169  CHECK(limits_.Contains(cell_index)) << cell_index;
170  return limits_.cell_limits().num_x_cells * cell_index.y() + cell_index.x();
171 }
172 
173 } // namespace mapping
174 } // namespace cartographer
virtual void GrowLimits(const Eigen::Vector2f &point)
Definition: grid_2d.cc:116
const Eigen::Vector2d & max() const
Definition: map_limits.h:61
float ValueToCorrespondenceCost(const uint16 value)
Grid2D(const MapLimits &limits, float min_correspondence_cost, float max_correspondence_cost)
Definition: grid_2d.cc:36
constexpr float kMaxCorrespondenceCost
virtual proto::Grid2D ToProto() const
Definition: grid_2d.cc:147
Eigen::AlignedBox2i known_cells_box_
Definition: grid_2d.h:101
const Eigen::AlignedBox2i & known_cells_box() const
Definition: grid_2d.h:80
const std::vector< uint16 > & correspondence_cost_cells() const
Definition: grid_2d.h:76
void ComputeCroppedLimits(Eigen::Array2i *const offset, CellLimits *const limits) const
Definition: grid_2d.cc:101
bool Contains(const Eigen::Array2i &cell_index) const
Definition: map_limits.h:79
float GetCorrespondenceCost(const Eigen::Array2i &cell_index) const
Definition: grid_2d.cc:86
bool IsKnown(const Eigen::Array2i &cell_index) const
Definition: grid_2d.cc:93
Eigen::Array2i GetCellIndex(const Eigen::Vector2f &point) const
Definition: map_limits.h:69
const std::vector< int > & update_indices() const
Definition: grid_2d.h:79
const MapLimits & limits() const
Definition: grid_2d.h:41
proto::MapLimits ToProto(const MapLimits &map_limits)
Definition: map_limits.h:92
constexpr uint16 kUpdateMarker
int ToFlatIndex(const Eigen::Array2i &cell_index) const
Definition: grid_2d.cc:168
constexpr uint16 kUnknownCorrespondenceValue
std::vector< uint16 > correspondence_cost_cells_
Definition: grid_2d.h:95
constexpr float kMinCorrespondenceCost
std::vector< int > update_indices_
Definition: grid_2d.h:98
const CellLimits & cell_limits() const
Definition: map_limits.h:64
proto::GridOptions2D CreateGridOptions2D(common::LuaParameterDictionary *const parameter_dictionary)
Definition: grid_2d.cc:23


cartographer
Author(s): The Cartographer Authors
autogenerated on Mon Feb 28 2022 22:00:58