cartographer/sensor/point_cloud.h

Overview

PointCloud represents a collection of 3D points with optional intensity values. Used for lidar data, depth camera output, and intermediate processing.

Types

PointCloud

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

Simple vector of 3D points (x, y, z in meters).

TimedPointCloud

using TimedPointCloud = std::vector<TimedPoint>;

struct TimedPoint {
  Eigen::Vector3f point;
  float time;  // Relative time offset within scan (seconds)
};

Point cloud with per-point timestamps for motion compensation.

PointCloudWithIntensities

using PointCloudWithIntensities = std::vector<PointWithIntensity>;

struct PointWithIntensity {
  Eigen::Vector3f point;
  float intensity;
};

Point cloud with intensity values (for lidars that provide reflectivity).

Functions

Transform

PointCloud TransformPointCloud(const PointCloud& point_cloud,
                               const transform::Rigid3f& transform);

TimedPointCloud TransformTimedPointCloud(const TimedPointCloud& point_cloud,
                                         const transform::Rigid3f& transform);

Applies rigid transform to all points.

Crop

PointCloud CropPointCloud(const PointCloud& point_cloud,
                          float min_z, float max_z);

Filters points by Z coordinate.

Downsample

PointCloud VoxelFilter(const PointCloud& point_cloud, float voxel_size);

Voxel grid downsampling — keeps one point per voxel.

Intensity

PointCloudWithIntensities IntensityToColor(const PointCloudWithIntensities& cloud);

Maps intensity values to colors (for visualization).

Usage

// Create point cloud
sensor::PointCloud cloud;
cloud.push_back(Eigen::Vector3f(1.0, 2.0, 0.5));
cloud.push_back(Eigen::Vector3f(1.1, 2.0, 0.5));

// Transform to robot frame
auto transformed = sensor::TransformPointCloud(cloud, sensor_to_robot);

// Voxel filter
auto filtered = sensor::VoxelFilter(cloud, 0.025f);

// Create RangeData from point cloud
sensor::RangeData range_data;
range_data.origin = Eigen::Vector3f(0, 0, 0);
range_data.returns = cloud;
range_data.misses = sensor::PointCloud{};  // No miss info

Integration

Point clouds are typically converted to RangeData for SLAM:

// In sensor driver
auto point_cloud = lidar_driver->GetPointCloud();
auto timed_point_cloud = ConvertToTimedPointCloud(point_cloud);

// Motion compensation
auto compensated = sensor::TransformTimedPointCloud(
    timed_point_cloud, 
    extrapolator.ExtrapolatePose(scan_start_time, scan_end_time));

// Convert to RangeData (project to 2D for 2D SLAM)
sensor::RangeData range_data = ConvertToRangeData(compensated);

Serialization

message PointCloud {
  repeated float x = 1;
  repeated float y = 2;
  repeated float z = 3;
}

message TimedPointCloud {
  repeated float x = 1;
  repeated float y = 2;
  repeated float z = 3;
  repeated float time = 4;
}

See Also