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.
The source code for this module is available on the viam-cartographer
GitHub repository.
Info
Currently, the cartographer
modular resource supports taking 2D LiDAR and optionally IMU and/or odometry data as input.
Support for taking 3D LiDAR data as input may be added in the future.
Using Cartographer
The cartographer
module supports three modes of operation:
Hardware requirements
Running cartographer in the cloud
Creating and updating SLAM maps with Cartographer is especially CPU-intensive. If you do not have enough resources locally, you can use the cloudslam wrapper module to move computation to the cloud.
Running cartographer
in the cloud incurs cost for Data Management, Cloud Data Upload, and Cloud Data Egress. Currently, you incur no cost for compute.
See Viam’s Pricing for more information.
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.SUPPORT
Currently, the
rplidar
andcartographer
modules only support the Linux platform.
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
- Requires a movement sensor that supports
AngularVelocity
andLinearAcceleration
readings
- Requires a movement sensor that supports
- Add only odometry data
- Requires a movement sensor that collects
Position
andOrientation
data (for example,wheeled-odometry
)
- Requires a movement sensor that collects
- Add both IMU and odometry data
- Requires all four of the above kinds of data, merged together using the
merged
movement sensor model - 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.
- Requires all four of the above kinds of data, merged together using the
Create a new map
To create a new map, follow the instructions below.
Ensure any sensors you wish to use are configured on the machine. See the Hardware Requirements above.
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, chooseCreate 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 therplidar
module to your machine. Example: “my-rplidar”. Then set theData polling rate (Hz)
for retrieving pointclouds from the camera. For RPLidar A1 and A3 we recommend a frequency of 5 Hz. - 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 thename
of themerged
movement sensor, not thename
of either of the individual movement sensors. Examples: “my-imu”, “MyOdometer,” or “merged-ms”. Then set theData polling rate (Hz)
for retrieving readings from the movement sensor. We recommend a frequency of 20 Hz. - 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 the click {} button to switch to the advanced view, then edit the
config_params
from there. See theconfig_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.
- Camera: Select the
(Optional) Configure cartographer to use cloudSLAM:
On the
SLAM
service configuration pane, click the {} button to switch to advanced views and set theuse_cloud_slam
field to true. This setting disables local mapping to limit cpu usage in favor of using cloudSLAM.In addition, your configured LiDAR camera and movement sensor must have data capture enabled. See the cloudSLAM documentation for more information on how to configure the feature on your machine and how to use cloudSLAM.
This example JSON configuration:
- adds the
viam:rplidar
and theviam:cartographer
modules - configures the
viam:slam:cartographer
service
{
"modules": [
{
"type": "registry",
"name": "viam_rplidar",
"module_id": "viam:rplidar",
"version": "0.1.16"
},
{
"type": "registry",
"name": "viam_cartographer",
"module_id": "viam:cartographer",
"version": "0.3.45"
}
],
"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": false
},
"name": "slam",
"type": "slam",
"namespace": "rdk",
"model": "viam:slam:cartographer"
}
],
"components": [
{
"namespace": "rdk",
"attributes": {},
"depends_on": [],
"name": "rplidar",
"model": "viam:lidar:rplidar",
"type": "camera"
}
]
}
For more information about the configuration attributes, see Attributes.
After configuring cartographer the machine should begin mapping automatically. Navigate to the CONTROL tab on your machine’s page and click on the dropdown menu matching the name
of the service you created. See our tips for making good maps. If you want to save your locally built map, you can use the GetInternalState API or use the local map uploading feature of the cloudslam wrapper module.
Update an existing map
To update an existing map with new pointcloud data from a new SLAM session, follow the instructions below.
Configure your
cartographer
SLAM service using a map from your location:- Select the Mapping mode dropdown and choose the Update existing map option.
- 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 by clicking View SLAM library.
This example JSON configuration:
- adds the
viam:rplidar
and theviam:cartographer
modules - configures the
viam:slam:cartographer
service - adds an
viam:lidar:rplidar
camera - specifies the
slam_map
to be updated in thepackages
{ "modules": [ { "type": "registry", "name": "viam_rplidar", "module_id": "viam:rplidar", "version": "0.1.16" }, { "type": "registry", "name": "viam_cartographer", "module_id": "viam:cartographer", "version": "0.3.45" } ], "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": false, "existing_map": "${packages.slam_map.test-map-1}/internalState.pbstream" }, "name": "slam", "type": "slam", "namespace": "rdk", "model": "viam:slam:cartographer" } ], "components": [ { "namespace": "rdk", "attributes": {}, "depends_on": [], "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.
If you want to configure cartographer to use a locally saved map instead, see Using locally built maps.
After configuring cartographer the machine should begin mapping automatically. Navigate to the CONTROL tab on your machine’s page and click on the dropdown menu matching the
name
of the service you created.
See our tips for making a good map! If you want to save your locally built map, you can use the GetInternalState API or use the local map uploading feature of the cloudslam wrapper module
Info
Cartographer may take several minutes to find your machine’s position on the existing map.
In the meantime, your machine will show up at the map’s origin (with the (x,y)
coordinates (0,0)
).
Localize only
In this mode, the cartographer
module on your machine executes the Cartographer algorithm to find its position on a map. This mode is better when using motion planning’s MoveOnMap because the map will not be modified.
Configure your
cartographer
SLAM service:- Select the Mapping mode dropdown and choose the Update existing map option.
- Configure Select map and Map version with the name and version of the map you would like to localize on. 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 by clicking View SLAM library.
This example JSON configuration:
- adds the
viam:rplidar
and theviam:cartographer
modules - configures the
viam:slam:cartographer
service - adds an
viam:lidar:rplidar
- specifies the
slam_map
for localization in thepackages
{ "modules": [ { "type": "registry", "name": "viam_rplidar", "module_id": "viam:rplidar", "version": "0.1.16" }, { "type": "registry", "name": "viam_cartographer", "module_id": "viam:cartographer", "version": "0.3.45" } ], "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.
If you want to configure cartographer to use a locally saved map instead, see Using locally built maps.
After configuring cartographer on the machine, the map should appear automatically. Navigate to the CONTROL tab on your machine’s page and click on the dropdown menu matching the
name
of the service you created.Info
Cartographer may take several minutes to find your machine’s position on the existing map. In the meantime, your machine will show up at the map’s origin (with the
(x,y)
coordinates(0,0)
).If you move your machine, it will appear to be moving in a trajectory from the map’s origin.
Attributes
Name | Data Type | Required? | Description |
---|---|---|---|
use_cloud_slam | boolean | Required | If true , the Cartographer algorithm will disable mapping on the machine. This feature should only be used when trying to use cloudslam. |
camera | obj | Required | An 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_sensor | obj | Optional | An 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_mapping | boolean | Optional | If true , Cartographer will build the map in addition to doing localization.
true |
existing_map | string | Optional | The alias of the package containing the existing map to build on (in “Update existing map” mode) or localize on (in “Localize only” mode). Can also point to a locally saved .pbstream file. |
config_params | obj | Optional | Parameters available to fine-tune the cartographer algorithm: read more below. |
config_params
Parameter Mode | Description | Required? | Default Value | Notes |
---|---|---|---|---|
mode | 2d | Required | None | |
optimize_every_n_nodes | How many trajectory nodes are inserted before the global optimization is run. | Optional | 3 | To disable global SLAM and use only local SLAM, set this to 0 . |
num_range_data | Number of measurements in each submap. | Optional | 30 | |
missing_data_ray_length_meters | Replaces the length of ranges that are further than max_range with this value. | Optional | 25 | Typically the same as max_range . |
max_range_meters | Maximum range of valid measurements. | Optional | 25 | For an RPlidar A3, set this value to 25 . For an RPlidar A1, use 12 . |
min_range_meters | Minimum range of valid measurements. | Optional | 0.2 | For an RPlidar A3, set this value to 0.2 . For RPlidar A1, use 0.15 . |
max_submaps_to_keep | Number of submaps to use and track for localization. | Optional | 3 | Only for LOCALIZING mode. |
fresh_submaps_count | Length of submap history considered when running SLAM in updating mode. | Optional | 3 | Only for UPDATING mode. |
min_covered_area_meters_squared | The minimum overlapping area, in square meters, for an old submap to be considered for deletion. | Optional | 1.0 | Only for UPDATING mode. |
min_added_submaps_count | The minimum number of added submaps before deletion of the old submap is considered. | Optional | 1 | Only for UPDATING mode. |
occupied_space_weight | Emphasis to put on scanned data points between measurements. | Optional | 20.0 | Higher values make it harder to overwrite prior scanned points. Relative to translation weight and rotation weight . |
translation_weight | Emphasis to put on expected translational change from pose extrapolator data between measurements. | Optional | 10.0 | Higher values make it harder for scan matching to translate prior scans. Relative to occupied space weight and rotation weight . |
rotation_weight | Emphasis to put on expected rotational change from pose extrapolator data between measurements. | Optional | 1.0 | Higher 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.
Using locally built maps
You can see details about the available maps from your machine’s Location page by clicking View SLAM library. If you do not have any maps, and you do not wish to use cloudslam, but you still want to use localizing and updating modes with cartographer, you can take the following steps.
- Save a
.pbstream
file by using the GetInternalState or InternalStateFull APIs by using one of the SDKs. Note,InternalStateFull
is currently only implemented in Go. - Ensure the
.pbstream
file is located somewhere on the machine, and note the directory path to that file. - In your cartographer’s config, update the
existing_map
field with the path to the file that was noted in #2.
your config should look something like the following:
{
"modules": [
{
"type": "registry",
"name": "viam_rplidar",
"module_id": "viam:rplidar",
"version": "0.1.16"
},
{
"type": "registry",
"name": "viam_cartographer",
"module_id": "viam:cartographer",
"version": "0.3.45"
}
],
"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": false,
"existing_map": "/PATH/TO/FILE/<INTERNAL-STATE-NAME>.pbstream"
},
"name": "slam",
"type": "slam",
"namespace": "rdk",
"model": "viam:slam:cartographer"
}
],
"components": [
{
"namespace": "rdk",
"attributes": {},
"depends_on": [],
"name": "rplidar",
"model": "viam:lidar:rplidar",
"type": "camera"
}
],
"packages": []
}
Now your cartographer
service should be running using your locally saved map.
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.
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!