Sentinel

Legacy install (launcher)

Install the Sentinel runtime with the run_sentinel.sh launcher.

This is the previous install method: a launcher script that reads the license key from the config file and runs the runtime container directly. It keeps working, but new setups should use the daemon install — new capabilities land there only.

The Sentinel runtime runs as a container on the computer connected to your robot. This page installs the host dependencies and launcher. Robot configuration is a separate step.

Latest version: 0.13.0. Versions below 0.7.0 are no longer supported and cannot be used. 0.7.0 introduced major breaking changes — configs made for earlier versions must be replaced. Contact us to update your config.

Requirements

Choose the container that matches the computer connected to your robot.

Container tagComputerGPU supportHost software
amd64x86-64 computerCPU onlyUbuntu 22.04 or 24.04
arm64ARM64 computerCPU onlyUbuntu 22.04 or 24.04
amd64-cu13x86-64 computer with a discrete NVIDIA GPUCUDA 13 and NVENCUbuntu 22.04 or 24.04, a CUDA 13-compatible NVIDIA driver, and NVIDIA Container Toolkit
jp6.2NVIDIA Jetson OrinJetson GPU and NVENCJetPack 6.2 or later and NVIDIA Container Toolkit

There is no general-purpose ARM64 CUDA container. Use jp6.2 for NVIDIA Jetson hardware. Use arm64 for other ARM64 computers.

Use amd64-cu13 or jp6.2 when the computer has supported NVIDIA hardware. NVENC provides better video quality and encoding performance than CPU encoding for the same compute budget.

Required on every platform

  • Docker Engine v27+
  • Python 3 with PyYAML — the launcher uses it to read the license key from the config: python3 -m pip install pyyaml
  • 10 GB of free space on the root filesystem

Required for NVIDIA platforms

Install the NVIDIA Container Toolkit when using amd64-cu13 or jp6.2.

  • For amd64-cu13, install an NVIDIA driver compatible with CUDA 13 and confirm the GPU is visible with nvidia-smi.
  • For jp6.2, install JetPack 6.2 or later. JetPack provides the CUDA and Jetson multimedia components used for hardware video encoding.

Setup

Create a local Sentinel folder

On the computer connected to your robot, create a folder for the Sentinel launcher:

mkdir -p ~/sentinel
cd ~/sentinel

Save the launcher script

Create run_sentinel.sh in ~/sentinel and paste the script below:

#!/bin/bash
set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
[[ -f "$SCRIPT_DIR/.env" ]] && source "$SCRIPT_DIR/.env"

CONFIG_FILE="$1"
VERSION="${2:-latest}"
NECK_CALIBRATION="${3:-}"
CONTAINER_NAME="${4:-sentinel-runtime}"

if [[ -z "$CONFIG_FILE" ]]; then
    cat >&2 <<EOF
Usage: $0 <config_file> [version] [neck_calibration_file] [container_name]
  $0 /abs/path/yam_dual.yaml 0.13.0-amd64-cu13
  $0 /abs/path/cfg.yaml      0.13.0-jp6.2 /abs/path/neck_calibration.json
  $0 /abs/path/cfg.yaml      0.13.0-jp6.2 /abs/path/neck_calibration.json my-name
EOF
    exit 1
fi
[[ -f "$CONFIG_FILE" ]] || { echo "ERROR: config not found: $CONFIG_FILE" >&2; exit 1; }
[[ -z "$NECK_CALIBRATION" || -f "$NECK_CALIBRATION" ]] \
    || { echo "ERROR: neck calibration not found: $NECK_CALIBRATION" >&2; exit 1; }

AUTH_URL="https://api-prod.avearobotics.com"
LICENSE_KEY="$(python3 - "$CONFIG_FILE" <<'PY'
import sys, yaml
sys_ = (yaml.safe_load(open(sys.argv[1])) or {}).get('system') or {}
print(sys_.get('license_key') or '')
PY
)"
[[ -n "$LICENSE_KEY" ]] \
    || { echo "ERROR: system.license_key not found in $CONFIG_FILE" >&2; exit 1; }

ECR_RESP="$(curl -fsS -X POST "$AUTH_URL/auth/robot/ecr-credentials" \
    -H 'Content-Type: application/json' \
    -d "{\"license_key\":\"$LICENSE_KEY\"}")"
[[ -n "$ECR_RESP" ]] || { echo "ERROR: empty ECR response from $AUTH_URL" >&2; exit 1; }

mapfile -t CREDS < <(printf '%s' "$ECR_RESP" | python3 -c \
    'import json,sys;r=json.load(sys.stdin);print(r["registry"]);print(r["password"])')
REGISTRY="${CREDS[0]}"
printf '%s' "${CREDS[1]}" \
    | docker login --username AWS --password-stdin "$REGISTRY" >/dev/null
unset CREDS ECR_RESP

IMAGE="$REGISTRY/sentinel-runtime:${VERSION}"

ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
if [[ "$ARCH" == "arm64" && -f /etc/nv_tegra_release ]]; then
    PLATFORM=jetson
elif [[ "$ARCH" == "amd64" ]] && command -v nvidia-smi >/dev/null && nvidia-smi -L >/dev/null 2>&1; then
    PLATFORM=cuda
else
    PLATFORM=cpu
fi

echo "sentinel-runtime $VERSION  $PLATFORM/$ARCH  $IMAGE  ($CONTAINER_NAME)"

cd "$REPO_ROOT"
mkdir -p datasets

ARGS=(
    -it --rm --name "$CONTAINER_NAME"
    --privileged --network host --ipc host
    -v /dev:/dev -v /tmp:/tmp
    -v "$REPO_ROOT/datasets:/datasets"
    -v "$(realpath "$CONFIG_FILE"):/config/robot.yaml:ro"
    -v zed-models:/usr/local/zed/resources
    --group-add video --group-add plugdev
    -e RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
    -e ENABLE_RECORDING=true
)

case "$PLATFORM" in
    cuda)
        ARGS+=(--gpus all -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=all) ;;
    jetson)
        ARGS+=(--runtime nvidia --gpus all
               -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=all)
        # ZED X / GMSL: Argus ISP settings + host zed/i2c/render GIDs.
        # /tmp is already bound, so argus_socket + zed_x_daemon sockets come along.
        [[ -d /var/nvidia/nvcam/settings ]] \
            && ARGS+=(-v /var/nvidia/nvcam/settings:/var/nvidia/nvcam/settings:ro)
        for grp in zed i2c render; do
            gid=$(getent group "$grp" 2>/dev/null | cut -d: -f3 || true)
            [[ -n "$gid" ]] && ARGS+=(--group-add "$gid")
        done
        ;;
esac

[[ -n "$NECK_CALIBRATION" ]] \
    && ARGS+=(-v "$(realpath "$NECK_CALIBRATION"):/config/neck_calibration.json:ro")

exec docker run "${ARGS[@]}" "$IMAGE"

Then make it executable:

chmod +x run_sentinel.sh

Your folder should now contain run_sentinel.sh.

Update Sentinel

To move to a new version, remove the old runtime images first, then start the launcher with the new version tag — it pulls the image automatically:

docker images --format '{{.Repository}}:{{.Tag}}' | grep sentinel-runtime | xargs -r docker rmi
./run_sentinel.sh /absolute/path/to/robot.yaml 0.13.0-amd64-cu13

Always prune old image versions before pulling a new one. Sentinel is safety-critical — running mismatched versions can produce undefined behavior.

Next step