Caasi v0.2.0 Data: dataset · sensor · vision

Data & Sensors

Generate simulation datasets as tracked runs, keep them inspectable and portable, discover the sensors attached to your machine, and verify the computer-vision stack — all without Caasi ever importing a single heavy library.

caasi dataset

SubcommandWhat it does
listList datasets under the datasets base directory.
generateGenerate a dataset from an experiment.
inspectInspect a dataset.
convertConvert a dataset into a portable index (jsonl/csv).
validateValidate a dataset.
downloadDownload a dataset (Hugging Face, NGC or URL) as a tracked run.

Descriptions are the CLI's own — caasi dataset --help prints this list. For datasets generated by Isaac Sim Replicator see caasi synth; for fetching existing ones see dataset download below and its extended treatment in synthetic.html.

What a dataset is

A dataset is a directory with a metadata.json plus any of the known data subdirectories:

wave-100-20260905-170412/
├── metadata.json
├── episodes/       # per-episode recordings
├── observations/   # agent observations
├── actions/
├── rewards/
├── poses/
├── images/         # RGB frames (--record-images)
├── depth/          # depth frames (--record-depth)
└── lidar/          # point clouds (--record-lidar)

Datasets are looked for in the project's datasets/ directory when you are inside a project, otherwise in paths.datasets (default ~/.caasi/datasets). Directory names follow <name-slug>-<YYYYmmdd-HHMMSS>.

The QUERY argument

inspect, convert and validate accept:

Unknown or ambiguous → Error: No dataset matching '<query>'. (exit 1).

caasi dataset list

caasi dataset list [--limit|-n N] [--json]

Every dataset under the base directory — the project's datasets/ when you are inside a project, else paths.datasets — newest first. A directory counts only when it holds a metadata.json; --limit defaults to 20 (and --limit 0 means “none”).

shellcaasi dataset list
Name                       Status       Files  Size
wave-100-20260905-170412   generating   1301   81.3 KiB
aloha-sim-20260905-180233  downloading  13     877 B
caasi dataset list --limit 1 --json | jq '.datasets[0]'
{
  "name": "wave-100-20260905-170412",
  "path": "/home/you/.caasi/datasets/wave-100-20260905-170412",
  "status": "generating",
  "source": null,
  "files": 1301,
  "size": 83269
}

Status and source come straight from metadata.json (unknown / null when absent), while Files and Size are counted on disk, recursively and including metadata.json — the same scan inspect reports. The JSON payload is {"base": "<datasets dir>", "datasets": [{"name", "path", "status", "source", "files", "size"}]}.

An empty base directory is data, not an error — No datasets found. in yellow, exit 0 ({"base": …, "datasets": []} in JSON):

shellcaasi dataset list
No datasets found.
caasi dataset list --json
{
  "base": "/home/you/.caasi/datasets",
  "datasets": []
}

caasi dataset generate

caasi dataset generate CONFIG_PATH [--episodes N] [--workers N] [--record-images]
            [--record-depth] [--record-lidar] [--name NAME] [--dry-run] [-- SCRIPT_ARGS…]
ParameterKindTypeDefaultDescription
CONFIG_PATHargumentpathrequiredThe experiment YAML whose script collects the data.
--episodesoptionint→ script arg --episodes N.
--workersoptionint→ script arg --workers N.
--record-imagesoptionflagoff→ script arg --record-images.
--record-depthoptionflagoff→ script arg --record-depth.
--record-lidaroptionflagoff→ script arg --record-lidar.
--nameoptionstrexperiment nameDataset name (dir name gets a timestamp suffix).
--dry-runoptionflagoffShow the command; create nothing.

What happens on launch:

  1. The dataset directory is created and metadata.json is written with status: "generating", the experiment path, backend, episodes/workers, the record flags and the linked run_id.
  2. The script receives --dataset-dir <dir> and the environment variable CAASI_DATASET_DIR — write your collected files there.
  3. A detached run (kind: dataset) is started exactly like sim run.
shellcaasi dataset generate experiments/collect.yaml --episodes 100 --record-images
Dataset generation started: /home/you/.caasi/datasets/wave-100-20260905-170412
Run: 20260905-170412-wave — follow it with 'caasi logs 20260905-170412-wave -f'

caasi dataset inspect

caasi dataset inspect QUERY [--json]

Shows the metadata, the linked run's live status, and what is actually on disk (file counts per subdirectory, total size):

