From 38be4ba09b497425e9e1427de7db2aad8696dc8d Mon Sep 17 00:00:00 2001 From: John Date: Tue, 4 Aug 2026 11:42:02 -0400 Subject: [PATCH 1/7] make RECORD_BAGS actually reach the bag recorder LOG_CONFIG selects which topic set in logging_bringup/config to record, default log.yaml. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 1 + .../logging/logging_bringup/launch/logging.launch.xml | 10 ++++++---- robot/docker/robot-base-docker-compose.yaml | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5ea32f38..cb8b4e7e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Robot name resolution now honors a pre-set `ROBOT_NAME` (e.g. injected via docker compose) instead of always overriding it from the container/hostname mapping (`robot/docker/.bashrc`) - Robot name-map catch-all fallback now maps to `unknown_robot` (valid ROS namespace token) instead of `unknown-robot` (`default_robot_name_map.yaml`) - l4t robot image: replace dustynv's `/ros_entrypoint.sh` with a passthrough so its prebuilt source-ROS libs (older `fastcdr`) no longer shadow the apt Jazzy runtime and crash apt-built nodes like MAVROS +- `RECORD_BAGS=true` never brought the bag recorder up on a robot: `logging.launch.xml` hardcoded `record_bag=false` and `onboard_autonomy_all.launch.xml` includes it with no arguments, so the variable was forwarded into the container and read by nobody (only `gcs.launch.xml` consumed it). With no `bag_record` node running, the GCS control panel's `set_recording_status` toggle had nothing to reach despite being bridged in `domain_bridge.yaml` / `dds_router.yaml`. It now reads `RECORD_BAGS` and selects its topic set via `LOG_CONFIG` ## [1.0.0] - 2024-12-19 diff --git a/common/ros_packages/logging/logging_bringup/launch/logging.launch.xml b/common/ros_packages/logging/logging_bringup/launch/logging.launch.xml index 6c6df0502..7b56ca1b9 100644 --- a/common/ros_packages/logging/logging_bringup/launch/logging.launch.xml +++ b/common/ros_packages/logging/logging_bringup/launch/logging.launch.xml @@ -1,13 +1,15 @@ - - + + + + - + - + diff --git a/robot/docker/robot-base-docker-compose.yaml b/robot/docker/robot-base-docker-compose.yaml index a4ed7e1bb..8cb714e18 100644 --- a/robot/docker/robot-base-docker-compose.yaml +++ b/robot/docker/robot-base-docker-compose.yaml @@ -12,6 +12,7 @@ services: - QT_QPA_PLATFORM # Record bags - RECORD_BAGS=${RECORD_BAGS} + - LOG_CONFIG=${LOG_CONFIG:-log.yaml} # docker compose interpolation to env variables - AUTONOMY_ROLE=${AUTONOMY_ROLE:-full} - URDF_FILE=${URDF_FILE} From ff39dedbac7c1732997353fc2ec9f8b520861617 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 4 Aug 2026 11:42:11 -0400 Subject: [PATCH 2/7] warn when the robot identity fails to resolve Co-Authored-By: Claude Opus 5 --- .agents/skills/configure-multi-robot/SKILL.md | 57 ++++++++++++++----- CHANGELOG.md | 2 + docs/robot/docker/robot_identity.md | 44 +++++++++++++- overrides/l4t-px4-realrobot.env | 6 +- robot/docker/.bashrc | 15 +++++ 5 files changed, 103 insertions(+), 21 deletions(-) diff --git a/.agents/skills/configure-multi-robot/SKILL.md b/.agents/skills/configure-multi-robot/SKILL.md index c70ba8dde..640b183bd 100644 --- a/.agents/skills/configure-multi-robot/SKILL.md +++ b/.agents/skills/configure-multi-robot/SKILL.md @@ -103,17 +103,35 @@ docker exec airstack-robot-desktop-1 bash -c 'echo $ROBOT_NAME $ROS_DOMAIN_ID' If you need a non-default name (custom hostname scheme on a physical robot, or you want `drone_alpha` instead of `robot_1`), you have two options: 1. **Write a mapping YAML** in `robot/docker/robot_name_map/` and point `ROBOT_NAME_MAP_CONFIG_FILE` at it. Preferred when the name should be derived from the machine (hostname/container) — keeps the resolver in charge of `ROS_DOMAIN_ID` co-assignment. -2. **Pin `ROBOT_NAME` directly** in a per-deployment override env file. `.bashrc` honors a pre-set `ROBOT_NAME` (guard: `if [ -z "${ROBOT_NAME:-}" ]`) and skips the map lookup. This is the clean shortcut for a **single real robot** whose hostname doesn't match `robot-` (see [Real robots and the `unknown_robot` fallback](#real-robots-and-the-unknown_robot-fallback) below): - - ```bash - # overrides/.env — single robot, named directly - ROBOT_NAME=robot_1 - ROS_DOMAIN_ID=1 # set alongside — pinning ROBOT_NAME skips the map's domain co-assignment - ``` - -**Only pin `ROBOT_NAME` in an *override env file*, never on the shared `robot-desktop`/`robot-l4t` *service* in compose.** The service is reused for every replica; a hardcoded `ROBOT_NAME` there collapses all robots onto one name/domain and silently breaks multi-robot. And when you pin it, set `ROS_DOMAIN_ID` too — the resolver is what normally co-assigns the domain, and skipping it leaves the domain at whatever the environment defaults to. - -For a one-off override (e.g. ad hoc debugging): +2. **Rename the device** so the default map resolves it. On real hardware + (`ROBOT_NAME_SOURCE=hostname`) the OS hostname *is* the identity, so + `hostnamectl set-hostname robot-1` is a complete, one-time fix — and it scales to a + fleet, since `robot-2` and `robot-3` then resolve on their own. + +!!! danger "Setting `ROBOT_NAME` in an env file does nothing" + No compose service declares `ROBOT_NAME` or `ROS_DOMAIN_ID` in its `environment:` + block, and Docker Compose only injects a variable into a container if some service + names it there. Putting `ROBOT_NAME=robot_1` in an override `.env` sets it for + **compose's own interpolation**, not for the container — `.bashrc` sees it unset, + the map lookup runs anyway, and there is no error. The robot simply comes up under + the resolved name instead of yours. + + `overrides/l4t-px4-realrobot.env` used to ship `ROBOT_NAME` / `ROS_DOMAIN_ID` on + this basis; they never had any effect and have been removed. Use a hostname or a + map file instead. + + The general lesson applies to **any** deployment knob: it needs a declaration in + the service's `environment:` *and* a consumer that reads it. Always + [verify](#verification-commands) rather than assuming. + +**Never hardcode `ROBOT_NAME` on a service in compose either.** `robot-desktop` and +friends are reused for every replica, so a pinned name there would collapse all robots +onto one name and domain and silently break multi-robot. Identity must come from +something that differs per container — the container name in sim, the device hostname on +real hardware — or from a map rule that derives it. + +For a one-off override (e.g. ad hoc debugging), pass it to the shell directly, which +does work because `docker exec -e` sets it in the process environment: ```bash docker exec -e ROBOT_NAME=robot_5 -e ROS_DOMAIN_ID=5 -it airstack-robot-desktop-1 bash @@ -349,16 +367,25 @@ On VOXL/Jetson the service uses `ROBOT_NAME_SOURCE=hostname`, so the **OS hostna Pick whichever fix matches your topology (see [Configuring a Single Robot](#configuring-a-single-robot)): -- **One robot, quickest:** pin `ROBOT_NAME=robot_1` + `ROS_DOMAIN_ID=1` in the deployment's override env file. The `.bashrc` guard honors it and skips the lookup — no hostname change, no map file. -- **One robot, machine-derived:** rename the device hostname to `robot-1` so the default map resolves it automatically. -- **A fleet:** name each machine `robot-` (default map handles it) **or** ship a mapping YAML that matches your hostnames and point `ROBOT_NAME_MAP_CONFIG_FILE` at it. Do **not** pin a single `ROBOT_NAME` on the shared service — every robot would collide on it. +- **Quickest, no config:** rename the device — `hostnamectl set-hostname robot-1`. The default map resolves it to `robot_1` on domain 1, and a fleet named `robot-2`, `robot-3`, … resolves the same way with nothing further to maintain. +- **Hostnames you can't change:** ship a mapping YAML matching them and point `ROBOT_NAME_MAP_CONFIG_FILE` at it. Needs no code change — the variable is already forwarded and `robot_name_map/` is bind-mounted into the container — and keeps the resolver co-assigning `ROS_DOMAIN_ID`. -Verify on the device: +Setting `ROBOT_NAME` in an override env file is **not** an option: nothing declares it in +compose, so it never reaches the container. See the danger note under +[Configuring a Single Robot](#configuring-a-single-robot). + +Verify on the device — do this every time, especially after pinning `ROBOT_NAME`, since +a pin that never reached the container fails silently: ```bash docker exec bash -c 'echo "$(hostname) -> ROBOT_NAME=$ROBOT_NAME ROS_DOMAIN_ID=$ROS_DOMAIN_ID"' ``` +If it still reports `unknown_robot` after you set `ROBOT_NAME`, the variable did not +reach the container. Check that the service (or the base compose file it extends) +declares it in `environment:` — see the warning under +[Configuring a Single Robot](#configuring-a-single-robot). + ## Pre-Merge Checklist Before merging a change that touches anything robot-namespaced: diff --git a/CHANGELOG.md b/CHANGELOG.md index cb8b4e7e9..04ce33da6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Robot name-map catch-all fallback now maps to `unknown_robot` (valid ROS namespace token) instead of `unknown-robot` (`default_robot_name_map.yaml`) - l4t robot image: replace dustynv's `/ros_entrypoint.sh` with a passthrough so its prebuilt source-ROS libs (older `fastcdr`) no longer shadow the apt Jazzy runtime and crash apt-built nodes like MAVROS - `RECORD_BAGS=true` never brought the bag recorder up on a robot: `logging.launch.xml` hardcoded `record_bag=false` and `onboard_autonomy_all.launch.xml` includes it with no arguments, so the variable was forwarded into the container and read by nobody (only `gcs.launch.xml` consumed it). With no `bag_record` node running, the GCS control panel's `set_recording_status` toggle had nothing to reach despite being bridged in `domain_bridge.yaml` / `dds_router.yaml`. It now reads `RECORD_BAGS` and selects its topic set via `LOG_CONFIG` +- Falling back to `unknown_robot` / domain 0 now logs a warning naming both fixes (rename the device `robot-` on the host, or supply a `ROBOT_NAME_MAP_CONFIG_FILE` matching your hostnames). The fallback itself is unchanged — it deliberately keeps an unidentified robot out of every real robot's namespace — but it used to resolve silently, so the symptoms surfaced far from the cause +- Dropped `ROBOT_NAME` / `ROS_DOMAIN_ID` from `overrides/l4t-px4-realrobot.env`: no compose service declares either, so an env file could never set them and the lines were inert ## [1.0.0] - 2024-12-19 diff --git a/docs/robot/docker/robot_identity.md b/docs/robot/docker/robot_identity.md index 494b5daae..2665a329d 100644 --- a/docs/robot/docker/robot_identity.md +++ b/docs/robot/docker/robot_identity.md @@ -107,8 +107,21 @@ The serial port for MAVLink (`/dev/ttyTHS4`) is hardcoded for real-robot profile export FCU_URL="/dev/ttyTHS4:115200" ``` -!!! warning "Hostname convention is required" - The hostname must match a rule in the mapping config file. If no rule matches, the script exits with an error and `ROBOT_NAME` / `ROS_DOMAIN_ID` will be unset. Make sure every physical robot has a hostname that matches a rule before deployment. +!!! warning "Hostname convention is required — and it fails quietly" + The hostname must match a rule in the mapping config file. With the stock + `default_robot_name_map.yaml` the failure is **silent, not loud**: its final `.*` + catch-all matches anything, so a device named e.g. `airlab-jetson-42` resolves to + `ROBOT_NAME=unknown_robot`, `ROS_DOMAIN_ID=0` with no error and a clean boot. The + symptoms surface later — topics under `/unknown_robot`, per-robot config lookups + keyed on `ROBOT_NAME` finding no profile, and containers pinned to another domain + (`zed-l4t` hardcodes `ROS_DOMAIN_ID=1`) no longer seeing the stack. + + Only a map with *no* catch-all makes `resolve_robot_name.py` exit non-zero. Either + way, verify after deployment rather than assuming: + + ```bash + docker exec bash -c 'echo "$(hostname) -> $ROBOT_NAME / $ROS_DOMAIN_ID"' + ``` ### Fallback (anything else) @@ -129,6 +142,12 @@ A warning is printed to the shell. This is safe for single-robot testing but **w | `simple` | `container_name` | Docker container name | Yes | | `voxl` | `hostname` | OS hostname of the device | Yes — set distinct hostnames | | `l4t` | `hostname` | OS hostname of the device | Yes — set distinct hostnames | + +On the `hostname` profiles the device name is not just how robots are told *apart* — it is +how each one gets named at all. There is no container replica index to fall back on, so a +Jetson called `airlab-desktop` has nothing to derive `robot_1` from and lands on the +catch-all. Naming devices `robot-` at provisioning time is the one step that makes both +the single-robot and fleet cases work with no further configuration. | _(fallback)_ | _(other)_ | Hardcoded defaults | **No** | ## Overriding Manually @@ -139,4 +158,23 @@ If you need to override the robot identity for testing, you can set the variable docker exec -e ROBOT_NAME=robot_5 -e ROS_DOMAIN_ID=5 -it bash ``` -Or add them to your project's `.env` file and pass them through in `docker-compose.yaml`. +For a **persistent** change, set the identity where the resolver reads it from — the +device hostname on real hardware, or a mapping rule: + +```bash +sudo hostnamectl set-hostname robot-1 # -> ROBOT_NAME=robot_1, ROS_DOMAIN_ID=1 +``` + +!!! danger "Setting `ROBOT_NAME` in an env file does nothing" + No compose service declares `ROBOT_NAME` or `ROS_DOMAIN_ID` in its `environment:` + block, and Docker Compose only injects a variable into a container if a service + names it there. Putting `ROBOT_NAME=robot_1` in an override `.env` sets it for + **compose's own interpolation**, not for the container — `.bashrc` sees it unset, + the map lookup runs anyway, and there is no error. + + `overrides/l4t-px4-realrobot.env` used to ship `ROBOT_NAME` / `ROS_DOMAIN_ID` on + this basis; they never had any effect and have been removed. + + The general lesson applies to any deployment knob: it needs a declaration in the + service's `environment:` **and** a consumer that reads it, or it silently does + nothing. diff --git a/overrides/l4t-px4-realrobot.env b/overrides/l4t-px4-realrobot.env index 271726801..e623f144a 100644 --- a/overrides/l4t-px4-realrobot.env +++ b/overrides/l4t-px4-realrobot.env @@ -14,9 +14,9 @@ AUTOLAUNCH="true" NUM_ROBOTS="1" # --- Robot identity ----------------------------------------------------------- -# Shortcut to name only a single agent. -ROBOT_NAME="robot_1" -ROS_DOMAIN_ID="1" +# Resolved from this device's hostname: name the Jetson robot-1 on the HOST +# (hostnamectl set-hostname robot-1) -> robot_1 on domain 1. Setting ROBOT_NAME here +# does nothing; no compose service declares it. See docs/robot/docker/robot_identity.md. # Launches entire robot autonomy stack AUTONOMY_ROLE="full" diff --git a/robot/docker/.bashrc b/robot/docker/.bashrc index b3903a144..a62e5f18b 100755 --- a/robot/docker/.bashrc +++ b/robot/docker/.bashrc @@ -103,6 +103,21 @@ if [ -z "${ROBOT_NAME:-}" ]; then export ROS_DOMAIN_ID=$existing_robot_domain_id fi fi + + # Warn about unknown robot mapping. + if [ -z "${ROBOT_NAME:-}" ] || [ "$ROBOT_NAME" == "unknown_robot" ]; then + echo "WARNING: could not resolve a robot identity from '${name_to_map:-}'" \ + "using $ROBOT_NAME_MAP_CONFIG_FILE." + echo " ROBOT_NAME='${ROBOT_NAME:-}' ROS_DOMAIN_ID='${ROS_DOMAIN_ID:-}'" + echo " Topics will not be namespaced under /robot_, so nothing will reach" + echo " the rest of the stack. Fix by either:" + echo " - on the HOST (not in this container): hostnamectl set-hostname robot-1," + echo " which the default map resolves to robot_ on domain ; or" + echo " - adding a mapping YAML under robot/docker/robot_name_map/ that" + echo " matches your hostnames and pointing ROBOT_NAME_MAP_CONFIG_FILE at it." + echo " If ROBOT_NAME is empty rather than unknown_robot, check stderr above" + echo " for a resolve_robot_name.py error (missing or malformed map file)." + fi fi From fd4b1319e867daad4ca69fe9812fb1ab3c0f87b8 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 4 Aug 2026 11:42:19 -0400 Subject: [PATCH 3/7] chore: bump version to 0.19.0-alpha.12 Co-Authored-By: Claude Opus 5 --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index 00cd4c639..04de90a2d 100644 --- a/.env +++ b/.env @@ -12,7 +12,7 @@ PROJECT_NAME="airstack" # If you've run ./airstack.sh setup, then this will auto-generate from the git commit hash every time a change is made # to a Dockerfile or docker-compose.yaml file. Otherwise this can also be set explicitly to make a release version. # auto-generated from git commit hash -VERSION="0.19.0-alpha.8" +VERSION="0.19.0-alpha.12" # Choose "dev" or "prebuilt". "dev" is for mounted code that must be built live. "prebuilt" is for built ros_ws baked into the image DOCKER_IMAGE_BUILD_MODE="dev" # Where to push and pull images from. Can replace with your docker hub username if using docker hub. From 05715469a0aae463213fa127489e1f8fe72a0b27 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 4 Aug 2026 12:46:58 -0400 Subject: [PATCH 4/7] fixed comments and documentation --- docs/robot/docker/robot_identity.md | 36 ++++++----------------------- overrides/l4t-px4-realrobot.env | 4 ++-- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/docs/robot/docker/robot_identity.md b/docs/robot/docker/robot_identity.md index 2665a329d..dde74696f 100644 --- a/docs/robot/docker/robot_identity.md +++ b/docs/robot/docker/robot_identity.md @@ -116,9 +116,12 @@ export FCU_URL="/dev/ttyTHS4:115200" keyed on `ROBOT_NAME` finding no profile, and containers pinned to another domain (`zed-l4t` hardcodes `ROS_DOMAIN_ID=1`) no longer seeing the stack. - Only a map with *no* catch-all makes `resolve_robot_name.py` exit non-zero. Either - way, verify after deployment rather than assuming: - + Make sure every physical robot has a hostname that matches a rule before deployment. + Run the following to set the hostname on a device: + ``` + hostnamectl set-hostname robot-1 + ``` + Then verify the mapping in a shell inside the container: ```bash docker exec bash -c 'echo "$(hostname) -> $ROBOT_NAME / $ROS_DOMAIN_ID"' ``` @@ -142,12 +145,6 @@ A warning is printed to the shell. This is safe for single-robot testing but **w | `simple` | `container_name` | Docker container name | Yes | | `voxl` | `hostname` | OS hostname of the device | Yes — set distinct hostnames | | `l4t` | `hostname` | OS hostname of the device | Yes — set distinct hostnames | - -On the `hostname` profiles the device name is not just how robots are told *apart* — it is -how each one gets named at all. There is no container replica index to fall back on, so a -Jetson called `airlab-desktop` has nothing to derive `robot_1` from and lands on the -catch-all. Naming devices `robot-` at provisioning time is the one step that makes both -the single-robot and fleet cases work with no further configuration. | _(fallback)_ | _(other)_ | Hardcoded defaults | **No** | ## Overriding Manually @@ -158,23 +155,4 @@ If you need to override the robot identity for testing, you can set the variable docker exec -e ROBOT_NAME=robot_5 -e ROS_DOMAIN_ID=5 -it bash ``` -For a **persistent** change, set the identity where the resolver reads it from — the -device hostname on real hardware, or a mapping rule: - -```bash -sudo hostnamectl set-hostname robot-1 # -> ROBOT_NAME=robot_1, ROS_DOMAIN_ID=1 -``` - -!!! danger "Setting `ROBOT_NAME` in an env file does nothing" - No compose service declares `ROBOT_NAME` or `ROS_DOMAIN_ID` in its `environment:` - block, and Docker Compose only injects a variable into a container if a service - names it there. Putting `ROBOT_NAME=robot_1` in an override `.env` sets it for - **compose's own interpolation**, not for the container — `.bashrc` sees it unset, - the map lookup runs anyway, and there is no error. - - `overrides/l4t-px4-realrobot.env` used to ship `ROBOT_NAME` / `ROS_DOMAIN_ID` on - this basis; they never had any effect and have been removed. - - The general lesson applies to any deployment knob: it needs a declaration in the - service's `environment:` **and** a consumer that reads it, or it silently does - nothing. +Or add them to your project's `.env` file and make sure to pass them through in `docker-compose.yaml`. diff --git a/overrides/l4t-px4-realrobot.env b/overrides/l4t-px4-realrobot.env index e623f144a..6da88cf8d 100644 --- a/overrides/l4t-px4-realrobot.env +++ b/overrides/l4t-px4-realrobot.env @@ -15,8 +15,8 @@ NUM_ROBOTS="1" # --- Robot identity ----------------------------------------------------------- # Resolved from this device's hostname: name the Jetson robot-1 on the HOST -# (hostnamectl set-hostname robot-1) -> robot_1 on domain 1. Setting ROBOT_NAME here -# does nothing; no compose service declares it. See docs/robot/docker/robot_identity.md. +# Run the following: ``hostnamectl set-hostname robot-1`` +# resulting in robot_1 on domain 1. # Launches entire robot autonomy stack AUTONOMY_ROLE="full" From cec4be2362644fd7bf8a016bb2b681d653ddd831 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 5 Aug 2026 03:55:29 -0400 Subject: [PATCH 5/7] fix the bag recording status bridge direction It was bridged gcs -> robot, the same direction as the command it answers, so status never reached the GCS and the rqt Recording: label stayed blank. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 1 + .../autonomy_bringup/onboard_all/config/domain_bridge.yaml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04ce33da6..9a3aaabc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `RECORD_BAGS=true` never brought the bag recorder up on a robot: `logging.launch.xml` hardcoded `record_bag=false` and `onboard_autonomy_all.launch.xml` includes it with no arguments, so the variable was forwarded into the container and read by nobody (only `gcs.launch.xml` consumed it). With no `bag_record` node running, the GCS control panel's `set_recording_status` toggle had nothing to reach despite being bridged in `domain_bridge.yaml` / `dds_router.yaml`. It now reads `RECORD_BAGS` and selects its topic set via `LOG_CONFIG` - Falling back to `unknown_robot` / domain 0 now logs a warning naming both fixes (rename the device `robot-` on the host, or supply a `ROBOT_NAME_MAP_CONFIG_FILE` matching your hostnames). The fallback itself is unchanged — it deliberately keeps an unidentified robot out of every real robot's namespace — but it used to resolve silently, so the symptoms surfaced far from the cause - Dropped `ROBOT_NAME` / `ROS_DOMAIN_ID` from `overrides/l4t-px4-realrobot.env`: no compose service declares either, so an env file could never set them and the lines were inert +- `bag_record/bag_recording_status` was bridged GCS -> robot in `domain_bridge.yaml`, the same direction as the command it answers, so recorder status never reached the GCS and every recording indicator stayed blank ## [1.0.0] - 2024-12-19 diff --git a/robot/ros_ws/src/autonomy_bringup/onboard_all/config/domain_bridge.yaml b/robot/ros_ws/src/autonomy_bringup/onboard_all/config/domain_bridge.yaml index b60935c87..34e7e1d26 100644 --- a/robot/ros_ws/src/autonomy_bringup/onboard_all/config/domain_bridge.yaml +++ b/robot/ros_ws/src/autonomy_bringup/onboard_all/config/domain_bridge.yaml @@ -33,8 +33,8 @@ topics: # bag recording status bag_record/bag_recording_status: type: std_msgs/msg/Bool - from_domain: $(var gcs_domain) - to_domain: $(env ROS_DOMAIN_ID) + from_domain: $(env ROS_DOMAIN_ID) + to_domain: $(var gcs_domain) # ============= Incoming to Robot ================ From a9ab6774a7e857bb16d28c17e312baaf0fc04562 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 5 Aug 2026 03:55:29 -0400 Subject: [PATCH 6/7] fix the exclude flag so the main bag section records ros2 bag record renamed --exclude to --exclude-regex, and the old name is now an ambiguous prefix of four options, so argparse rejected the command and any section using exclude: recorded nothing. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 1 + .../bag_recorder_pid/bag_record_pid/bag_record_node.py | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a3aaabc9..f05f4113f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Falling back to `unknown_robot` / domain 0 now logs a warning naming both fixes (rename the device `robot-` on the host, or supply a `ROBOT_NAME_MAP_CONFIG_FILE` matching your hostnames). The fallback itself is unchanged — it deliberately keeps an unidentified robot out of every real robot's namespace — but it used to resolve silently, so the symptoms surfaced far from the cause - Dropped `ROBOT_NAME` / `ROS_DOMAIN_ID` from `overrides/l4t-px4-realrobot.env`: no compose service declares either, so an env file could never set them and the lines were inert - `bag_record/bag_recording_status` was bridged GCS -> robot in `domain_bridge.yaml`, the same direction as the command it answers, so recorder status never reached the GCS and every recording indicator stayed blank +- `bag_record_node` passed `--exclude` to `ros2 bag record`, which Jazzy renamed to `--exclude-regex`. It is now an ambiguous prefix of four options, so argparse rejected the command and any section using `exclude:` (including `log.yaml`'s `airstack` section, i.e. everything but the cameras) recorded nothing — surfacing only as a usage dump in the node's stdout. Multiple `exclude:` entries are now alternated into one regex instead of repeating a single-valued flag, which had silently kept only the last ## [1.0.0] - 2024-12-19 diff --git a/common/ros_packages/logging/bag_recorder_pid/bag_record_pid/bag_record_node.py b/common/ros_packages/logging/bag_recorder_pid/bag_record_pid/bag_record_node.py index d3d746d99..a815b6047 100644 --- a/common/ros_packages/logging/bag_recorder_pid/bag_record_pid/bag_record_node.py +++ b/common/ros_packages/logging/bag_recorder_pid/bag_record_pid/bag_record_node.py @@ -128,9 +128,10 @@ def add_topics(self): exit() self.commands[section_name]['suffix'].append('--all') - for topic in section_config['exclude']: - self.commands[section_name]['suffix'].append('--exclude') - self.commands[section_name]['suffix'].append(topic) + # --exclude-regex takes a single regex, so entries are alternated. + excludes = [str(t) for t in section_config['exclude']] + self.commands[section_name]['suffix'].append('--exclude-regex') + self.commands[section_name]['suffix'].append('|'.join(excludes)) self.get_logger().info(str(self.commands[section_name])) else: for topic in section_config['topics']: From d89765b3bd4e5b664ac63420caf260b67091c96a Mon Sep 17 00:00:00 2001 From: John Date: Wed, 5 Aug 2026 03:55:29 -0400 Subject: [PATCH 7/7] restore the bags .gitignore files #318 dropped robot/bags/.gitignore and gcs/bags/.gitignore while moving a dozen others; nothing has covered recorded bags since. Co-Authored-By: Claude Opus 5 --- gcs/bags/.gitignore | 11 +++++++++++ robot/bags/.gitignore | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 gcs/bags/.gitignore create mode 100644 robot/bags/.gitignore diff --git a/gcs/bags/.gitignore b/gcs/bags/.gitignore new file mode 100644 index 000000000..cc6955f65 --- /dev/null +++ b/gcs/bags/.gitignore @@ -0,0 +1,11 @@ +# list of all ros2 bag files to ignore +*.mcap +*.mcap.index +*.mcap.meta +*.mcap.bag +*.mcap.bag.index +*.mcap.bag.meta +*.db3 +*.db3.index +*.db3.meta +*.yaml \ No newline at end of file diff --git a/robot/bags/.gitignore b/robot/bags/.gitignore new file mode 100644 index 000000000..cc6955f65 --- /dev/null +++ b/robot/bags/.gitignore @@ -0,0 +1,11 @@ +# list of all ros2 bag files to ignore +*.mcap +*.mcap.index +*.mcap.meta +*.mcap.bag +*.mcap.bag.index +*.mcap.bag.meta +*.db3 +*.db3.index +*.db3.meta +*.yaml \ No newline at end of file