Cartographer Modular Resource

The Cartographer Project contains a C++ library that performs dense Simultaneous Localization And Mapping (SLAM).

To use Cartographer with the Viam SLAM service, you can use the cartographer modular resource. See the Use Modules section for instructions on using a module from the Viam registry on your machine.

The source code for this module is available on the viam-cartographer GitHub repository.

Cartographer can operate:

Use a live machine

The cartographer module supports three modes of operation:

Creating and updating SLAM maps with Cartographer is especially CPU-intensive, so the cartographer modular resource runs in the cloud for these two tasks. For doing pure localization on an existing map, the cartographer modular resource runs locally on your machine.

Hardware requirements

RPLidar

  • You must have an RPlidar, such as the RPlidar A1 or RPlidar A3, physically connected to your machine.

    Be sure to position the RPlidar so that it faces forward in the direction of travel. For example, if you are using a Viam Rover and the RPlidar A1 model, mount it to the Rover so that the pointed end of the RPlidar mount housing is facing in the same direction as the webcam.

    Furthermore, ensure that the center of the RPlidar is mounted at the center of your machine’s base. In the case of the Viam Rover the center is in the middle between the wheels.

    If you need a mount plate for your RPlidar A1 or A3 model, you can 3D print an adapter plate using the following:

  • In addition, you must add the rplidar module to your machine to support the RPlidar hardware, if you have not done so already.

Movement sensors (optional)

You can use data from one or more movement sensors on your machine to supplement the required LiDAR data. If you choose to use movement sensor data for SLAM, you can:

  • Add only inertial measurement unit (IMU) data
  • Add only odometry data
  • Add both IMU and odometry data
  • If you choose this option, be sure to configure data capture on the merged sensor and not on the individual movement sensors when following the steps below.

Create a new map

To create a new map, follow the instructions below. Creating a new map uses an instance of the cartographer module running in the cloud.

  1. Enable data capture and configure your cartographer SLAM service:
  1. Add the data management service to your machine:

    Navigate to the CONFIGURE tab of your machine’s page in the Viam app. Click the + icon next to your machine part in the left-hand menu and select Service. Choose Data Management as the type and either use the suggested name or specify a name for your data management service, for example data_manager-1. Click Create.

    On the panel that appears, you can manage the capturing and syncing functions. You can also specify the directory, the sync interval, and any tags to apply to captured data. See the data management service for more information.

  2. Enable data capture for your camera, and for your movement sensor if you would like to use IMU data, odometry data, or both:

    Find the component’s card on your machine’s CONFIGURE tab. Click Add Method, then specify the method type and the capture frequency.

    • For the required LiDAR camera, choose the NextPointCloud method. Set the capture frequency. 5 hertz is a good starting place for most applications.

      An R P lidar camera configured in the Viam app config builder with next point cloud configured for capture at 5 hertz.
    • To capture data from one or more movement sensors:

For an IMU, choose the AngularVelocity and LinearAcceleration methods and set the capture frequency. 20 hertz is a good starting place for most applications.

An IMU configured in the Viam app config builder with angular velocity and linear acceleration both configured for capture at 20 hertz.

For a movement sensor that supports odometry, choose the Position and Orientation methods and set the capture frequency. 20 hertz is a good starting place for most applications.

A wheeled odometer configured in the Viam app config builder with position and orientation both configured for capture at 20 hertz.

For a merged movement sensor, choose all four methods (AngularVelocity, LinearAcceleration, Position, and Orientation) and set the capture frequency. 20 hertz is a good starting place for most applications. You do not need to configure data capture on the individual IMU and odometer.

An IMU configured in the Viam app config builder with angular velocity, linear acceleration, position, and orientation all configured for capture at 20 hertz.
  1. Set up the cartographer module on your machine:

    Navigate to the CONFIGURE tab of your machine’s page in the Viam app.

    Click the + icon next to your machine part in the left-hand menu and select Service. Select SLAM, then select cartographer. You can also search for “cartographer”.

    Click Add module, give your service a name of your choice, then click Create.

    In the resulting SLAM service configuration pane, choose Create new map as the Mapping mode, then configure the rest of the Attributes for that mapping mode:

    • Camera: Select the name of the camera component that you created when you added the rplidar module to your machine. Example: “my-rplidar”
    • Movement Sensor (Optional): Select the name of the movement sensor component that you want to use for SLAM. If you are using both an IMU and an odometer, select the name of the merged movement sensor, not the name of either of the individual movement sensors. Examples: “my-imu”, “MyOdometer,” or “merged-ms”.
    • Minimum range (meters): Set the minimum range of your rplidar. See config params for suggested values for RPLidar A1 and A3.
    • Maximum range (meters): Set the maximum range of your rplidar. See config params for suggested values for RPLidar A1 and A3.

    If you would like to tune additional Cartographer parameters, you can expand Show additional parameters. See the config_params section for more information on the other parameters.

    To save your changes, click the Save button in the top right corner of the page.

    Check the LOGS tab of your machine in the Viam app to make sure your RPlidar has connected and no errors are being raised.

