Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
76d57e8
sensing: deploy the camera producer to an Orin with one script
gareth-morgan-nv Nov 5, 2026
3a45748
sensing: send only changed source to the Orin; find uv and CUDA on th…
gareth-morgan-nv Nov 5, 2026
e711069
sensing: install the LiveKit licence files from the right FetchConten…
gareth-morgan-nv Nov 5, 2026
91a9626
sensing: document running the Orin deploy script
gareth-morgan-nv Nov 5, 2026
90b62b7
sensing: deploy another checkout or a branch's committed files to the…
gareth-morgan-nv Nov 6, 2026
38f7cea
sensing: deploy script no longer depends on the capture backend or br…
gareth-morgan-nv Nov 6, 2026
1a46576
sensing: stage the Orin release from the build tree and drop fixed de…
gareth-morgan-nv Nov 6, 2026
15c162e
sensing: deploy a producer without LiveKit; readiness per sensor; a r…
gareth-morgan-nv Nov 6, 2026
c85d76e
sensing: judge deploy readiness on the current session; one manifest …
gareth-morgan-nv Nov 6, 2026
e0d2c5f
deploy_orin: add an env option for extra unit environment variables
gareth-morgan-nv Nov 6, 2026
c02782d
deploy_orin: restart the producer after a fatal exit
gareth-morgan-nv Nov 8, 2026
80796b2
deploy_orin: put the start limit in [Unit], where systemd reads it
gareth-morgan-nv Nov 9, 2026
e6d63f6
sensing: add orin_setup.sh to prepare an Orin and find its cameras
gareth-morgan-nv Nov 9, 2026
17c03bf
sensing: deploy_orin.py installs prerequisites and finds the cameras …
gareth-morgan-nv Nov 9, 2026
f4fcc57
sensing: let deploy_orin.py upload the LiveKit token
gareth-morgan-nv Nov 10, 2026
770d73b
deploy_orin: count the staged files without failing when the stage di…
gareth-morgan-nv Nov 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/pre-commit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
python-version: "3.12"
- name: Test preview selection
run: python3 -m unittest discover -s tests/python/ci -p test_docs_preview.py -v
- name: Test the Orin deployment script
run: python3 -m unittest discover -s tests/python/ci -p test_deploy_orin.py -v

synthetic-xr-example-tests:
name: Test Synthetic XR task contracts
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/sensing/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,9 @@ camera runtime checks must not require build SDKs or cached vendor packages.
The quick-start camera command must open a live visual preview, not only print FPS.
Container preview must carry the desktop display and authorization into the image.

`deploy_orin.py` is the single entry point for putting an Orin into a working state.
A prerequisite or setup step belongs in it, through `orin_setup.sh`, not in a document
the operator must follow by hand before running it.

Support SSH launch with a local DISPLAY: when XAUTHORITY is unset, check the
current user's GDM authority file as well as ~/.Xauthority.
69 changes: 69 additions & 0 deletions src/plugins/sensing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ That guide owns the operating instructions; this README maps the source tree.

