curobo.examples.reference.lidar_volumetric_mapping module

Fuse Oxford Spires LiDAR clouds into a cuRobo block-sparse TSDF.

The default path builds a LiDAR-only RGB TSDF. Pass --enable-features to also sample C-RADIO features from timestamp-matched RGB cameras, fuse them into LidarObservation.feature_grid, and expose a Viser text-query overlay.

LiDAR volumetric mapping

Dataset

This example uses one sequence from the Oxford Spires dataset:

Download only that sequence into data/ from this cuRobo checkout:

python -m pip install -U "huggingface_hub[cli]"
# Optional: run this if Hugging Face asks for authentication.
hf auth login
hf download ori-drs/oxford_spires_dataset --repo-type dataset --local-dir data      --include 'sequences/2024-03-18-christ-church-03/processed/colmap/images.zip'      --include 'sequences/2024-03-18-christ-church-03/processed/colmap/transforms_colmap*.json'      --include 'sequences/2024-03-18-christ-church-03/processed/vilens-slam/undist-clouds.zip'      --include 'sequences/2024-03-18-christ-church-03/processed/vilens-slam/slam-poses.csv'      --include 'sequences/2024-03-18-christ-church-03/processed/trajectory/*'      --include 'calibration/*'      --include 'calibration/calibration-sequences-2024-03-19/*'
python -m zipfile -e data/sequences/2024-03-18-christ-church-03/processed/colmap/images.zip      data/sequences/2024-03-18-christ-church-03/processed/colmap
python -m zipfile -e data/sequences/2024-03-18-christ-church-03/processed/vilens-slam/undist-clouds.zip      data/sequences/2024-03-18-christ-church-03/processed/vilens-slam

The hf download command uses include patterns to fetch only sequences/2024-03-18-christ-church-03 plus required calibration files, not the full Hugging Face dataset. The default mapping command then finds the sequence at data/sequences/2024-03-18-christ-church-03.

Run LiDAR volumetric mapping:

python curobo/examples/reference/lidar_volumetric_mapping.py

Run feature mapping and text queries:

python curobo/examples/reference/lidar_volumetric_mapping.py --enable-features --max-frames 10
C-RADIO feature mapping and text query
default_curobo_root()
Return type:

Path

class TimedPose(
sec,
nsec,
position,
quaternion_wxyz,
)

Bases: object

Parameters:
sec: int
nsec: int
position: numpy.ndarray
quaternion_wxyz: numpy.ndarray
__init__(
sec,
nsec,
position,
quaternion_wxyz,
)
Parameters:
Return type:

None

class Frame(cloud_path, pose)

Bases: object

Parameters:
cloud_path: pathlib.Path
pose: curobo.examples.reference.lidar_volumetric_mapping.TimedPose
__init__(cloud_path, pose)
Parameters:
Return type:

None

class Bounds(
min_xyz,
max_xyz,
elevation_min_rad,
elevation_max_rad,
)

Bases: object

Parameters:
min_xyz: numpy.ndarray
max_xyz: numpy.ndarray
elevation_min_rad: float
elevation_max_rad: float
property center: numpy.ndarray
property extent_xyz: numpy.ndarray
__init__(
min_xyz,
max_xyz,
elevation_min_rad,
elevation_max_rad,
)
Parameters:
Return type:

None

class CameraCalibration(
name,
image_dir,
image_width,
image_height,
fx,
fy,
cx,
cy,
distortion,
T_cam_base,
image_timestamps_ns,
image_paths,
)

Bases: object

Parameters:
name: str
image_dir: pathlib.Path
image_width: int
image_height: int
fx: float
fy: float
cx: float
cy: float
distortion: numpy.ndarray
T_cam_base: numpy.ndarray
image_timestamps_ns: list[int]
image_paths: list[pathlib.Path]
__init__(
name,
image_dir,
image_width,
image_height,
fx,
fy,
cx,
cy,
distortion,
T_cam_base,
image_timestamps_ns,
image_paths,
)
Parameters:
Return type:

None

class RangeImageResult(
range_image,
rgb_image,
projected_pixels,
camera_rgb_pixels,
sample_points_base,
sample_colors,
feature_grid=None,
feature_pixels=0,
)

Bases: object

Parameters:
range_image: numpy.ndarray
rgb_image: numpy.ndarray
projected_pixels: int
camera_rgb_pixels: int
sample_points_base: numpy.ndarray
sample_colors: numpy.ndarray
feature_grid: numpy.ndarray | None = None
feature_pixels: int = 0
__init__(
range_image,
rgb_image,
projected_pixels,
camera_rgb_pixels,
sample_points_base,
sample_colors,
feature_grid=None,
feature_pixels=0,
)
Parameters:
Return type:

None

parse_args()
Return type:

Namespace

load_poses(csv_path)
Return type:

dict[tuple[int, int], TimedPose]

Parameters:

csv_path (pathlib.Path)

select_frames(args)
Return type:

list[Frame]

Parameters:

args (argparse.Namespace)

sequence_data_root(sequence_dir)
Return type:

Path

Parameters:

sequence_dir (pathlib.Path)

timestamp_ns(sec, nsec)
Return type:

int

Parameters:
timestamp_ns_from_image_path(path)
Return type:

int

Parameters:

path (pathlib.Path)

load_camera_calibrations(sequence_dir)
Return type:

list[CameraCalibration]

Parameters:

sequence_dir (pathlib.Path)

find_camera_image(camera, pose)
Return type:

Path | None

