Robotics sensor-data stack

From raw bags to training-ready datasets.

apairo is an open, modular toolkit for robotics sensor data — one numpy-native API to load, transform, preprocess and visualise LiDAR, images and trajectories across datasets.

$ pip install apairo

fig.01 — the pipeline, end to end


02 / Packages

The pieces, up close.

Pick the layers you need. They share one data model, so they always agree on what a frame is.

01

apairocore

Core · dataset loader

Unified Python loader for robotics sensor datasets — one API across synchronous and asynchronous layouts. Everything comes back as plain numpy arrays.

  • RELLIS-3D · SemanticKITTI · GOOSE · TartanKitti
  • Views, caching & sequence filtering
  • Frames, calibration & transforms
  • CLI + YAML dataset profiles
pip install apairo
02

apairo_extractor

Ingest

Turn ROS bags into an apairo-native dataset — interactive TUI, KITTI-style .apairo layout, /tf handling and per-channel frame ids.

  • Interactive TUI
  • KITTI layout · Zarr (WIP)
  • /tf & /tf_static aware
03

apairo_transform

Runtime

Transforms & augmentations applied lazily at access time — nothing written to disk, numpy-only, no heavy dependencies.

  • Range · Subsample · Voxel
  • AccumulateFrames (temporal)
  • Compose on any dataset
04

apairo_preprocess

Offline

Offline pipelines for LiDAR odometry, ground segmentation and traversability ground-truth generation.

  • KISS-ICP / GICP odometry
  • CSF · RANSAC · TerraSeg
  • Voxelisation & priors
05

apairo_rr

Visualise

Rerun visualisation layer for clouds, semantic labels and trajectories — side-by-side pipelines, sequence-aware navigation.

  • Rerun viewer
  • Side-by-side pipelines
  • Any apairo dataset

03 / Quickstart

Loaded and training in a dozen lines.

The core ships on PyPI. Add only the layers you need — every package speaks the same numpy-native data model, so nothing has to be glued together by hand.

  1. Load any supported dataset behind one class.
  2. Transform lazily — augment on access, leave disk untouched.
  3. Use raw arrays in PyTorch, JAX, anything.
Full documentation
quickstart.py
import apairo
from apairo_transform import RangeFilter, RandomSubsample

# 1 · Load — one API across every dataset
ds = apairo.Rellis3DDataset(
    "/data/RELLIS-3D",
    keys=["lidar", "labels"],
)

# 2 · Transform — lazy, on access, nothing written to disk
ds.transform("lidar", RangeFilter(max=50.0))
ds.transform("lidar", RandomSubsample(8192))

# 3 · Use — plain numpy, ready for any framework
sample = ds[0]
sample.data["lidar"]    # ndarray (N, 4)  ·  x y z intensity
sample.data["labels"]   # ndarray (N,)    ·  int64