- [`scripts/`](scripts/): host setup, validation, diagnostics, the Bash
compatibility Docker launcher, and `setup_orin_crosscompile.py` for building on a PC. Each entry point exposes `--help`.
`scripts/deploy_orin.py` builds the producer on an Orin from this checkout and runs it as a systemd service.
- [`docker/`](docker/): example image, image-side group configuration, and
host-side container setup.
- [`configs/`](configs/): the platform configuration and its provenance.
Expand Down Expand Up @@ -46,3 +47,71 @@ SIPL drivers.
hardware encoder and publishes one LiveKit video track per camera. The
[SENSING user guide](https://nvidia.github.io/IsaacCapture/main/device/camera/sensing.html)
has the build and run steps.

## Orin: deploy from the desktop with one script

`scripts/deploy_orin.py` builds the producer on an Orin from the checkout you run it in and runs it as the
`isaaccapture-producer.service` systemd service, so you do not build by hand on the Orin. It needs `ssh`, `scp` and
`git` on the desktop, and `python3`, CMake, g++, CUDA, `uv` and the SDK headers (see `scripts/setup.sh`) on the Orin.

Write a config naming the producer's own options. `"mode"` says what the producer does and so how readiness is
judged: `"direct"` (the default) for a producer that sends only over TCP to the PC video stage, or `"livekit"` for one
that publishes to LiveKit itself, which also needs `livekit_url` and `token_file` (the token file stays on the Orin;
only its path is used). Add `"token_source": "join.token"` (a local file, relative to the config) and the deploy uploads
it to `token_file` with mode 0600 before anything is stopped, so no separate copy step is needed. Everything else goes in `args`, spelled as the deployed source's producer expects.

```json
{"args": ["--link-masks=0x0000 0x1100",
"--add-stream=sensor=0,name=sensing-left,direct=PC_HOST:5600",
"--add-stream=sensor=1,name=sensing-right,direct=PC_HOST:5601"]}
```

```json
{"mode": "livekit",
"livekit_url": "ws://127.0.0.1:7880",
"token_file": "/home/ido/livekit/join.token",
"args": ["--link-masks=0x0000 0x1100",
"--add-stream=sensor=0,livekit=sensing-left", "--add-stream=sensor=1,livekit=sensing-right"]}
```

Then run it from the repository root. The ssh user and password can come from the environment, which keeps the
password out of the command line and the output:

```bash
export ORIN_USER=ido
read -rs ORIN_PASSWORD && export ORIN_PASSWORD # optional; without it ssh and sudo prompt
python3 src/plugins/sensing/scripts/deploy_orin.py 192.168.1.176 --config orin.json \
--sdk-root /home/ido/sensing-sdk/root --replace-unmanaged
```

- The script has no knowledge of which capture SDK the deployed source uses: that comes from the source's own CMake.
`--cmake-arg=ARG` (repeatable, `=` form) passes options only some source trees define, such as a capture backend
switch. `--sdk-root DIR` is the Orin directory holding `usr/src/jetson_multimedia_api` and
`usr/src/jetson_sipl_api` when they are not under `/usr/src`.
- `--source DIR` deploys another checkout (for example a git worktree of a feature branch) instead of the one holding
the script; `--branch NAME` deploys that branch's committed files from it, ignoring the working tree. Without them
the script deploys its own checkout, local edits included.
- `--replace-unmanaged` stops a `camera_plugin_sensing` that someone started by hand (its exact PIDs are shown);
without it the deployment refuses and changes nothing. `--no-activate` builds and packages only, and `--jobs N`
bounds compile jobs. The release is installed under `/opt/isaaccapture`.
- `scripts/orin_setup.sh` installs the Orin's prerequisites and the SENSING drivers (`setup.sh`), then checks the cameras (`verify.sh`, then a
`validate.sh` stream). The deploy uploads it, with those scripts, to `~/.cache/isaaccapture-deploy/tools/scripts/`
before the preflight, so a missing prerequisite can be fixed first, and each release carries a copy under
`plugins/sensing_camera/scripts/`. `--prereqs-only` and `--check-only` run one half; stop the producer service
before the camera check, since SIPL serves one client at a time. From the desktop, `deploy_orin.py USER@ORIN
--install-prereqs` and `--check-camera` run them over ssh without deploying (the sudo password is asked on the
Orin's terminal); together they run both halves.
- `"cameras": "auto"` in the deploy config makes the deploy find the cameras itself, on any of the carrier's 8 inputs, and
start the producer with them (at most the two the vendor config names; streams for sensors that were not found are
dropped). The inputs found are saved in `known-cameras.json` in the deploy's cache directory on the Orin and tried
first on the next deploy. All 8 are scanned again only when that file is missing or a saved camera does not answer, or
with `--rescan-cameras`. Leave `--link-masks`, `--platform-config` and `--config-name` out of `args` in this mode.
- The script checks the ssh connection first, then preflights the Orin, uploads only the source files that differ
from what the Orin already holds, builds, installs a versioned release, replaces the running producer and waits for
every configured camera to be up. "Up" is the producer's own latest output for its current session: frames captured
and, for a stream with a `direct=` destination, that link connected (a stream with none is reported as capture-only).
Steps are numbered and the upload and packing show progress. The sudo steps prompt for the Orin password.
- A failed build or transfer leaves the running producer untouched. There is no automatic rollback; earlier releases
stay under `/opt/isaaccapture/releases/`. Logs: `journalctl -u isaaccapture-producer.service -f` on the Orin. Stop
it with `sudo systemctl stop isaaccapture-producer.service` before starting a producer by hand: the cameras are
exclusive.
Loading
Loading