diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b3cea90 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +.git/ +build/ +bin/ +tmp/ +models/ diff --git a/AGENTS.md b/AGENTS.md index b82454d..310a548 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -18,6 +18,8 @@ The binary is installed to `bin/dora_zed` relative to the repo root. The first build clones dora-rs from GitHub and compiles `dora-node-api-cxx` via Cargo. This takes a while. Subsequent builds are incremental. If `DORA_ROOT_DIR` is set to a local dora checkout, it builds against that instead. +For a build without installing the SDK stack on the host, see the `Dockerfile` (Ubuntu 24.04 — the newest release with a ZED SDK; there is no Stereolabs build for 26.04). Run the compile with `--gpus all`. + ## Run ```bash @@ -39,6 +41,7 @@ Camera and detection behavior is configured entirely through environment variabl - **`src/main.cc`** — Dora event loop. Selects engine via `ZED_ENGINE` env var (`yolo_onnx`/`onnx` or `native`), holds a `std::unique_ptr`. Parses `ZED_PC_MODE` (`FULL`/`HALF`/`ROI`) once before the loop. On any input event (intended to be driven by a tick timer; the id is not inspected): calls `camera.grab()` and `detector->detect()`, then sends `image_bgr`, `point_cloud`, `camera_info`, and `objects` outputs. Point cloud output varies by mode: `FULL` sends the raw `sl::Mat` pointer (no copy); `HALF` downsamples by 2 in each dimension; `ROI` emits only valid points within detected bounding boxes as a flat `[N, 4]` array. Handles reconnection on grab failure. - **`DoraTargets.cmake`** — Handles building or fetching dora-rs and generating the CXX bridge files. Two paths: local (`DORA_ROOT_DIR`) or git clone. Produces `dora_node_api_cxx` library and the `node_bridge.cc` glue. - **`dataflow.yml`** — Example dora dataflow definition using the `git:` source format. +- **`Dockerfile`** — Ubuntu 24.04 x86-64 build environment (CUDA 12.8, ZED SDK 5.2, ONNX Runtime, Rust). No ARM64/Jetson image; build natively there. No camera needed; run the compile with `--gpus all`. Sets `NVIDIA_DRIVER_CAPABILITIES=compute,utility,video` — the `video` capability is what makes the container runtime mount NVDEC/NVENC, which `libsl_zed.so` links against. ONNX Runtime's CMake package files are relocated to `/usr/local/lib/cmake` because Ubuntu's multiarch CMake does not search `lib64`. Rust lives at `/usr/local/{rustup,cargo}` rather than `/root` so the build can run as the invoking user. `docker build -t dora-zed-build . && docker run --rm --gpus all --user "$(id -u):$(id -g)" -v "$PWD:/src" -v dora-zed-cargo:/usr/local/cargo/registry dora-zed-build`. - **`scripts/export_yolo.py`** — PEP 723 uv script. Exports a standard YOLOv11 model to ONNX for closed-vocabulary detection. Run: `uv run scripts/export_yolo.py --model n --output-dir models/`. - **`src/test_yolo_onnx.cc`** — Standalone C++ test binary (`bin/test_yolo_onnx`). Exercises `YoloOnnx` with an image (default `test/assets/yolo.png`). No dora and no live camera required. Uses the same env vars as the main binary. Saves an annotated result image alongside the input. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2e30c15 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,75 @@ +# Reproducible build environment for dora-zed. +# +# Compiles only — no camera is needed. Requires an NVIDIA driver and the NVIDIA +# Container Toolkit on the host, as the ZED SDK does anyway. +# +# NVIDIA_DRIVER_CAPABILITIES below includes `video` because libsl_zed.so links +# against NVDEC (libnvcuvid) and NVENC (libnvidia-encode); the container runtime +# mounts those from the host only when `video` is in the list. +# +# Ubuntu 24.04 is the newest release Stereolabs ships a ZED SDK for. +# +# docker build -t dora-zed-build . +# docker run --rm --gpus all --user "$(id -u):$(id -g)" \ +# -v "$PWD:/src" -v dora-zed-cargo:/usr/local/cargo/registry dora-zed-build +# +# --user keeps build/ and bin/ owned by you instead of root. +# +# The first run clones dora-rs and compiles it with Cargo, which takes a while; +# the named volume keeps the registry cache across runs. + +FROM nvidia/cuda:12.8.1-devel-ubuntu24.04 + +ARG ZED_VERSION=5.2 +ARG ORT_VERSION=1.24.4 + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential cmake git curl ca-certificates pkg-config \ + libopencv-dev zstd udev sudo \ + && rm -rf /var/lib/apt/lists/* + +# The toolchain lives outside /root so the container can run as the invoking +# user (--user) and still write the cargo caches. registry/ is created here so +# that a named volume mounted over it inherits these permissions rather than +# being created root-owned. +ENV RUSTUP_HOME=/usr/local/rustup \ + CARGO_HOME=/usr/local/cargo \ + PATH=/usr/local/cargo/bin:${PATH} +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ + | sh -s -- -y --profile minimal --default-toolchain stable \ + && mkdir -p ${CARGO_HOME}/registry \ + && chmod -R a+w ${RUSTUP_HOME} ${CARGO_HOME} + +# The installer leaves /usr/local/zed as drwxrwx--- root:zed, which an arbitrary +# --user uid cannot read, so relax it to make find_package(zed) work for one. +RUN curl -fSL -o /tmp/ZED_SDK.run \ + "https://download.stereolabs.com/zedsdk/${ZED_VERSION}/cu12/ubuntu24" \ + && chmod +x /tmp/ZED_SDK.run \ + && /tmp/ZED_SDK.run -- silent skip_python skip_tools skip_drivers skip_cuda \ + && chmod -R a+rX /usr/local/zed \ + && rm -f /tmp/ZED_SDK.run + +# The tarball puts its CMake package files under lib/, but onnxruntimeTargets.cmake +# resolves the library as /lib64. Ubuntu is multiarch, so CMake does not +# search lib64 for packages and ld.so does not search /usr/local/lib64 at all: +# keep the libraries in lib64, move only the package files to lib/cmake, and add +# lib64 to the linker path. +RUN curl -fSL -o /tmp/ort.tgz \ + "https://github.com/microsoft/onnxruntime/releases/download/v${ORT_VERSION}/onnxruntime-linux-x64-gpu-${ORT_VERSION}.tgz" \ + && tar -xzf /tmp/ort.tgz -C /tmp \ + && mkdir -p /usr/local/include/onnxruntime /usr/local/lib64 \ + && cp -r /tmp/onnxruntime-linux-x64-gpu-${ORT_VERSION}/include/* /usr/local/include/onnxruntime/ \ + && cp -r /tmp/onnxruntime-linux-x64-gpu-${ORT_VERSION}/lib/* /usr/local/lib64/ \ + && mkdir -p /usr/local/lib/cmake \ + && mv /usr/local/lib64/cmake/onnxruntime /usr/local/lib/cmake/ \ + && rmdir /usr/local/lib64/cmake \ + && echo /usr/local/lib64 > /etc/ld.so.conf.d/onnxruntime.conf \ + && ldconfig \ + && rm -rf /tmp/ort.tgz /tmp/onnxruntime-linux-x64-gpu-${ORT_VERSION} + +ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility,video + +WORKDIR /src +CMD ["bash", "-lc", "mkdir -p build && cd build && cmake .. && make -j$(nproc) install"] diff --git a/README.md b/README.md index dce948c..2bfe4cf 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,29 @@ mkdir -p build && cd build && cmake .. && make install Binary installed to `bin/dora_zed`. +### Containerized build + +[`Dockerfile`](Dockerfile) provides the full toolchain — CUDA, ZED SDK, ONNX Runtime and Rust — on Ubuntu 24.04, the newest release Stereolabs ships a ZED SDK for. No camera is needed. + +```bash +docker build -t dora-zed-build . +docker run --rm --gpus all --user "$(id -u):$(id -g)" \ + -v "$PWD:/src" -v dora-zed-cargo:/usr/local/cargo/registry dora-zed-build +``` + +The first run clones dora-rs and compiles it with Cargo; the named volume keeps that cache across runs. +`--user` keeps `build/` and `bin/` owned by you rather than root. + +x86-64 only. On Jetson, run [`scripts/install_linux_arm.sh`](scripts/install_linux_arm.sh) on the +device and build natively — there is no ARM64 image here. + +Needs an NVIDIA driver and the +[NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) +on the host, as the ZED SDK does anyway. The image sets +`NVIDIA_DRIVER_CAPABILITIES=compute,utility,video`: `libsl_zed.so` links against NVDEC +(`libnvcuvid`) and NVENC (`libnvidia-encode`), which the container runtime mounts from the host +only when `video` is in the capability list. + ## Configuration All behavior is controlled via environment variables.