shellcaasi dataset inspect latest
wave-100-20260905-170412
  /home/you/.caasi/datasets/wave-100-20260905-170412
  name       wave-100
  created    2026-09-05T17:04:12+08:00
  experiment /home/you/demo/experiments/collect.yaml
  backend    sim
  episodes   100
  record     images=True depth=False lidar=False
  status     generating
  Run: 20260905-170412-wave (succeeded)
Directory  Files
episodes     100
images      1200
caasi dataset inspect latest --json | jq '.run'
{ "id": "20260905-170412-wave", "status": "succeeded" }

JSON payload: {"path", "metadata", "contents": {"files", "size", "dirs"}, "run"}; run is null when unlinked, or {"id", "status": "unknown"} if the run was deleted.

caasi dataset convert

caasi dataset convert QUERY [--to jsonl|csv] [--output PATH]

Builds a portable index of every file in the dataset (relative path + size, excluding metadata.json and previous indexes) — handy for training pipelines that just need a file list:

shellcaasi dataset convert latest --to csv
Index written to /home/you/.caasi/datasets/wave-100-20260905-170412/index.csv (1300 file(s)).
head -3 /home/you/.caasi/datasets/wave-100-20260905-170412/index.csv
path,size
episodes/ep_000.json,4213
images/frame_00000.png,184322

Defaults: --to jsonl (one {"path": …, "size": …} object per line), output <dataset>/index.<fmt>. Unknown format → Error: unknown index format '…' (expected one of jsonl, csv) (exit 1).

caasi dataset validate

caasi dataset validate QUERY [--json]

Structural validation:

shellcaasi dataset validate latest --json
{
  "path": "/home/you/.caasi/datasets/wave-100-20260905-170412",
  "valid": false,
  "issues": ["metadata declares 100 episode(s) but episodes/ contains 97"]
}
exit code: 1

Exit 0 valid / 1 any issue — in both human and JSON mode.

caasi dataset download

caasi dataset download REF [--backend hf|ngc|url] [--name NAME] [--dry-run] [-- EXTRA…]

Fetches a dataset that already exists instead of generating one. The backend is auto-detected from the reference's scheme; --backend forces one (and then a bare org/name is accepted too). Caasi resolves an upstream downloader and delegates the whole transfer to it — no HTTP client, no SDK, nothing imported:

ReferenceBackendTool (first found on PATH)Command built
hf://org/namehfhf, then huggingface-cli<tool> download org/name [EXTRA…] --local-dir <dataset-dir>
ngc://org/name:versionngcngc<tool> registry dataset download-version org/name:version [EXTRA…] --dest <dataset-dir>
http(s)://…/fileurlcurl, then wgetcurl -L [EXTRA…] -o <dataset-dir>/file <url> (wget [EXTRA…] -O …)

The destination is a fresh dataset directory named --name or the source's last path segment, plus the usual timestamp suffix. The transfer starts as a detached run — kind: dataset, backend = the detected backend, extra: {source, dataset} in the manifest — and metadata.json is written at launch with status: "downloading" and the run_id, so caasi run status and caasi logs follow it like any other run:

shellcaasi dataset download hf://lerobot/aloha_sim --dry-run
Dry run — nothing was started:
  command: hf download lerobot/aloha_sim --local-dir /home/you/.caasi/datasets/aloha-sim-20260905-180233
  dest:    /home/you/.caasi/datasets/aloha-sim-20260905-180233
caasi dataset download https://example.com/data.tar.gz --dry-run
Dry run — nothing was started:
  command: /usr/bin/curl -L -o /home/you/.caasi/datasets/data-tar-gz-20260905-180411/data.tar.gz https://example.com/data.tar.gz
  dest:    /home/you/.caasi/datasets/data-tar-gz-20260905-180411
caasi dataset download https://example.com/data.tar.gz
Dataset download started: /home/you/.caasi/datasets/data-tar-gz-20260905-180512
  Run: 20260905-180512-data-tar-gz — follow it with 'caasi logs 20260905-180512-data-tar-gz -f'

