Preprocessing pipelines for apairo datasets — LiDAR odometry and traversability ground truth generation.
pip install git+https://github.com/apairo-robotics/apairo_preprocess.gitOptional dependencies:
pip install kiss-icp # for KissICPOdometry
pip install open3d # for GICPOdometryRequires Python ≥ 3.11.
| Class | Output channel | Backend | Output |
|---|---|---|---|
KissICPOdometry |
kissicp_poses |
KISS-ICP | (4, 4) float64 pose per scan |
GICPOdometry |
gicp_poses |
Open3D GICP | (4, 4) float64 pose per scan |
| Class | Output channel | Method |
|---|---|---|
TraversabilityFromLabels |
trav_label |
Maps semantic class IDs to binary traversable/non-traversable |
TraversabilityFromTrajectory |
trav_gt |
Labels points inside the robot's forward footprint along the trajectory |
from apairo.dataset.rellis import Rellis3DDataset
from apairo_preprocess import KissICPOdometry
Rellis3DDataset.run_preprocess(
KissICPOdometry(voxel_size=1.0),
"/data/Rellis-3D/00000",
)
# writes kissicp_poses/000000.npy, 000001.npy, ...from apairo.dataset.rellis import Rellis3DDataset
from apairo_preprocess import TraversabilityFromLabels
# Default traversable IDs for RELLIS-3D: {dirt, grass, asphalt, concrete, puddle, mud}
Rellis3DDataset.run_preprocess(
TraversabilityFromLabels(),
"/data/Rellis-3D/00000",
)
# writes trav_label/000000.npy, ... (uint8: 1=traversable, 0=not)Custom IDs for SemanticKITTI:
from apairo.dataset.semantic_kitti import SemanticKittiDataset
from apairo_preprocess import TraversabilityFromLabels
SemanticKittiDataset.run_preprocess(
TraversabilityFromLabels(traversable_ids=frozenset({40, 44, 48, 49, 60, 72})),
"/data/sequences/00",
)Requires poses to be computed first (e.g. with KissICPOdometry).
import numpy as np
from apairo.dataset.goose import Goose3DDataset
from apairo_preprocess import KissICPOdometry, TraversabilityFromTrajectory
# Step 1 — odometry
Goose3DDataset.run_preprocess(
KissICPOdometry(voxel_size=1.0),
"/data/goose/seq_001",
)
# Step 2 — load poses and compute traversability ground truth
ds = Goose3DDataset("/data/goose/seq_001", keys=["kissicp_poses"])
poses = np.stack([ds[i].data["kissicp_poses"] for i in range(len(ds))])
Goose3DDataset.run_preprocess(
TraversabilityFromTrajectory(poses, robot_radius=0.75, height_min=-0.3, height_max=0.5),
"/data/goose/seq_001",
)
# writes trav_gt/000000.npy, ... (uint8: 1=traversable, 0=not)Ready-to-run scripts in examples/:
# KISS-ICP odometry on any supported dataset
python examples/kissicp_odometry.py /data/Rellis-3D/00000 --dataset rellis
# Traversability from semantic labels
python examples/traversability_from_labels.py /data/Rellis-3D/00000
# Traversability ground truth from trajectory (runs odometry first if needed)
python examples/traversability_from_trajectory.py /data/goose/seq_001MIT