This example JSON configuration:

  • adds the viam:rplidar and the viam:cartographer modules

  • configures the viam:slam:cartographer service and the data management service

  • adds an viam:lidar:rplidar camera with data capture configured


{
  "modules": [
    {
      "type": "registry",
      "name": "viam_rplidar",
      "module_id": "viam:rplidar",
      "version": "0.1.14"
    },
    {
      "type": "registry",
      "name": "viam_cartographer",
      "module_id": "viam:cartographer",
      "version": "0.3.36"
    }
  ],
  "services": [
    {
      "attributes": {
        "config_params": {
          "max_range_meters": "25",
          "mode": "2d",
          "min_range_meters": "0.2"
        },
        "camera": {
          "name": "rplidar",
          "data_frequency_hz": "5"
        },
        "enable_mapping": true,
        "use_cloud_slam": true
      },
      "name": "slam",
      "type": "slam",
      "namespace": "rdk",
      "model": "viam:slam:cartographer"
    },
    {
      "name": "data_manager-1",
      "type": "data_manager",
      "attributes": {
        "tags": [],
        "additional_sync_paths": [],
        "sync_interval_mins": 0.1,
        "capture_dir": ""
      }
    }
  ],
  "components": [
    {
      "namespace": "rdk",
      "attributes": {},
      "depends_on": [],
      "service_configs": [
        {
          "attributes": {
            "capture_methods": [
              {
                "disabled": false,
                "method": "NextPointCloud",
                "capture_frequency_hz": 5
              }
            ]
          },
          "type": "data_manager"
        }
      ],
      "name": "rplidar",
      "model": "viam:lidar:rplidar",
      "type": "camera"
    }
  ]
}

For more information about the configuration attributes, see Attributes.

  1. Start a mapping session:

    Navigate to the CONTROL tab on your machine’s page and click on the dropdown menu matching the name of the service you created. On the cartographer panel, you can start a mapping session.

    When you start a mapping session, Cartographer uses the data captured from when you click Start session until you click End session to create the map.

    Enter a name or use the suggested name for your new map and click Start session. Wait for the slam session to finish starting up in the cloud, which takes about 2 minutes.

    Make sure to either manually refresh, or change the refresh frequency to something other than Manual.

    slam RC card start session

    While the slam session is starting, you will see a loading screen.

    slam RC card wait for session to finish starting

    Once the slam session has finished starting, your first pointcloud will appear.

    slam RC card first pointcloud

    You can see that your cloud slam session is in progress from your Location page’s SLAM library tab.

    offline mapping maps computing table

    When you are ready to end the slam session, return to your machine’s CONTROL tab and click End session. If you do not click End session, the slam session will automatically end after 45 minutes.

    Once the session has ended, the map is saved to your Location page’s SLAM library tab.

    offline mapping available maps

    You can click View map to view the map in a dynamic pointcloud viewer.

    slam library view map

Update an existing map

