本次阅读的源码为 release-1.0 版本的代码
https://github.com/googlecartographer/cartographer_ros/tree/release-1.0
https://github.com/googlecartographer/cartographer/tree/release-1.0
也可以下载我上传的 全套工作空间的代码,包括 protobuf, cartographer, cartographer_ros, ceres,
https://download.csdn.net/download/tiancailx/11224156,现在上传资源自己不能选下载需要的积分。。。完全靠系统。
1 map_limits.h
struct CellLimits {
CellLimits() = default;
CellLimits(int init_num_x_cells, int init_num_y_cells)
: num_x_cells(init_num_x_cells), num_y_cells(init_num_y_cells) {}
explicit CellLimits(const proto::CellLimits& cell_limits)
: num_x_cells(cell_limits.num_x_cells()),
num_y_cells(cell_limits.num_y_cells()) {}
int num_x_cells = 0;
int num_y_cells = 0;
};
// Defines the limits of a grid map. This class must remain inlined for
// performance reasons.
class MapLimits {
private:
// Returns the cell size in meters. All cells are square and the resolution is the length of one side.
double resolution_;
// Returns the corner of the limits, i.e., all pixels have positions with smaller coordinates.
Eigen::Vector2d max_;
// Returns the limits of the grid in number of cells.
CellLimits cell_limits_;
};
map_limits 记录了地图的各种信息,分辨率,物理世界坐标的最大值(左上角的栅格最大),栅格的x, y方向的格子数量。
max_ 为该栅格在物理世界中的坐标,不是栅格的坐标。
2 grid2d.h
class Grid2D : public GridInterface {
public:
explicit Grid2D(const MapLimits& limits, float min_correspondence_cost,
float max_correspondence_cost);
explicit Grid2D(const proto::Grid2D& proto);
// Returns the limits of this Grid2D.
const MapLimits& limits() const { return limits_; }
// Finishes the update sequence.
void FinishUpdate();
// Returns the correspondence cost of the cell with 'cell_index'.
float GetCorrespondenceCost(const Eigen::Array2i& cell_index) const;
// Returns the minimum possible correspondence cost.
float GetMinCorrespondenceCost() const { return min_correspondence_cost_; }
// Returns the maximum possible correspondence cost.
float GetMaxCorrespondenceCost() const { return max_correspondence_cost_; }
// Returns true if the probability at the specified index is known.
bool IsKnown(const Eigen::Array2i& cell_index) const;
// Fills in 'offset' and 'limits' to define a subregion of that contains all
// known cells.
void ComputeCroppedLimits(Eigen::Array2i* const offset,
CellLimits* const limits) const;
// Grows the map as necessary to include 'point'. This changes the meaning of
// these coordinates going forward. This method must be called immediately
// after 'FinishUpdate', before any calls to 'ApplyLookupTable'.
virtual void GrowLimits(const Eigen::Vector2f& point);
virtual std::unique_ptr<Grid2D> ComputeCroppedGrid() const = 0;
virtual proto::Grid2D ToProto() const;
virtual bool DrawToSubmapTexture(
proto::SubmapQuery::Response::SubmapTexture* const texture,
transform::Rigid3d local_pose) const = 0;
protected:
const std::vector<uint16>& correspondence_cost_cells() const {
return correspondence_cost_cells_;
}
const std::vector<int>& update_indices() const { return update_indices_; }
const Eigen::AlignedBox2i& known_cells_box() const {
return known_cells_box_;
}
std::vector<uint16>* mutable_correspondence_cost_cells() {
return &correspondence_cost_cells_;
}
std::vector<int>* mutable_update_indices() { return &update_indices_; }
Eigen::AlignedBox2i* mutable_known_cells_box() { return &known_cells_box_; }
// Converts a 'cell_index' into an index into 'cells_'.
int ToFlatIndex(const Eigen::Array2i& cell_index) const;
private:
// 地图信息
MapLimits limits_;
// 栅格地图每个栅格的概率值
std::vector<uint16> correspondence_cost_cells_;
// 概率最小值,最大值
float min_correspondence_cost_;
float max_correspondence_cost_;
//
std::vector<int> update_indices_;
// Bounding box of known cells to efficiently compute cropping limits.
Eigen::AlignedBox2i known_cells_box_;
};
// Returns the correspondence cost of the cell with 'cell_index'.
float Grid2D::GetCorrespondenceCost(const Eigen::Array2i& cell_index) const {
if (!limits().Contains(cell_index)) return kMaxCorrespondenceCost;
return ValueToCorrespondenceCost(
correspondence_cost_cells()[ToFlatIndex(cell_index)]);
}
const std::vector<uint16>& correspondence_cost_cells() const {
return correspondence_cost_cells_;
}
int Grid2D::ToFlatIndex(const Eigen::Array2i& cell_index) const {
CHECK(limits_.Contains(cell_index)) << cell_index;
return limits_.cell_limits().num_x_cells * cell_index.y() + cell_index.x();
}
// Converts a uint16 (which may or may not have the update marker set) to a
// correspondence cost in the range [kMinCorrespondenceCost,
// kMaxCorrespondenceCost].
inline float ValueToCorrespondenceCost(const uint16 value) {
return (*kValueToCorrespondenceCost)[value];
}
const std::vector<float>* const kValueToCorrespondenceCost =
PrecomputeValueToCorrespondenceCost().release();
std::unique_ptr<std::vector<float>> PrecomputeValueToCorrespondenceCost() {
return PrecomputeValueToBoundedFloat(
kUnknownCorrespondenceValue, kMaxCorrespondenceCost,
kMinCorrespondenceCost, kMaxCorrespondenceCost);
}
std::unique_ptr<std::vector<float>> PrecomputeValueToBoundedFloat(
const uint16 unknown_value, const float unknown_result,
const float lower_bound, const float upper_bound) {
auto result = common::make_unique<std::vector<float>>();
// Repeat two times, so that both values with and without the update marker
// can be converted to a probability.
for (int repeat = 0; repeat != 2; ++repeat) {
for (int value = 0; value != 32768; ++value) {
result->push_back(SlowValueToBoundedFloat(
value, unknown_value, unknown_result, lower_bound, upper_bound));
}
}
return result;
}
// 0 is unknown, [1, 32767] maps to [lower_bound, upper_bound].
float SlowValueToBoundedFloat(const uint16 value, const uint16 unknown_value,
const float unknown_result,
const float lower_bound,
const float upper_bound) {
CHECK_GE(value, 0);
CHECK_LE(value, 32767);
if (value == unknown_value) return unknown_result;
const float kScale = (upper_bound - lower_bound) / 32766.f;
return value * kScale + (lower_bound - kScale);
}