Unrecognized flags pass straight through to the tool, between the source and the destination flags — --revision main yields hf download lerobot/aloha_sim --revision main --local-dir <dataset-dir>. A --dry-run needs no downloader installed (the command is printed with the backend's default tool name) and leaves no directory behind.

Both refusals happen before anything is created, and both exit 1:

shell# neither hf nor huggingface-cli on PATH
caasi dataset download hf://lerobot/aloha_sim
Error: No download tool found for backend 'hf'.
exit code: 1
caasi dataset download ftp://example.com/x
Error: Cannot detect a download backend for 'ftp://example.com/x' (use hf://, ngc://, http(s):// or --backend hf|ngc|url).
exit code: 1

Once the files land the directory is an ordinary dataset: dataset list shows it with its source and status, and inspect / convert / validate all work on it. Cache behaviour and the Replicator-side workflow are covered in synthetic.html.

caasi sensor

Discovers sensors by scanning /dev, sysfs and pip metadata — vendor SDKs are never imported. Five sensors are known:

NameKindDetected viaIf missing
camerasvideo4linux/dev/video* + /sys/class/video4linux/*/namehint: v4l2-ctl --list-devices
realsensedepth-camerapip package pyrealsense2hint: pip install pyrealsense2
zeddepth-cameradirectory /usr/local/zedhint: install the ZED SDK
lidarserial/dev/ttyUSB*, /dev/ttyACM*hint: connection/udev rules
isaacsimsimulationthe usual Isaac Sim detection chainhint: caasi setup isaacsim

caasi sensor list

caasi sensor list [--json]
shellcaasi sensor list
Sensor     Kind          Status        Detail
cameras    video4linux   detected      1 device(s)
realsense  depth-camera  not detected  pyrealsense2 not installed
zed        depth-camera  not detected  ZED SDK not found
lidar      serial        not detected  0 serial device(s)
isaacsim   simulation    detected      Isaac Sim 6.0 at /opt/isaac-sim-6.0
caasi sensor list --json | jq '.[0]'
{ "name": "cameras", "kind": "video4linux", "detected": true,
  "detail": "1 device(s)", "devices": ["/dev/video0 (Integrated Webcam)"],
  "hint": "check the device with 'v4l2-ctl --list-devices'" }

Always exits 0 — missing sensors are data, not errors.

caasi sensor inspect

caasi sensor inspect NAME [--json]

Detail for one sensor (devices list, hint). Exit 0 even when not detected; 1 for an unknown name (Error: Unknown sensor '<n>'. Valid: cameras, realsense, zed, lidar, isaacsim).

caasi sensor test

caasi sensor test NAME [--json]

Gating version of inspect: exits 0 when the sensor is detected, 1 when not — for scripts like:

shellcaasi sensor test cameras || echo "no camera — using sim sensors"
Sensor 'cameras' is available: 1 device(s)
caasi sensor test lidar --json
{ "name": "lidar", "ok": false, "detail": "0 serial device(s)" }
exit code: 1

caasi vision

Diagnoses the computer-vision Python stack. “Installed” means pip metadata is present — the package is never imported by status/inspect. Six components, each mapped to its import module and candidate distributions:

ComponentModuleDistributions checked (in order)
opencvcv2opencv-python, opencv-python-headless, opencv-contrib-python
open3dopen3dopen3d, open3d-cpu
onnxruntimeonnxruntimeonnxruntime-gpu, onnxruntime
tensorrttensorrttensorrt
pytorchtorchtorch
pillowPILpillow

caasi vision status

caasi vision status [--json]
shellcaasi vision status
Component    Status     Version  Module
opencv       installed  4.10.0   cv2
open3d       installed  0.18.0   open3d
onnxruntime  installed  1.19.0   onnxruntime
tensorrt     missing    —        tensorrt
pytorch      installed  2.4.0    torch
pillow       installed  10.4.0   PIL
Install missing components with 'pip install <package>'.

JSON: array of {"name", "installed", "version", "module"}. Always exits 0.

caasi vision inspect

caasi vision inspect COMPONENT [--json]

One component in detail, with an install hint when missing. Exit 0 for known names (installed or not); 1 for unknown names.

caasi vision test

caasi vision test [COMPONENT…] [--python PATH] [--json]

The real proof: imports each component — in a subprocess, with a 30-second timeout, optionally using a different interpreter (--python, default: the CLI's own). This catches broken installs that pip metadata alone would happily report as fine.

shellcaasi vision test
opencv: 4.10.0
open3d: 0.18.0
onnxruntime: 1.19.0
tensorrt: missing
pytorch: 2.4.0
pillow: 10.4.0
exit code: 1
caasi vision test opencv pytorch --python /opt/IsaacLab/_isaac_sim/python.sh --json
[ { "name": "opencv", "ok": true, "detail": "4.10.0" },
  { "name": "pytorch", "ok": true, "detail": "2.4.0" } ]

Exit 0 only if every tested component imports successfully; 1 if any fails, times out, or the name is unknown. No arguments = all six.