To update an existing map with new pointcloud data from a new SLAM session, follow the instructions below. Updating an existing map uses an instance of the cartographer module running in the cloud, and does not overwrite the existing map.

  1. Configure your cartographer SLAM service:

    Configure Select map and Map version with the name and version of the map you would like to update. For the other attributes, review the information in Create a new map. You can see more details about the available maps from your machine’s Location page under the SLAM library tab.

    This example JSON configuration:

    • adds the viam:rplidar and the viam:cartographer modules
    • configures the viam:slam:cartographer service and the data management service
    • adds an viam:lidar:rplidar camera with data capture configured
    • specifies the slam_map to be updated in the packages

    {
      "modules": [
        {
          "type": "registry",
          "name": "viam_rplidar",
          "module_id": "viam:rplidar",
          "version": "0.1.14"
        },
        {
          "type": "registry",
          "name": "viam_cartographer",
          "module_id": "viam:cartographer",
          "version": "0.3.36"
        }
      ],
      "services": [
        {
          "attributes": {
            "config_params": {
              "max_range_meters": "25",
              "mode": "2d",
              "min_range_meters": "0.2"
            },
            "camera": {
              "name": "rplidar",
              "data_frequency_hz": "5"
            },
            "enable_mapping": true,
            "use_cloud_slam": true,
            "existing_map": "${packages.slam_map.test-map-1}/internalState.pbstream"
          },
          "name": "slam",
          "type": "slam",
          "namespace": "rdk",
          "model": "viam:slam:cartographer"
        },
        {
          "name": "data_manager-1",
          "type": "data_manager",
          "attributes": {
            "tags": [],
            "additional_sync_paths": [],
            "sync_interval_mins": 0.1,
            "capture_dir": ""
          }
        }
      ],
      "components": [
        {
          "namespace": "rdk",
          "attributes": {},
          "depends_on": [],
          "service_configs": [
            {
              "attributes": {
                "capture_methods": [
                  {
                    "disabled": false,
                    "method": "NextPointCloud",
                    "capture_frequency_hz": 5
                  }
                ]
              },
              "type": "data_manager"
            }
          ],
          "name": "rplidar",
          "model": "viam:lidar:rplidar",
          "type": "camera"
        }
      ],
      "packages": [
        {
          "name": "test-map-1",
          "version": "1697208847",
          "package": "d1c224e8-483e-4cc7-980f-76b89d8fb507/test-map-1",
          "type": "slam_map"
        }
      ]
    }
    

    For more information about the configuration attributes, see Attributes.

  2. Start a mapping session:

    Navigate to the CONTROL tab on your machine’s page and click on the dropdown menu matching the name of the service you created. On the cartographer panel, you can start a mapping session.

    When you start a mapping session, Cartographer uses the data captured from when you click Start session until you click End session to create the map.

    Once you click End session, the map is uploaded to the cloud and visible on your Location page under SLAM library.

    Click Start session. Wait for the slam session to finish starting up in the cloud, which takes about 2 minutes.

    Once the slam session has started, you can follow the same steps as in Create a new map to view your map.

Localize only

In this mode, the cartographer module on your machine executes the Cartographer algorithm itself locally to find its position on a map.

  1. Configure your cartographer SLAM service:

    The configuration is similar to the configuration for updating an existing map, except instead of adding a data management service and configuring data capture on the camera and movement sensor, set a Data polling rate (Hz) on both. The cartographer module on your machine polls the live LiDAR and IMU directly at these rates, whereas data capture is only used when data is being sent to the cloud.

    This example JSON configuration:

    • adds the viam:rplidar and the viam:cartographer modules
    • configures the viam:slam:cartographer service
    • adds an viam:lidar:rplidar camera with a Data polling rate (Hz) of 5
    • specifies the slam_map for localization in the packages

    {
      "modules": [
        {
          "type": "registry",
          "name": "viam_rplidar",
          "module_id": "viam:rplidar",
          "version": "0.1.14"
        },
        {
          "type": "registry",
          "name": "viam_cartographer",
          "module_id": "viam:cartographer",
          "version": "0.3.36"
        }
      ],
      "services": [
        {
          "type": "slam",
          "namespace": "rdk",
          "model": "viam:slam:cartographer",
          "attributes": {
            "config_params": {
              "min_range_meters": "0.2",
              "max_range_meters": "25",
              "mode": "2d"
            },
            "camera": {
              "name": "rplidar",
              "data_frequency_hz": "5"
            },
            "enable_mapping": false,
            "use_cloud_slam": false,
            "existing_map": "${packages.slam_map.test-map-1}/internalState.pbstream"
          },
          "name": "slam"
        }
      ],
      "components": [
        {
          "model": "viam:lidar:rplidar",
          "type": "camera",
          "namespace": "rdk",
          "attributes": {},
          "depends_on": [],
          "name": "rplidar"
        }
      ],
      "packages": [
        {
          "type": "slam_map",
          "name": "test-map-1",
          "version": "1697208847",
          "package": "d1c224e8-483e-4cc7-980f-76b89d8fb507/test-map-1"
        }
      ]
    }
    

    For more information about the configuration attributes, see Attributes.

  2. Start a mapping session:

    Navigate to the CONTROL tab on your machine’s page and click on the dropdown menu matching the name of the service you created.

    Unlike when creating or updating a map, you do not need to start and end a slam session. The pointcloud for the existing map will appear immediately and Cartographer will try to find your machine’s position on it.

    Since the map will not change, nothing new will be added to this machine’s location’s SLAM library.

    slam RC card localize only

Attributes

NameData TypeInclusionDescription
use_cloud_slambooleanRequiredIf true, the Cartographer algorithm will execute in the cloud rather than locally on your machine.
cameraobjRequiredAn object of the form { "name": <string>, "data_frequency_hz": <int> } where name is the name of the LiDAR camera component to use as input and data_frequency_hz is the rate at which to capture (in “Create new map” or “Update existing map” modes) or poll (in “Localize only” mode) data from that camera component.
movement_sensorobjOptionalAn object of the form { "name": <string>, "data_frequency_hz": <int> } where name is the name of the IMU movement sensor (that is, a movement sensor that supports the GetAngularVelocity and GetLinearAcceleration API methods) to use as additional input and data_frequency_hz is the rate at which to capture (in “Create new map” or “Update existing map” modes) or poll (in “Localize only” mode) data from that movement sensor component.
enable_mappingbooleanOptionalIf true, Cartographer will build the map in addition to doing localization.
    Default: true
