From 3cb6d5ee3b2de61e45dda52f7918beafc51376c7 Mon Sep 17 00:00:00 2001 From: Bernard Maacaron Date: Tue, 5 May 2026 09:41:47 +0200 Subject: [PATCH] Refactor BallBalance demo scripts and update YARP manager applications - Consolidated BallBalance demo scripts into a single script for both moving and stationary trials. - Updated `launch-ballbalance-demo.sh` to select trials based on a defaults file. - Removed deprecated demo scripts: `demo-ballbalance-moving.sh` and `demo-ballbalance-stationary.sh`. - Enhanced `launch-ballbalance-tool.sh` to handle RGB data availability and create datasets without RGB if necessary. - Added new YARP manager application for the consolidated BallBalance demo. - Updated existing YARP manager applications to reflect changes in demo structure and added a new Skin GUI application. - Modified `compose.yaml` to include new environment variables for Metavision SDK installation. - Updated build log and Dockerfile to reflect changes in dependencies and installation processes. - Changed author names in YARP manager application XML files from "Codex" to "Bear". --- .env | 5 +- .env.example | 8 +- DEVELOPER_README.md | 76 +++++++++-- Dockerfile | 36 ++++- REPOSITORY_REFERENCE.md | 25 ++-- USER_README.md | 96 +++++++++++--- build_log.txt | 70 ++++++++++ compose.yaml | 6 +- scripts/demo-ballbalance-stationary.sh | 6 - scripts/demo-ballbalance.sh | 31 +++-- scripts/internal/launch-ballbalance-demo.sh | 35 +++-- scripts/internal/launch-ballbalance-tool.sh | 123 ++++++++++++++---- scripts/internal/yarpscope_encoders.xml | 34 +++++ ...-ballbalance-moving.sh => open-skingui.sh} | 3 +- scripts/show-versions.sh | 7 + scripts/stop-demo.sh | 2 +- scripts/workstation-menu.sh | 16 +-- .../applications/01-yarp-data-player.xml | 2 +- yarpmanager/applications/02-yarp-scope.xml | 2 +- yarpmanager/applications/03-yarp-view.xml | 2 +- yarpmanager/applications/04-vframer-left.xml | 2 +- yarpmanager/applications/04-vframer-right.xml | 2 +- yarpmanager/applications/05-all-tools.xml | 12 +- .../applications/06-ballbalance-demo.xml | 15 +++ .../06-ballbalance-moving-demo.xml | 76 ----------- .../07-ballbalance-stationary-demo.xml | 76 ----------- yarpmanager/applications/07-skin-gui.xml | 16 +++ yarpmanager/defaults.env | 5 +- 28 files changed, 516 insertions(+), 273 deletions(-) create mode 100644 build_log.txt delete mode 100755 scripts/demo-ballbalance-stationary.sh create mode 100644 scripts/internal/yarpscope_encoders.xml rename scripts/{demo-ballbalance-moving.sh => open-skingui.sh} (63%) create mode 100644 yarpmanager/applications/06-ballbalance-demo.xml delete mode 100644 yarpmanager/applications/06-ballbalance-moving-demo.xml delete mode 100644 yarpmanager/applications/07-ballbalance-stationary-demo.xml create mode 100644 yarpmanager/applications/07-skin-gui.xml diff --git a/.env b/.env index 03ea4e0..f9bf966 100644 --- a/.env +++ b/.env @@ -1,8 +1,11 @@ DISPLAY=:1 HOST_DATA_PATH=/home/bmaacaron-iit.local/Documents/Datasets/2026_PRIMI/ +# Default base image avoids anonymous Docker Hub pull-rate limits. +BASE_IMAGE=public.ecr.aws/ubuntu/ubuntu:22.04 + # These defaults track the latest upstream refs validated in this repo. YCM_VERSION=v0.18.4 YARP_VERSION=v3.12.2 ED_VERSION=main -ED_COMMIT=bf0a4d71c1013d2bbdf911d0ba88678ce3909ae8 +ED_COMMIT=45bce288ba616b2f19152ee96cecbb4da1c924cf diff --git a/.env.example b/.env.example index 57e0770..5f436a1 100644 --- a/.env.example +++ b/.env.example @@ -8,4 +8,10 @@ BASE_IMAGE=public.ecr.aws/ubuntu/ubuntu:22.04 YCM_VERSION=v0.18.4 YARP_VERSION=v3.12.2 ED_VERSION=main -ED_COMMIT=bf0a4d71c1013d2bbdf911d0ba88678ce3909ae8 +ED_COMMIT=45bce288ba616b2f19152ee96cecbb4da1c924cf + +# Default builds omit Metavision SDK because the current SDK 5.x packages +# require authenticated access to Prophesee's JFrog server. +INSTALL_METAVISION_SDK=0 +PROPHESEE_JFROG_USER= +PROPHESEE_JFROG_TOKEN= diff --git a/DEVELOPER_README.md b/DEVELOPER_README.md index 30eb115..9eb76b2 100644 --- a/DEVELOPER_README.md +++ b/DEVELOPER_README.md @@ -17,7 +17,7 @@ The policy is: - redundancy in access methods is acceptable - hidden implementation layers should not be duplicated unnecessarily -- `yarpmanager` applications should launch the applications themselves, not `bash` wrappers +- `yarpmanager` applications should launch the applications themselves unless a shared script carries essential coordination behavior - deprecated launch wrappers should be removed when they stop carrying their own behavior ## Current Architecture @@ -42,8 +42,8 @@ The policy is: There are two real launch engines now: 1. `yarpmanager` XML apps - - generic tools and BallBalance demos launch the applications directly - - the BallBalance manager apps use native dependencies and connections + - generic tools launch the applications directly + - the BallBalance manager entry reuses the shared coordinated launcher so it behaves the same way as the menu and CLI 2. script-based internal launchers - [launch-ballbalance-demo.sh](scripts/internal/launch-ballbalance-demo.sh) @@ -87,6 +87,9 @@ The most important values are: - `YARP_VERSION` - `ED_VERSION` - `ED_COMMIT` +- `INSTALL_METAVISION_SDK` +- `PROPHESEE_JFROG_USER` +- `PROPHESEE_JFROG_TOKEN` ### `BASE_IMAGE` @@ -107,9 +110,50 @@ This keeps Ubuntu 22.04 compatibility while avoiding anonymous Docker Hub pull-r Update both together when you intentionally refresh to a newer upstream snapshot. -### `vFramer` Defaults +### `INSTALL_METAVISION_SDK` -There are intentionally three configuration points now, because there are still two real launch engines and two event streams: +The image now omits Metavision SDK by default. + +This is deliberate: + +- the BallBalance and generic GUI workflows in this repository use recorded YARP streams and do not need the SDK +- the older anonymous `apt.prophesee.ai` feed used by upstream historical Dockerfiles is no longer the current documented Prophesee install path +- the current SDK 5.x package flow requires authenticated JFrog access + +If a maintainer or user needs the SDK for live Prophesee camera integration, including upstream tools such as `atis3-bridge`, they can opt in by setting: + +- `INSTALL_METAVISION_SDK=1` +- `PROPHESEE_JFROG_USER=` +- `PROPHESEE_JFROG_TOKEN=` + +and then rebuilding with: + +```bash +./scripts/build.sh +``` + +The Dockerfile follows the current documented JFrog-based install flow only when this opt-in is enabled. + +Reference: + +- Prophesee Linux SDK installation guide: https://docs.prophesee.ai/stable/installation/linux.html + +### Script Defaults + +The script launchers read [defaults.env](yarpmanager/defaults.env). + +That file now carries: + +- `BALLBALANCE_DEMO_TRIAL` +- `VFRAMER_DEFAULT_SIDE` +- `VFRAMER_LEFT_SRC` +- `VFRAMER_RIGHT_SRC` +- `VFRAMER_LEFT_NAME` +- `VFRAMER_RIGHT_NAME` +- `VFRAMER_WIDTH` +- `VFRAMER_HEIGHT` + +There are still three `vFramer` configuration points, because there are still two real launch engines and two event streams: - `yarpmanager` `VFramer Left` app: [04-vframer-left.xml](yarpmanager/applications/04-vframer-left.xml) - `yarpmanager` `VFramer Right` app: [04-vframer-right.xml](yarpmanager/applications/04-vframer-right.xml) @@ -126,6 +170,8 @@ The shared `vFramer` defaults now cover: - width - height +The BallBalance demo scripts also read `BALLBALANCE_DEMO_TRIAL` from the same file, so switching between `trial_0`, `trial_1`, and `trial_2` is a one-line change. + ## Developer Workflows Build: @@ -175,18 +221,26 @@ The generic `yarpmanager` applications are direct-launch only: ### BallBalance -BallBalance is intentionally available via two approaches: +BallBalance is intentionally available through the menu, the direct CLI entrypoint, and `yarpmanager`, but those now share one implementation path. + +The public entrypoint is: + +```bash +./scripts/demo-ballbalance.sh +``` -- script-based demos from the public CLI wrappers -- direct-launch `yarpmanager` demos +and the manager exposes one `BallBalance Demo` application that runs the same internal coordinator. -Those duplicate some session metadata, but the duplication is currently justified because the script path still carries behavior that the manager path does not: +This shared path is intentional because the BallBalance launcher carries behavior that is worth centralizing: - pre-cleanup of matching old GUI/demo tools - explicit waits for ports - retry logic for connections +- RGB-port fallback between `/yarpdataplayer/grabber` and `/yarpdataplayer/rgb` +- trial selection from `BALLBALANCE_DEMO_TRIAL` +- omission of the RGB replay stream when the selected trial has an empty `rgb/data.log`, because that input currently makes `yarpdataplayer` crash -If this behavior ever gets unified elsewhere, that duplicated session metadata should be reduced. +The older multi-demo split was removed because the mounted dataset now uses the current trial-based layout, and the supported BallBalance entry is a single demo launcher with a configurable trial. ## GitHub Distribution @@ -471,7 +525,7 @@ Official GitHub references for the GHCR workflow: ## Known Limits -- the current image still assumes the Prophesee / Metavision SDK path from the upstream `event-driven` Dockerfile +- the default image omits Metavision SDK, so Prophesee-specific live camera integration is not available unless a user opts in with valid JFrog credentials - the exact live camera vendor is still a hardware-specific unknown - scripted BallBalance demos intentionally pre-clean matching GUI/demo tools before launch - manager-launched BallBalance demos do not pre-clean matching GUI/demo tools before launch diff --git a/Dockerfile b/Dockerfile index 3aa1f8d..0239a90 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,8 +7,12 @@ ARG CODE_DIR=/usr/local/src ARG BASE_IMAGE ARG YCM_VERSION=v0.18.4 ARG YARP_VERSION=v3.12.2 +ARG ICUB_MAIN_VERSION=v2.9.0 ARG ED_VERSION=main -ARG ED_COMMIT=bf0a4d71c1013d2bbdf911d0ba88678ce3909ae8 +ARG ED_COMMIT=45bce288ba616b2f19152ee96cecbb4da1c924cf +ARG INSTALL_METAVISION_SDK=0 +ARG PROPHESEE_JFROG_USER= +ARG PROPHESEE_JFROG_TOKEN= RUN apt-get update && apt-get install -y \ ca-certificates \ @@ -25,6 +29,7 @@ RUN apt-get update && apt-get install -y \ libglew-dev \ libglfw3-dev \ libglm-dev \ + libgsl-dev \ libgraphviz-dev \ libgstreamer-plugins-base1.0-dev \ libgstreamer1.0-dev \ @@ -51,11 +56,25 @@ RUN apt-get update && apt-get install -y \ gosu \ && rm -rf /var/lib/apt/lists/* -# The upstream event-driven Dockerfile uses Prophesee's Ubuntu 22.04 SDK feed. -RUN echo "deb [arch=amd64 trusted=yes] https://apt.prophesee.ai/dists/public/baiTh5si/ubuntu jammy sdk" >> /etc/apt/sources.list \ - && apt-get update \ - && apt-get install -y metavision-sdk \ - && rm -rf /var/lib/apt/lists/* +# Metavision SDK is optional. The default image omits it because the current +# Prophesee SDK 5.x install flow requires authenticated access to JFrog. +RUN if [ "${INSTALL_METAVISION_SDK}" = "1" ]; then \ + if [ -z "${PROPHESEE_JFROG_USER}" ] || [ -z "${PROPHESEE_JFROG_TOKEN}" ]; then \ + echo "INSTALL_METAVISION_SDK=1 requires PROPHESEE_JFROG_USER and PROPHESEE_JFROG_TOKEN" >&2; \ + exit 1; \ + fi; \ + apt-get update; \ + apt-get install -y curl; \ + curl -L https://propheseeai.jfrog.io/artifactory/api/security/keypair/prophesee-gpg/public >/tmp/propheseeai.jfrog.op.asc; \ + cp /tmp/propheseeai.jfrog.op.asc /etc/apt/trusted.gpg.d/propheseeai.jfrog.op.asc; \ + printf 'machine propheseeai.jfrog.io\nlogin %s\npassword %s\n' "${PROPHESEE_JFROG_USER}" "${PROPHESEE_JFROG_TOKEN}" >/etc/apt/auth.conf.d/prophesee-jfrog.conf; \ + chmod 600 /etc/apt/auth.conf.d/prophesee-jfrog.conf; \ + printf 'deb https://propheseeai.jfrog.io/artifactory/metavision-sdk-5-debian/ /\n' >/etc/apt/sources.list.d/metavision-sdk.list; \ + apt-get update; \ + apt-get install -y metavision-sdk; \ + rm -f /etc/apt/auth.conf.d/prophesee-jfrog.conf /etc/apt/sources.list.d/metavision-sdk.list /tmp/propheseeai.jfrog.op.asc; \ + rm -rf /var/lib/apt/lists/*; \ + fi RUN git clone --depth 1 --branch "${YCM_VERSION}" https://github.com/robotology/ycm-cmake-modules.git "${CODE_DIR}/ycm" \ && cmake -S "${CODE_DIR}/ycm" -B "${CODE_DIR}/ycm/build" \ @@ -68,6 +87,11 @@ RUN git clone --depth 1 --branch "${YARP_VERSION}" https://github.com/robotology && cmake --install "${CODE_DIR}/yarp/build" \ && yarp check +RUN git clone --depth 1 --branch "${ICUB_MAIN_VERSION}" https://github.com/robotology/icub-main.git "${CODE_DIR}/icub-main" \ + && cmake -S "${CODE_DIR}/icub-main" -B "${CODE_DIR}/icub-main/build" -DBUILD_TESTING=OFF \ + && cmake --build "${CODE_DIR}/icub-main/build" -j"$(nproc)" \ + && cmake --install "${CODE_DIR}/icub-main/build" + RUN git clone --depth 1 --branch "${ED_VERSION}" https://github.com/robotology/event-driven.git "${CODE_DIR}/event-driven" \ && test "$(git -C "${CODE_DIR}/event-driven" rev-parse HEAD)" = "${ED_COMMIT}" \ && cmake -S "${CODE_DIR}/event-driven" -B "${CODE_DIR}/event-driven/build" \ diff --git a/REPOSITORY_REFERENCE.md b/REPOSITORY_REFERENCE.md index 3836396..465992c 100644 --- a/REPOSITORY_REFERENCE.md +++ b/REPOSITORY_REFERENCE.md @@ -22,9 +22,9 @@ Conventions used below: | Path | Type | What it does | | --- | --- | --- | -| [Dockerfile](Dockerfile) | config file | Builds the Ubuntu-based workstation image. Installs system dependencies, Prophesee/Metavision SDK, YCM, YARP, `event-driven`, the `robotology` user, and the in-container helper scripts. | +| [Dockerfile](Dockerfile) | config file | Builds the Ubuntu-based workstation image. Installs system dependencies, optionally installs Prophesee Metavision SDK when explicitly enabled with credentials, then installs YCM, YARP, `event-driven`, the `robotology` user, and the in-container helper scripts. | | [compose.yaml](compose.yaml) | config file | Defines the single `robotology` container. Builds from the Dockerfile, uses host networking, mounts the project and data directories, forwards X11, and keeps the container alive with `sleep infinity`. | -| [`.env.example`](.env.example) | config file | Template for the local environment file. Sets the display, host data path, build versions, and default base image. | +| [`.env.example`](.env.example) | config file | Template for the local environment file. Sets the display, host data path, build versions, default base image, and the optional Metavision SDK opt-in variables. | | [`.env`](.env) | config file | Local machine-specific copy of `.env.example`. Docker Compose reads this automatically when scripts call `docker compose`. | ## Public Host Scripts @@ -37,7 +37,7 @@ These are the main scripts people are expected to run from the host machine. | [scripts/start-workstation.sh](scripts/start-workstation.sh) | Starts the container if needed, ensures `yarpserver` is up, and exits once the workstation is ready. | | [scripts/start-yarpserver.sh](scripts/start-yarpserver.sh) | Ensures `yarpserver` is running inside the already-started container. It is safe to call repeatedly. | | [scripts/status.sh](scripts/status.sh) | Shows the Compose service status and reports whether the YARP name server is currently detectable inside the container. | -| [scripts/show-versions.sh](scripts/show-versions.sh) | Prints the configured build refs and, when the container is running, the installed `YARP` and `event-driven` versions from inside the image. | +| [scripts/show-versions.sh](scripts/show-versions.sh) | Prints the configured build refs and, when the container is running, the installed `YARP`, `event-driven`, and Metavision SDK status from inside the image. | | [scripts/stop-workstation.sh](scripts/stop-workstation.sh) | Stops and removes the Compose-managed container with `docker compose down`. | | [scripts/shell.sh](scripts/shell.sh) | Opens an interactive shell inside the running container as the `robotology` user. | | [scripts/list-data.sh](scripts/list-data.sh) | Prints the mounted container data path and lists the contents of `/workspace/data`. Useful for checking that the host dataset mount is correct. | @@ -45,12 +45,10 @@ These are the main scripts people are expected to run from the host machine. | [scripts/open-dataplayer.sh](scripts/open-dataplayer.sh) | Launches the generic `yarpdataplayer` GUI from the container. | | [scripts/open-yarpview.sh](scripts/open-yarpview.sh) | Launches the generic `yarpview` GUI from the container. | | [scripts/open-yarpscope.sh](scripts/open-yarpscope.sh) | Launches the generic `yarpscope` GUI from the container. | -| [scripts/open-vframer.sh](scripts/open-vframer.sh) | Launches `vFramer` through the script-based launcher. Accepts `left` or `right` and still reads defaults from `yarpmanager/defaults.env`. | -| [scripts/demo-ballbalance.sh](scripts/demo-ballbalance.sh) | Shared BallBalance demo launcher. Accepts `moving` or `stationary`, ensures X11 and `yarpserver`, then starts the internal coordinated demo launcher. | -| [scripts/demo-ballbalance-moving.sh](scripts/demo-ballbalance-moving.sh) | Thin wrapper that runs `demo-ballbalance.sh moving`. | -| [scripts/demo-ballbalance-stationary.sh](scripts/demo-ballbalance-stationary.sh) | Thin wrapper that runs `demo-ballbalance.sh stationary`. | +| [scripts/open-vframer.sh](scripts/open-vframer.sh) | Launches `vFramer` through the script-based launcher. Accepts `left` or `right` and reads defaults from `yarpmanager/defaults.env`. | +| [scripts/demo-ballbalance.sh](scripts/demo-ballbalance.sh) | BallBalance demo launcher. Ensures X11 and `yarpserver`, reads `BALLBALANCE_DEMO_TRIAL` from `yarpmanager/defaults.env`, then starts the internal coordinated launcher for that trial. If the selected recording has no RGB replay data, it tells the user that `yarpview` will be skipped. | | [scripts/stop-demo.sh](scripts/stop-demo.sh) | Stops matching GUI/demo processes inside the container (`yarpdataplayer`, `yarpview`, `yarpscope`, `vFramer`) and cleans stale YARP ports. | -| [scripts/workstation-menu.sh](scripts/workstation-menu.sh) | Text menu that exposes the main public scripts in a guided interactive form. | +| [scripts/workstation-menu.sh](scripts/workstation-menu.sh) | Text menu that exposes the main public scripts in a guided interactive form. The BallBalance menu entry launches the trial selected by `BALLBALANCE_DEMO_TRIAL` from the mounted `2026_PRIMI` tree. | | [scripts/verify-repo.sh](scripts/verify-repo.sh) | Developer consistency check. Validates `yarpmanager` XML, ensures the XML apps are not shelling out through `bash`, and checks that the left/right `vFramer` source, name, width, and height defaults stay aligned. | ## Shared And Internal Host Scripts @@ -61,8 +59,8 @@ These scripts support the public entrypoints. Most are not intended as the first | --- | --- | | [scripts/common.sh](scripts/common.sh) | Shared function library for the host scripts. Wraps `docker compose`, handles Docker checks, X11 access, exec modes, container startup, and `yarpserver` detection. | | [scripts/require-docker.sh](scripts/require-docker.sh) | Checks whether Docker is reachable and prints tailored troubleshooting guidance for common failure modes such as socket permissions or a stopped daemon. | -| [scripts/internal/launch-ballbalance-demo.sh](scripts/internal/launch-ballbalance-demo.sh) | Coordinates the script-based BallBalance demo startup. Starts the dataplayer first, then launches the viewers, tracks child PIDs, and cleans them up on exit. | -| [scripts/internal/launch-ballbalance-tool.sh](scripts/internal/launch-ballbalance-tool.sh) | Implements the script-based BallBalance tool logic for one tool at a time. Chooses the dataset, waits for ports, performs YARP connections, and handles cleanup/retry behavior. | +| [scripts/internal/launch-ballbalance-demo.sh](scripts/internal/launch-ballbalance-demo.sh) | Coordinates the BallBalance demo startup. Reads `BALLBALANCE_DEMO_TRIAL`, starts the dataplayer first, launches the remaining tools, skips `yarpview` when the selected recording has no RGB replay log, tracks child PIDs, and cleans them up on exit. | +| [scripts/internal/launch-ballbalance-tool.sh](scripts/internal/launch-ballbalance-tool.sh) | Implements the BallBalance tool logic for one tool at a time. Uses the trial selected by `BALLBALANCE_DEMO_TRIAL`, checks that it exists, builds a replay-safe dataset without RGB when the selected recording has an empty `rgb/data.log`, waits for ports, performs YARP connections, and handles cleanup/retry behavior. | | [scripts/internal/launch-vframer.sh](scripts/internal/launch-vframer.sh) | Reads `yarpmanager/defaults.env`, resolves the requested side-specific source, YARP name, width, and height, and starts `vFramer`. | ## Container Scripts @@ -81,15 +79,14 @@ These files define what `yarpmanager` sees and how it behaves. | Path | What it does | | --- | --- | | [yarpmanager/ymanager.ini](yarpmanager/ymanager.ini) | Main `yarpmanager` configuration. Points to the applications/modules/resources folders and enables `auto_connect` so the BallBalance app-defined connections can happen automatically. | -| [yarpmanager/defaults.env](yarpmanager/defaults.env) | Script-only defaults for the `vFramer` launcher, including the left/right source ports, unique YARP names, and shared window size. This does not drive the direct-launch `yarpmanager` XML by itself. | +| [yarpmanager/defaults.env](yarpmanager/defaults.env) | Shared defaults for the script-based launchers. It currently stores `BALLBALANCE_DEMO_TRIAL` plus the `vFramer` source ports, unique YARP names, and shared window size. | | [yarpmanager/applications/01-yarp-data-player.xml](yarpmanager/applications/01-yarp-data-player.xml) | `yarpmanager` application definition for the generic `yarpdataplayer` GUI. | | [yarpmanager/applications/02-yarp-scope.xml](yarpmanager/applications/02-yarp-scope.xml) | `yarpmanager` application definition for the generic `yarpscope` GUI. | | [yarpmanager/applications/03-yarp-view.xml](yarpmanager/applications/03-yarp-view.xml) | `yarpmanager` application definition for the generic `yarpview` GUI. | | [yarpmanager/applications/04-vframer-left.xml](yarpmanager/applications/04-vframer-left.xml) | `yarpmanager` application definition for the generic left `vFramer` GUI, using `/zynqGrabber/left/AE:o`, the unique name `/vframer/left`, and a `640x480` window. | | [yarpmanager/applications/04-vframer-right.xml](yarpmanager/applications/04-vframer-right.xml) | `yarpmanager` application definition for the generic right `vFramer` GUI, using `/zynqGrabber/right/AE:o`, the unique name `/vframer/right`, and a `640x480` window. | | [yarpmanager/applications/05-all-tools.xml](yarpmanager/applications/05-all-tools.xml) | `yarpmanager` application that launches the generic tools together, including both `vFramer` viewers. It does not auto-load a dataset. | -| [yarpmanager/applications/06-ballbalance-moving-demo.xml](yarpmanager/applications/06-ballbalance-moving-demo.xml) | Direct-launch `yarpmanager` application for the moving BallBalance demo. Loads `test_moving`, declares port dependencies, and connects the RGB stream to `yarpview`. | -| [yarpmanager/applications/07-ballbalance-stationary-demo.xml](yarpmanager/applications/07-ballbalance-stationary-demo.xml) | Direct-launch `yarpmanager` application for the stationary BallBalance demo. Loads `test_stationary`, declares port dependencies, and connects the RGB stream to `yarpview`. | +| [yarpmanager/applications/06-ballbalance-demo.xml](yarpmanager/applications/06-ballbalance-demo.xml) | `yarpmanager` application for the single supported BallBalance demo. It reuses the coordinated internal launcher so the manager path gets the same trial selection, cleanup, waits, and empty-RGB handling as the menu and CLI. | | [yarpmanager/modules/.gitkeep](yarpmanager/modules/.gitkeep) | Placeholder to keep the modules directory in Git even though this repo does not currently define custom module XML files. | | [yarpmanager/resources/.gitkeep](yarpmanager/resources/.gitkeep) | Placeholder to keep the resources directory in Git even though this repo does not currently define custom resource files. | @@ -115,4 +112,4 @@ The key implementation split is: - shared logic lives in [scripts/common.sh](scripts/common.sh) - script-only orchestration lives in [scripts/internal](scripts/internal/) - in-container runtime helpers live in [container-scripts](container-scripts/) -- direct-launch `yarpmanager` behavior lives in [yarpmanager/applications](yarpmanager/applications/) +- `yarpmanager` behavior lives in [yarpmanager/applications](yarpmanager/applications/) diff --git a/USER_README.md b/USER_README.md index 67fd9f1..70c89b1 100644 --- a/USER_README.md +++ b/USER_README.md @@ -7,7 +7,7 @@ This guide is for operators and users who want to run the workstation, open the - one Dockerized `YARP` + `event-driven` workstation - GUI forwarding from the container to the host desktop - helper scripts for common tasks -- `yarpmanager` applications for the generic tools and BallBalance demos +- `yarpmanager` applications for the generic tools and the BallBalance demo Inside the container, user data is mounted at: @@ -81,6 +81,8 @@ Check the configured build refs and the currently installed container versions: ./scripts/show-versions.sh ``` +The default image omits Prophesee's Metavision SDK. That is intentional. The documented BallBalance and generic GUI workflows in this repository use recorded YARP streams and do not need the SDK. + If your repository owner has already published a GHCR image for this project, they may give you a pull-first path instead of a local build. This guide keeps the local build as the default operator workflow. Pull-first alternative: @@ -103,21 +105,64 @@ If you use that path, make sure your maintainer also tells you how they want [co ./scripts/workstation-menu.sh ``` -5. In the menu, choose `Open yarpmanager`. - -6. Inside `yarpmanager`, launch one of: - -- `BallBalance Moving Demo` -- `BallBalance Stationary Demo` +5. In the menu, choose `Run BallBalance demo`. What opens: - `yarpdataplayer` -- `yarpview` - `yarpscope` - `vFramer Left` - `vFramer Right` +If the selected trial is mounted with an empty `rgb/data.log`, `yarpview` is skipped. +That recording's `rgb/data.log` is empty, and `yarpdataplayer` crashes on it unless the RGB stream is omitted. + +The menu demo loads: + +- `/workspace/data/BallBalance/` + +Change the selected BallBalance recording in [yarpmanager/defaults.env](yarpmanager/defaults.env): + +```bash +BALLBALANCE_DEMO_TRIAL=trial_2 +``` + +## Optional Metavision SDK + +This repository omits Metavision SDK by default. + +What we need it for: + +- live Prophesee event-camera integration through the upstream `event-driven` Prophesee bridge tooling such as `atis3-bridge` +- development work that specifically depends on Prophesee's proprietary SDK packages rather than recorded YARP datasets + +What the problem is: + +- the old anonymous `apt.prophesee.ai` package feed used by older Dockerfiles is no longer the current documented install path +- the current Prophesee SDK 5.x Linux install flow uses authenticated access to Prophesee's JFrog server +- without those credentials, the Docker build either times out against the old feed or cannot install `metavision-sdk` + +What still works without it: + +- `yarpmanager` +- `yarpdataplayer` +- `yarpview` +- `yarpscope` +- `vFramer` +- BallBalance demos based on recorded data under `/workspace/data` + +How to include the SDK if you have access: + +1. Obtain your Prophesee JFrog credentials by following Prophesee's Linux installation guide for Metavision SDK: https://docs.prophesee.ai/stable/installation/linux.html +2. Open your local [`.env`](.env) file. +3. Set `INSTALL_METAVISION_SDK=1`. +4. Set `PROPHESEE_JFROG_USER` to your Prophesee JFrog login. +5. Set `PROPHESEE_JFROG_TOKEN` to your Prophesee JFrog identity token. +6. Rebuild the image with `./scripts/build.sh`. +7. Run `./scripts/show-versions.sh` after starting the workstation and confirm it reports `Metavision SDK: installed`. + +Keep those credentials only in your local [`.env`](.env). Do not commit them. + ## Main Ways To Use It ### Menu Workflow @@ -133,14 +178,15 @@ The menu exposes: - workstation start - status - `yarpmanager` -- BallBalance moving demo -- BallBalance stationary demo +- BallBalance demo - each individual GUI tool - stop demo only - list data - shell - stop workstation +The menu demo entry loads the trial selected by `BALLBALANCE_DEMO_TRIAL` in [yarpmanager/defaults.env](yarpmanager/defaults.env). + ### CLI Workflow Use this if you want script-based entrypoints without entering the container manually. @@ -180,11 +226,10 @@ Open generic tools: ./scripts/open-dataplayer.sh ``` -Run the BallBalance demos: +Run the BallBalance demo: ```bash -./scripts/demo-ballbalance-moving.sh -./scripts/demo-ballbalance-stationary.sh +./scripts/demo-ballbalance.sh ``` Stop the matching GUI demo tools: @@ -215,8 +260,9 @@ Configured applications: - `VFramer Left` - `VFramer Right` - `All Tools` -- `BallBalance Moving Demo` -- `BallBalance Stationary Demo` +- `BallBalance Demo` + +The BallBalance demo entry loads the trial selected by `BALLBALANCE_DEMO_TRIAL` in [yarpmanager/defaults.env](yarpmanager/defaults.env). What they mean: @@ -226,8 +272,7 @@ What they mean: - `VFramer Left`: opens `vFramer` using the left source configured in [04-vframer-left.xml](yarpmanager/applications/04-vframer-left.xml) - `VFramer Right`: opens `vFramer` using the right source configured in [04-vframer-right.xml](yarpmanager/applications/04-vframer-right.xml) - `All Tools`: opens the generic tools together, including both `vFramer` viewers, and does not auto-load a dataset -- `BallBalance Moving Demo`: auto-loads `test_moving` and opens the four matching viewers directly in `yarpmanager` -- `BallBalance Stationary Demo`: auto-loads `test_stationary` and opens the four matching viewers directly in `yarpmanager` +- `BallBalance Demo`: runs the coordinated launcher for the trial selected by `BALLBALANCE_DEMO_TRIAL`; if the mounted recording has an empty `rgb/data.log`, it skips `yarpview` If you want to stop a manager-launched BallBalance session from the CLI, use: @@ -267,16 +312,19 @@ If you change `YCM_VERSION`, `YARP_VERSION`, `ED_VERSION`, or `ED_COMMIT`, rebui ## Important Behavior - BallBalance demos use `yarpdataplayer` replay outputs under `/yarpdataplayer/...` -- scripted BallBalance demos clean up matching old GUI/demo tools before launching a new session -- manager-launched BallBalance demos run tools directly and do not pre-clean old GUI/demo tools +- the BallBalance demo always loads `/workspace/data/BallBalance/` +- change the selected trial in [yarpmanager/defaults.env](yarpmanager/defaults.env) with `BALLBALANCE_DEMO_TRIAL=trial_0`, `trial_1`, or `trial_2` +- the menu, CLI, and `yarpmanager` BallBalance entry all reuse the same coordinated launcher +- the launcher cleans up matching old GUI/demo tools before starting a new session +- if the selected trial has an empty `rgb/data.log`, the launcher omits the RGB stream so `yarpdataplayer` does not crash - `All Tools` is generic and does not auto-load a dataset ## BallBalance Tool Associations | Tool | Dataset / source | Purpose | | --- | --- | --- | -| `yarpdataplayer` | `/workspace/data/BallBalance/test_moving` or `/workspace/data/BallBalance/test_stationary` | replays the recorded session | -| `yarpview` | `/yarpdataplayer/grabber` | shows the RGB camera stream | +| `yarpdataplayer` | `/workspace/data/BallBalance/` | replays the selected recorded session | +| `yarpview` | `/yarpdataplayer/grabber` or `/yarpdataplayer/rgb` | shows the RGB camera stream when the mounted recording actually contains RGB replay data | | `yarpscope` | `/yarpdataplayer/icub/right_arm/state:o` | plots the right-arm encoder stream | | `vFramer Left` | `/yarpdataplayer/zynqGrabber/left/AE:o` | visualizes the left event-camera stream | | `vFramer Right` | `/yarpdataplayer/zynqGrabber/right/AE:o` | visualizes the right event-camera stream | @@ -323,6 +371,12 @@ VFRAMER_WIDTH=640 VFRAMER_HEIGHT=480 ``` +If you want the BallBalance demo to use a different recording, edit the same file: + +```bash +BALLBALANCE_DEMO_TRIAL=trial_0 +``` + If the host data folder changes, update [`.env`](.env) and re-apply the runtime: ```bash diff --git a/build_log.txt b/build_log.txt new file mode 100644 index 0000000..25bf96d --- /dev/null +++ b/build_log.txt @@ -0,0 +1,70 @@ + Image primi_iit_docker-robotology Building +#1 [internal] load local bake definitions +#1 reading from stdin 991B done +#1 DONE 0.0s + +#2 [internal] load build definition from Dockerfile +#2 transferring dockerfile: 4.56kB done +#2 DONE 0.0s + +#3 [internal] load metadata for public.ecr.aws/ubuntu/ubuntu:22.04 +#3 DONE 1.1s + +#4 [internal] load .dockerignore +#4 transferring context: 89B done +#4 DONE 0.0s + +#5 [ 1/12] FROM public.ecr.aws/ubuntu/ubuntu:22.04@sha256:74f1fdaef92dff9c4da5c35e90b92b07807ef8c27114f622c700107d7042d79e +#5 resolve public.ecr.aws/ubuntu/ubuntu:22.04@sha256:74f1fdaef92dff9c4da5c35e90b92b07807ef8c27114f622c700107d7042d79e 0.0s done +#5 DONE 0.0s + +#6 [internal] load build context +#6 transferring context: 157B done +#6 DONE 0.0s + +#7 [ 5/12] RUN git clone --depth 1 --branch "v3.12.2" https://github.com/robotology/yarp.git "/usr/local/src/yarp" && cmake -S "/usr/local/src/yarp" -B "/usr/local/src/yarp/build" && cmake --build "/usr/local/src/yarp/build" -j"$(nproc)" && cmake --install "/usr/local/src/yarp/build" && yarp check +#7 CACHED + +#8 [10/12] COPY container-scripts/container-entrypoint.sh /usr/local/bin/container-entrypoint +#8 CACHED + +#9 [ 2/12] RUN apt-get update && apt-get install -y ca-certificates build-essential cmake cmake-curses-gui ffmpeg git libace-dev libassimp-dev libboost-program-options-dev libcanberra-gtk-module libeigen3-dev libglew-dev libglfw3-dev libglm-dev libgsl-dev libgraphviz-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libjpeg-dev libopencv-dev libqcustomplot-dev mesa-utils python3 python3-pip qtbase5-dev qtdeclarative5-dev qtmultimedia5-dev qml-module-qtmultimedia qml-module-qt-labs-folderlistmodel qml-module-qt-labs-settings qml-module-qtquick-controls qml-module-qtquick-dialogs qml-module-qtquick-window2 qml-module-qtquick2 gstreamer1.0-libav gstreamer1.0-plugins-bad gstreamer1.0-plugins-base gstreamer1.0-plugins-good gosu && rm -rf /var/lib/apt/lists/* +#9 CACHED + +#10 [ 8/12] RUN groupadd -g 1000 -o robotology && useradd -m -u 1000 -g 1000 -o -s /bin/bash robotology +#10 CACHED + +#11 [ 3/12] RUN if [ "0" = "1" ]; then if [ -z "" ] || [ -z "" ]; then echo "INSTALL_METAVISION_SDK=1 requires PROPHESEE_JFROG_USER and PROPHESEE_JFROG_TOKEN" >&2; exit 1; fi; apt-get update; apt-get install -y curl; curl -L https://propheseeai.jfrog.io/artifactory/api/security/keypair/prophesee-gpg/public >/tmp/propheseeai.jfrog.op.asc; cp /tmp/propheseeai.jfrog.op.asc /etc/apt/trusted.gpg.d/propheseeai.jfrog.op.asc; printf 'machine propheseeai.jfrog.io\nlogin %s\npassword %s\n' "" "" >/etc/apt/auth.conf.d/prophesee-jfrog.conf; chmod 600 /etc/apt/auth.conf.d/prophesee-jfrog.conf; printf 'deb https://propheseeai.jfrog.io/artifactory/metavision-sdk-5-debian/ /\n' >/etc/apt/sources.list.d/metavision-sdk.list; apt-get update; apt-get install -y metavision-sdk; rm -f /etc/apt/auth.conf.d/prophesee-jfrog.conf /etc/apt/sources.list.d/metavision-sdk.list /tmp/propheseeai.jfrog.op.asc; rm -rf /var/lib/apt/lists/*; fi +#11 CACHED + +#12 [ 4/12] RUN git clone --depth 1 --branch "v0.18.4" https://github.com/robotology/ycm-cmake-modules.git "/usr/local/src/ycm" && cmake -S "/usr/local/src/ycm" -B "/usr/local/src/ycm/build" && cmake --build "/usr/local/src/ycm/build" -j"$(nproc)" && cmake --install "/usr/local/src/ycm/build" +#12 CACHED + +#13 [11/12] RUN chmod +x /usr/local/bin/start-yarpserver /usr/local/bin/container-entrypoint +#13 CACHED + +#14 [ 9/12] COPY container-scripts/start-yarpserver.sh /usr/local/bin/start-yarpserver +#14 CACHED + +#15 [ 6/12] RUN git clone --depth 1 --branch "v2.9.0" https://github.com/robotology/icub-main.git "/usr/local/src/icub-main" && cmake -S "/usr/local/src/icub-main" -B "/usr/local/src/icub-main/build" -DBUILD_TESTING=OFF && cmake --build "/usr/local/src/icub-main/build" -j"$(nproc)" && cmake --install "/usr/local/src/icub-main/build" +#15 CACHED + +#16 [ 7/12] RUN git clone --depth 1 --branch "main" https://github.com/robotology/event-driven.git "/usr/local/src/event-driven" && test "$(git -C "/usr/local/src/event-driven" rev-parse HEAD)" = "45bce288ba616b2f19152ee96cecbb4da1c924cf" && cmake -S "/usr/local/src/event-driven" -B "/usr/local/src/event-driven/build" && cmake --build "/usr/local/src/event-driven/build" -j"$(nproc)" && cmake --install "/usr/local/src/event-driven/build" +#16 CACHED + +#17 [12/12] WORKDIR /workspace/project +#17 CACHED + +#18 exporting to image +#18 exporting layers done +#18 exporting manifest sha256:9ae38b4cab4fc2a02e66a85816329bf33eb2dd7b311b68ef00575d2de0828a4d done +#18 exporting config sha256:96d2cbe6b2d776e7f807ae57525351870d19eabc67342dc4306e315c2984a2af done +#18 exporting attestation manifest sha256:61c21aba3d6298da87f87866c24683d629765a94e10afd6d37ba9747cc17bff5 0.0s done +#18 exporting manifest list sha256:0d5ba3bdacf7c5679f18a4fec1494879d7388359b3fb6d836b37f5bea7368e1c done +#18 naming to docker.io/library/primi_iit_docker-robotology:latest done +#18 unpacking to docker.io/library/primi_iit_docker-robotology:latest done +#18 DONE 0.1s + +#19 resolving provenance for metadata file +#19 DONE 0.0s + Image primi_iit_docker-robotology Built diff --git a/compose.yaml b/compose.yaml index 5eab5c0..1df280b 100644 --- a/compose.yaml +++ b/compose.yaml @@ -3,12 +3,16 @@ services: build: context: . dockerfile: Dockerfile + network: host args: BASE_IMAGE: ${BASE_IMAGE:-public.ecr.aws/ubuntu/ubuntu:22.04} YCM_VERSION: ${YCM_VERSION:-v0.18.4} YARP_VERSION: ${YARP_VERSION:-v3.12.2} ED_VERSION: ${ED_VERSION:-main} - ED_COMMIT: ${ED_COMMIT:-bf0a4d71c1013d2bbdf911d0ba88678ce3909ae8} + ED_COMMIT: ${ED_COMMIT:-45bce288ba616b2f19152ee96cecbb4da1c924cf} + INSTALL_METAVISION_SDK: ${INSTALL_METAVISION_SDK:-0} + PROPHESEE_JFROG_USER: ${PROPHESEE_JFROG_USER:-} + PROPHESEE_JFROG_TOKEN: ${PROPHESEE_JFROG_TOKEN:-} container_name: robotology-dev command: ["bash", "-lc", "sleep infinity"] privileged: true diff --git a/scripts/demo-ballbalance-stationary.sh b/scripts/demo-ballbalance-stationary.sh deleted file mode 100755 index 49ef9d0..0000000 --- a/scripts/demo-ballbalance-stationary.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" - -exec "$SCRIPT_DIR/demo-ballbalance.sh" stationary "$@" diff --git a/scripts/demo-ballbalance.sh b/scripts/demo-ballbalance.sh index ad932dd..02dc259 100755 --- a/scripts/demo-ballbalance.sh +++ b/scripts/demo-ballbalance.sh @@ -3,25 +3,36 @@ set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/common.sh" +DEFAULTS_FILE="$SCRIPT_DIR/../yarpmanager/defaults.env" -session="${1:-}" +if [[ -f "$DEFAULTS_FILE" ]]; then + # shellcheck disable=SC1090 + source "$DEFAULTS_FILE" +fi -if [[ "$session" != "moving" && "$session" != "stationary" ]]; then - echo "Usage: $(basename "$0") " >&2 +if (($# != 0)); then + echo "Usage: $(basename "$0")" >&2 exit 1 fi +selected_trial="${BALLBALANCE_DEMO_TRIAL:-trial_2}" +dataset="/workspace/data/BallBalance/$selected_trial" + allow_local_x11 ensure_yarpserver -launch_demo_tool() { - local selected_session="$1" - - compose_exec_detached bash -lc 'cd /workspace/project && exec ./scripts/internal/launch-ballbalance-demo.sh "$@"' bash "$selected_session" -} +rgb_available=1 +if ! compose_exec bash -lc "test -s '$dataset/rgb/data.log'"; then + rgb_available=0 +fi -launch_demo_tool "$session" +compose_exec_detached bash -lc 'cd /workspace/project && exec ./scripts/internal/launch-ballbalance-demo.sh' -echo "BallBalance $session demo started." +echo "BallBalance demo started." +echo "Selected trial: $selected_trial" +echo "Container dataset path: $dataset" echo "Dataset is loaded in yarpdataplayer." +if [[ "$rgb_available" -eq 0 ]]; then + echo "RGB replay data is empty for $selected_trial, so yarpview is skipped for this demo." +fi echo "Use the dataplayer window to press Play." diff --git a/scripts/internal/launch-ballbalance-demo.sh b/scripts/internal/launch-ballbalance-demo.sh index 10cbbbe..8d97ad7 100755 --- a/scripts/internal/launch-ballbalance-demo.sh +++ b/scripts/internal/launch-ballbalance-demo.sh @@ -2,11 +2,19 @@ set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" -session="${1:?Usage: launch-ballbalance-demo.sh }" +DEFAULTS_FILE="$SCRIPT_DIR/../../yarpmanager/defaults.env" -if [[ "$session" != "moving" && "$session" != "stationary" ]]; then - echo "Unknown session: $session" >&2 - exit 1 +if [[ -f "$DEFAULTS_FILE" ]]; then + # shellcheck disable=SC1090 + source "$DEFAULTS_FILE" +fi + +selected_trial="${BALLBALANCE_DEMO_TRIAL:-trial_2}" +rgb_data_log="/workspace/data/BallBalance/$selected_trial/rgb/data.log" +has_rgb=0 + +if [[ -s "$rgb_data_log" ]]; then + has_rgb=1 fi pids=() @@ -22,21 +30,30 @@ cleanup() { trap cleanup EXIT INT TERM -"$SCRIPT_DIR/launch-ballbalance-tool.sh" "$session" dataplayer & +"$SCRIPT_DIR/launch-ballbalance-tool.sh" dataplayer & pids+=("$!") sleep 2 -"$SCRIPT_DIR/launch-ballbalance-tool.sh" "$session" yarpview & +if [[ "$has_rgb" -eq 1 ]]; then + "$SCRIPT_DIR/launch-ballbalance-tool.sh" yarpview & + pids+=("$!") +fi + +"$SCRIPT_DIR/launch-ballbalance-tool.sh" yarpscope & pids+=("$!") -"$SCRIPT_DIR/launch-ballbalance-tool.sh" "$session" yarpscope & +"$SCRIPT_DIR/launch-ballbalance-tool.sh" skingui & pids+=("$!") -"$SCRIPT_DIR/launch-ballbalance-tool.sh" "$session" vframer-left & +"$SCRIPT_DIR/launch-ballbalance-tool.sh" vframer-left & pids+=("$!") -"$SCRIPT_DIR/launch-ballbalance-tool.sh" "$session" vframer-right & +# vFramer derives an internal AE input port name at startup. Launching the +# two instances back-to-back can make them collide on that generated name. +sleep 1 + +"$SCRIPT_DIR/launch-ballbalance-tool.sh" vframer-right & pids+=("$!") wait "${pids[@]}" diff --git a/scripts/internal/launch-ballbalance-tool.sh b/scripts/internal/launch-ballbalance-tool.sh index a46ded9..c5004ce 100755 --- a/scripts/internal/launch-ballbalance-tool.sh +++ b/scripts/internal/launch-ballbalance-tool.sh @@ -1,29 +1,54 @@ #!/usr/bin/env bash set -euo pipefail -session="${1:?Usage: launch-ballbalance-tool.sh }" -tool="${2:?Usage: launch-ballbalance-tool.sh }" - -case "$session" in - moving) - dataset="/workspace/data/BallBalance/test_moving" - label="BallBalance Moving" - local_prefix="/ballbalance_moving" - ;; - stationary) - dataset="/workspace/data/BallBalance/test_stationary" - label="BallBalance Stationary" - local_prefix="/ballbalance_stationary" - ;; - *) - echo "Unknown session: $session" >&2 - exit 1 - ;; -esac +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +DEFAULTS_FILE="$SCRIPT_DIR/../../yarpmanager/defaults.env" + +if [[ -f "$DEFAULTS_FILE" ]]; then + # shellcheck disable=SC1090 + source "$DEFAULTS_FILE" +fi + +tool="${1:?Usage: launch-ballbalance-tool.sh }" + +selected_trial="${BALLBALANCE_DEMO_TRIAL:-trial_2}" +source_dataset="/workspace/data/BallBalance/$selected_trial" +dataset="$source_dataset" +label="BallBalance Demo" +local_prefix="/ballbalance_demo" + +if [[ ! -d "$source_dataset" ]]; then + echo "Dataset not found: $source_dataset" >&2 + exit 1 +fi + +rgb_data_log="$source_dataset/rgb/data.log" + +if [[ ! -s "$rgb_data_log" ]]; then + trial_tag="${selected_trial//[^A-Za-z0-9_-]/_}" + dataset="/tmp/ballbalance_${trial_tag}_without_rgb" + + rm -rf "$dataset" + mkdir -p "$dataset" + + # Some recordings ship an empty RGB replay log. yarpdataplayer crashes on + # that input, so build a replay dataset with the valid streams only. + for stream in atisleft atisright head rightarm skinrighthand torso; do + if [[ ! -d "$source_dataset/$stream" ]]; then + echo "Dataset stream not found: $source_dataset/$stream" >&2 + exit 1 + fi + + ln -sfn "$source_dataset/$stream" "$dataset/$stream" + done +fi # yarpdataplayer publishes replay outputs under its fixed /yarpdataplayer prefix. player_prefix="/yarpdataplayer" -rgb_remote="${player_prefix}/grabber" +rgb_remote_candidates=( + "${player_prefix}/grabber" + "${player_prefix}/rgb" +) left_events_remote="${player_prefix}/zynqGrabber/left/AE:o" right_events_remote="${player_prefix}/zynqGrabber/right/AE:o" encoders_remote="${player_prefix}/icub/right_arm/state:o" @@ -47,6 +72,23 @@ wait_for_port() { return 1 } +wait_for_any_port() { + local port + + for _ in $(seq 1 40); do + for port in "$@"; do + if yarp ping "$port" >/dev/null 2>&1; then + printf '%s\n' "$port" + return 0 + fi + done + sleep 0.25 + done + + echo "Timed out waiting for one of: $*" >&2 + return 1 +} + retry_connect() { local source="$1" local target="$2" @@ -67,7 +109,7 @@ cleanup_demo_tools() { while read -r pid comm; do case "$comm" in - yarpdataplayer|yarpdataplayer-c|yarpview|yarpscope|vFramer) + yarpdataplayer|yarpdataplayer-c|yarpview|yarpscope|vFramer|iCubSkinGui) pids+=("$pid") ;; esac @@ -91,7 +133,7 @@ case "$tool" in yarpview --name "$view_local" --title "$label RGB" & view_pid=$! - wait_for_port "$rgb_remote" || { + rgb_remote="$(wait_for_any_port "${rgb_remote_candidates[@]}")" || { kill "$view_pid" 2>/dev/null || true exit 1 } @@ -104,8 +146,41 @@ case "$tool" in wait "$view_pid" ;; yarpscope) - wait_for_port "$encoders_remote" - exec yarpscope --remote "$encoders_remote" --carrier tcp --title "$label Right Arm Encoders" + wait_for_port "${player_prefix}/icub/right_arm/state:o" + wait_for_port "${player_prefix}/icub/head/state:o" + wait_for_port "${player_prefix}/icub/torso/state:o" + + xml_file="$SCRIPT_DIR/yarpscope_encoders.xml" + + exec yarpscope --title "$label Encoders (Arm, Head, Torso)" --xml "$xml_file" + ;; + skingui) + skin_remote="${player_prefix}/icub/skin/righthand_comp" + skin_local="/skinGui/right_hand:i" + + # If the dataset port is just /icub/skin/righthand without _comp, it will be mapped correctly below + # since yarpdataplayer appends the original port name. I'll pick the comp data if possible, else fallback. + + skin_remote_candidates=( + "${player_prefix}/icub/skin/right_hand" + "${player_prefix}/icub/skin/righthand_comp" + "${player_prefix}/icub/skin/righthand" + ) + + iCubSkinGui --from right_hand.ini & + skin_pid=$! + + skin_remote="$(wait_for_any_port "${skin_remote_candidates[@]}")" || { + kill "$skin_pid" 2>/dev/null || true + exit 1 + } + + retry_connect "$skin_remote" "$skin_local" || { + kill "$skin_pid" 2>/dev/null || true + exit 1 + } + + wait "$skin_pid" ;; vframer-left) wait_for_port "$left_events_remote" diff --git a/scripts/internal/yarpscope_encoders.xml b/scripts/internal/yarpscope_encoders.xml new file mode 100644 index 0000000..b230deb --- /dev/null +++ b/scripts/internal/yarpscope_encoders.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/demo-ballbalance-moving.sh b/scripts/open-skingui.sh similarity index 63% rename from scripts/demo-ballbalance-moving.sh rename to scripts/open-skingui.sh index 2471c90..ffa3519 100755 --- a/scripts/demo-ballbalance-moving.sh +++ b/scripts/open-skingui.sh @@ -2,5 +2,6 @@ set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/common.sh" -exec "$SCRIPT_DIR/demo-ballbalance.sh" moving "$@" +open_gui_tool iCubSkinGui "$@" \ No newline at end of file diff --git a/scripts/show-versions.sh b/scripts/show-versions.sh index 23c53b5..da69acc 100755 --- a/scripts/show-versions.sh +++ b/scripts/show-versions.sh @@ -18,6 +18,7 @@ echo " YCM: $(extract_build_arg YCM_VERSION)" echo " YARP: $(extract_build_arg YARP_VERSION)" echo " event-driven ref: $(extract_build_arg ED_VERSION)" echo " event-driven commit: $(extract_build_arg ED_COMMIT)" +echo " Metavision SDK requested: $(extract_build_arg INSTALL_METAVISION_SDK)" echo echo "Installed versions:" @@ -33,9 +34,15 @@ set -euo pipefail yarp_version="$(yarp version 2>/dev/null | sed -n "s/^YARP version //p")" ed_package_version="$(sed -n "s/^set(PACKAGE_VERSION \"\\(.*\\)\")/\\1/p" /usr/local/lib/cmake/event-driven/event-driven-config-version.cmake 2>/dev/null || true)" ed_source_ref="$(git -c safe.directory=/usr/local/src/event-driven -C /usr/local/src/event-driven log -1 --format="%H %cs %s" 2>/dev/null || true)" +metavision_status="not installed" + +if dpkg-query -W -f="\${Status}" metavision-sdk 2>/dev/null | grep -q "install ok installed"; then + metavision_status="installed" +fi echo " YARP: ${yarp_version:-unknown}" echo " event-driven package: ${ed_package_version:-unknown}" +echo " Metavision SDK: ${metavision_status}" if [[ -n "${ed_source_ref:-}" ]]; then echo " event-driven source: ${ed_source_ref}" diff --git a/scripts/stop-demo.sh b/scripts/stop-demo.sh index c9ad6a9..90c5cbf 100755 --- a/scripts/stop-demo.sh +++ b/scripts/stop-demo.sh @@ -15,7 +15,7 @@ compose_exec bash -lc ' pids=() while read -r pid comm; do case "$comm" in - yarpdataplayer|yarpdataplayer-c|yarpview|yarpscope|vFramer) + yarpdataplayer|yarpdataplayer-c|yarpview|yarpscope|vFramer|iCubSkinGui) pids+=("$pid") ;; esac diff --git a/scripts/workstation-menu.sh b/scripts/workstation-menu.sh index 37bca3a..c9742ed 100755 --- a/scripts/workstation-menu.sh +++ b/scripts/workstation-menu.sh @@ -7,12 +7,12 @@ actions=( "Start workstation" "Show status" "Open yarpmanager" - "Run BallBalance moving demo" - "Run BallBalance stationary demo" + "Run BallBalance demo" "Open yarpview" "Open yarpscope" "Open vFramer Left" "Open vFramer Right" + "Open Skin Gui" "Open yarpdataplayer" "Stop demo tools only" "List mounted data" @@ -28,12 +28,12 @@ select action in "${actions[@]}"; do 1) "$SCRIPT_DIR/start-workstation.sh" ;; 2) "$SCRIPT_DIR/status.sh" ;; 3) "$SCRIPT_DIR/open-manager.sh" ;; - 4) "$SCRIPT_DIR/demo-ballbalance-moving.sh" ;; - 5) "$SCRIPT_DIR/demo-ballbalance-stationary.sh" ;; - 6) "$SCRIPT_DIR/open-yarpview.sh" ;; - 7) "$SCRIPT_DIR/open-yarpscope.sh" ;; - 8) "$SCRIPT_DIR/open-vframer.sh" left ;; - 9) "$SCRIPT_DIR/open-vframer.sh" right ;; + 4) "$SCRIPT_DIR/demo-ballbalance.sh" ;; + 5) "$SCRIPT_DIR/open-yarpview.sh" ;; + 6) "$SCRIPT_DIR/open-yarpscope.sh" ;; + 7) "$SCRIPT_DIR/open-vframer.sh" left ;; + 8) "$SCRIPT_DIR/open-vframer.sh" right ;; + 9) "$SCRIPT_DIR/open-skingui.sh" ;; 10) "$SCRIPT_DIR/open-dataplayer.sh" ;; 11) "$SCRIPT_DIR/stop-demo.sh" ;; 12) "$SCRIPT_DIR/list-data.sh" ;; diff --git a/yarpmanager/applications/01-yarp-data-player.xml b/yarpmanager/applications/01-yarp-data-player.xml index 29f9064..cb3c4d3 100644 --- a/yarpmanager/applications/01-yarp-data-player.xml +++ b/yarpmanager/applications/01-yarp-data-player.xml @@ -4,7 +4,7 @@ Launch the YARP data replay GUI. 1.0 - Codex + Bear yarpdataplayer diff --git a/yarpmanager/applications/02-yarp-scope.xml b/yarpmanager/applications/02-yarp-scope.xml index a197bb6..a220e41 100644 --- a/yarpmanager/applications/02-yarp-scope.xml +++ b/yarpmanager/applications/02-yarp-scope.xml @@ -4,7 +4,7 @@ Launch the joint/vector plotting GUI. 1.0 - Codex + Bear yarpscope diff --git a/yarpmanager/applications/03-yarp-view.xml b/yarpmanager/applications/03-yarp-view.xml index 2d4496f..5821caa 100644 --- a/yarpmanager/applications/03-yarp-view.xml +++ b/yarpmanager/applications/03-yarp-view.xml @@ -4,7 +4,7 @@ Launch the RGB image viewer GUI. 1.0 - Codex + Bear yarpview diff --git a/yarpmanager/applications/04-vframer-left.xml b/yarpmanager/applications/04-vframer-left.xml index 34b2d81..7a7df0d 100644 --- a/yarpmanager/applications/04-vframer-left.xml +++ b/yarpmanager/applications/04-vframer-left.xml @@ -4,7 +4,7 @@ Launch the left event-camera viewer using the configured default source port. 1.0 - Codex + Bear vFramer diff --git a/yarpmanager/applications/04-vframer-right.xml b/yarpmanager/applications/04-vframer-right.xml index 9ec1c87..0593ae3 100644 --- a/yarpmanager/applications/04-vframer-right.xml +++ b/yarpmanager/applications/04-vframer-right.xml @@ -4,7 +4,7 @@ Launch the right event-camera viewer using the configured default source port. 1.0 - Codex + Bear vFramer diff --git a/yarpmanager/applications/05-all-tools.xml b/yarpmanager/applications/05-all-tools.xml index 6751454..f53772c 100644 --- a/yarpmanager/applications/05-all-tools.xml +++ b/yarpmanager/applications/05-all-tools.xml @@ -4,7 +4,7 @@ Launch YARP Data Player, YARP Scope, YARP View, and both VFramer viewers together. 1.0 - Codex + Bear yarpdataplayer @@ -33,6 +33,16 @@ 2.0 + + iCubSkinGui + --from right_hand.ini + localhost + /workspace/project + --visible_na + + 2.0 + + vFramer --name /vframer/left --src /zynqGrabber/left/AE:o --width 640 --height 480 diff --git a/yarpmanager/applications/06-ballbalance-demo.xml b/yarpmanager/applications/06-ballbalance-demo.xml new file mode 100644 index 0000000..a99f3ee --- /dev/null +++ b/yarpmanager/applications/06-ballbalance-demo.xml @@ -0,0 +1,15 @@ + + + BallBalance Demo + Launch the coordinated BallBalance demo using the trial selected in yarpmanager/defaults.env. + 1.0 + + Bear + + + ./scripts/internal/launch-ballbalance-demo.sh + localhost + /workspace/project + --visible_na + + diff --git a/yarpmanager/applications/06-ballbalance-moving-demo.xml b/yarpmanager/applications/06-ballbalance-moving-demo.xml deleted file mode 100644 index 2f38e97..0000000 --- a/yarpmanager/applications/06-ballbalance-moving-demo.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - BallBalance Moving Demo - Load the moving BallBalance recording in yarpdataplayer and open the associated viewers. - 1.0 - - Codex - - - yarpdataplayer - --dataset /workspace/data/BallBalance/test_moving --add_prefix - localhost - /workspace/project - --visible_na - - 2.0 - - - - yarpview - --name /ballbalance_moving/yarpview/img:i - localhost - /workspace/project - --visible_na - - /yarpdataplayer/grabber - - - 2.0 - - - - yarpscope - --remote /yarpdataplayer/icub/right_arm/state:o --carrier tcp - localhost - /workspace/project - --visible_na - - /yarpdataplayer/icub/right_arm/state:o - - - 2.0 - - - - vFramer - --name /ballbalance_moving/vframer/left --src /yarpdataplayer/zynqGrabber/left/AE:o --width 640 --height 480 - localhost - /workspace/project - --visible_na - - /yarpdataplayer/zynqGrabber/left/AE:o - - - 2.0 - - - - vFramer - --name /ballbalance_moving/vframer/right --src /yarpdataplayer/zynqGrabber/right/AE:o --width 640 --height 480 - localhost - /workspace/project - --visible_na - - /yarpdataplayer/zynqGrabber/right/AE:o - - - 2.0 - - - - /yarpdataplayer/grabber - /ballbalance_moving/yarpview/img:i - tcp - - diff --git a/yarpmanager/applications/07-ballbalance-stationary-demo.xml b/yarpmanager/applications/07-ballbalance-stationary-demo.xml deleted file mode 100644 index b34f003..0000000 --- a/yarpmanager/applications/07-ballbalance-stationary-demo.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - BallBalance Stationary Demo - Load the stationary BallBalance recording in yarpdataplayer and open the associated viewers. - 1.0 - - Codex - - - yarpdataplayer - --dataset /workspace/data/BallBalance/test_stationary --add_prefix - localhost - /workspace/project - --visible_na - - 2.0 - - - - yarpview - --name /ballbalance_stationary/yarpview/img:i - localhost - /workspace/project - --visible_na - - /yarpdataplayer/grabber - - - 2.0 - - - - yarpscope - --remote /yarpdataplayer/icub/right_arm/state:o --carrier tcp - localhost - /workspace/project - --visible_na - - /yarpdataplayer/icub/right_arm/state:o - - - 2.0 - - - - vFramer - --name /ballbalance_stationary/vframer/left --src /yarpdataplayer/zynqGrabber/left/AE:o --width 640 --height 480 - localhost - /workspace/project - --visible_na - - /yarpdataplayer/zynqGrabber/left/AE:o - - - 2.0 - - - - vFramer - --name /ballbalance_stationary/vframer/right --src /yarpdataplayer/zynqGrabber/right/AE:o --width 640 --height 480 - localhost - /workspace/project - --visible_na - - /yarpdataplayer/zynqGrabber/right/AE:o - - - 2.0 - - - - /yarpdataplayer/grabber - /ballbalance_stationary/yarpview/img:i - tcp - - diff --git a/yarpmanager/applications/07-skin-gui.xml b/yarpmanager/applications/07-skin-gui.xml new file mode 100644 index 0000000..d1c8b28 --- /dev/null +++ b/yarpmanager/applications/07-skin-gui.xml @@ -0,0 +1,16 @@ + + + Skin Gui + Launch the Skin Gui display visualizing fingertip/skin tactile sensors. + 1.0 + + Bear + + + iCubSkinGui + --from right_hand.ini + localhost + /workspace/project + --visible_na + + \ No newline at end of file diff --git a/yarpmanager/defaults.env b/yarpmanager/defaults.env index 04a151c..fec522c 100644 --- a/yarpmanager/defaults.env +++ b/yarpmanager/defaults.env @@ -1,5 +1,8 @@ +# Shared defaults for the script-based launchers. +# The direct-launch yarpmanager XML applications keep their own generic tool values. +BALLBALANCE_DEMO_TRIAL=trial_0 + # Default side and source ports for the script-based vFramer launcher. -# The yarpmanager application definitions keep their own direct-launch values. VFRAMER_DEFAULT_SIDE=left VFRAMER_LEFT_SRC=/zynqGrabber/left/AE:o VFRAMER_RIGHT_SRC=/zynqGrabber/right/AE:o