cartographer/sensor/range_data.h

Overview

RangeData is the core sensor data structure for lidar/rangefinder measurements. It represents a single scan as an origin point plus two point clouds: returns (obstacle hits) and misses (free space along rays).

Struct: cartographer::sensor::RangeData

struct RangeData {
  Eigen::Vector3f origin;     // Sensor origin in sensor frame
  PointCloud returns;         // Points where rays hit obstacles
  PointCloud misses;          // Points along rays with no return
};

Semantics

  • Origin — Sensor position at measurement time (typically 0,0,0 in sensor frame)

  • Returns — 3D points where laser/radar detected an obstruction

  • Misses — Points at configured max range along rays with no return; represents free space

Assumptions

  • Space between origin and misses is free (unoccupied)

  • returns and misses have the same number of points (one per ray)

  • Points are in the sensor’s local frame

Functions

TransformRangeData

RangeData TransformRangeData(const RangeData& range_data,
                             const transform::Rigid3f& transform);

Applies a rigid transform (rotation + translation) to all points.

CropRangeData

RangeData CropRangeData(const RangeData& range_data, float min_z, float max_z);

Filters points by Z coordinate. Useful for removing ground/ceiling returns.

ToProto / FromProto

proto::RangeData ToProto(const RangeData& range_data);
RangeData FromProto(const proto::RangeData& proto);

Serialization to/from protobuf for storage and RPC.

PointCloud

using PointCloud = std::vector<Eigen::Vector3f>;

Simple vector of 3D points. For large point clouds, consider CompressedPointCloud.

Usage

// Create from raw sensor data
sensor::RangeData range_data;
range_data.origin = Eigen::Vector3f(0, 0, 0);
range_data.returns = {Eigen::Vector3f(1, 0, 0), Eigen::Vector3f(0, 1, 0), ...};
range_data.misses = {Eigen::Vector3f(30, 0, 0), Eigen::Vector3f(0, 30, 0), ...};

// Transform to tracking frame
auto transformed = sensor::TransformRangeData(range_data, sensor_to_tracking);

// Crop to 2D slice
auto cropped = sensor::CropRangeData(range_data, -0.5, 2.0);

// Serialize
proto::RangeData proto = sensor::ToProto(range_data);

Integration with TrajectoryBuilder

// Wrap in Dispatchable for sensor collator
auto dispatchable = sensor::MakeDispatchable(
    "laser",  // sensor ID
    common::FromUniversal(timestamp),
    range_data);

// Add to trajectory builder
trajectory_builder->AddSensorData("laser", std::move(dispatchable));

Configuration

Range data processing configured in trajectory builder options:

TRAJECTORY_BUILDER_2D = {
  min_range = 0.1,      -- Ignore returns closer than this
  max_range = 30.0,     -- Max range for returns and misses
  missing_data_ray_length = 5.0,  -- Length of miss rays
  voxel_filter_size = 0.025,      -- Downsample before insertion
}

See Also