existing_mapstringOptionalThe alias of the package containing the existing map to build on (in “Update existing map” mode) or localize on (in “Localize only” mode).
config_paramsobjOptionalParameters available to fine-tune the cartographer algorithm: read more below.

config_params

Parameter ModeDescriptionInclusionDefault ValueNotes
mode2dRequiredNone
optimize_every_n_nodesHow many trajectory nodes are inserted before the global optimization is run.Optional3To disable global SLAM and use only local SLAM, set this to 0.
num_range_dataNumber of measurements in each submap.Optional30
missing_data_ray_length_metersReplaces the length of ranges that are further than max_range with this value.Optional25Typically the same as max_range.
max_range_metersMaximum range of valid measurements.Optional25For an RPlidar A3, set this value to 25. For an RPlidar A1, use 12.
min_range_metersMinimum range of valid measurements.Optional0.2For an RPlidar A3, set this value to 0.2. For RPlidar A1, use 0.15.
max_submaps_to_keepNumber of submaps to use and track for localization.Optional3Only for LOCALIZING mode.
fresh_submaps_countLength of submap history considered when running SLAM in updating mode.Optional3Only for UPDATING mode.
min_covered_area_meters_squaredThe minimum overlapping area, in square meters, for an old submap to be considered for deletion.Optional1.0Only for UPDATING mode.
min_added_submaps_countThe minimum number of added submaps before deletion of the old submap is considered.Optional1Only for UPDATING mode.
occupied_space_weightEmphasis to put on scanned data points between measurements.Optional20.0Higher values make it harder to overwrite prior scanned points. Relative to translation weight and rotation weight.
translation_weightEmphasis to put on expected translational change from pose extrapolator data between measurements.Optional10.0Higher values make it harder for scan matching to translate prior scans. Relative to occupied space weight and rotation weight.
rotation_weightEmphasis to put on expected rotational change from pose extrapolator data between measurements.Optional1.0Higher values make it harder for scan matching to rotate prior scans. Relative to occupied space weight and translation weight.

For more information, see the Cartographer algorithm walkthrough, tuning overview, and config parameter list.

Use previously captured data

You can specify a range of previously captured LiDAR and optional IMU data to create a map or update an existing map in the cloud. You can browse your previously captured data from the Data page under the Point clouds tab (for LiDAR data) and Sensors tab (for IMU data).

Requirements

To create a map, you must have already captured LiDAR data in the location in which you would like to create the map.

The following example shows the previously-captured LiDAR data under the Point clouds tab for a machine named test. Selecting a row opens a pane to the right that contains more information, such as the Machine ID of the machine the component belongs to:

UI showing captured point clouds

Example of previously captured IMU data:

UI showing captured sensor data

Create or update a map

Navigate to the SLAM library tab on your location page, and click Make new map on the top right and specify a map name or click Update map next to an existing map.

  1. Enter the Machine name, Camera name, and optionally the Movement Sensor name of the components whose previously captured data you want to use to create or update a map. If your machine has been deleted, you can alternatively specify the machine ID.
  2. Adjust the configuration parameters as needed. See config_params for details.
  3. Select the timeframe of the data you’d like to use.
  4. At the bottom, you can see the total number of PCD files and movement sensor data points that will be processed.
  5. Click Generate map.
UI for creating a new map from captured data

View the map

Unlike in Online mode, you cannot see the map being created while the slam session is in progress, but similar to when creating or updating a map in Online mode, you can see that your cloud slam session is in progress from your Location page’s SLAM library tab. When all the data has been processed (or 45 minutes have passed, whichever occurs first), the map will be saved to your Location page’s SLAM library tab.

Delete the map

To clear a SLAM map, go to your Location page’s SLAM library tab. Click on the trash can icon in the upper right-hand corner of a map’s card to delete the map.

SLAM mapping best practices

The best way to improve map quality is by taking extra care when creating the initial map. While in a slam session, you should:

  • turn gently and gradually, completely avoiding sudden quick turns
  • make frequent loop closures, arriving back at a previously mapped area so the machine can correct for errors in the map layout
  • stay relatively (but not extremely) close to walls
  • use a robot that can go smoothly over bumps and transitions between flooring areas
  • drive at a moderate speed

You can find additional assistance in the Troubleshooting section.

Have questions, or want to meet other people working on robots? Join our Community Discord.

If you notice any issues with the documentation, feel free to file an issue or edit this file.