cartographer/mapping/submaps.h¶
Overview¶
Submap classes represent local map regions as probabilistic grids. They are the fundamental building blocks of Cartographer’s mapping system. Separate implementations exist for 2D and 3D.
Class Hierarchy¶
Submap (abstract)
├── Submap2D
│ ├── ProbabilityGrid (grid_2d.h)
│ └── TSDF (tsdf_2d.h) -- alternative representation
└── Submap3D
└── HybridGrid (3d/hybrid_grid.h)
Class: cartographer::mapping::Submap¶
Interface¶
class Submap {
public:
explicit Submap(const transform::Rigid3d& local_pose);
virtual ~Submap() {}
const transform::Rigid3d& local_pose() const { return local_pose_; }
int num_range_data() const { return num_range_data_; }
bool insertion_finished() const { return insertion_finished_; }
void set_insertion_finished() { insertion_finished_ = true; }
// Subclasses implement grid access
virtual std::unique_ptr<Submap> ToProto() const = 0;
virtual void UpdateFromProto(const proto::Submap& proto) = 0;
protected:
const transform::Rigid3d local_pose_;
int num_range_data_ = 0;
bool insertion_finished_ = false;
};
Members¶
local_pose— Pose of submap origin in the local trajectory framenum_range_data— Number of range data insertions into this submapinsertion_finished— True when submap has received all its range data
Class: cartographer::mapping::Submap2D¶
Located in 2d/submap_2d.h/.cc.
Grid Types¶
ProbabilityGrid — Occupancy grid with log-odds representation (default)
TSDF — Truncated Signed Distance Function grid (alternative)
Configuration¶
From trajectory_builder_2d.lua:
submaps = {
num_range_data = 90,
grid_options_2d = {
grid_type = "PROBABILITY_GRID", -- or "TSDF"
resolution = 0.05,
},
range_data_inserter = {
range_data_inserter_type = "PROBABILITY_GRID_INSERTER_2D",
probability_grid_range_data_inserter = {
insert_free_space = true,
hit_probability = 0.55,
miss_probability = 0.49,
},
tsdf_range_data_inserter = {
truncation_distance = 0.3,
maximum_weight = 10.,
update_free_space = false,
-- normal estimation options...
},
},
}
Probability Grid Inserter¶
Updates occupancy using log-odds:
Hit (return):
log(hit_probability / (1 - hit_probability))Miss (free space):
log(miss_probability / (1 - miss_probability))
Default: hit=0.55, miss=0.49 → slight preference for free space.
TSDF Inserter¶
Stores truncated signed distance to surface. Supports:
Free space updates (optional)
Normal estimation for surface reconstruction
Weighted fusion of multiple scans
Class: cartographer::mapping::Submap3D¶
Located in 3d/submap_3d.h/.cc.
Hybrid Grid¶
3D submaps use a HybridGrid — a sparse 3D voxel grid implemented as a hash map (std::unordered_map<uint64_t, Cell>).
Structure¶
Each submap has two resolutions:
High resolution (e.g., 0.10m) — Near range, up to
high_resolution_max_range(e.g., 20m)Low resolution (e.g., 0.45m) — Far range, up to
max_range(e.g., 60m)
Configuration¶
From trajectory_builder_3d.lua:
submaps = {
high_resolution = 0.10,
high_resolution_max_range = 20.,
low_resolution = 0.45,
num_range_data = 160,
range_data_inserter = {
hit_probability = 0.55,
miss_probability = 0.49,
num_free_space_voxels = 2,
intensity_threshold = 40,
},
}
Insertion¶
For each return point:
Mark voxel as occupied (update hit probability)
Mark
num_free_space_voxelsvoxels along ray as freeOptionally use intensity for weighting
Submap Lifecycle¶
1. Created by TrajectoryBuilder (AddSubmap)
2. Receives range data insertions (num_range_data times)
3. Marked insertion_finished = true
4. New submap created, previous becomes "finished"
5. After loop closure, may be trimmed (overlapping_submaps_trimmer_2d)
Serialization¶
Submaps are serialized as part of the pose graph state:
message Submap {
SubmapId id;
Rigid3d local_pose;
int32 num_range_data;
bool insertion_finished;
// Grid data (ProbabilityGrid/TSDF/HybridGrid)
}
Usage¶
// Access submap data from pose graph
auto submap_data = pose_graph->GetSubmapData();
for (const auto& [submap_id, data] : submap_data) {
// data.submap->local_pose() -- submap origin
// data.submap->grid() -- access grid cells
}
// For 2D probability grid
auto* prob_grid = dynamic_cast<ProbabilityGrid*>(submap->grid());
for (const auto& cell : prob_grid->cells()) {
float prob = prob_grid->GetProbability(cell.index);
}
See Also¶
ProbabilityGrid — 2D occupancy grid
Submap2D — 2D submap representation
HybridGrid — 3D sparse voxel grid