# 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 ```cpp 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` ```cpp int AddTrajectoryBuilder( const std::set& 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` ```cpp 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` ```cpp void FinishTrajectory(int trajectory_id); ``` Marks a trajectory as finished. No further sensor data will be accepted. Triggers final optimization. #### `SubmapToProto` ```cpp 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` ```cpp 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` ```cpp std::map LoadState(io::ProtoStreamReaderInterface* reader, bool load_frozen_state); std::map 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()` ```cpp mapping::PoseGraphInterface* pose_graph() override; ``` Returns the underlying `PoseGraph` for direct access to constraints, trajectories, and global optimization. #### `GetTrajectoryBuilder` ```cpp 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 ```cpp std::unique_ptr 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: ```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 ```cpp // 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 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 - [MapBuilderInterface](map_builder_interface.md) — Interface definition - [TrajectoryBuilderInterface](trajectory_builder_interface.md) — Local SLAM interface - [PoseGraphInterface](pose_graph_interface.md) — Global optimization - [Configuration Files](../configuration_files/map_builder.md) — Lua configuration