diff --git a/.github/workflows/publish-image.yml b/.github/workflows/publish-image.yml
index d8a30c5..c210a94 100644
--- a/.github/workflows/publish-image.yml
+++ b/.github/workflows/publish-image.yml
@@ -56,3 +56,23 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
+
+ - name: Summarize published image
+ run: |
+ {
+ echo "## Published image"
+ echo
+ echo "- Package: \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\`"
+ echo "- Workflow run: \`${{ github.workflow }}\`"
+ echo
+ echo "### Published tags"
+ while IFS= read -r tag; do
+ [[ -n "$tag" ]] || continue
+ echo "- \`$tag\`"
+ done <<< "${{ steps.meta.outputs.tags }}"
+ echo
+ echo "### Visibility note"
+ echo "- GHCR package visibility is controlled in GitHub Packages settings, not by this workflow alone."
+ echo "- If the package is still private after publish, open the package page on GitHub and change its visibility to Public."
+ echo "- If this repository is private, GitHub may keep the package inheriting repository access by default; remove inherited permissions on the package, or disable automatic inheritance for new org packages, before expecting a public package."
+ } >> "$GITHUB_STEP_SUMMARY"
diff --git a/DEVELOPER_README.md b/DEVELOPER_README.md
index 1b25fa9..30eb115 100644
--- a/DEVELOPER_README.md
+++ b/DEVELOPER_README.md
@@ -109,13 +109,23 @@ Update both together when you intentionally refresh to a newer upstream snapshot
### `vFramer` Defaults
-There are intentionally two configuration points now, because there are still two real launch engines:
+There are intentionally three configuration points now, because there are still two real launch engines and two event streams:
-- `yarpmanager` `VFramer` app: [04-vframer.xml](yarpmanager/applications/04-vframer.xml)
-- script-based `vFramer` launcher: [defaults.env](yarpmanager/defaults.env)
+- `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)
+- script-based `vFramer` launcher defaults: [defaults.env](yarpmanager/defaults.env)
Keep them aligned when changing defaults.
+The shared `vFramer` defaults now cover:
+
+- left source
+- right source
+- left name
+- right name
+- width
+- height
+
## Developer Workflows
Build:
@@ -159,7 +169,8 @@ The generic `yarpmanager` applications are direct-launch only:
- [01-yarp-data-player.xml](yarpmanager/applications/01-yarp-data-player.xml)
- [02-yarp-scope.xml](yarpmanager/applications/02-yarp-scope.xml)
- [03-yarp-view.xml](yarpmanager/applications/03-yarp-view.xml)
-- [04-vframer.xml](yarpmanager/applications/04-vframer.xml)
+- [04-vframer-left.xml](yarpmanager/applications/04-vframer-left.xml)
+- [04-vframer-right.xml](yarpmanager/applications/04-vframer-right.xml)
- [05-all-tools.xml](yarpmanager/applications/05-all-tools.xml)
### BallBalance
@@ -282,7 +293,28 @@ docker compose pull
1. Push this repository to GitHub with Actions enabled.
2. Run the workflow once manually or push to `main` / `master` / a `v*` tag.
3. Confirm the GHCR package appears under the repository owner namespace.
-4. Set the GHCR package visibility to public if you want anonymous pulls.
+4. Make the GHCR package public if you want anonymous pulls.
+
+### Making The GHCR Package Public
+
+GitHub does not provide a repo-only switch in this workflow that guarantees the published GHCR package becomes public automatically.
+
+What GitHub documents today is:
+
+- the Container registry defaults a newly published package to private
+- public container packages allow anonymous pulls
+- packages linked to a repository inherit that repository's access permissions by default
+
+That means the exact public path depends on where the repository lives:
+
+- personal account repository:
+ open the package on GitHub, go to `Package settings`, and change visibility to `Public`
+- organization repository:
+ either change the package visibility to `Public` after the first publish, or have an org owner set the default package creation visibility to `Public`
+- private repository publishing to GHCR:
+ if the package inherits access from the private source repository, remove inherited permissions on the package first, or disable automatic inheritance for new packages at the organization level, then set the package visibility to `Public`
+
+Once a GHCR package is made public, GitHub warns that it cannot be made private again.
### Workflow Files
@@ -413,6 +445,7 @@ GitHub workflow checks:
8. Confirm the expected tags exist: `latest` on the default branch, branch tags like `main`, release tags like `v1.0.0`, and `sha-...`.
9. Confirm both workflows use the Dockerfile in the repo root and build `linux/amd64`.
10. Confirm later runs reuse the GitHub Actions cache instead of rebuilding every layer from scratch.
+11. Confirm the workflow summary includes the package name, published tags, and the GHCR visibility reminder.
GHCR pull checks:
diff --git a/REPOSITORY_REFERENCE.md b/REPOSITORY_REFERENCE.md
index c7fcc0f..3836396 100644
--- a/REPOSITORY_REFERENCE.md
+++ b/REPOSITORY_REFERENCE.md
@@ -45,13 +45,13 @@ 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 so it can still read the default source from `yarpmanager/defaults.env`. |
+| [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/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/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 `vFramer` default source stays aligned. |
+| [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
@@ -63,7 +63,7 @@ These scripts support the public entrypoints. Most are not intended as the first
| [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-vframer.sh](scripts/internal/launch-vframer.sh) | Reads `yarpmanager/defaults.env`, resolves `VFRAMER_SRC`, and starts `vFramer` with that source. |
+| [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,12 +81,13 @@ 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 default source for the `vFramer` launcher. This does not drive the direct-launch `yarpmanager` XML by itself. |
+| [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/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.xml](yarpmanager/applications/04-vframer.xml) | `yarpmanager` application definition for the generic `vFramer` GUI, using the direct-launch default source `/zynqGrabber/left/AE:o`. |
-| [yarpmanager/applications/05-all-tools.xml](yarpmanager/applications/05-all-tools.xml) | `yarpmanager` application that launches the four generic tools together. It does not auto-load a dataset. |
+| [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/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. |
@@ -97,7 +98,7 @@ These files define what `yarpmanager` sees and how it behaves.
| Path | What it does |
| --- | --- |
| [.github/workflows/test-image-build.yml](.github/workflows/test-image-build.yml) | GitHub Actions build-only workflow. It builds the Docker image on GitHub-hosted runners, loads it locally on the runner, and runs a lightweight smoke test without pushing to GHCR. |
-| [.github/workflows/publish-image.yml](.github/workflows/publish-image.yml) | GitHub Actions workflow that builds the Docker image on GitHub-hosted runners and pushes it to GitHub Container Registry (`ghcr.io`). It triggers on manual dispatch, pushes to `main`/`master`, and version tags like `v*`. |
+| [.github/workflows/publish-image.yml](.github/workflows/publish-image.yml) | GitHub Actions workflow that builds the Docker image on GitHub-hosted runners and pushes it to GitHub Container Registry (`ghcr.io`). It triggers on manual dispatch, pushes to `main`/`master`, and version tags like `v*`. After pushing, it writes a workflow summary with the published image tags and a reminder that GHCR package visibility is managed in GitHub package settings. |
## How The Pieces Fit Together
diff --git a/USER_README.md b/USER_README.md
index 31918ec..67fd9f1 100644
--- a/USER_README.md
+++ b/USER_README.md
@@ -115,7 +115,8 @@ What opens:
- `yarpdataplayer`
- `yarpview`
- `yarpscope`
-- `vFramer`
+- `vFramer Left`
+- `vFramer Right`
## Main Ways To Use It
@@ -174,7 +175,8 @@ Open generic tools:
./scripts/open-manager.sh
./scripts/open-yarpview.sh
./scripts/open-yarpscope.sh
-./scripts/open-vframer.sh
+./scripts/open-vframer.sh left
+./scripts/open-vframer.sh right
./scripts/open-dataplayer.sh
```
@@ -210,7 +212,8 @@ Configured applications:
- `YARP Data Player`
- `YARP Scope`
- `YARP View`
-- `VFramer`
+- `VFramer Left`
+- `VFramer Right`
- `All Tools`
- `BallBalance Moving Demo`
- `BallBalance Stationary Demo`
@@ -220,10 +223,11 @@ What they mean:
- `YARP Data Player`: opens the generic `yarpdataplayer` GUI
- `YARP Scope`: opens the generic `yarpscope` GUI
- `YARP View`: opens the generic `yarpview` GUI
-- `VFramer`: opens `vFramer` using the default source configured in [04-vframer.xml](yarpmanager/applications/04-vframer.xml)
-- `All Tools`: opens the four generic tools together and does not auto-load a dataset
-- `BallBalance Moving Demo`: auto-loads `test_moving` and opens the three matching viewers directly in `yarpmanager`
-- `BallBalance Stationary Demo`: auto-loads `test_stationary` and opens the three matching viewers directly in `yarpmanager`
+- `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`
If you want to stop a manager-launched BallBalance session from the CLI, use:
@@ -274,7 +278,8 @@ If you change `YCM_VERSION`, `YARP_VERSION`, `ED_VERSION`, or `ED_COMMIT`, rebui
| `yarpdataplayer` | `/workspace/data/BallBalance/test_moving` or `/workspace/data/BallBalance/test_stationary` | replays the recorded session |
| `yarpview` | `/yarpdataplayer/grabber` | shows the RGB camera stream |
| `yarpscope` | `/yarpdataplayer/icub/right_arm/state:o` | plots the right-arm encoder stream |
-| `vFramer` | `/yarpdataplayer/zynqGrabber/left/AE:o` | visualizes the event-camera 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 |
## Troubleshooting
@@ -297,16 +302,25 @@ If no GUI window appears, check:
- you are running from a desktop session
- the X11 socket mount exists at `/tmp/.X11-unix`
-If the `yarpmanager` `VFramer` application needs a different default source, edit [04-vframer.xml](yarpmanager/applications/04-vframer.xml):
+If the `yarpmanager` `VFramer Left` application needs a different default source, edit [04-vframer-left.xml](yarpmanager/applications/04-vframer-left.xml):
+
+```xml
+--name /vframer/left --src /zynqGrabber/left/AE:o --width 640 --height 480
+```
+
+If the `yarpmanager` `VFramer Right` application needs a different default source, edit [04-vframer-right.xml](yarpmanager/applications/04-vframer-right.xml):
```xml
---src /zynqGrabber/left/AE:o
+--name /vframer/right --src /zynqGrabber/right/AE:o --width 640 --height 480
```
-If the script-based `./scripts/open-vframer.sh` launcher needs a different default source, edit [defaults.env](yarpmanager/defaults.env):
+If the script-based `./scripts/open-vframer.sh` launcher needs different default source or size settings, edit [defaults.env](yarpmanager/defaults.env):
```bash
-VFRAMER_SRC=/zynqGrabber/left/AE:o
+VFRAMER_LEFT_SRC=/zynqGrabber/left/AE:o
+VFRAMER_RIGHT_SRC=/zynqGrabber/right/AE:o
+VFRAMER_WIDTH=640
+VFRAMER_HEIGHT=480
```
If the host data folder changes, update [`.env`](.env) and re-apply the runtime:
diff --git a/container-scripts/start-yarpserver.sh b/container-scripts/start-yarpserver.sh
index 7ec36b1..4458777 100755
--- a/container-scripts/start-yarpserver.sh
+++ b/container-scripts/start-yarpserver.sh
@@ -1,4 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
-exec yarpserver >/tmp/yarpserver.log 2>&1
+export HOME="${HOME:-/home/robotology}"
+mkdir -p "$HOME/.config/yarp"
+
+# Refresh the stored YARP name-server address when the host IP changes.
+exec yarpserver --write >/tmp/yarpserver.log 2>&1
diff --git a/scripts/common.sh b/scripts/common.sh
index 769a3c7..426228d 100755
--- a/scripts/common.sh
+++ b/scripts/common.sh
@@ -89,7 +89,7 @@ ensure_yarpserver() {
return 0
fi
- compose_exec_detached start-yarpserver
+ compose_exec_detached bash -lc 'exec /workspace/project/container-scripts/start-yarpserver.sh'
for _ in 1 2 3 4 5; do
if yarpserver_detected; then
diff --git a/scripts/internal/launch-ballbalance-demo.sh b/scripts/internal/launch-ballbalance-demo.sh
index 784e84c..10cbbbe 100755
--- a/scripts/internal/launch-ballbalance-demo.sh
+++ b/scripts/internal/launch-ballbalance-demo.sh
@@ -33,7 +33,10 @@ pids+=("$!")
"$SCRIPT_DIR/launch-ballbalance-tool.sh" "$session" yarpscope &
pids+=("$!")
-"$SCRIPT_DIR/launch-ballbalance-tool.sh" "$session" vframer &
+"$SCRIPT_DIR/launch-ballbalance-tool.sh" "$session" vframer-left &
+pids+=("$!")
+
+"$SCRIPT_DIR/launch-ballbalance-tool.sh" "$session" vframer-right &
pids+=("$!")
wait "${pids[@]}"
diff --git a/scripts/internal/launch-ballbalance-tool.sh b/scripts/internal/launch-ballbalance-tool.sh
index 0d1680c..a46ded9 100755
--- a/scripts/internal/launch-ballbalance-tool.sh
+++ b/scripts/internal/launch-ballbalance-tool.sh
@@ -24,10 +24,14 @@ esac
# yarpdataplayer publishes replay outputs under its fixed /yarpdataplayer prefix.
player_prefix="/yarpdataplayer"
rgb_remote="${player_prefix}/grabber"
-events_remote="${player_prefix}/zynqGrabber/left/AE:o"
+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"
view_local="${local_prefix}/yarpview/img:i"
-vframer_name="${local_prefix}/vframer"
+vframer_left_name="${local_prefix}/vframer/left"
+vframer_right_name="${local_prefix}/vframer/right"
+vframer_width="640"
+vframer_height="480"
wait_for_port() {
local port="$1"
@@ -103,9 +107,13 @@ case "$tool" in
wait_for_port "$encoders_remote"
exec yarpscope --remote "$encoders_remote" --carrier tcp --title "$label Right Arm Encoders"
;;
- vframer)
- wait_for_port "$events_remote"
- exec vFramer --name "$vframer_name" --src "$events_remote"
+ vframer-left)
+ wait_for_port "$left_events_remote"
+ exec vFramer --name "$vframer_left_name" --src "$left_events_remote" --width "$vframer_width" --height "$vframer_height"
+ ;;
+ vframer-right)
+ wait_for_port "$right_events_remote"
+ exec vFramer --name "$vframer_right_name" --src "$right_events_remote" --width "$vframer_width" --height "$vframer_height"
;;
*)
echo "Unknown tool: $tool" >&2
diff --git a/scripts/internal/launch-vframer.sh b/scripts/internal/launch-vframer.sh
index cde1fa0..616001e 100755
--- a/scripts/internal/launch-vframer.sh
+++ b/scripts/internal/launch-vframer.sh
@@ -8,6 +8,40 @@ if [[ -f "$DEFAULTS_FILE" ]]; then
source "$DEFAULTS_FILE"
fi
-VFRAMER_SRC="${VFRAMER_SRC:-/zynqGrabber/left/AE:o}"
+default_side="${VFRAMER_DEFAULT_SIDE:-left}"
+side="$default_side"
-exec vFramer --src "$VFRAMER_SRC" "$@" --height 480 --width 640
+if (($# > 0)); then
+ case "$1" in
+ left|right)
+ side="$1"
+ shift
+ ;;
+ -*)
+ ;;
+ *)
+ echo "Usage: $(basename "$0") [left|right] [vFramer args...]" >&2
+ exit 1
+ ;;
+ esac
+fi
+
+case "$side" in
+ left)
+ vframer_src="${VFRAMER_LEFT_SRC:-${VFRAMER_SRC:-/zynqGrabber/left/AE:o}}"
+ vframer_name="${VFRAMER_LEFT_NAME:-/vframer/left}"
+ ;;
+ right)
+ vframer_src="${VFRAMER_RIGHT_SRC:-/zynqGrabber/right/AE:o}"
+ vframer_name="${VFRAMER_RIGHT_NAME:-/vframer/right}"
+ ;;
+ *)
+ echo "Unsupported vFramer side: $side" >&2
+ exit 1
+ ;;
+esac
+
+vframer_width="${VFRAMER_WIDTH:-640}"
+vframer_height="${VFRAMER_HEIGHT:-480}"
+
+exec vFramer --name "$vframer_name" --src "$vframer_src" "$@" --width "$vframer_width" --height "$vframer_height"
diff --git a/scripts/open-vframer.sh b/scripts/open-vframer.sh
index 3817e8a..e9dd456 100755
--- a/scripts/open-vframer.sh
+++ b/scripts/open-vframer.sh
@@ -4,4 +4,21 @@ set -euo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common.sh"
-open_gui_command 'cd /workspace/project && exec ./scripts/internal/launch-vframer.sh "$@"' "$@"
+side="left"
+
+if (($# > 0)); then
+ case "$1" in
+ left|right)
+ side="$1"
+ shift
+ ;;
+ -*)
+ ;;
+ *)
+ echo "Usage: $(basename "$0") [left|right] [vFramer args...]" >&2
+ exit 1
+ ;;
+ esac
+fi
+
+open_gui_command 'cd /workspace/project && exec ./scripts/internal/launch-vframer.sh "$@"' "$side" "$@"
diff --git a/scripts/verify-repo.sh b/scripts/verify-repo.sh
index 3f7b142..002ab0d 100755
--- a/scripts/verify-repo.sh
+++ b/scripts/verify-repo.sh
@@ -21,20 +21,50 @@ if "${search_cmd[@]}" >/dev/null; then
exit 1
fi
-default_src="$(sed -n 's/^VFRAMER_SRC=//p' yarpmanager/defaults.env)"
-manager_src="$(sed -n 's@.*--src \(.*\)@\1@p' yarpmanager/applications/04-vframer.xml)"
-all_tools_src="$(sed -n 's@.*--src \(.*\)@\1@p' yarpmanager/applications/05-all-tools.xml)"
+default_side="$(sed -n 's/^VFRAMER_DEFAULT_SIDE=//p' yarpmanager/defaults.env)"
+default_left_src="$(sed -n 's/^VFRAMER_LEFT_SRC=//p' yarpmanager/defaults.env)"
+default_right_src="$(sed -n 's/^VFRAMER_RIGHT_SRC=//p' yarpmanager/defaults.env)"
+default_left_name="$(sed -n 's/^VFRAMER_LEFT_NAME=//p' yarpmanager/defaults.env)"
+default_right_name="$(sed -n 's/^VFRAMER_RIGHT_NAME=//p' yarpmanager/defaults.env)"
+default_width="$(sed -n 's/^VFRAMER_WIDTH=//p' yarpmanager/defaults.env)"
+default_height="$(sed -n 's/^VFRAMER_HEIGHT=//p' yarpmanager/defaults.env)"
-if [[ -z "$default_src" || -z "$manager_src" || -z "$all_tools_src" ]]; then
+left_manager_src="$(sed -n 's@.*--name /vframer/left --src \([^ ]*\) .*@\1@p' yarpmanager/applications/04-vframer-left.xml)"
+right_manager_src="$(sed -n 's@.*--name /vframer/right --src \([^ ]*\) .*@\1@p' yarpmanager/applications/04-vframer-right.xml)"
+all_tools_left_src="$(sed -n 's@.*--name /vframer/left --src \([^ ]*\) .*@\1@p' yarpmanager/applications/05-all-tools.xml)"
+all_tools_right_src="$(sed -n 's@.*--name /vframer/right --src \([^ ]*\) .*@\1@p' yarpmanager/applications/05-all-tools.xml)"
+
+left_manager_name="$(sed -n 's@.*--name \([^ ]*\) --src .*@\1@p' yarpmanager/applications/04-vframer-left.xml)"
+right_manager_name="$(sed -n 's@.*--name \([^ ]*\) --src .*@\1@p' yarpmanager/applications/04-vframer-right.xml)"
+all_tools_left_name="$(sed -n 's@.*--name \(/vframer/left\) --src .*@\1@p' yarpmanager/applications/05-all-tools.xml)"
+all_tools_right_name="$(sed -n 's@.*--name \(/vframer/right\) --src .*@\1@p' yarpmanager/applications/05-all-tools.xml)"
+left_manager_width="$(sed -n 's@.*--width \([^ ]*\) .*@\1@p' yarpmanager/applications/04-vframer-left.xml)"
+right_manager_width="$(sed -n 's@.*--width \([^ ]*\) .*@\1@p' yarpmanager/applications/04-vframer-right.xml)"
+all_tools_left_width="$(sed -n 's@.*--name /vframer/left .*--width \([^ ]*\) .*@\1@p' yarpmanager/applications/05-all-tools.xml)"
+all_tools_right_width="$(sed -n 's@.*--name /vframer/right .*--width \([^ ]*\) .*@\1@p' yarpmanager/applications/05-all-tools.xml)"
+left_manager_height="$(sed -n 's@.*--height \([^ <]*\)@\1@p' yarpmanager/applications/04-vframer-left.xml)"
+right_manager_height="$(sed -n 's@.*--height \([^ <]*\)@\1@p' yarpmanager/applications/04-vframer-right.xml)"
+all_tools_left_height="$(sed -n 's@.*--name /vframer/left .*--height \([^ <]*\)@\1@p' yarpmanager/applications/05-all-tools.xml)"
+all_tools_right_height="$(sed -n 's@.*--name /vframer/right .*--height \([^ <]*\)@\1@p' yarpmanager/applications/05-all-tools.xml)"
+
+if [[ -z "$default_side" || -z "$default_left_src" || -z "$default_right_src" || -z "$default_left_name" || -z "$default_right_name" || -z "$default_width" || -z "$default_height" || -z "$left_manager_src" || -z "$right_manager_src" || -z "$all_tools_left_src" || -z "$all_tools_right_src" || -z "$left_manager_name" || -z "$right_manager_name" || -z "$all_tools_left_name" || -z "$all_tools_right_name" || -z "$left_manager_width" || -z "$right_manager_width" || -z "$all_tools_left_width" || -z "$all_tools_right_width" || -z "$left_manager_height" || -z "$right_manager_height" || -z "$all_tools_left_height" || -z "$all_tools_right_height" ]]; then
echo "Failed to extract one or more vFramer defaults for verification." >&2
exit 1
fi
-if [[ "$default_src" != "$manager_src" || "$default_src" != "$all_tools_src" ]]; then
+if [[ "$default_side" != "left" ]]; then
+ echo "VFRAMER_DEFAULT_SIDE must stay set to left for the default CLI behavior." >&2
+ exit 1
+fi
+
+if [[ "$default_left_src" != "$left_manager_src" || "$default_left_src" != "$all_tools_left_src" || "$default_right_src" != "$right_manager_src" || "$default_right_src" != "$all_tools_right_src" || "$default_left_name" != "$left_manager_name" || "$default_left_name" != "$all_tools_left_name" || "$default_right_name" != "$right_manager_name" || "$default_right_name" != "$all_tools_right_name" || "$default_width" != "$left_manager_width" || "$default_width" != "$right_manager_width" || "$default_width" != "$all_tools_left_width" || "$default_width" != "$all_tools_right_width" || "$default_height" != "$left_manager_height" || "$default_height" != "$right_manager_height" || "$default_height" != "$all_tools_left_height" || "$default_height" != "$all_tools_right_height" ]]; then
echo "vFramer defaults are out of sync:" >&2
- echo " defaults.env: $default_src" >&2
- echo " 04-vframer.xml: $manager_src" >&2
- echo " 05-all-tools.xml: $all_tools_src" >&2
+ echo " defaults.env left: $default_left_name $default_left_src ${default_width}x${default_height}" >&2
+ echo " defaults.env right: $default_right_name $default_right_src ${default_width}x${default_height}" >&2
+ echo " 04-vframer-left.xml: $left_manager_name $left_manager_src ${left_manager_width}x${left_manager_height}" >&2
+ echo " 04-vframer-right.xml: $right_manager_name $right_manager_src ${right_manager_width}x${right_manager_height}" >&2
+ echo " 05-all-tools.xml left: $all_tools_left_name $all_tools_left_src ${all_tools_left_width}x${all_tools_left_height}" >&2
+ echo " 05-all-tools.xml right: $all_tools_right_name $all_tools_right_src ${all_tools_right_width}x${all_tools_right_height}" >&2
exit 1
fi
diff --git a/scripts/workstation-menu.sh b/scripts/workstation-menu.sh
index f9f25cd..37bca3a 100755
--- a/scripts/workstation-menu.sh
+++ b/scripts/workstation-menu.sh
@@ -11,7 +11,8 @@ actions=(
"Run BallBalance stationary demo"
"Open yarpview"
"Open yarpscope"
- "Open vFramer"
+ "Open vFramer Left"
+ "Open vFramer Right"
"Open yarpdataplayer"
"Stop demo tools only"
"List mounted data"
@@ -31,13 +32,14 @@ select action in "${actions[@]}"; do
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" ;;
- 9) "$SCRIPT_DIR/open-dataplayer.sh" ;;
- 10) "$SCRIPT_DIR/stop-demo.sh" ;;
- 11) "$SCRIPT_DIR/list-data.sh" ;;
- 12) "$SCRIPT_DIR/shell.sh" ;;
- 13) "$SCRIPT_DIR/stop-workstation.sh" ;;
- 14) exit 0 ;;
+ 8) "$SCRIPT_DIR/open-vframer.sh" left ;;
+ 9) "$SCRIPT_DIR/open-vframer.sh" right ;;
+ 10) "$SCRIPT_DIR/open-dataplayer.sh" ;;
+ 11) "$SCRIPT_DIR/stop-demo.sh" ;;
+ 12) "$SCRIPT_DIR/list-data.sh" ;;
+ 13) "$SCRIPT_DIR/shell.sh" ;;
+ 14) "$SCRIPT_DIR/stop-workstation.sh" ;;
+ 15) exit 0 ;;
*) echo "Invalid choice." >&2 ;;
esac
done
diff --git a/yarpmanager/applications/04-vframer.xml b/yarpmanager/applications/04-vframer-left.xml
similarity index 60%
rename from yarpmanager/applications/04-vframer.xml
rename to yarpmanager/applications/04-vframer-left.xml
index 2553339..34b2d81 100644
--- a/yarpmanager/applications/04-vframer.xml
+++ b/yarpmanager/applications/04-vframer-left.xml
@@ -1,14 +1,14 @@
- VFramer
- Launch the event-camera viewer using the configured default source port.
+ VFramer Left
+ Launch the left event-camera viewer using the configured default source port.
1.0
Codex
vFramer
- --src /zynqGrabber/left/AE:o
+ --name /vframer/left --src /zynqGrabber/left/AE:o --width 640 --height 480
localhost
/workspace/project
--visible_na
diff --git a/yarpmanager/applications/04-vframer-right.xml b/yarpmanager/applications/04-vframer-right.xml
new file mode 100644
index 0000000..9ec1c87
--- /dev/null
+++ b/yarpmanager/applications/04-vframer-right.xml
@@ -0,0 +1,19 @@
+
+
+ VFramer Right
+ Launch the right event-camera viewer using the configured default source port.
+ 1.0
+
+ Codex
+
+
+ vFramer
+ --name /vframer/right --src /zynqGrabber/right/AE:o --width 640 --height 480
+ localhost
+ /workspace/project
+ --visible_na
+
+ 2.0
+
+
+
diff --git a/yarpmanager/applications/05-all-tools.xml b/yarpmanager/applications/05-all-tools.xml
index 4923103..6751454 100644
--- a/yarpmanager/applications/05-all-tools.xml
+++ b/yarpmanager/applications/05-all-tools.xml
@@ -1,7 +1,7 @@
All Tools
- Launch YARP Data Player, YARP Scope, YARP View, and VFramer together.
+ Launch YARP Data Player, YARP Scope, YARP View, and both VFramer viewers together.
1.0
Codex
@@ -35,7 +35,17 @@
vFramer
- --src /zynqGrabber/left/AE:o
+ --name /vframer/left --src /zynqGrabber/left/AE:o --width 640 --height 480
+ localhost
+ /workspace/project
+ --visible_na
+
+ 2.0
+
+
+
+ vFramer
+ --name /vframer/right --src /zynqGrabber/right/AE:o --width 640 --height 480
localhost
/workspace/project
--visible_na
diff --git a/yarpmanager/applications/06-ballbalance-moving-demo.xml b/yarpmanager/applications/06-ballbalance-moving-demo.xml
index 8deb052..2f38e97 100644
--- a/yarpmanager/applications/06-ballbalance-moving-demo.xml
+++ b/yarpmanager/applications/06-ballbalance-moving-demo.xml
@@ -44,7 +44,7 @@
vFramer
- --name /ballbalance_moving/vframer --src /yarpdataplayer/zynqGrabber/left/AE:o
+ --name /ballbalance_moving/vframer/left --src /yarpdataplayer/zynqGrabber/left/AE:o --width 640 --height 480
localhost
/workspace/project
--visible_na
@@ -55,6 +55,19 @@
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
diff --git a/yarpmanager/applications/07-ballbalance-stationary-demo.xml b/yarpmanager/applications/07-ballbalance-stationary-demo.xml
index fbe351b..b34f003 100644
--- a/yarpmanager/applications/07-ballbalance-stationary-demo.xml
+++ b/yarpmanager/applications/07-ballbalance-stationary-demo.xml
@@ -44,7 +44,7 @@
vFramer
- --name /ballbalance_stationary/vframer --src /yarpdataplayer/zynqGrabber/left/AE:o
+ --name /ballbalance_stationary/vframer/left --src /yarpdataplayer/zynqGrabber/left/AE:o --width 640 --height 480
localhost
/workspace/project
--visible_na
@@ -55,6 +55,19 @@
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
diff --git a/yarpmanager/defaults.env b/yarpmanager/defaults.env
index a5c2f3e..04a151c 100644
--- a/yarpmanager/defaults.env
+++ b/yarpmanager/defaults.env
@@ -1,3 +1,9 @@
-# Default event-camera source for the script-based vFramer launcher.
-# The yarpmanager application definitions keep their own direct-launch value.
-VFRAMER_SRC=/zynqGrabber/left/AE:o
+# 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
+VFRAMER_LEFT_NAME=/vframer/left
+VFRAMER_RIGHT_NAME=/vframer/right
+VFRAMER_WIDTH=640
+VFRAMER_HEIGHT=480