-
Notifications
You must be signed in to change notification settings - Fork 278
Bsb/lyrical jetty build #889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: vrx4
Are you sure you want to change the base?
Changes from all commits
e8a3cfd
c1dd6b3
9341308
b315bcc
4697a0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| # VRX 4 development image | ||
| # ROS 2 Lyrical Luth (Ubuntu 26.04 "Resolute") + Gazebo Jetty. | ||
| # | ||
| # Unlike the legacy image, this does NOT fake the gz vendor packages or build | ||
| # ros_gz from source. VRX 4's gz_waves packages `find_package(gz_sim_vendor)`, | ||
| # so we install the REAL ros-<distro>-gz-*-vendor packages (they carry the CMake | ||
| # shims and pull in Gazebo Jetty). This image only provides the environment; | ||
| # build the VRX workspace at runtime in the mounted ~/vrx_ws. | ||
| FROM ros:lyrical-ros-base AS vrx-base | ||
|
|
||
| ENV DEBIAN_FRONTEND=noninteractive | ||
| ENV TZ=Etc/UTC | ||
|
|
||
| # ---- Locale + base tooling ------------------------------------------------ | ||
| RUN apt-get update \ | ||
| && apt-get install -y --no-install-recommends \ | ||
| ca-certificates curl gnupg lsb-release locales tzdata \ | ||
| && ln -fs /usr/share/zoneinfo/$TZ /etc/localtime \ | ||
| && echo $TZ > /etc/timezone \ | ||
| && locale-gen en_US en_US.UTF-8 \ | ||
| && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
| ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 | ||
|
|
||
| # ---- OSRF Gazebo apt repo ------------------------------------------------- | ||
| # Provides Gazebo Jetty and the libs the gz_*_vendor packages depend on. | ||
| RUN curl -s https://packages.osrfoundation.org/gazebo.gpg \ | ||
| -o /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg \ | ||
| && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" \ | ||
| > /etc/apt/sources.list.d/gazebo-stable.list | ||
|
|
||
| # ---- Gazebo Jetty + ROS gz vendor shims + ros_gz -------------------------- | ||
| # The gz-*-vendor packages provide the CMake shims that VRX 4's gz_waves | ||
| # packages find_package(). The quoted glob is passed literally to apt, which | ||
| # expands it to every ros-<distro>-gz-<x>-vendor package (msgs, transport, | ||
| # fuel-tools, sim, rendering, ...). Gazebo itself arrives via these vendor | ||
| # packages + ros-gz; Resolute (26.04) has no standalone `gz-jetty` metapackage | ||
| # in the OSRF repo, and installing one alongside the vendors would be redundant. | ||
| RUN apt-get update \ | ||
| && apt-get install -y --no-install-recommends \ | ||
| ros-${ROS_DISTRO}-ros-gz \ | ||
| "ros-${ROS_DISTRO}-gz-*-vendor" \ | ||
| ros-${ROS_DISTRO}-sdformat-vendor \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # ---- Standard ROS packages + build tooling VRX uses ----------------------- | ||
| # NOTE: nav2 (navigation2, nav2-bringup, nav2-minimal-*) is intentionally | ||
| # omitted — it is often not yet released early in a new distro's life. Add | ||
| # ros-${ROS_DISTRO}-navigation2 etc. once available on Lyrical. | ||
| RUN apt-get update \ | ||
| && apt-get install -y --no-install-recommends \ | ||
| ros-${ROS_DISTRO}-ackermann-msgs \ | ||
| ros-${ROS_DISTRO}-actuator-msgs \ | ||
| ros-${ROS_DISTRO}-ament-cmake-pycodestyle \ | ||
| ros-${ROS_DISTRO}-image-transport \ | ||
| ros-${ROS_DISTRO}-image-transport-plugins \ | ||
| ros-${ROS_DISTRO}-joy-teleop \ | ||
| ros-${ROS_DISTRO}-joy-linux \ | ||
| ros-${ROS_DISTRO}-mavros-msgs \ | ||
| ros-${ROS_DISTRO}-radar-msgs \ | ||
| ros-${ROS_DISTRO}-vision-msgs \ | ||
| ros-${ROS_DISTRO}-xacro \ | ||
| python3-colcon-common-extensions \ | ||
| python3-rosdep \ | ||
| python3-vcstool \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # ---- Dev tools + NVIDIA GL (rocker --nvidia) ------------------------------ | ||
| RUN apt-get update \ | ||
| && apt-get install -y --no-install-recommends \ | ||
| atop expect gdb gnutls-bin iputils-ping libbluetooth-dev libcwiid-dev \ | ||
| net-tools python3-dbg python3-pip python3-venv vim wget xvfb \ | ||
| && dpkg --add-architecture i386 \ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need the i386 GL libs? Nothing in VRX is 32 bit, so this block could probably go. |
||
| && apt-get update \ | ||
| && apt-get install -y --no-install-recommends \ | ||
| libxau6 libxau6:i386 libxdmcp6 libxdmcp6:i386 libxcb1 libxcb1:i386 \ | ||
| libxext6 libxext6:i386 libx11-6 libx11-6:i386 libglvnd0 libglvnd0:i386 \ | ||
| libgl1 libgl1:i386 libglx0 libglx0:i386 libegl1 libegl1:i386 \ | ||
| libgles2 libgles2:i386 \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # ---- Source ROS for interactive + non-interactive shells ------------------ | ||
| RUN echo "source /opt/ros/${ROS_DISTRO}/setup.bash" > /etc/profile.d/ros.sh \ | ||
| && chmod +x /etc/profile.d/ros.sh \ | ||
| && echo "source /etc/profile.d/ros.sh" >> /etc/bash.bashrc | ||
| ENV BASH_ENV=/etc/profile.d/ros.sh | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Heads up: BASH_ENV makes every noninteractive bash source the ROS setup, which can surprise scripts that use set -u. |
||
|
|
||
| WORKDIR /ws | ||
| CMD ["/bin/bash"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # | ||
| # Copyright (C) 2018 Open Source Robotics Foundation | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| # | ||
| # | ||
|
|
||
| # Builds a Docker image. | ||
| # Usage: build.bash <dir containing Dockerfile> [tag] | ||
| # tag defaults to the resolved directory name, so passing '.' works too. | ||
| # | ||
| # For the VRX dev container, build it as vrx_dev:lyrical so it matches the | ||
| # image referenced in compose.yaml: | ||
| # ./build.bash <dir containing Dockerfile> lyrical | ||
| image_name=vrx_dev | ||
|
bsb808 marked this conversation as resolved.
|
||
|
|
||
| if [ $# -lt 1 ] | ||
| then | ||
| echo "Usage: $0 <path to directory containing Dockerfile> [tag]" | ||
| exit 1 | ||
| fi | ||
|
|
||
| context="$1" | ||
| if [ ! -f "${context}/Dockerfile" ] | ||
| then | ||
| echo "Err: ${context} does not contain a Dockerfile to build." | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Tag: explicit 2nd arg, else the resolved directory basename (handles '.'). | ||
| distro="${2:-$(basename "$(cd "${context}" && pwd)")}" | ||
|
|
||
| image_plus_tag=$image_name:$(export LC_ALL=C; date +%Y_%m_%d_%H%M) | ||
| docker build --rm -t "$image_plus_tag" -f "${context}/Dockerfile" "${context}" && \ | ||
| docker tag "$image_plus_tag" "$image_name:$distro" && \ | ||
| echo "Built $image_plus_tag and tagged as $image_name:$distro" && \ | ||
| echo "To run: ./docker/run_compose.bash" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing newline at end of file. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # NVIDIA overlay for the VRX 4 dev container. | ||
| # | ||
| # run_compose.bash layers this on top of compose.yaml ONLY when it detects an | ||
| # NVIDIA GPU on the host, so the base stays portable (Intel/AMD iGPU via | ||
| # /dev/dri) and NVIDIA hosts render on the dGPU via PRIME offload. | ||
| # | ||
| # Manual use: docker compose -f docker/compose.yaml -f docker/compose.nvidia.yaml run --rm dev | ||
| services: | ||
| dev: | ||
| # nvidia-container-toolkit injects the driver libs + /dev/nvidia* when these | ||
| # are set and the reservation below requests the GPU. | ||
| environment: | ||
| - NVIDIA_VISIBLE_DEVICES=all | ||
| - NVIDIA_DRIVER_CAPABILITIES=all | ||
| # PRIME render offload: on a hybrid/Optimus host the X display is driven by | ||
| # the iGPU and NVIDIA is the offload GPU. /dev/dri (base) is the present path. | ||
| - __NV_PRIME_RENDER_OFFLOAD=1 | ||
| - __GLX_VENDOR_LIBRARY_NAME=nvidia | ||
| - __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/10_nvidia.json | ||
|
|
||
| # Modern Compose + nvidia-container-toolkit. If your Docker still uses the | ||
| # legacy runtime, replace this block with `runtime: nvidia`. | ||
| deploy: | ||
| resources: | ||
| reservations: | ||
| devices: | ||
| - driver: nvidia | ||
| count: all | ||
| capabilities: [gpu] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| # Dev container for VRX 4 (ROS 2 Lyrical + Gazebo Jetty), via plain Docker | ||
| # Compose so it does NOT depend on rocker knowing Ubuntu 26.04. | ||
| # | ||
| # Mirrors: rocker --home --user --x11 --nvidia --devices /dev/input/js0 ... bash | ||
| # | ||
| # Easiest: ./docker/run_compose.bash | ||
| # | ||
| # Manually: | ||
| # xhost +SI:localuser:$(id -un) # let the container reach your X server (once per login) | ||
| # cd ~/WorkingCopies/oceansim/vrx_ws/src/vrx | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This personal path is still here. Maybe something generic like |
||
| # MY_UID=$(id -u) MY_GID=$(id -g) docker compose -f docker/compose.yaml run --rm --remove-orphans dev | ||
| # ( `UID` is a bash readonly var, so we pass MY_UID/MY_GID instead. ) | ||
| # | ||
| # (`run --rm` gives a fresh interactive shell and removes the container on exit, | ||
| # which is the rocker-like behaviour. Use `exec` instead if you prefer a | ||
| # long-lived container: `docker compose ... up -d` then `... exec dev bash`.) | ||
|
|
||
| services: | ||
| dev: | ||
| image: vrx_dev:lyrical # <- the tag you built; adjust if different | ||
|
|
||
| # --- interactive shell (rocker's default) --- | ||
| stdin_open: true # docker -i | ||
| tty: true # docker -t | ||
| command: bash | ||
|
|
||
| # --- run as your host user so files created in the mounted home keep your | ||
| # ownership (rocker --user). UID/GID come from the run command; the | ||
| # prompt may read "I have no name!" — cosmetic, since this UID has no | ||
| # /etc/passwd entry in the image. Drop this line to run as root. --- | ||
| user: "${MY_UID:-1000}:${MY_GID:-1000}" | ||
|
|
||
| # --- host networking: ROS 2 DDS discovery + simplest X11 (DISPLAY reaches | ||
| # the host X server directly) --- | ||
| network_mode: host | ||
| ipc: host | ||
|
|
||
| # Workspace root. run_compose.bash derives VRX_WS from the compose file's | ||
| # location; the default (current directory) covers a bare `docker compose ...` | ||
| # invocation, dropping you in wherever you're standing. | ||
| working_dir: ${VRX_WS:-${PWD}} | ||
|
|
||
| environment: | ||
| - DISPLAY=${DISPLAY} | ||
| - HOME=${HOME} | ||
| - QT_X11_NO_MITSHM=1 | ||
| # This base runs on the Intel/AMD iGPU via the /dev/dri passthrough below. | ||
| # NVIDIA access + PRIME render offload live in compose.nvidia.yaml, which | ||
| # run_compose.bash layers in automatically when an NVIDIA GPU is detected. | ||
|
|
||
| volumes: | ||
| - ${HOME}:${HOME} # rocker --home | ||
|
bsb808 marked this conversation as resolved.
|
||
| - /tmp/.X11-unix:/tmp/.X11-unix:rw # X11 socket | ||
| # No .Xauthority mount: run_compose.bash's `xhost +SI:localuser:$(id -un)` | ||
| # grants local access without it, and GDM's $XAUTHORITY | ||
| # (/run/user/.../gdm/Xauthority) collides with the home mount if | ||
| # bind-mounted onto ~/.Xauthority. | ||
|
|
||
| devices: | ||
| # - /dev/input/js0:/dev/input/js0 # joystick (delete if absent) | ||
| - /dev/dri:/dev/dri # direct rendering (Intel/AMD/GL) | ||
|
|
||
| # --- GPU: the NVIDIA reservation + PRIME offload are in compose.nvidia.yaml, | ||
| # layered in by run_compose.bash only when an NVIDIA GPU is present. | ||
| # This base alone renders on the Intel/AMD iGPU via /dev/dri above. --- | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| #!/usr/bin/env bash | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| # | ||
| # Minimal launcher for the VRX 4 dev container via Docker Compose | ||
| # (ROS 2 Lyrical + Gazebo Jetty). Mirrors rocker: interactive shell, home mount, | ||
| # GPU, X11, joystick. Service definition lives in docker/compose.yaml. | ||
| # | ||
| # Usage: | ||
| # ./docker/run_compose.bash # interactive bash in the container | ||
| # ./docker/run_compose.bash <cmd...> # run a command instead of bash | ||
| # | ||
| set -euo pipefail | ||
|
|
||
| # Resolve compose.yaml next to this script, so it works from any directory. | ||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
|
|
||
| # Workspace root = three levels up from docker/ (…/<ws>/src/vrx/docker). | ||
| # Derived from the script's own location so the repo can live anywhere; the | ||
| # compose file falls back to a default if this isn't exported. | ||
| export VRX_WS | ||
| VRX_WS="$(cd "${SCRIPT_DIR}/../../.." && pwd)" | ||
|
|
||
| # Let the container's (host-UID) process reach the host X server. Harmless to | ||
| # re-run; warn but don't abort if there's no X server (e.g. headless). | ||
| xhost +SI:localuser:"$(id -un)" >/dev/null 2>&1 \ | ||
| || echo "WARN: xhost failed (no X server?); GUI apps may not display." >&2 | ||
|
|
||
| # Host UID/GID so files created in the mounted home keep your ownership. | ||
| # (`UID` is a bash readonly variable, hence the MY_ prefix the compose expects.) | ||
| export MY_UID MY_GID | ||
| MY_UID="$(id -u)" | ||
| MY_GID="$(id -g)" | ||
|
|
||
| # GPU selection: prefer the NVIDIA dGPU when one is present and usable on the | ||
| # host, otherwise fall back to the Intel/AMD iGPU (base compose only). The | ||
| # NVIDIA reservation refuses to start the container on a host without an NVIDIA | ||
| # GPU, so only layer the overlay in when nvidia-smi actually reports one. | ||
| compose_files=(-f "${SCRIPT_DIR}/compose.yaml") | ||
| if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi -L >/dev/null 2>&1; then | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the driver is present but the nvidia container toolkit is not, compose fails to start instead of falling back to the iGPU. Maybe also check |
||
| compose_files+=(-f "${SCRIPT_DIR}/compose.nvidia.yaml") | ||
| echo "GPU: NVIDIA detected -> dGPU via PRIME offload." >&2 | ||
| else | ||
| echo "GPU: no usable NVIDIA -> Intel/AMD iGPU via /dev/dri." >&2 | ||
| fi | ||
|
|
||
| exec docker compose "${compose_files[@]}" run --rm --remove-orphans dev "$@" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,27 +28,28 @@ find_package(gz-rendering REQUIRED COMPONENTS ogre2) | |
| # registry (CreateWaveSimulation); the GUI-side factory registration lives in | ||
| # the per-engine GUI plugins (gz-sim-waves-<engine>-gui), loaded by the world. | ||
|
|
||
| # Discover Ogre Next headers. Different Gazebo installs sit on different Ogre | ||
| # Next patch versions (ROS gz_ogre_next_vendor 2.3.3 vs Ubuntu libogre-next-dev | ||
| # 2.3.1). Compiling against one but loading the other silently swaps in slow | ||
| # Hlms/barrier code paths (no crash, but RTF tanks), so probe which Ogre Next | ||
| # the *resolved* gz-rendering-ogre2 links against and match our header path. | ||
| get_target_property(_gz_rend_ogre2_lib gz-rendering::ogre2 LOCATION) | ||
| if(_gz_rend_ogre2_lib MATCHES "/opt/ros/([^/]+)/") | ||
| set(_ros_distro "${CMAKE_MATCH_1}") | ||
| set(OGRE_NEXT_INCLUDE_DIR | ||
| "/opt/ros/${_ros_distro}/opt/gz_ogre_next_vendor/include/OGRE-Next" | ||
| CACHE PATH "Ogre Next include dir matched to gz-rendering-ogre2 distro") | ||
| else() | ||
| # Non-ROS-distro install (e.g. local jetty_ws build) → system Ogre Next. | ||
| set(OGRE_NEXT_INCLUDE_DIR "/usr/include/OGRE-2.3" | ||
| CACHE PATH "Ogre Next include dir from libogre-next-dev") | ||
| endif() | ||
| if(NOT EXISTS "${OGRE_NEXT_INCLUDE_DIR}/OgreRoot.h") | ||
| # Discover the Ogre Next headers. We must compile against the SAME Ogre Next the | ||
| # resolved gz-rendering-ogre2 uses (mixing patch versions silently swaps in slow | ||
| # Hlms/barrier paths). The previous approach parsed gz-rendering::ogre2's | ||
| # LOCATION, but that property is empty for imported/interface targets (it is | ||
| # NOTFOUND on the ROS gz vendor + Gazebo Jetty), so it wrongly fell back to a | ||
| # hardcoded /usr/include/OGRE-2.3. Instead, search for the OGRE-Next headers, | ||
| # seeded by the ogre2 target's own interface include dirs. PATH_SUFFIXES exclude | ||
| # a bare "OGRE" so we never pick up classic Ogre 1.x (/usr/include/OGRE, | ||
| # rviz_ogre_vendor), whose ABI-incompatible headers would break the build. | ||
| get_target_property(_ogre2_incs gz-rendering::ogre2 INTERFACE_INCLUDE_DIRECTORIES) | ||
| find_path(OGRE_NEXT_INCLUDE_DIR | ||
| NAMES OgreRoot.h | ||
| HINTS ${_ogre2_incs} | ||
| PATHS | ||
| /opt/ros/$ENV{ROS_DISTRO}/opt/gz_ogre_next_vendor/include | ||
| /usr/include | ||
| PATH_SUFFIXES OGRE-Next OGRE-2.4 OGRE-2.3 | ||
| ) | ||
|
Comment on lines
+41
to
+48
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| if(NOT OGRE_NEXT_INCLUDE_DIR) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| message(FATAL_ERROR | ||
| "OgreRoot.h not found under ${OGRE_NEXT_INCLUDE_DIR} " | ||
| "(probed from gz-rendering::ogre2 = ${_gz_rend_ogre2_lib}). " | ||
| "Install libogre-next-dev or gz_ogre_next_vendor as appropriate.") | ||
| "OGRE-Next headers (OgreRoot.h) not found. Install libogre-next-dev or the " | ||
| "gz_ogre_next_vendor package.") | ||
| endif() | ||
| message(STATUS "Ogre Next headers: ${OGRE_NEXT_INCLUDE_DIR}") | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This list can drift from our
package.xmlfiles over time. Maybe generate it with rosdep or note rosdep as the source of truth.