cartographer/mapping/map_builder.h

Overview

MapBuilder is the main entry point for the Cartographer SLAM system. It wires together TrajectoryBuilder instances for local submap construction and a PoseGraph for global loop closure optimization.

Class: cartographer::mapping::MapBuilder

Constructor

explicit MapBuilder(const proto::MapBuilderOptions& options);

Creates a MapBuilder with the given options. Initializes:

  • Background thread pool (num_background_threads from options)

  • PoseGraph instance

  • Sensor collator (based on collate_by_trajectory option)

Public Methods

AddTrajectoryBuilder

int AddTrajectoryBuilder(
    const std::set<SensorId>& expected_sensor_ids,
    const proto::TrajectoryBuilderOptions& trajectory_options,
    LocalSlamResultCallback local_slam_result_callback);

Creates a new trajectory builder for live SLAM. Returns a trajectory ID.

Parameters:

  • expected_sensor_ids — Set of sensor IDs this trajectory expects (e.g., {"rangefinder", "laser"}, {"imu", "imu"})

  • trajectory_options — Configuration for 2D or 3D trajectory builder

  • local_slam_result_callback — Called when local SLAM produces a result (submap update, pose estimate)

AddTrajectoryForDeserialization

int AddTrajectoryForDeserialization(
    const proto::TrajectoryBuilderOptionsWithSensorIds& options_with_sensor_ids_proto);

Creates a trajectory placeholder for deserialization. The trajectory builder will be nullptr until state is loaded.

FinishTrajectory

void FinishTrajectory(int trajectory_id);

Marks a trajectory as finished. No further sensor data will be accepted. Triggers final optimization.

SubmapToProto

std::string SubmapToProto(const SubmapId& submap_id,
                          proto::SubmapQuery::Response* response);

Fills a protobuf response with submap data for visualization or inspection. Returns empty string on success, error message on failure.

SerializeState / SerializeStateToFile

void SerializeState(bool include_unfinished_submaps,
                    io::ProtoStreamWriterInterface* writer);

bool SerializeStateToFile(bool include_unfinished_submaps,
                          const std::string& filename);

Serializes the complete SLAM state (submaps, trajectories, constraints, pose graph) to a proto stream or file. If include_unfinished_submaps is true, submaps not yet fully populated with range data are included.

LoadState / LoadStateFromFile

std::map<int, int> LoadState(io::ProtoStreamReaderInterface* reader,
                             bool load_frozen_state);

std::map<int, int> LoadStateFromFile(const std::string& filename,
                                     bool load_frozen_state);

Loads SLAM state from a serialized stream/file. Returns a mapping from trajectory IDs in the proto to new trajectory IDs. If load_frozen_state is true, loads the frozen (optimized) trajectory poses; otherwise loads the active (unoptimized) poses.

pose_graph()

mapping::PoseGraphInterface* pose_graph() override;

Returns the underlying PoseGraph for direct access to constraints, trajectories, and global optimization.

GetTrajectoryBuilder

mapping::TrajectoryBuilderInterface* GetTrajectoryBuilder(int trajectory_id) const;

Returns the trajectory builder for the given ID, or nullptr if the trajectory has no builder (e.g., deserialization-only trajectories).

Factory Function

std::unique_ptr<MapBuilderInterface> CreateMapBuilder(
    const proto::MapBuilderOptions& options);

Creates a MapBuilder instance. This is the recommended way to instantiate the SLAM system.

Configuration

MapBuilder is configured via proto::MapBuilderOptions (defined in map_builder_options.proto), which is typically populated from Lua:

MAP_BUILDER = {
  use_trajectory_builder_2d = true,   -- or use_trajectory_builder_3d
  num_background_threads = 4,
  pose_graph = POSE_GRAPH,            -- from pose_graph.lua
  collate_by_trajectory = false,
}

Key options:

Option

Type

Description

use_trajectory_builder_2d

bool

Enable 2D SLAM

use_trajectory_builder_3d

bool

Enable 3D SLAM

num_background_threads

int

Threads for scan matching/optimization

collate_by_trajectory

bool

Collate sensor data per trajectory vs. globally

pose_graph

PoseGraphOptions

Global optimization config

Usage Example

// Load configuration
auto resolver = cartographer::common::ConfigurationFileResolver({config_dir});
auto lua_code = resolver.GetFileContentOrDie("my_config.lua");
auto lua_dict = cartographer::common::MakeLuaParameterDictionary(lua_code);
auto options = cartographer::mapping::CreateMapBuilderOptions(lua_dict.get());

// Create MapBuilder
auto map_builder = cartographer::mapping::CreateMapBuilder(options);

// Add trajectory for 2D lidar + IMU
std::set<SensorId> sensors = {{"rangefinder", "laser"}, {"imu", "imu"}};
int traj_id = map_builder->AddTrajectoryBuilder(
    sensors, options.trajectory_builder_options(),
    [](const LocalSlamResultData& result) {
      // Process local SLAM result
    });

// Feed sensor data via trajectory builder
auto* traj_builder = map_builder->GetTrajectoryBuilder(traj_id);
traj_builder->AddSensorData("laser", MakeDispatchable("laser", time, range_data));
traj_builder->AddSensorData("imu", MakeDispatchable("imu", time, imu_data));

// Later: finish and serialize
map_builder->FinishTrajectory(traj_id);
map_builder->SerializeStateToFile(true, "map.pbstream");

Thread Safety

  • MapBuilder methods are not thread-safe. External synchronization required.

  • Background threads are managed internally for scan matching and optimization.

  • Sensor data should be added from a single thread per trajectory builder.

See Also