Projects
A Caasi project is a plain directory with a caasi.yaml marker and a fixed layout for
robots, scenes, tasks, experiments, datasets and runs. No lock-in: everything is YAML and
folders you can inspect with ls.
Project layout
my-project/
├── caasi.yaml # project marker + metadata (kind, name, version)
├── robots/ # robot definitions (one YAML per robot)
├── scenes/ # scene definitions (one YAML per scene)
├── tasks/ # task definitions (one YAML per task)
├── experiments/ # experiment configs for `caasi sim run` / `train` / …
├── datasets/ # generated datasets
└── runs/ # project-local runs (optional; global runs live in ~/.caasi/runs)
Project commands find the root by walking upward from the current directory
until a caasi.yaml file appears — so they work from any subdirectory. Outside a
project they fail with:
shellcaasi project info
Error: Not inside a Caasi project (no caasi.yaml found). Run 'caasi init' first.
caasi init
Creates the scaffold. Never deletes anything: existing subdirectories are left untouched and
only caasi.yaml can be overwritten (with --force).
caasi init [PATH] [--name NAME] [--force] [--json]
| Parameter | Kind | Type | Default | Description |
|---|---|---|---|---|
PATH | argument | path | . | Directory to create the project in (~ expanded, resolved to absolute). |
--name | option | str | directory name | Project name stored in caasi.yaml. |
--force | option | flag | off | Overwrite an existing caasi.yaml. |
--json | option | flag | off | Machine-readable result. |
shellcaasi init ~/experiments/demo
Created project 'demo' at /home/you/experiments/demo
caasi.yaml
robots/
scenes/
tasks/
experiments/
datasets/
runs/
Next: create components with 'caasi robot create <name>'.
caasi init ~/experiments/demo
Error: '/home/you/experiments/demo/caasi.yaml' already exists (use --force to overwrite)
The generated caasi.yaml:
kind: project
name: demo
version: 1
JSON payload: {"root": "…", "name": "demo", "dirs": ["robots", "scenes", "tasks",
"experiments", "datasets", "runs"]}. Exit 0 on success, 1 on
collision or if PATH is an existing file.
caasi setup
Detects the five installable ecosystem components and — for a named component — prints a step-by-step installation guide tailored to how Caasi will later find it. Read-only: it never installs anything itself.
caasi setup [COMPONENT] [--json]
COMPONENT ∈ isaacsim, isaaclab, ros2,
pytorch, docker. Omit it for the summary table.
Summary mode
shellcaasi setup
Ecosystem Setup
Component Status Detail
isaacsim ✗ fail Isaac Sim not detected
isaaclab ✗ fail Isaac Lab not detected
ros2 ✓ ok distro 'jazzy', ros2 at /opt/ros/jazzy/bin/ros2
pytorch ✓ ok torch 2.4.0
docker ✓ ok Docker version 27.1.1, build 6312585
Missing core components: isaacsim, isaaclab. Run 'caasi setup <component>' for guidance.
exit code: 1
Exit code: 1 only when a core component
(isaacsim, isaaclab, ros2) fails detection —
pytorch/docker are optional. JSON payload:
{"components": {name: {"status", "detail"}}, "missing": [ … ]}.
Guide mode
shellcaasi setup isaacsim
✗ isaacsim — Isaac Sim not detected
Install Isaac Sim (pip, Omniverse launcher or NGC container), then either
register it:
caasi config set tools.isaacsim.versions."6.0".path /opt/isaac-sim-6.0
caasi config set tools.isaacsim.default "6.0"
or point the environment at it:
export ISAACSIM_PATH=/opt/isaac-sim-6.0
Each component has its own guide (ros2 → apt + sourcing, pytorch → pip index matching your
CUDA from caasi gpu status, docker → group setup + NVIDIA Container Toolkit).
Single-component mode exits 1 only if that component's status is
fail. JSON payload: {"component", "status", "detail", "guide"}.
Detection order per component
| Component | Looked for, in order |
|---|---|
isaacsim | registry tools.isaacsim → ISAACSIM_PATH → ~/isaacsim, ~/.local/share/ov/pkg/isaac-sim*, /opt/isaac-sim*, /opt/isaacsim* → pip isaacsim |
isaaclab | registry tools.isaaclab → ISAACLAB_PATH → ~/isaaclab, ~/IsaacLab, ~/workspace/isaaclab, ~/workspace/IsaacLab → pip isaaclab |
ros2 | ROS_DISTRO / /opt/ros scan → distro's bin/ros2 → ros2 on PATH |
pytorch | pip metadata of torch (never imported) |
docker | docker on PATH, probed with docker --version (status skip when absent) |
caasi project
caasi project info
caasi project info [--json]
shellcd ~/experiments/demo && caasi project info
Project
Root /home/you/experiments/demo
Name demo
Robots 2
Scenes 1
Tasks 3
Experiments 1
caasi project info --json
{ "root": "/home/you/experiments/demo", "name": "demo",
"counts": { "robot": 2, "scene": 1, "task": 3, "experiments": 1 } }
Counts are simply the number of *.yaml files in robots/,
scenes/, tasks/ and experiments/.
caasi project validate
caasi project validate
Checks the whole layout and every definition file:
caasi.yamlexists, parses, is a mapping, and has aname;- all six directories exist;
- every
robots/*.yaml,scenes/*.yaml,tasks/*.yamlparses and itskind:field matches its directory.
shellcaasi project validate
2 issue(s) found:
✗ missing directory 'datasets/'
✗ robots/agv.yaml: kind is 'scene', expected 'robot'
exit code: 1
mkdir datasets && caasi project validate
Project at /home/you/experiments/demo is valid.
Exit 0 valid / 1 any issue. No --json.
caasi robot / scene / task
Three parallel groups manage the definition YAMLs. A definition is one file:
robots/<name>.yaml, scenes/<name>.yaml,
tasks/<name>.yaml. The same subcommands exist for all three
(info is robot-only).
list
caasi robot list [--json] # same for scene / task
shellcaasi robot list
Robots
Name Description
agv Warehouse AGV
arm 6-DOF manipulator
caasi robot list --json
[ { "name": "agv", "description": "Warehouse AGV",
"path": "/home/you/experiments/demo/robots/agv.yaml" }, … ]
An empty directory is not an error — it prints a “create one with…” hint and exits 0.
create
caasi robot create NAME [--description|-d TEXT] # same for scene / task
NAMEmust match[A-Za-z0-9][A-Za-z0-9_-]*(start alphanumeric, then letters/digits/-/_).- Never overwrites: an existing file fails with
Error: '<path>' already exists(exit 1). There is no--force— edit the file instead.
shellcaasi robot create agv -d "Warehouse AGV"
Created robot 'agv' at /home/you/experiments/demo/robots/agv.yaml.
The generated templates (fill them in with your asset paths):
# robots/<name>.yaml # scenes/<name>.yaml # tasks/<name>.yaml
kind: robot kind: scene kind: task
name: agv name: warehouse name: pick-place
description: Warehouse AGV description: "" description: ""
urdf: "" usd: ""
usd: ""
dof: 0
sensors: []
tasks: []
inspect
caasi robot inspect NAME [--json] # same for scene / task
Prints the definition file as-is (human: YAML; --json: the parsed object).
A missing definition fails with Error: No robot named 'agv2' (looked in 'robots/').
(exit 1).
caasi robot info
caasi robot info NAME
A short human summary of one robot — the fields that matter, skipping empty ones:
shellcaasi robot info agv
agv
Warehouse AGV
DOF: 4
URDF: assets/agv/agv.urdf
Sensors: lidar, camera_front
Tasks: navigate, dock
No --json (use inspect --json).
Putting it together
a typical sessioncaasi setup
# → ros2 ok, isaacsim missing? follow the guide
caasi init ~/experiments/warehouse && cd ~/experiments/warehouse
caasi robot create agv -d "Warehouse AGV"
caasi scene create aisles -d "Racking aisles"
caasi task create navigate
# edit robots/agv.yaml → set urdf:/usd:, sensors, tasks
# write experiments/wave.yaml → see the Simulation page
caasi project validate && caasi sim run experiments/wave.yaml