Skip to content

Commit c476db3

Browse files
General robot deployment infra: aarch64 build args + robot-name resolution fixes (#370)
Foundational real-robot deployment fixes extracted from the OptiTrack emulation PR (#367) so they can be reviewed and merged first; #367 will be rebased on top afterward, shrinking its diff. Docker / ARM build: - Add TARGET_ARCH build arg (default x86_64) to Dockerfile.robot and use it to parametrize LD_LIBRARY_PATH, so the aarch64 (Jetson/l4t, voxl) images link against the correct arch triplet. - docker-compose.yaml passes TARGET_ARCH: aarch64 to the voxl and l4t image builds. - Install ros-${ROS_DISTRO}-mavros-extras (generic dep; also provides the vision_pose plugin used by external-pose deployments). Robot name resolution: - .bashrc now follows a pre-set ROBOT_NAME (e.g. injected by docker compose) instead of always overriding it from the container/hostname mapping. The bws() flock build lock is retained. - default_robot_name_map.yaml catch-all fallback maps to unknown_robot (valid ROS namespace token) instead of unknown-robot. Version bumped 0.19.0-alpha.5 -> 0.19.0-alpha.6 for the version-increment gate. Note: the trajectory_controller/trajectory_library robustness fixes originally listed for extraction are already present on develop (PR #365), so they are not included here. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent fa990f4 commit c476db3

6 files changed

Lines changed: 47 additions & 30 deletions

File tree

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ PROJECT_NAME="airstack"
1212
# If you've run ./airstack.sh setup, then this will auto-generate from the git commit hash every time a change is made
1313
# to a Dockerfile or docker-compose.yaml file. Otherwise this can also be set explicitly to make a release version.
1414
# auto-generated from git commit hash
15-
VERSION="0.19.0-alpha.5"
15+
VERSION="0.19.0-alpha.6"
1616
# Choose "dev" or "prebuilt". "dev" is for mounted code that must be built live. "prebuilt" is for built ros_ws baked into the image
1717
DOCKER_IMAGE_BUILD_MODE="dev"
1818
# Where to push and pull images from. Can replace with your docker hub username if using docker hub.

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- Battery and telemetry display in GCS RQT control panel (voltage and percentage per robot when MAVROS battery topic is bridged)
13+
- `TARGET_ARCH` build arg (default `x86_64`) in `Dockerfile.robot` to arch-parametrize `LD_LIBRARY_PATH`; `docker-compose.yaml` passes `TARGET_ARCH: aarch64` to the `voxl` and `l4t` real-robot image builds
14+
- `ros-${ROS_DISTRO}-mavros-extras` in the robot image (provides the vision_pose plugin used for external-pose deployments)
15+
16+
### Fixed
17+
18+
- 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`)
19+
- Robot name-map catch-all fallback now maps to `unknown_robot` (valid ROS namespace token) instead of `unknown-robot` (`default_robot_name_map.yaml`)
1320

1421
## [1.0.0] - 2024-12-19
1522

robot/docker/.bashrc

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -69,35 +69,39 @@ function cws(){
6969
source /opt/ros/jazzy/setup.bash
7070
sws # source the ROS2 workspace by default
7171

72-
# Only extract robot name and ROS domain ID iff they are not already set in the environment (e.g. by docker compose)
73-
if [ "$ROBOT_NAME_SOURCE" == "container_name" ]; then
74-
# https://wiki.psuter.ch/doku.php?id=get_docker_container_name_from_within_the_container
75-
# WARNING: this technique ONLY works with docker version 29 and up.
76-
name_to_map=$(host $(host $(hostname) | awk '{print $NF}') | awk '{print $NF}' | awk -F . '{print $1}')
77-
CONTAINER_NAME=":$name_to_map"
78-
elif [ "$ROBOT_NAME_SOURCE" == "hostname" ]; then
79-
name_to_map=$(hostname)
80-
else
81-
echo "Warning: ROBOT_NAME_SOURCE=$ROBOT_NAME_SOURCE not set to a valid value. Defaulting to 'unknown_robot'."
82-
name_to_map=""
83-
export ROBOT_NAME="unknown_robot"
84-
export ROS_DOMAIN_ID=0
85-
fi
86-
# set ROBOT_NAME and ROS_DOMAIN_ID from the mapping script if NAME_TO_MAP is not empty
87-
if [ -n "$name_to_map" ]; then
88-
script_path="$HOME/AirStack/robot/docker/robot_name_map/resolve_robot_name.py"
89-
script_dir=$(dirname "$script_path")
72+
# If ROBOT_NAME is pre-set (e.g. via docker compose), keep it.
73+
# Otherwise extract robot name and ROS domain ID from the container/hostname mapping.
74+
if [ -z "${ROBOT_NAME:-}" ]; then
75+
if [ "$ROBOT_NAME_SOURCE" == "container_name" ]; then
76+
# https://wiki.psuter.ch/doku.php?id=get_docker_container_name_from_within_the_container
77+
# WARNING: this technique ONLY works with docker version 29 and up.
78+
name_to_map=$(host $(host $(hostname) | awk '{print $NF}') | awk '{print $NF}' | awk -F . '{print $1}')
79+
CONTAINER_NAME=":$name_to_map"
80+
elif [ "$ROBOT_NAME_SOURCE" == "hostname" ]; then
81+
name_to_map=$(hostname)
82+
else
83+
echo "Warning: ROBOT_NAME_SOURCE=$ROBOT_NAME_SOURCE not set to a valid value. Defaulting to 'unknown_robot'."
84+
name_to_map=""
85+
export ROBOT_NAME="unknown_robot"
86+
export ROS_DOMAIN_ID=0
87+
fi
9088

91-
existing_robot_domain_id=${ROS_DOMAIN_ID:-}
89+
# set ROBOT_NAME and ROS_DOMAIN_ID from the mapping script if NAME_TO_MAP is not empty
90+
if [ -n "$name_to_map" ]; then
91+
script_path="$HOME/AirStack/robot/docker/robot_name_map/resolve_robot_name.py"
92+
script_dir=$(dirname "$script_path")
9293

93-
eval "$($script_path $name_to_map $script_dir/$ROBOT_NAME_MAP_CONFIG_FILE)"
94-
export ROBOT_NAME
94+
existing_robot_domain_id=${ROS_DOMAIN_ID:-}
9595

96-
# if ROS_DOMAIN_ID was already set in the environment, use that instead of the mapped value
97-
if [ -z "$existing_robot_domain_id" ]; then
98-
export ROS_DOMAIN_ID
99-
else
100-
export ROS_DOMAIN_ID=$existing_robot_domain_id
96+
eval "$($script_path $name_to_map $script_dir/$ROBOT_NAME_MAP_CONFIG_FILE)"
97+
export ROBOT_NAME
98+
99+
# if ROS_DOMAIN_ID was already set in the environment, use that instead of the mapped value
100+
if [ -z "$existing_robot_domain_id" ]; then
101+
export ROS_DOMAIN_ID
102+
else
103+
export ROS_DOMAIN_ID=$existing_robot_domain_id
104+
fi
101105
fi
102106
fi
103107

robot/docker/Dockerfile.robot

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ ARG UPDATE_FLAGS="-o Acquire::AllowInsecureRepositories=true -o Acquire::AllowDo
1212
ARG INSTALL_FLAGS="-o APT::Get::AllowUnauthenticated=true"
1313
ARG SKIP_MACVO=false
1414
ARG SKIP_TENSORRT=false
15+
ARG TARGET_ARCH=x86_64
1516

1617
ARG PIP_VERSION=24.0
1718
ARG PYTHON_VERSION=3.12
@@ -65,7 +66,7 @@ RUN sudo add-apt-repository universe \
6566

6667
ENV AMENT_PREFIX_PATH=/opt/ros/${ROS_DISTRO}
6768
ENV COLCON_PREFIX_PATH=/opt/ros/${ROS_DISTRO}
68-
ENV LD_LIBRARY_PATH=/opt/ros/${ROS_DISTRO}/lib/x86_64-linux-gnu:/opt/ros/${ROS_DISTRO}/lib
69+
ENV LD_LIBRARY_PATH=/opt/ros/${ROS_DISTRO}/lib/${TARGET_ARCH}-linux-gnu:/opt/ros/${ROS_DISTRO}/lib
6970
ENV PATH=/opt/ros/${ROS_DISTRO}/bin:$PATH
7071
ENV PYTHONPATH=/opt/ros/${ROS_DISTRO}/local/lib/python${PYTHON_VERSION}/dist-packages:/opt/ros/${ROS_DISTRO}/lib/python${PYTHON_VERSION}/site-packages
7172
ENV ROS_PYTHON_VERSION=3
@@ -96,6 +97,7 @@ RUN python3 -m pip install --no-cache-dir --break-system-packages --ignore-insta
9697
RUN apt update -y && apt install -y --no-install-recommends \
9798
ros-dev-tools \
9899
ros-${ROS_DISTRO}-mavros \
100+
ros-${ROS_DISTRO}-mavros-extras \
99101
ros-${ROS_DISTRO}-tf2* \
100102
ros-${ROS_DISTRO}-stereo-image-proc \
101103
ros-${ROS_DISTRO}-image-view \
@@ -245,6 +247,7 @@ ARG UPDATE_FLAGS="-o Acquire::AllowInsecureRepositories=true -o Acquire::AllowDo
245247
ARG INSTALL_FLAGS="-o APT::Get::AllowUnauthenticated=true"
246248
ARG SKIP_MACVO=false
247249
ARG SKIP_TENSORRT=false
250+
ARG TARGET_ARCH=x86_64
248251

249252
ARG PIP_VERSION=24.0
250253
ARG PYTHON_VERSION=3.12
@@ -297,7 +300,7 @@ RUN sudo add-apt-repository universe \
297300

298301
ENV AMENT_PREFIX_PATH=/opt/ros/${ROS_DISTRO}
299302
ENV COLCON_PREFIX_PATH=/opt/ros/${ROS_DISTRO}
300-
ENV LD_LIBRARY_PATH=/opt/ros/${ROS_DISTRO}/lib/x86_64-linux-gnu:/opt/ros/${ROS_DISTRO}/lib
303+
ENV LD_LIBRARY_PATH=/opt/ros/${ROS_DISTRO}/lib/${TARGET_ARCH}-linux-gnu:/opt/ros/${ROS_DISTRO}/lib
301304
ENV PATH=/opt/ros/${ROS_DISTRO}/bin:$PATH
302305
ENV PYTHONPATH=/opt/ros/${ROS_DISTRO}/local/lib/python${PYTHON_VERSION}/dist-packages:/opt/ros/${ROS_DISTRO}/lib/python${PYTHON_VERSION}/site-packages
303306
ENV ROS_PYTHON_VERSION=3
@@ -328,6 +331,7 @@ RUN python3 -m pip install --no-cache-dir --break-system-packages --ignore-insta
328331
RUN apt update -y && apt install -y --no-install-recommends \
329332
ros-dev-tools \
330333
ros-${ROS_DISTRO}-mavros \
334+
ros-${ROS_DISTRO}-mavros-extras \
331335
ros-${ROS_DISTRO}-tf2* \
332336
ros-${ROS_DISTRO}-stereo-image-proc \
333337
ros-${ROS_DISTRO}-image-view \

robot/docker/docker-compose.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ services:
122122
REAL_ROBOT: true
123123
SKIP_MACVO: true
124124
SKIP_TENSORRT: true
125+
TARGET_ARCH: aarch64
125126
ROS_DISTRO: jazzy
126127
tags:
127128
- *voxl_image
@@ -179,6 +180,7 @@ services:
179180
REAL_ROBOT: true
180181
SKIP_MACVO: true
181182
SKIP_TENSORRT: true
183+
TARGET_ARCH: aarch64
182184
ROS_DISTRO: jazzy
183185
tags:
184186
- *l4t_image

robot/docker/robot_name_map/default_robot_name_map.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ mappings:
1212

1313
# catch all fall-back
1414
- pattern: '.*'
15-
robot: 'unknown-robot'
15+
robot: 'unknown_robot'
1616
domain_id: '0'

0 commit comments

Comments
 (0)