Parameters:
load_rgb_image(path)
Return type:

ndarray

Parameters:

path (pathlib.Path)

read_binary_pcd_xyz_intensity(path)
Return type:

tuple[ndarray, ndarray | None]

Parameters:

path (pathlib.Path)

normalize_quat(q_wxyz)
Return type:

ndarray

Parameters:

q_wxyz (numpy.ndarray)

quat_wxyz_to_matrix(q_wxyz)
Return type:

ndarray

Parameters:

q_wxyz (numpy.ndarray)

quat_wxyz_from_matrix(rotation)
Return type:

ndarray

Parameters:

rotation (numpy.ndarray)

transform_from_t_xyz_q_xyzw(
t_xyz_q_xyzw,
)
Return type:

ndarray

Parameters:

t_xyz_q_xyzw (numpy.ndarray)

transform_from_timed_pose(pose)
Return type:

ndarray

Parameters:

pose (curobo.examples.reference.lidar_volumetric_mapping.TimedPose)

invert_transform(T)
Return type:

ndarray

Parameters:

T (numpy.ndarray)

finite_range_mask(
xyz,
range_min,
range_max,
)
Return type:

tuple[ndarray, ndarray]

Parameters:
transform_points(points_lidar, pose)
Return type:

ndarray

Parameters:
transform_points_h(points, T_dst_src)
Return type:

ndarray

Parameters:
camera_world_transform(frame, camera)
Return type:

ndarray

Parameters:
downsample_image_for_viser(
image,
max_width,
)
Return type:

ndarray

Parameters:
project_fisheye(points_cam, camera)
Return type:

tuple[ndarray, ndarray, ndarray]

Parameters:
colorize_from_registered_cameras(
points_base,
frame,
cameras,
fallback_colors,
)
Return type:

tuple[ndarray, ndarray, dict[str, int]]

Parameters:
extract_camera_feature_grid(
feature_model,
image,
torch_module,
device,
)
Parameters:
empty_cuda_cache(torch_module)
Return type:

None

colorize_and_featurize_from_registered_cameras(
points_base,
frame,
cameras,
fallback_colors,
feature_model,
torch_module,
device,
feature_dim,
)
Return type:

tuple[ndarray, ndarray, ndarray, ndarray, dict[str, int], dict[str, int]]

Parameters:
infer_bounds(
frames,
range_min,
range_max,
padding_m,
elevation_min_deg,
elevation_max_deg,
)
Return type:

Bounds

Parameters:
grid_shape_nzyx(extent_xyz, voxel_size)
Return type:

tuple[int, int, int]

Parameters:
make_range_image(
xyz,
intensity,
*,
image_height,
image_width,
range_min,
range_max,
elevation_min_rad,
elevation_max_rad,
color_mode,
point_colors=None,
camera_color_mask=None,
point_features=None,
feature_mask=None,
)
Return type:

RangeImageResult

Parameters:
colorize_points(
points,
intensity,
color_mode,
)
Return type:

ndarray

Parameters:
downsample_points(
points,
colors,
max_points,
)
Return type:

tuple[ndarray, ndarray]

Parameters:
box_line_segments(center, extent)
Return type:

ndarray

Parameters:
tsdf_surface_voxels_with_blocks(mapper)
Return type:

tuple[ndarray, ndarray, ndarray, dict]

tsdf_surface_voxel_preview(mapper)
Return type:

tuple[ndarray, ndarray]

write_metadata(path, payload)
Return type:

None

Parameters:
start_viser()
add_viser_context(
visualizer,
frames,
grid_center,
extent_xyz,
)
Return type:

None

Parameters:
update_viser_tsdf_voxels(
visualizer,
mapper,
voxel_size,
)
Return type:

int

Parameters:

voxel_size (float)

pose_from_transform(
T,
Pose,
torch_module,
)
Parameters:

T (numpy.ndarray)

synchronize_if_cuda(
torch_module,
device,
)
Return type:

None

esdf_xy_slice_image(
voxel_grid,
slice_size_m,
slice_resolution,
torch_module,
)
Return type:

ndarray | None

Parameters:
  • slice_size_m (float)

  • slice_resolution (int)

update_viser_esdf_slice(
visualizer,
voxel_grid,
Pose,
torch_module,
slice_size_m,
slice_resolution,
)
Return type:

tuple[int, int, int] | None

Parameters:
  • slice_size_m (float)

  • slice_resolution (int)

update_viser_rgb_cameras(
visualizer,
frame,
cameras,
Pose,
torch_module,
)
Return type:

int

Parameters:
update_viser_feature_voxels(
visualizer,
mapper,
voxel_size,
pca_basis,
pca_colorize_tensor,
)
Return type:

tuple[int, object]

Parameters:

voxel_size (float)

setup_text_query_gui(
visualizer,
mapper,
feature_model,
args,
torch_module,
)
Parameters:

args (argparse.Namespace)

keep_viser_alive(
port,
*,
enable_features=False,
enable_esdf=False,
)
Return type:

None

Parameters:
run_mapper(args, frames, bounds)
Return type:

None

Parameters:
build_metadata(
args,
frames,
bounds,
stats,
projected_points,
integrated_frames,
camera_rgb_pixels,
camera_rgb_counts,
feature_pixels=None,
camera_feature_counts=None,
feature_dim=None,
feature_shape_hw=None,
)
Return type:

dict

Parameters:
print_dry_run(args, frames, bounds)
Return type:

None

Parameters:
main()
Return type:

None