# 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` ```cpp using PointCloud = std::vector; ``` Simple vector of 3D points (x, y, z in meters). ### `TimedPointCloud` ```cpp using TimedPointCloud = std::vector; struct TimedPoint { Eigen::Vector3f point; float time; // Relative time offset within scan (seconds) }; ``` Point cloud with per-point timestamps for motion compensation. ### `PointCloudWithIntensities` ```cpp using PointCloudWithIntensities = std::vector; struct PointWithIntensity { Eigen::Vector3f point; float intensity; }; ``` Point cloud with intensity values (for lidars that provide reflectivity). ## Functions ### Transform ```cpp 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 ```cpp PointCloud CropPointCloud(const PointCloud& point_cloud, float min_z, float max_z); ``` Filters points by Z coordinate. ### Downsample ```cpp PointCloud VoxelFilter(const PointCloud& point_cloud, float voxel_size); ``` Voxel grid downsampling — keeps one point per voxel. ### Intensity ```cpp PointCloudWithIntensities IntensityToColor(const PointCloudWithIntensities& cloud); ``` Maps intensity values to colors (for visualization). ## Usage ```cpp // 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: ```cpp // 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 ```proto 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 - [RangeData](range_data.md) — SLAM input format - [CompressedPointCloud](compressed_point_cloud.md) — Compressed storage - [VoxelFilter](internal/voxel_filter.md) — Downsampling implementation