Using the API

Spatial Mapping Configuration

Spatial Mapping configuration is similar to previous modules. Use InitParameters to set the video mode, coordinate system and units.

// Set configuration parameters
InitParameters init_params;
init_params.camera_resolution = RESOLUTION_HD720; // Use HD720 video mode (default fps: 60)
init_params.coordinate_system = COORDINATE_SYSTEM_RIGHT_HANDED_Y_UP; // Use a right-handed Y-up coordinate system
init_params.coordinate_units = UNIT_METER; // Set units in meters

The coordinate system determines the axes convention of the mesh, and coordinate units specify the metrics used for the mesh. Since spatial mapping uses positional tracking to create its map, we recommend using the HD720 video mode at 60fps for optimal results.

Enabling Spatial Mapping

After opening the camera, enable positional tracking using enableTracking() and spatial mapping using enableSpatialMapping() with SpatialMappingParameters default parameters.

Two main Spatial Mapping parameters can be adjusted: resolution and range.

Adjusting Resolution

Mapping resolution can be specified manually (in meters) or through the following presets:

  • MAPPING_RESOLUTION_HIGH: Set resolution to 2cm. Use this setting to map small areas.
  • MAPPING_RESOLUTION_MEDIUM: Set resolution to 5cm. Good balance between performance and level of detail.
  • MAPPING_RESOLUTION_LOW: Set resolution of 8cm. Use this settings to map large areas or create a collision mesh.

Note that high resolution mapping is resource-intensive and slows down mesh updates. Use lower resolutions to get faster mesh updates.

SpatialMappingParameters mapping_parameters;
mapping_parameters.resolution_meter = 0.03 ;  // Set resolution to 3cm
mapping_parameters.resolution_meter = SpatialMappingParameters::get(MAPPING_RESOLUTION_LOW); // Or use preset

Adjusting Range

The range of depth data that is integrated in the mapping process can be specified manually (in meters) or through the following presets:

  • MAPPING_RANGE_NEAR: integrates depth up to 3.5 meters.
  • MAPPING_RANGE_MEDIUM: integrates depth up to 5 meters.
  • MAPPING_RANGE_FAR: integrates depth up to 10 meters.

Since depth accuracy decreases with distance, mapping range has been limited to 10 meters. Use a careful balance of resolution and range when mapping to maintain a good quality/performance ratio.

SpatialMappingParameters mapping_parameters;  
mapping_parameters.range_meter = 5 ;  // Set maximum depth mapping range to 5m
mapping_parameters.range_meter = SpatialMappingParameters::get(MAPPING_RANGE_MEDIUM); // Or use preset

Enabling textures

By allowing the spatial mapping to save images of the scene, you’ll be able to export a textured version of the mesh.

SpatialMappingParameters mapping_parameters;  
mapping_parameters.save_texture = true ;  // Scene texture will be recorded

Getting a 3D Map

To start spatial mapping, you just need to launch grab(). New images, depth and tracking will be ingested in background to create the mesh.

One-time Mapping

The process to map a whole area and save the result is:

  • Start spatial mapping. Capture the entire area.
  • When done, use extractWholeMesh(sl::Mesh) to retrieve the mesh. This can take some time depending on the size and resolution of the mesh.
  • Use mesh.filter() to refine it.
  • Create the texture using mesh.applyTexture().
  • Save the mesh with mesh.save("filename.obj").
// Configure spatial mapping parameters
sl::SpatialMappingParameters mapping_parameters(SpatialMappingParameters::MAPPING_RESOLUTION_LOW,
                                                SpatialMappingParameters::MAPPING_RANGE_FAR);
mapping_parameters.save_texture = true;
filter_params.set(MeshFilterParameters::MESH_FILTER_LOW);

// Enable tracking and mapping
zed.enableTracking();
zed.enableSpatialMapping(mapping_parameters);

sl::Mesh mesh; // Create a mesh object
int timer=0;

// Grab 500 frames and stop
while (timer < 500) {
  if (zed.grab() == SUCCESS) {
    // When grab() = SUCCESS, a new image, depth and pose is available.
    // Spatial mapping automatically ingests the new data to build the mesh.
    timer++;
  }      
}

// Retrieve the mesh
zed.extractWholeMesh(mesh);
// Filter the mesh
mesh.filter(filter_params);
// Apply the texture
mesh.applyTexture();
// Save the mesh in .obj format
mesh.save("mesh.obj");

Continuous Mapping

To get a mesh continuously, a request and update system is available:

  • Enable spatial mapping.
  • Send a request to get an updated mesh using requestMeshAsync(). This will launch mesh extraction in the background.
  • Check the request status with getMeshRequestStatusAsync(). When the mesh is ready, a SUCCESS status is returned.
  • Retrieve the mesh with retrieveMeshAsync(sl::Mesh).
  • Use in your application.

Requesting and retrieving a mesh is resource-intensive. To improve performance, do not request a new mesh too frequently.

// Request an updated mesh every 0.5s
sl::Mesh mesh; // Create a mesh object
int timer=0;
while (1) {
  if (zed.grab() == SUCCESS) {

      // Request an update of the mesh every 30 frames (0.5s in HD720 mode)
      if (timer%30 == 0)
         zed.requestMeshAsync();

      // Retrieve mesh when ready
      if (zed.getMeshRequestStatusAsync() == SUCCESS && timer > 0)
         zed.retrieveMeshAsync(mesh);

      timer++;
  }      
}

Disabling Spatial Mapping

Once spatial mapping is disabled, you will not be able to retrieve the mesh anymore. Make sure to extract it before disabling the modules and closing the camera.

// Disable spatial mapping, positional tracking and close the camera
zed.disableSpatialMapping();
zed.disableTracking();
zed.close();
return 0;

Spatial Mapping States

It is recommended to check the state of spatial mapping during use with getSpatialMappingState().

SPATIAL_MAPPING_STATE state = zed.getSpatialMappingState();

When spatial mapping is running correctly, SPATIAL_MAPPING_STATE_OKis returned. If a system does not allow to reach the framerate required to offer a consistent mapping experience, SPATIAL_MAPPING_STATE_FPS_TOO_LOW is returned. Similarly, if memory limit is reached during mapping, SPATIAL_MAPPING_STATE_NOT_ENOUGH_MEMORY is returned. In both cases, spatial mapping will stop integrating new data into the model, but the 3D model can still be extracted.

Code Example

For code examples, check out the Tutorial and Sample on GitHub.