Portable Ithaca capture node: one install for every Jetson
Extract the install that was applied by hand to the Jetson Nano into a single checkout that builds itself for whatever Jetson it lands on. The two nodes on the rig share no JetPack — tegra210 caps at 4, tegra234 needs 5+ — so nothing binary is portable between them. The source and the procedure are: install.sh detects the platform (L4T / JetPack / SoC), installs deps, builds the OrbbecSDK and the preview server from source locally, and generates a per-user config and systemd unit. The tested bridge.py ships verbatim; all machine-specific paths live in the generated config, so it stays unmodified — its one hardcoded path is made home-relative. The retired GStreamer/RTSP target is dropped: the direct route encodes no video. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
c167c836e6
15 files changed
+3168
No files matched your search
@@ -0,0 +1,104 @@
|
||||
# Ithaca capture node
|
||||
|
||||
The software a Jetson runs to join an Ithaca RGBD capture rig: a Python bridge that
|
||||
puts the node on the WebSocket mesh and answers Preview / Record, and a C++ preview
|
||||
server that streams each camera's colour (the sensor's own JPEG) and depth (its own
|
||||
16-bit millimetres, LZ4-compressed) straight to the Unity viewer.
|
||||
|
||||
One checkout, one command, on any Jetson:
|
||||
|
||||
```sh
|
||||
git clone <this repo> ~/ithaca-node
|
||||
cd ~/ithaca-node
|
||||
./install.sh
|
||||
```
|
||||
|
||||
## Why an install script and not a disk image
|
||||
|
||||
The rig currently spans two Jetsons with **no JetPack in common**:
|
||||
|
||||
| Node | SoC | JetPack | Ubuntu / CUDA |
|
||||
|------|-----|---------|---------------|
|
||||
| Jetson Nano (2019) | tegra210 | **4.x only** (EOL) | 18.04 / 10.2 |
|
||||
| Jetson Orin Nano | tegra234 | **5 or 6** | 22.04 / 12.x |
|
||||
|
||||
tegra210 never got a newer L4T and the Orin refuses the old one, so no single OS
|
||||
image covers both, and no compiled binary is portable between them — CUDA, glibc
|
||||
and the C++ ABI all differ by generation.
|
||||
|
||||
What *is* portable is the **source and the procedure**. `install.sh` detects the
|
||||
platform and builds the C++ locally against a locally-built OrbbecSDK, so the same
|
||||
command produces a correct binary on each machine. Adding a future Orin NX or a Thor
|
||||
needs nothing new here — the script compiles against whatever toolchain it finds.
|
||||
|
||||
The bridge is pure Python and already runs identically everywhere; keep it that way
|
||||
by never giving it a dependency that has to be compiled.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
install.sh one entry point, idempotent
|
||||
bridge/
|
||||
bridge.py the node client — shipped verbatim, tested in place
|
||||
config.template.json @PLACEHOLDERS@ filled per user by install.sh
|
||||
server/
|
||||
ithaca_rgbd_server.cpp the preview server
|
||||
CMakeLists.txt links a prebuilt libOrbbecSDK, no GStreamer
|
||||
systemd/
|
||||
ithaca-bridge.service.in templated with the user and repo path
|
||||
usbfs-memory.service raises usbfs_memory_mb for the camera bandwidth
|
||||
udev/
|
||||
99-obsensor-libusb.rules reference copy (the SDK's own installer wins if present)
|
||||
scripts/
|
||||
detect_platform.sh L4T / JetPack / SoC, as KEY=value
|
||||
install_deps.sh apt + websockets
|
||||
build_sdk.sh reuse or build OrbbecSDK v2 for this platform
|
||||
build_server.sh cmake + make the preview server
|
||||
```
|
||||
|
||||
## What install.sh does
|
||||
|
||||
1. Detects L4T / JetPack / SoC (`scripts/detect_platform.sh`).
|
||||
2. Installs build and run dependencies (no GStreamer — the direct route encodes no
|
||||
video).
|
||||
3. Locates a working OrbbecSDK build, or clones and builds one. A node that already
|
||||
has a good build (the Nano) is left untouched.
|
||||
4. Builds `ithaca_rgbd_server` against it.
|
||||
5. Generates `bridge/config.json` for the current user — this is where all the
|
||||
machine-specific paths live, so `bridge.py` itself stays unmodified.
|
||||
6. Installs the udev rules and the `usbfs-memory` service, and adds the user to the
|
||||
`video` group.
|
||||
7. Generates and starts the `ithaca-bridge` systemd service.
|
||||
|
||||
Re-run it after a `git pull`: it rebuilds, regenerates the unit and config, and
|
||||
restarts the service. It keeps an existing `config.json` (delete it to regenerate)
|
||||
and an existing SDK build.
|
||||
|
||||
## The SDK is the one thing to watch on a new JetPack
|
||||
|
||||
`build_sdk.sh` reuses an existing build when it finds one. On a machine with none it
|
||||
clones the official OrbbecSDK v2 and builds it — this is the step most likely to
|
||||
need attention on a JetPack it has not been tried on. If it fails, build the SDK by
|
||||
hand once and re-run with its location:
|
||||
|
||||
```sh
|
||||
OB_SDK_ROOT=/path/to/OrbbecSDK_v2 ./install.sh
|
||||
```
|
||||
|
||||
Override the source with `OB_SDK_REPO` / `OB_SDK_REF` to pin a tag known to build on
|
||||
your JetPack.
|
||||
|
||||
## Operating the node
|
||||
|
||||
```sh
|
||||
systemctl status ithaca-bridge # is it up
|
||||
journalctl -u ithaca-bridge -f # live log
|
||||
```
|
||||
|
||||
Runtime state the bridge writes beside itself (git-ignored):
|
||||
|
||||
- `config.json` — this machine's config (generated).
|
||||
- `cam_settings.json` — per-camera settings, kept across restarts.
|
||||
- `stream_map.txt` — the live composition: line 1 the cameras to stream, line 2 the
|
||||
alignment (`raw` or `compare`). The preview server re-reads it once a second, so a
|
||||
camera can be turned on or off, and Compare switched, without restarting.
|
||||
Reference in new issue
Block a user