From ec1db10e0beab8200d4367df18fc9b64e8cc594e Mon Sep 17 00:00:00 2001 From: yeseorizi <172019512+yeseorizi@users.noreply.github.com> Date: Wed, 9 Sep 2026 12:24:05 +0900 Subject: [PATCH 1/9] Migrate DAVE to ROS 2 Lyrical and Gazebo Jetty --- .docker/jazzy.amd64.dockerfile | 104 --------- .docker/jazzy.arm64v8.dockerfile | 197 ---------------- .docker/lyrical.amd64.dockerfile | 60 +++++ .docker/lyrical.arm64v8.dockerfile | 214 ++++++++++++++++++ .dockerignore | 6 + .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/good-first-issue.md | 2 +- .github/workflows/docker-amd64.yml | 55 +++-- .github/workflows/docker-arm64v8.yml | 58 +++-- .github/workflows/lint.yml | 2 +- README.md | 7 +- dave_interfaces/CMakeLists.txt | 2 - .../bluerov2_reconciled_path_control_ros2.md | 4 +- extras/ardusub-ubuntu-install-local.sh | 33 ++- extras/ardusub-ubuntu-install.sh | 36 ++- extras/docker-arm64-entrypoint.sh | 18 ++ .../{dave.jazzy.repos => dave.lyrical.repos} | 1 - ...all.sh => ros-lyrical-gz-jetty-install.sh} | 89 ++++---- gazebo/dave_gz_model_plugins/CMakeLists.txt | 37 +-- gazebo/dave_gz_multibeam_sonar/README.md | 2 +- .../multibeam_sonar/CMakeLists.txt | 48 ++-- .../multibeam_sonar_system/CMakeLists.txt | 44 ++-- gazebo/dave_gz_sensor_plugins/CMakeLists.txt | 57 ++--- gazebo/dave_gz_world_plugins/CMakeLists.txt | 71 +++--- gazebo/dave_ros_gz_plugins/CMakeLists.txt | 62 ++--- .../src/SphericalCoords.cc | 29 ++- 26 files changed, 635 insertions(+), 605 deletions(-) delete mode 100644 .docker/jazzy.amd64.dockerfile delete mode 100644 .docker/jazzy.arm64v8.dockerfile create mode 100644 .docker/lyrical.amd64.dockerfile create mode 100644 .docker/lyrical.arm64v8.dockerfile create mode 100644 .dockerignore mode change 100644 => 100755 extras/ardusub-ubuntu-install-local.sh mode change 100644 => 100755 extras/ardusub-ubuntu-install.sh create mode 100755 extras/docker-arm64-entrypoint.sh rename extras/repos/{dave.jazzy.repos => dave.lyrical.repos} (99%) rename extras/{ros-jazzy-gz-harmonic-install.sh => ros-lyrical-gz-jetty-install.sh} (62%) mode change 100644 => 100755 diff --git a/.docker/jazzy.amd64.dockerfile b/.docker/jazzy.amd64.dockerfile deleted file mode 100644 index 74b04c3e..00000000 --- a/.docker/jazzy.amd64.dockerfile +++ /dev/null @@ -1,104 +0,0 @@ -ARG ROS_DISTRO="jazzy" -FROM osrf/ros:$ROS_DISTRO-desktop-full -ARG BRANCH="ros2" - -# Install Utilities -# hadolint ignore=DL3008 -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - sudo xterm init systemd snapd vim net-tools \ - curl wget git build-essential cmake cppcheck \ - gnupg libeigen3-dev libgles2-mesa-dev \ - lsb-release pkg-config protobuf-compiler \ - python3-dbg python3-pip python3-venv python3-pexpect \ - python-is-python3 python3-future python3-wxgtk4.0 \ - qtbase5-dev ruby dirmngr gnupg2 nano xauth \ - software-properties-common htop libtool \ - x11-apps mesa-utils bison flex automake \ - && rm -rf /var/lib/apt/lists/ - -# Locale for UTF-8 -RUN truncate -s0 /tmp/preseed.cfg && \ - (echo "tzdata tzdata/Areas select Etc" >> /tmp/preseed.cfg) && \ - (echo "tzdata tzdata/Zones/Etc select UTC" >> /tmp/preseed.cfg) && \ - debconf-set-selections /tmp/preseed.cfg && \ - rm -f /etc/timezone && \ - dpkg-reconfigure -f noninteractive tzdata -# hadolint ignore=DL3008 -RUN apt-get update && \ - apt-get -y install --no-install-recommends locales tzdata \ - && rm -rf /tmp/* -RUN locale-gen en_US en_US.UTF-8 && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 && \ - export LANG=en_US.UTF-8 - -# Install ROS-Gazebo framework (including ardusub and mavros) -ADD https://raw.githubusercontent.com/IOES-Lab/dave/$BRANCH/\ -extras/ros-jazzy-gz-harmonic-install.sh install.sh -RUN bash install.sh - -# Expose ArduSub and Gazebo paths to non-interactive container commands. The installer -# adds the same paths through a shell startup file, so remove that hook to avoid duplicates. -RUN sed -i '\|^source \$HOME/.ros_ardusub_env/env$|d' /root/.bashrc -ENV PATH="/opt/ardusub_ws/ardupilot/Tools/autotest:/opt/ardusub_ws/ardupilot/build/sitl/bin:${PATH}" -ENV GEOGRAPHICLIB_GEOID_PATH="/usr/share/GeographicLib/geoids" -ENV GZ_SIM_SYSTEM_PLUGIN_PATH="/opt/ardusub_ws/ardupilot_gazebo/build" -ENV GZ_SIM_RESOURCE_PATH="/opt/ardusub_ws/ardupilot_gazebo/models:/opt/ardusub_ws/ardupilot_gazebo/worlds" - -# Install QGroundControl -RUN mkdir -p /opt/QGC && cd /opt/QGC && wget -O /opt/QGC/QGroundControl-x86_64.AppImage \ - "https://d176tv9ibo4jno.cloudfront.net/latest/QGroundControl-x86_64.AppImage" && \ - chmod +x QGroundControl-x86_64.AppImage && \ - ./QGroundControl-x86_64.AppImage --appimage-extract && \ - mv squashfs-root/* /opt/QGC/ && rm QGroundControl-x86_64.AppImage && \ - ln -sf /opt/QGC/AppRun /usr/local/bin/qgroundcontrol - -# Install Firefox from Mozilla (aarch64 tarball) -RUN curl -L "https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US" \ - -o /tmp/firefox.tar.xz && \ - mkdir -p /opt/firefox && \ - tar -xJf /tmp/firefox.tar.xz -C /opt && \ - ln -sf /opt/firefox/firefox /usr/local/bin/firefox && \ - rm -f /tmp/firefox.tar.xz - -# Set up Dave workspace -ENV DAVE_WS=/opt/dave_ws -WORKDIR $DAVE_WS/src - -ADD https://raw.githubusercontent.com/IOES-Lab/dave/$BRANCH/\ -extras/repos/dave.$ROS_DISTRO.repos $DAVE_WS/dave.repos -RUN vcs import --shallow --input $DAVE_WS/dave.repos - -# Install dave dependencies -RUN apt-get update && rosdep update && \ - rosdep install -iy --from-paths . && \ - rm -rf /var/lib/apt/lists/ - -# Compile Dave -WORKDIR $DAVE_WS -RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ - colcon build --symlink-install -WORKDIR / - -# Set up bashrc for root -RUN echo "source $DAVE_WS/install/setup.bash" >> /root/.bashrc && \ - echo "export PS1='\[\e[1;36m\]\u@DAVE_docker\[\e[0m\]\[\e[1;34m\](\$(hostname | cut -c1-12))\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ '" >> /root/.bashrc - -RUN touch /root/.dave_entrypoint && printf '\033[1;36m =====\n' >> /root/.dave_entrypoint && \ - printf ' ____ ___ _______ _ _ _ \n' >> /root/.dave_entrypoint && \ - printf ' | _ \ / \ \ / | ____| / \ __ _ _ _ __ _| |_(_) ___ \n' >> /root/.dave_entrypoint && \ - printf ' | | | |/ _ \ \ / /| _| / _ \ / _` | | | |/ _` | __| |/ __|\n' >> /root/.dave_entrypoint && \ - printf ' | |_| / ___ \ V / | |___ / ___ | (_| | |_| | (_| | |_| | (__ \n' >> /root/.dave_entrypoint && \ - printf ' |____/_/ \_\_/ |_____| /_/ \_\__, |\__,_|\__,_|\__|_|\___|\n' >> /root/.dave_entrypoint && \ - printf ' __ ___ _ _ _____ _ \n' >> /root/.dave_entrypoint && \ - printf ' \ \ / (_)_ __| |_ _ _ __ _| | | ____|_ ____ _(_)_ __ \n' >> /root/.dave_entrypoint && \ - printf ' \ \ / /| | `__| __| | | |/ _` | | | _| | `_ \ \ / | | `__| \n' >> /root/.dave_entrypoint && \ - printf ' \ V / | | | | |_| |_| | (_| | | | |___| | | \ V /| | |_ \n' >> /root/.dave_entrypoint && \ - printf ' \_/ |_|_| \__|\__,_|\__,_|_| |_____|_| |_|\_/ |_|_(_) \n\033[0m' >> /root/.dave_entrypoint && \ - printf '\033[1;32m\n =====\n\033[0m' >> /root/.dave_entrypoint && \ - printf "\\033[1;32m ๐Ÿ‘‹ Hi! This is Docker virtual environment for DAVE\n\\033[0m" \ - >> /root/.dave_entrypoint && \ - printf "\\033[1;33m\tROS2 Jazzy - Gazebo Harmonic (w ardupilot(ardusub) + mavros)\n\n\\033[0m" \ - >> /root/.dave_entrypoint && \ - echo 'cat /root/.dave_entrypoint' >> /root/.bashrc - -WORKDIR /root diff --git a/.docker/jazzy.arm64v8.dockerfile b/.docker/jazzy.arm64v8.dockerfile deleted file mode 100644 index e7782004..00000000 --- a/.docker/jazzy.arm64v8.dockerfile +++ /dev/null @@ -1,197 +0,0 @@ -# FROM arm64v8/ubuntu:24.04 -# # Set RDP and SSH environments -# ARG X11Forwarding=true -# # hadolint ignore=DL3008,DL3015,DL3009 -# RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ -# apt-get install -y ubuntu-desktop-minimal dbus-x11 xrdp sudo; \ -# [ $X11Forwarding = 'true' ] && apt-get install -y openssh-server; \ -# apt-get autoremove --purge; \ -# apt-get clean; \ -# rm /run/reboot-required* - -# ARG USER=docker -# ARG PASS=docker - -# RUN useradd -s /bin/bash -m $USER -p "$(openssl passwd "$PASS")"; \ -# usermod -aG sudo $USER; echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers; \ -# adduser xrdp ssl-cert; \ -# # Setting the required environment variables -# echo 'LANG=en_US.UTF-8' >> /etc/default/locale; \ -# echo 'export GNOME_SHELL_SESSION_MODE=ubuntu' > /home/$USER/.xsessionrc; \ -# echo 'export XDG_CURRENT_DESKTOP=ubuntu:GNOME' >> /home/$USER/.xsessionrc; \ -# echo 'export XDG_SESSION_TYPE=x11' >> /home/$USER/.xsessionrc; \ -# # Enabling log to the stdout -# sed -i "s/#EnableConsole=false/EnableConsole=true/g" /etc/xrdp/xrdp.ini; \ -# # Disabling system animations and reducing the -# # image quality to improve the performance -# sed -i 's/max_bpp=32/max_bpp=16/g' /etc/xrdp/xrdp.ini; \ -# gsettings set org.gnome.desktop.interface enable-animations true; \ -# # Listening on wildcard address for X forwarding -# [ $X11Forwarding = 'true' ] && \ -# sed -i 's/#X11UseLocalhost yes/X11UseLocalhost no/g' /etc/ssh/sshd_config || \ -# sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/g' /etc/ssh/sshd_config || \ -# :; - -# # Disable initial welcome window -# RUN echo "X-GNOME-Autostart-enabled=false" >> /etc/xdg/autostart/gnome-initial-setup-first-login.desktop - -# # Install basics -# ENV DEBIAN_FRONTEND noninteractive -# ENV DEBCONF_NONINTERACTIVE_SEEN=true -# # hadolint ignore=DL3008 -# RUN apt-get update && \ -# apt-get install -y --no-install-recommends \ -# sudo xterm init systemd snapd vim net-tools \ -# curl wget git build-essential cmake cppcheck \ -# gnupg libeigen3-dev libgles2-mesa-dev \ -# lsb-release pkg-config protobuf-compiler \ -# python3-dbg python3-pip python3-venv \ -# qtbase5-dev ruby dirmngr gnupg2 nano xauth \ -# software-properties-common htop libtool \ -# x11-apps mesa-utils bison flex automake && \ -# rm -rf /var/lib/apt/lists/ - -# Locale for UTF-8 -# RUN truncate -s0 /tmp/preseed.cfg && \ -# (echo "tzdata tzdata/Areas select Etc" >> /tmp/preseed.cfg) && \ -# (echo "tzdata tzdata/Zones/Etc select UTC" >> /tmp/preseed.cfg) && \ -# debconf-set-selections /tmp/preseed.cfg && \ -# rm -f /etc/timezone && \ -# dpkg-reconfigure -f noninteractive tzdata -# # hadolint ignore=DL3008 -# RUN apt-get update && \ -# apt-get -y install --no-install-recommends locales tzdata \ -# && rm -rf /tmp/* -# RUN locale-gen en_US en_US.UTF-8 && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 && \ -# export LANG=en_US.UTF-8 - -# # Run -# EXPOSE 3389/tcp -# EXPOSE 22/tcp -# # hadolint ignore=DL3025 -# CMD sudo rm -f /var/run/xrdp/xrdp*.pid >/dev/null 2>&1; \ -# sudo service dbus restart >/dev/null 2>&1; \ -# sudo /usr/lib/systemd/systemd-logind >/dev/null 2>&1 & \ -# [ -f /usr/sbin/sshd ] && sudo /usr/sbin/sshd; \ -# sudo xrdp-sesman --config /etc/xrdp/sesman.ini; \ -# sudo xrdp --nodaemon --config /etc/xrdp/xrdp.ini - -# Using the pre-built image for above commented out dockerfile code lines -# hadolint ignore=DL3007 -FROM woensugchoi/ubuntu-arm-rdp-base:latest -ARG USER=docker - -# ROS-Gazebo arg -ARG BRANCH="ros2" -ARG ROS_DISTRO="jazzy" - -# Update OS -RUN apt update && apt full-upgrade -y && apt autoremove -y - -# Install ROS-Gazebo framework (including ardusub and mavros) -ADD https://raw.githubusercontent.com/IOES-Lab/dave/$BRANCH/\ -extras/ros-jazzy-gz-harmonic-install.sh install.sh -RUN sudo bash install.sh - -# Download the background image from GitHub raw content URL -# hadolint ignore=DL3047 -RUN wget -O /usr/share/backgrounds/custom-background.png -q \ - https://raw.githubusercontent.com/IOES-Lab/dave/$BRANCH/\ -extras/background.png && \ - mv /usr/share/backgrounds/warty-final-ubuntu.png \ - /usr/share/backgrounds/warty-final-ubuntu.png.bak && \ - mv /usr/share/backgrounds/custom-background.png \ - /usr/share/backgrounds/warty-final-ubuntu.png && \ - cp /usr/share/backgrounds/warty-final-ubuntu.png \ - /usr/share/backgrounds/ubuntu-wallpaper-d.png - -# Install QGroundControl -RUN usermod -aG dialout "$(id -un)" && apt -y remove modemmanager -RUN apt-get -q update && \ - apt-get install -y --no-install-recommends \ - ffmpeg python3-venv python3-websockets \ - ros-${ROS_DISTRO}-joy-linux gstreamer1.0-tools gstreamer1.0-plugins-base \ - gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly python3-gi python3-gst-1.0 \ - libfuse2 libxcb-xinerama0 libxkbcommon-x11-0 libxcb-cursor-dev gstreamer1.0-qt6 \ - gstreamer1.0-gl libqt6qml6 qml6-module-qtquick qml6-module-qtquick-window && \ - rm -rf /var/lib/apt/lists/* -USER docker -RUN mkdir ~/QGC && wget -O ~/QGC/QGroundControl-aarch64-DailyBuild.AppImage \ - "https://d176tv9ibo4jno.cloudfront.net/builds/master/QGroundControl-aarch64.AppImage" && \ - cd ~/QGC && chmod +x QGroundControl-aarch64-DailyBuild.AppImage && \ - cd ~/QGC && ./QGroundControl-aarch64-DailyBuild.AppImage --appimage-extract && \ - mv ~/QGC/squashfs-root/* ~/QGC/. && rm ~/QGC/QGroundControl-aarch64-DailyBuild.AppImage && \ - mkdir -p /home/$USER/.local/bin && \ - ln -sf /home/$USER/QGC/AppRun /home/$USER/.local/bin/qgroundcontrol - -# Install Firefox from Mozilla (aarch64 tarball) -RUN curl -L "https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64-aarch64&lang=en-US" \ - -o /tmp/firefox.tar.xz && \ - tar -xJf /tmp/firefox.tar.xz -C /home/$USER && \ - ln -sf /home/$USER/firefox/firefox /home/$USER/.local/bin/firefox && \ - rm -f /tmp/firefox.tar.xz - -# Set up Dave workspace -ENV DAVE_UNDERLAY=/home/$USER/dave_ws -WORKDIR $DAVE_UNDERLAY/src -RUN wget -O /home/$USER/dave_ws/dave.repos -q https://raw.githubusercontent.com/IOES-Lab/dave/$BRANCH/\ -extras/repos/dave.$ROS_DISTRO.repos -RUN vcs import --shallow --input "/home/$USER/dave_ws/dave.repos" - -# hadolint ignore=DL3027 -RUN rosdep update --rosdistro $ROS_DISTRO && \ - rosdep install --rosdistro $ROS_DISTRO -iy --from-paths . - -# Build dave workspace -WORKDIR $DAVE_UNDERLAY -RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && colcon build --symlink-install - -# Set User as user -USER docker -RUN echo "source $DAVE_UNDERLAY/install/setup.bash" >> ~/.bashrc && \ - echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc && \ - echo "export PATH=/opt/ardusub_ws/ardupilot/Tools/autotest:\$PATH" >> ~/.bashrc && \ - echo "export PATH=/opt/ardusub_ws/ardupilot/build/sitl/bin:\$PATH" >> ~/.bashrc && \ - echo "export GEOGRAPHICLIB_GEOID_PATH=/usr/share/GeographicLib/geoids" >> ~/.bashrc && \ - echo "export GZ_SIM_SYSTEM_PLUGIN_PATH=/opt/ardusub_ws/ardupilot_gazebo/build:\$GZ_SIM_SYSTEM_PLUGIN_PATH" >> ~/.bashrc && \ - echo "export GZ_SIM_RESOURCE_PATH=/opt/ardusub_ws/ardupilot_gazebo/models:/opt/ardusub_ws/ardupilot_gazebo/worlds:\$GZ_SIM_RESOURCE_PATH" >> ~/.bashrc && \ - echo "export GST_PLUGIN_PATH=/usr/lib/aarch64-linux-gnu/gstreamer-1.0:\$GST_PLUGIN_PATH" >> ~/.bashrc && \ - echo "export QML2_IMPORT_PATH=/usr/lib/aarch64-linux-gnu/qt6/qml:\$QML2_IMPORT_PATH" >> ~/.bashrc && \ - echo "export LD_LIBRARY_PATH=/usr/lib/aarch64-linux-gnu:\$LD_LIBRARY_PATH" >> ~/.bashrc && \ - echo "\n" >> ~/.bashrc && echo "if [ -d ~/HOST ]; then chown $USER:$USER ~/HOST; fi" >> ~/.bashrc && \ - echo "export PS1='\[\e[1;36m\]\u@DAVE_docker\[\e[0m\]\[\e[1;34m\](\$(hostname | cut -c1-12))\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ '" >> ~/.bashrc - -# Other environment variables -RUN echo "export XDG_RUNTIME_DIR=~/.xdg_log" >> ~/.bashrc && \ - echo "unset SESSION_MANAGER" >> ~/.bashrc - -# Create and write the welcome message to a new file -RUN mkdir -p /home/docker/.config/autostart && \ - printf '\033[1;36m =====\n' >> ~/.hi && \ - printf ' ____ ___ _______ _ _ _ \n' >> ~/.hi && \ - printf ' | _ \ / \ \ / | ____| / \ __ _ _ _ __ _| |_(_) ___ \n' >> ~/.hi && \ - printf ' | | | |/ _ \ \ / /| _| / _ \ / _` | | | |/ _` | __| |/ __|\n' >> ~/.hi && \ - printf ' | |_| / ___ \ V / | |___ / ___ | (_| | |_| | (_| | |_| | (__ \n' >> ~/.hi && \ - printf ' |____/_/ \_\_/ |_____| /_/ \_\__, |\__,_|\__,_|\__|_|\___|\n' >> ~/.hi && \ - printf ' __ ___ _ _ _____ _ \n' >> ~/.hi && \ - printf ' \ \ / (_)_ __| |_ _ _ __ _| | | ____|_ ____ _(_)_ __ \n' >> ~/.hi && \ - printf ' \ \ / /| | `__| __| | | |/ _` | | | _| | `_ \ \ / | | `__| \n' >> ~/.hi && \ - printf ' \ V / | | | | |_| |_| | (_| | | | |___| | | \ V /| | |_ \n' >> ~/.hi && \ - printf ' \_/ |_|_| \__|\__,_|\__,_|_| |_____|_| |_|\_/ |_|_(_) \n\033[0m' >> ~/.hi && \ - printf '\033[1;32m\n =====\n\033[0m' >> ~/.hi && \ - printf "\\033[1;32m ๐Ÿ‘‹ Hi! This is Docker virtual environment for DAVE\n\\033[0m" \ - >> ~/.hi && \ - printf "\\033[1;33m\tROS2 Jazzy - Gazebo Harmonic (w ardupilot(ardusub) + mavros)\n\n\n\\033[0m" \ - >> ~/.hi - -# Remove sudo message -RUN touch /home/docker/.sudo_as_admin_successful - -# Autostart terminal -# hadolint ignore=SC3037 -RUN echo "[Desktop Entry]\nType=Application" \ - > /home/docker/.config/autostart/terminal.desktop && \ - echo "Exec=gnome-terminal -- bash -c 'cat ~/.hi; exec bash'" \ - >> /home/docker/.config/autostart/terminal.desktop && \ - echo -e "X-GNOME-Autostart-enabled=true" \ - >> /home/docker/.config/autostart/terminal.desktop diff --git a/.docker/lyrical.amd64.dockerfile b/.docker/lyrical.amd64.dockerfile new file mode 100644 index 00000000..61a2ae87 --- /dev/null +++ b/.docker/lyrical.amd64.dockerfile @@ -0,0 +1,60 @@ +ARG ROS_DISTRO="lyrical" +FROM osrf/ros:${ROS_DISTRO}-desktop-full + +ARG ROS_DISTRO="lyrical" +ENV ROS_DISTRO=${ROS_DISTRO} +ENV DEBIAN_FRONTEND=noninteractive + +# The installer expects sudo even when the image build runs as root. +RUN apt-get update && \ + apt-get install -y --no-install-recommends sudo ca-certificates xz-utils && \ + rm -rf /var/lib/apt/lists/* + +# Install ROS 2 Lyrical, Gazebo Jetty, ArduSub, and MAVROS from this checkout. +COPY extras /tmp/dave-extras +RUN DAVE_EXTRAS_DIR=/tmp/dave-extras \ + bash /tmp/dave-extras/ros-lyrical-gz-jetty-install.sh + +# Install QGroundControl. +RUN mkdir -p /opt/QGC && cd /opt/QGC && \ + wget -O QGroundControl-x86_64.AppImage \ + "https://d176tv9ibo4jno.cloudfront.net/latest/QGroundControl-x86_64.AppImage" && \ + chmod +x QGroundControl-x86_64.AppImage && \ + ./QGroundControl-x86_64.AppImage --appimage-extract && \ + mv squashfs-root/* /opt/QGC/ && \ + rm QGroundControl-x86_64.AppImage && \ + ln -sf /opt/QGC/AppRun /usr/local/bin/qgroundcontrol + +# Install Firefox from Mozilla. +RUN curl -L "https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US" \ + -o /tmp/firefox.tar.xz && \ + tar -xJf /tmp/firefox.tar.xz -C /opt && \ + ln -sf /opt/firefox/firefox /usr/local/bin/firefox && \ + rm -f /tmp/firefox.tar.xz + +# Build the exact DAVE revision supplied as the Docker build context. Import the +# companion repositories, but never replace the checked-out DAVE source. +ENV DAVE_WS=/opt/dave_ws +WORKDIR $DAVE_WS/src +COPY . dave +RUN vcs import --shallow --skip-existing \ + --input dave/extras/repos/dave.lyrical.repos + +RUN rosdep update --rosdistro "$ROS_DISTRO" && \ + rosdep install --rosdistro "$ROS_DISTRO" -iy --from-paths . && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR $DAVE_WS +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ + colcon build --merge-install --executor sequential --symlink-install + +RUN echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> /root/.bashrc && \ + echo "source $DAVE_WS/install/setup.bash" >> /root/.bashrc && \ + echo "export PS1='\[\e[1;36m\]\u@DAVE_docker\[\e[0m\]\[\e[1;34m\](\$(hostname | cut -c1-12))\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ '" >> /root/.bashrc + +RUN touch /root/.dave_entrypoint && \ + printf '\033[1;36mDAVE underwater robotics simulation\033[0m\n' >> /root/.dave_entrypoint && \ + printf '\033[1;33mROS 2 Lyrical ยท Gazebo Jetty ยท ArduSub ยท MAVROS\033[0m\n\n' >> /root/.dave_entrypoint && \ + echo 'cat /root/.dave_entrypoint' >> /root/.bashrc + +WORKDIR /root diff --git a/.docker/lyrical.arm64v8.dockerfile b/.docker/lyrical.arm64v8.dockerfile new file mode 100644 index 00000000..833ef044 --- /dev/null +++ b/.docker/lyrical.arm64v8.dockerfile @@ -0,0 +1,214 @@ +# DAVE development image for ROS 2 Lyrical / Gazebo Jetty on ARM64. +# Validated on Apple Silicon with Ubuntu 26.04, XFCE, and xrdp. +# +# Design notes: +# - FROM arm64v8/ubuntu:26.04 directly instead of a prebuilt personal base image โ€” the RDP/xrdp +# setup below is the adapted version of what that base image contained, plus the xrdp +# group-permission fix required by the verified Apple Silicon build. +# - ROS_DISTRO=lyrical; ros-lyrical-ros-gz supplies the Gazebo Jetty vendor packages. +# - The current CUDA sonar remains disabled on ARM64; the open WGPU PR is intentionally excluded. +# - ArduSub SITL includes the Python 3.14 compatibility shims validated on Ubuntu 26.04 +# (imp/pipes modules, python-argparse removal, and PEP 668 handling). + +FROM arm64v8/ubuntu:26.04 + +ARG USER=docker +ARG PASS=docker +ARG X11Forwarding=true + +# --- RDP / XFCE desktop setup --- +# hadolint ignore=DL3008,DL3015,DL3009 +RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ + apt-get install -y --no-install-recommends \ + dbus dbus-x11 xrdp xorgxrdp \ + xfce4 xfce4-goodies xfce4-terminal xterm \ + sudo openssl; \ + [ $X11Forwarding = 'true' ] && apt-get install -y openssh-server; \ + apt-get autoremove --purge; \ + apt-get clean; \ + rm -f /run/reboot-required* + +RUN useradd -s /bin/bash -m $USER && echo "$USER:$PASS" | chpasswd; \ + usermod -aG sudo $USER; echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers; \ + adduser xrdp ssl-cert; \ + # xrdp daemon needs root-group access to session sockets under /run/xrdp/sockdir/ โ€” + # without this, RDP connections time out after ~30s ("connection problem, giving up") + usermod -aG root xrdp; \ + echo 'LANG=en_US.UTF-8' >> /etc/default/locale; \ + echo 'export XDG_CURRENT_DESKTOP=XFCE' > /home/$USER/.xsessionrc; \ + echo 'export XDG_SESSION_DESKTOP=xfce' >> /home/$USER/.xsessionrc; \ + echo 'export DESKTOP_SESSION=xfce' >> /home/$USER/.xsessionrc; \ + echo 'export XDG_SESSION_TYPE=x11' >> /home/$USER/.xsessionrc; \ + sed -i "s/#EnableConsole=false/EnableConsole=true/g" /etc/xrdp/xrdp.ini; \ + sed -i 's/max_bpp=32/max_bpp=16/g' /etc/xrdp/xrdp.ini; \ + [ $X11Forwarding = 'true' ] && \ + sed -i 's/#X11UseLocalhost yes/X11UseLocalhost no/g' /etc/ssh/sshd_config || \ + sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/g' /etc/ssh/sshd_config || \ + :; \ + chown $USER:$USER /home/$USER/.xsessionrc + +# Bypass the Debian Xsession wrapper. In a systemd-less container it can exit +# before reaching ~/.xsession. Each RDP login gets its own DBus session. +RUN printf '%s\n' \ + '#!/bin/bash' \ + 'exec >>/home/docker/xrdp-startwm.log 2>&1' \ + 'export HOME=/home/docker' \ + 'export USER=docker' \ + 'export LOGNAME=docker' \ + 'export XDG_SESSION_TYPE=x11' \ + 'export XDG_CURRENT_DESKTOP=XFCE' \ + 'export XDG_SESSION_DESKTOP=xfce' \ + 'export DESKTOP_SESSION=xfce' \ + 'export XDG_RUNTIME_DIR="/run/user/$(id -u)"' \ + 'unset GNOME_SHELL_SESSION_MODE SESSION_MANAGER DBUS_SESSION_BUS_ADDRESS' \ + 'exec /usr/bin/dbus-run-session -- /usr/bin/startxfce4' \ + > /etc/xrdp/startwm.sh && \ + chmod 0755 /etc/xrdp/startwm.sh + +ENV DEBIAN_FRONTEND=noninteractive +ENV DEBCONF_NONINTERACTIVE_SEEN=true +# hadolint ignore=DL3008 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + xterm vim net-tools \ + curl wget git build-essential cmake cppcheck \ + gnupg libeigen3-dev libgles2-mesa-dev \ + lsb-release pkg-config protobuf-compiler \ + python3-pip python3-venv \ + nano xauth htop libtool \ + x11-apps mesa-utils bison flex automake && \ + rm -rf /var/lib/apt/lists/ + +RUN truncate -s0 /tmp/preseed.cfg && \ + (echo "tzdata tzdata/Areas select Etc" >> /tmp/preseed.cfg) && \ + (echo "tzdata tzdata/Zones/Etc select UTC" >> /tmp/preseed.cfg) && \ + debconf-set-selections /tmp/preseed.cfg && \ + rm -f /etc/timezone && \ + dpkg-reconfigure -f noninteractive tzdata +RUN apt-get update && \ + apt-get -y install --no-install-recommends locales tzdata && \ + rm -rf /tmp/* +RUN locale-gen en_US en_US.UTF-8 && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 + +EXPOSE 3389/tcp +EXPOSE 22/tcp + +# --- ROS 2 Lyrical + Gazebo Jetty --- +ARG ROS_DISTRO="lyrical" + +RUN apt update && apt full-upgrade -y && apt autoremove -y + +# Gazebo Jetty is vendored by ros-lyrical-ros-gz on apt already โ€” no separate Gazebo source build +RUN export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}') && \ + curl -L -o /tmp/ros2-apt-source.deb \ + "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb" && \ + dpkg -i /tmp/ros2-apt-source.deb && \ + apt update && \ + apt install -y --no-install-recommends \ + ros-${ROS_DISTRO}-desktop ros-${ROS_DISTRO}-ros-gz \ + python3-rosdep python3-vcstool python3-colcon-common-extensions + +# --- DAVE workspace --- +# Build the exact checked-out revision supplied as the Docker build context. +ENV DAVE_UNDERLAY=/home/$USER/dave_ws +WORKDIR $DAVE_UNDERLAY/src +COPY . dave +RUN chown -R $USER:$USER $DAVE_UNDERLAY/src/dave + +# Keep the companion repositories from the official DAVE workspace, while +# preserving the exact DAVE checkout copied above. +RUN vcs import --shallow --skip-existing \ + --input dave/extras/repos/dave.lyrical.repos && \ + chown -R $USER:$USER $DAVE_UNDERLAY + +RUN rosdep init 2>/dev/null || true && rosdep update --rosdistro $ROS_DISTRO && \ + rosdep install --rosdistro $ROS_DISTRO -iy --from-paths . + +USER $USER +WORKDIR $DAVE_UNDERLAY +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ + colcon build --merge-install --executor sequential --symlink-install + +# --- ArduSub SITL (BlueROV2) โ€” Python 3.14 compatibility shims required, see notes/ardusub-sitl-setup.md --- +# Pinned to the commit used by the verified Ubuntu 26.04 / Python 3.14 build. +USER root +ARG ARDUSUB_COMMIT="30257f01185471ab4c1ac544e47d1b4437e44c98" +WORKDIR /home/$USER +RUN git clone --recurse-submodules https://github.com/ArduPilot/ardupilot.git && \ + cd ardupilot && git fetch --tags && git checkout --detach "$ARDUSUB_COMMIT" && \ + git submodule update --init --recursive + +RUN mkdir -p /home/$USER/imp_shim && \ + printf 'import types\ndef new_module(name):\n return types.ModuleType(name)\n' > /home/$USER/imp_shim/imp.py && \ + printf 'import shlex\ndef quote(s):\n return shlex.quote(s)\n' > /home/$USER/imp_shim/pipes.py + +ENV PYTHONPATH=/home/$USER/imp_shim:/home/$USER/ardupilot/modules/waf/waflib/extras +ENV PIP_BREAK_SYSTEM_PACKAGES=1 + +# chown first โ€” the repo was cloned as root but must be built as $USER, and git refuses to +# operate across ownership boundaries ("detected dubious ownership") since CVE-2022-24765 +RUN chown -R $USER:$USER /home/$USER/ardupilot /home/$USER/imp_shim && \ + cd /home/$USER/ardupilot && \ + sed -i "s/ python-argparse//g" Tools/environment_install/install-prereqs-ubuntu.sh && \ + su $USER -c "git config --global --add safe.directory /home/$USER/ardupilot" && \ + su $USER -c "cd /home/$USER/ardupilot && Tools/environment_install/install-prereqs-ubuntu.sh -y" && \ + su $USER -c "cd /home/$USER/ardupilot && ./waf configure --board sitl && ./waf sub" && \ + cp /home/$USER/ardupilot/build/sitl/bin/ardusub /usr/local/bin/ardusub + +# Build the Gazebo Jetty ArduPilot plugin against the ROS vendor packages. +RUN git clone --depth 1 https://github.com/ArduPilot/ardupilot_gazebo.git \ + /home/$USER/ardupilot_gazebo && \ + chown -R $USER:$USER /home/$USER/ardupilot_gazebo && \ + mkdir -p /home/$USER/ardupilot_gazebo/build && \ + cd /home/$USER/ardupilot_gazebo/build && \ + . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ + cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo && \ + make -j2 + +ENV GZ_SIM_SYSTEM_PLUGIN_PATH=/home/$USER/ardupilot_gazebo/build +ENV GZ_SIM_RESOURCE_PATH=/home/$USER/ardupilot_gazebo/models:/home/$USER/ardupilot_gazebo/worlds + +# --- QGroundControl, Firefox, environment --- +RUN usermod -aG dialout $USER && apt -y remove modemmanager || true +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ffmpeg python3-venv python3-websockets \ + ros-${ROS_DISTRO}-joy-linux ros-${ROS_DISTRO}-mavros ros-${ROS_DISTRO}-mavros-msgs \ + gstreamer1.0-tools gstreamer1.0-plugins-base \ + gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly python3-gi python3-gst-1.0 \ + libfuse2 libxcb-xinerama0 libxkbcommon-x11-0 libxcb-cursor-dev gstreamer1.0-qt6 \ + gstreamer1.0-gl libqt6qml6 qml6-module-qtquick qml6-module-qtquick-window && \ + rm -rf /var/lib/apt/lists/* + +USER $USER +RUN mkdir -p ~/QGC && wget -O ~/QGC/QGroundControl-aarch64-DailyBuild.AppImage \ + "https://d176tv9ibo4jno.cloudfront.net/builds/master/QGroundControl-aarch64.AppImage" && \ + cd ~/QGC && chmod +x QGroundControl-aarch64-DailyBuild.AppImage && \ + ./QGroundControl-aarch64-DailyBuild.AppImage --appimage-extract && \ + mv ~/QGC/squashfs-root/* ~/QGC/. && rm ~/QGC/QGroundControl-aarch64-DailyBuild.AppImage && \ + mkdir -p /home/$USER/.local/bin && \ + ln -sf /home/$USER/QGC/AppRun /home/$USER/.local/bin/qgroundcontrol + +# Install Firefox from Mozilla's ARM64 archive, matching the previous image. +RUN curl -L "https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64-aarch64&lang=en-US" \ + -o /tmp/firefox.tar.xz && \ + tar -xJf /tmp/firefox.tar.xz -C /home/$USER && \ + ln -sf /home/$USER/firefox/firefox /home/$USER/.local/bin/firefox && \ + rm -f /tmp/firefox.tar.xz + +USER root +RUN echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> /home/$USER/.bashrc && \ + echo "source $DAVE_UNDERLAY/install/setup.bash" >> /home/$USER/.bashrc && \ + echo "export PATH=/home/$USER/.local/bin:/usr/local/bin:\$PATH" >> /home/$USER/.bashrc && \ + echo "export GZ_SIM_SYSTEM_PLUGIN_PATH=/home/$USER/ardupilot_gazebo/build:\${GZ_SIM_SYSTEM_PLUGIN_PATH:-}" >> /home/$USER/.bashrc && \ + echo "export GZ_SIM_RESOURCE_PATH=/home/$USER/ardupilot_gazebo/models:/home/$USER/ardupilot_gazebo/worlds:\${GZ_SIM_RESOURCE_PATH:-}" >> /home/$USER/.bashrc && \ + echo "export GEOGRAPHICLIB_GEOID_PATH=/usr/share/GeographicLib/geoids" >> /home/$USER/.bashrc && \ + echo "export GST_PLUGIN_PATH=/usr/lib/aarch64-linux-gnu/gstreamer-1.0:\${GST_PLUGIN_PATH:-}" >> /home/$USER/.bashrc && \ + echo "export QML2_IMPORT_PATH=/usr/lib/aarch64-linux-gnu/qt6/qml:\${QML2_IMPORT_PATH:-}" >> /home/$USER/.bashrc && \ + echo "export LD_LIBRARY_PATH=/usr/lib/aarch64-linux-gnu:\${LD_LIBRARY_PATH:-}" >> /home/$USER/.bashrc && \ + echo "export PS1='\[\e[1;36m\]\u@lyrical_docker\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ '" >> /home/$USER/.bashrc + +# --- Run (no systemd inside this container) --- +COPY extras/docker-arm64-entrypoint.sh /usr/local/bin/dave-rdp-entrypoint +RUN chmod 0755 /usr/local/bin/dave-rdp-entrypoint +CMD ["/usr/local/bin/dave-rdp-entrypoint"] diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..f6eb6176 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.git +build +install +log +*.pptx +*.pdf diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 812af5d8..d8ba78be 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -25,7 +25,7 @@ If applicable, add screenshots to help explain your problem. **Environment (please complete the following information):** - Machine [e.g. Mac VMWare, Linux Ubuntu] - - OS Version: [e.g. Ubuntu 24.04] + - OS Version: [e.g. Ubuntu 26.04] - Anything that may be unusual about your environment **Additional context** diff --git a/.github/ISSUE_TEMPLATE/good-first-issue.md b/.github/ISSUE_TEMPLATE/good-first-issue.md index e852bd9b..fdd34583 100644 --- a/.github/ISSUE_TEMPLATE/good-first-issue.md +++ b/.github/ISSUE_TEMPLATE/good-first-issue.md @@ -28,7 +28,7 @@ Nothing. This issue is meant to welcome you to Open Source :) We are happy to wa - [ ] ๐Ÿ™‹ **Claim this issue**: Comment below. If someone else has claimed it, ask if they've opened a pull request already and if they're stuck -- maybe you can help them solve a problem or move it along! -- [ ] ๐Ÿ—„๏ธ **Create a local workspace** for making your changes and testing [following these instructions](https://docs.ros.org/en/jazzy/Tutorials/Workspace/Creating-A-Workspace.html) +- [ ] ๐Ÿ—„๏ธ **Create a local workspace** for making your changes and testing [following these instructions](https://docs.ros.org/en/lyrical/Tutorials/Beginner-Client-Libraries/Creating-A-Workspace.html) - [ ] ๐Ÿด **Fork the repository** using the handy button at the top of the repository page and **clone** it into `~/ros2_ws/src/dave`, [here is a guide that you can follow](https://guides.github.com/activities/forking/) (You will have to remove or empty the existing `dave` folder before cloning your own fork) diff --git a/.github/workflows/docker-amd64.yml b/.github/workflows/docker-amd64.yml index dfb43bea..17c96db0 100644 --- a/.github/workflows/docker-amd64.yml +++ b/.github/workflows/docker-amd64.yml @@ -1,22 +1,35 @@ --- -name: Publish a Docker image (AMD64; Common X86_64 Linux Machine) +name: Build Lyrical / Jetty Docker image (AMD64) # yamllint disable-line rule:truthy on: + workflow_dispatch: + pull_request: + branches: [ros2] + paths: + - ".docker/**" + - ".dockerignore" + - ".github/workflows/docker-amd64.yml" + - "dave_interfaces/**" + - "examples/**" + - "extras/**" + - "gazebo/**" + - "models/**" + - "README.md" push: tags: ["*"] - branches: - - ros2 - - dockertest + branches: [ros2, dockertest] env: - IMAGE_NAME: ${{ github.repository }} - ROS_DISTRO: jazzy - BRANCH: ${{ github.ref_name }} + IMAGE_NAME: ioeslab/dave + ROS_DISTRO: lyrical jobs: build-and-push-to-docker-hub: - # runs-on: ubuntu-latest + # Never execute untrusted fork code on a self-hosted runner. + if: >- + github.event_name != 'pull_request' || + github.event.pull_request.head.repo.full_name == github.repository runs-on: [self-hosted, x64] timeout-minutes: 1440 permissions: @@ -24,42 +37,38 @@ jobs: packages: write steps: - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Checkout repository uses: actions/checkout@v4 - - name: Log in to the Docker Hub Container registry + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + if: github.event_name != 'pull_request' uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Docker meta + - name: Docker metadata id: meta uses: docker/metadata-action@v5 with: - images: ioeslab/dave + images: ${{ env.IMAGE_NAME }} tags: | type=ref,event=branch + type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} - - name: Build and push Docker image + - name: Build Docker image uses: docker/build-push-action@v5 with: context: . - push: true + push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - file: .docker/jazzy.amd64.dockerfile + file: .docker/lyrical.amd64.dockerfile platforms: linux/amd64 build-args: | ROS_DISTRO=${{ env.ROS_DISTRO }} - BRANCH=${{ env.BRANCH }} - - - name: Debug environment variables - run: | - echo "ROS_DISTRO: ${ROS_DISTRO}" - echo "BRANCH: ${BRANCH}" diff --git a/.github/workflows/docker-arm64v8.yml b/.github/workflows/docker-arm64v8.yml index c3f02c64..f581b797 100644 --- a/.github/workflows/docker-arm64v8.yml +++ b/.github/workflows/docker-arm64v8.yml @@ -1,22 +1,35 @@ --- -name: Publish a Docker image (ARM64; Apple Silicon) +name: Build Lyrical / Jetty Docker image (ARM64) # yamllint disable-line rule:truthy on: + workflow_dispatch: + pull_request: + branches: [ros2] + paths: + - ".docker/**" + - ".dockerignore" + - ".github/workflows/docker-arm64v8.yml" + - "dave_interfaces/**" + - "examples/**" + - "extras/**" + - "gazebo/**" + - "models/**" + - "README.md" push: tags: ["*"] - branches: - - ros2 - - dockertest + branches: [ros2, dockertest] env: - IMAGE_NAME: ${{ github.repository }} - ROS_DISTRO: jazzy - BRANCH: ${{ github.ref_name }} + IMAGE_NAME: ioeslab/dave + ROS_DISTRO: lyrical jobs: build-and-push-to-docker-hub: - # runs-on: ubuntu-latest + # Never execute untrusted fork code on a self-hosted runner. + if: >- + github.event_name != 'pull_request' || + github.event.pull_request.head.repo.full_name == github.repository runs-on: [self-hosted, ARM64] timeout-minutes: 1440 permissions: @@ -24,39 +37,36 @@ jobs: packages: write steps: - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Checkout repository uses: actions/checkout@v4 - - name: Log in to the Docker Hub Container registry + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + if: github.event_name != 'pull_request' uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Docker meta + - name: Docker metadata id: meta uses: docker/metadata-action@v5 with: - images: ioeslab/dave - tags: ros2-arm-rdp + images: ${{ env.IMAGE_NAME }} + tags: | + type=raw,value=ros2-arm-rdp,enable=${{ github.event_name != 'pull_request' }} + type=ref,event=pr - - name: Build and push Docker image + - name: Build Docker image uses: docker/build-push-action@v5 with: context: . - push: true + push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - file: .docker/jazzy.arm64v8.dockerfile + file: .docker/lyrical.arm64v8.dockerfile platforms: linux/arm64/v8 build-args: | ROS_DISTRO=${{ env.ROS_DISTRO }} - BRANCH=${{ env.BRANCH }} - - - name: Debug environment variables - run: | - echo "ROS_DISTRO: ${ROS_DISTRO}" - echo "BRANCH: ${BRANCH}" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1684173c..677c35bc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,7 +14,7 @@ jobs: # ament_lint: # runs-on: ubuntu-latest # container: - # image: rostooling/setup-ros-docker:ubuntu-noble-ros-jazzy-desktop-latest + # image: rostooling/setup-ros-docker:ubuntu-resolute-ros-lyrical-desktop-latest # options: -u root # strategy: # fail-fast: false diff --git a/README.md b/README.md index 0a66e49a..d9ef3ca0 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ # DAVE -[![Publish a Docker image (AMD64; Common X86_64 Linux Machine)](https://github.com/IOES-Lab/dave/actions/workflows/docker-amd64.yml/badge.svg)](https://github.com/IOES-Lab/dave/actions/workflows/docker-amd64.yml) -[![Publish a Docker image (ARM64; Apple Silicon)](https://github.com/IOES-Lab/dave/actions/workflows/docker-arm64v8.yml/badge.svg?branch=ros2)](https://github.com/IOES-Lab/dave/actions/workflows/docker-arm64v8.yml) +[![Publish Lyrical / Jetty Docker image (AMD64)](https://github.com/IOES-Lab/dave/actions/workflows/docker-amd64.yml/badge.svg?branch=ros2)](https://github.com/IOES-Lab/dave/actions/workflows/docker-amd64.yml) +[![Publish Lyrical / Jetty Docker image (ARM64)](https://github.com/IOES-Lab/dave/actions/workflows/docker-arm64v8.yml/badge.svg?branch=ros2)](https://github.com/IOES-Lab/dave/actions/workflows/docker-arm64v8.yml) Documentation is currently at [http://dave-ros2.notion.site](http://dave-ros2.notion.site) +The current `ros2` stack targets **ROS 2 Lyrical on Ubuntu 26.04** and +**Gazebo Jetty** (provided through the ROS `ros_gz` vendor packages). + For contribution, do `pip3 install pre-commit && pre-commit install && pre-commit run --all-files` before commit. diff --git a/dave_interfaces/CMakeLists.txt b/dave_interfaces/CMakeLists.txt index 36eda427..56276f13 100644 --- a/dave_interfaces/CMakeLists.txt +++ b/dave_interfaces/CMakeLists.txt @@ -11,8 +11,6 @@ find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) find_package(geometry_msgs REQUIRED) find_package(rosidl_default_generators REQUIRED) -find_package(gz-cmake3 REQUIRED) -find_package(gz-msgs10 REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} "msg/UsblCommand.msg" diff --git a/examples/community/bluerov2_reconciled_path_control_ros2.md b/examples/community/bluerov2_reconciled_path_control_ros2.md index f1e25028..50402baa 100644 --- a/examples/community/bluerov2_reconciled_path_control_ros2.md +++ b/examples/community/bluerov2_reconciled_path_control_ros2.md @@ -6,8 +6,8 @@ for DAVE / Gazebo: [BlueROV2 reconciled path control](https://github.com/drwa92/bluerov2_reconciled_path_control_ros2) > [!NOTE] -> This package is developed and released outside DAVE. ROS 2 Jazzy startup and package -> discovery fixes found during DAVE validation are tracked in the +> This package is developed and released outside DAVE. Startup and package-discovery +> fixes found during DAVE validation are tracked in the > [external compatibility PR](https://github.com/drwa92/bluerov2_reconciled_path_control_ros2/pull/1). > Check that PR before following the external project's quick-start instructions. diff --git a/extras/ardusub-ubuntu-install-local.sh b/extras/ardusub-ubuntu-install-local.sh old mode 100644 new mode 100755 index 6da8c3f2..f5e4e762 --- a/extras/ardusub-ubuntu-install-local.sh +++ b/extras/ardusub-ubuntu-install-local.sh @@ -1,25 +1,36 @@ -#!/bin/bash +#!/usr/bin/env bash +set -euo pipefail # Source Ros and Gazebo # shellcheck source=/dev/null -source /opt/ros/jazzy/setup.bash +ROS_DISTRO="${ROS_DISTRO:-lyrical}" +source "/opt/ros/${ROS_DISTRO}/setup.bash" USER_NAME=$(logname 2>/dev/null || echo "${SUDO_USER:-$USER}") export USER="$USER_NAME" -# Really should do version pinning but Sub-4.5 is waaaay behind master -# (e.g. it doesn't know about "noble" yet) -export ARDUPILOT_RELEASE=master +ARDUPILOT_COMMIT="${ARDUPILOT_COMMIT:-30257f01185471ab4c1ac544e47d1b4437e44c98}" mkdir -p "/home/$USER/ardusub_ws" && cd "/home/$USER/ardusub_ws" || exit -git clone -b $ARDUPILOT_RELEASE https://github.com/ArduPilot/ardupilot.git --recurse-submodules +git clone https://github.com/ArduPilot/ardupilot.git --recurse-submodules +cd "/home/$USER/ardusub_ws/ardupilot" || exit +git checkout --detach "$ARDUPILOT_COMMIT" +git submodule update --init --recursive + +mkdir -p "/home/$USER/ardusub_ws/python_compat" +printf 'import types\ndef new_module(name):\n return types.ModuleType(name)\n' \ + > "/home/$USER/ardusub_ws/python_compat/imp.py" +printf 'import shlex\ndef quote(value):\n return shlex.quote(value)\n' \ + > "/home/$USER/ardusub_ws/python_compat/pipes.py" +export PYTHONPATH="/home/$USER/ardusub_ws/python_compat:/home/$USER/ardusub_ws/ardupilot/modules/waf/waflib/extras${PYTHONPATH:+:$PYTHONPATH}" +export PIP_BREAK_SYSTEM_PACKAGES=1 # Install ArduSub dependencies -cd "/home/$USER/ardusub_ws/ardupilot" || exit export SKIP_AP_EXT_ENV=1 SKIP_AP_GRAPHIC_ENV=1 SKIP_AP_COV_ENV=1 SKIP_AP_GIT_CHECK=1 # Do not install the STM development tools export DO_AP_STM_ENV=0 # Do not activate the Ardupilot venv by default export DO_PYTHON_VENV_ENV=0 +sed -i 's/ python-argparse//g' Tools/environment_install/install-prereqs-ubuntu.sh Tools/environment_install/install-prereqs-ubuntu.sh -y # Build ArduSub @@ -37,10 +48,10 @@ mkdir -p "/home/$USER/ardusub_ws/ardupilot_gazebo/build" \ cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo && make -j2 # Add results of ArduSub build -export PATH=/home/$USER/ardusub_ws/ardupilot/build/sitl/bin:\$PATH +export PATH=/home/$USER/ardusub_ws/ardupilot/build/sitl/bin:$PATH # Optional: add autotest to the PATH, helpful for running sim_vehicle.py -export PATH=/home/$USER/ardusub_ws/ardupilot/Tools/autotest:\$PATH +export PATH=/home/$USER/ardusub_ws/ardupilot/Tools/autotest:$PATH # Add ardupilot_gazebo plugin -export GZ_SIM_SYSTEM_PLUGIN_PATH=/home/$USER/ardusub_ws/ardupilot_gazebo/build:\$GZ_SIM_SYSTEM_PLUGIN_PATH +export GZ_SIM_SYSTEM_PLUGIN_PATH=/home/$USER/ardusub_ws/ardupilot_gazebo/build:${GZ_SIM_SYSTEM_PLUGIN_PATH:-} # Add ardupilot_gazebo models and worlds -export GZ_SIM_RESOURCE_PATH=/home/$USER/ardusub_ws/ardupilot_gazebo/models:/home/$USER/ardusub_ws/ardupilot_gazebo/worlds:\$GZ_SIM_RESOURCE_PATH \ No newline at end of file +export GZ_SIM_RESOURCE_PATH=/home/$USER/ardusub_ws/ardupilot_gazebo/models:/home/$USER/ardusub_ws/ardupilot_gazebo/worlds:${GZ_SIM_RESOURCE_PATH:-} diff --git a/extras/ardusub-ubuntu-install.sh b/extras/ardusub-ubuntu-install.sh old mode 100644 new mode 100755 index 9a7d70cd..5374d9c5 --- a/extras/ardusub-ubuntu-install.sh +++ b/extras/ardusub-ubuntu-install.sh @@ -1,22 +1,36 @@ -#!/bin/bash +#!/usr/bin/env bash +set -euo pipefail # Source Ros and Gazebo # shellcheck source=/dev/null -source /opt/ros/jazzy/setup.bash +ROS_DISTRO="${ROS_DISTRO:-lyrical}" +source "/opt/ros/${ROS_DISTRO}/setup.bash" -# Really should do version pinning but Sub-4.5 is waaaay behind master -# (e.g. it doesn't know about "noble" yet) -export ARDUPILOT_RELEASE=master +# Commit used by the verified Lyrical / Python 3.14 build. +ARDUPILOT_COMMIT="${ARDUPILOT_COMMIT:-30257f01185471ab4c1ac544e47d1b4437e44c98}" mkdir -p "/opt/ardusub_ws" && cd "/opt/ardusub_ws" || exit -git clone -b $ARDUPILOT_RELEASE https://github.com/ArduPilot/ardupilot.git --recurse-submodules +git clone https://github.com/ArduPilot/ardupilot.git --recurse-submodules +cd "/opt/ardusub_ws/ardupilot" || exit +git checkout --detach "$ARDUPILOT_COMMIT" +git submodule update --init --recursive + +# ArduPilot's waf extras still import Python modules removed in 3.12/3.13. +# These minimal compatibility shims were used in the verified Ubuntu 26.04 build. +mkdir -p /opt/ardusub_ws/python_compat +printf 'import types\ndef new_module(name):\n return types.ModuleType(name)\n' \ + > /opt/ardusub_ws/python_compat/imp.py +printf 'import shlex\ndef quote(value):\n return shlex.quote(value)\n' \ + > /opt/ardusub_ws/python_compat/pipes.py +export PYTHONPATH="/opt/ardusub_ws/python_compat:/opt/ardusub_ws/ardupilot/modules/waf/waflib/extras${PYTHONPATH:+:$PYTHONPATH}" +export PIP_BREAK_SYSTEM_PACKAGES=1 # Install ArduSub dependencies -cd "/opt/ardusub_ws/ardupilot" || exit export SKIP_AP_EXT_ENV=1 SKIP_AP_GRAPHIC_ENV=1 SKIP_AP_COV_ENV=1 SKIP_AP_GIT_CHECK=1 # Do not install the STM development tools export DO_AP_STM_ENV=0 # Do not activate the Ardupilot venv by default export DO_PYTHON_VENV_ENV=0 +sed -i 's/ python-argparse//g' Tools/environment_install/install-prereqs-ubuntu.sh Tools/environment_install/install-prereqs-ubuntu.sh -y # Build ArduSub @@ -34,10 +48,10 @@ mkdir -p "/opt/ardusub_ws/ardupilot_gazebo/build" \ cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo && make -j2 # Add results of ArduSub build -export PATH=/opt/ardusub_ws/ardupilot/build/sitl/bin:\$PATH +export PATH=/opt/ardusub_ws/ardupilot/build/sitl/bin:$PATH # Optional: add autotest to the PATH, helpful for running sim_vehicle.py -export PATH=/opt/ardusub_ws/ardupilot/Tools/autotest:\$PATH +export PATH=/opt/ardusub_ws/ardupilot/Tools/autotest:$PATH # Add ardupilot_gazebo plugin -export GZ_SIM_SYSTEM_PLUGIN_PATH=/opt/ardusub_ws/ardupilot_gazebo/build:\$GZ_SIM_SYSTEM_PLUGIN_PATH +export GZ_SIM_SYSTEM_PLUGIN_PATH=/opt/ardusub_ws/ardupilot_gazebo/build:${GZ_SIM_SYSTEM_PLUGIN_PATH:-} # Add ardupilot_gazebo models and worlds -export GZ_SIM_RESOURCE_PATH=/opt/ardusub_ws/ardupilot_gazebo/models:/opt/ardusub_ws/ardupilot_gazebo/worlds:\$GZ_SIM_RESOURCE_PATH \ No newline at end of file +export GZ_SIM_RESOURCE_PATH=/opt/ardusub_ws/ardupilot_gazebo/models:/opt/ardusub_ws/ardupilot_gazebo/worlds:${GZ_SIM_RESOURCE_PATH:-} diff --git a/extras/docker-arm64-entrypoint.sh b/extras/docker-arm64-entrypoint.sh new file mode 100755 index 00000000..f9118f20 --- /dev/null +++ b/extras/docker-arm64-entrypoint.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +uid="$(id -u docker)" +install -d -m 0755 /run/xrdp /run/xrdp/sockdir +install -d -m 0700 -o docker -g docker "/run/user/${uid}" +rm -f /run/xrdp/*.pid /var/run/xrdp/*.pid + +mkdir -p /run/dbus +rm -f /run/dbus/pid +dbus-daemon --system --fork + +if [[ -x /usr/sbin/sshd ]]; then + /usr/sbin/sshd +fi + +xrdp-sesman --nodaemon --config /etc/xrdp/sesman.ini & +exec xrdp --nodaemon --config /etc/xrdp/xrdp.ini diff --git a/extras/repos/dave.jazzy.repos b/extras/repos/dave.lyrical.repos similarity index 99% rename from extras/repos/dave.jazzy.repos rename to extras/repos/dave.lyrical.repos index 575954c9..0ccdf36e 100644 --- a/extras/repos/dave.jazzy.repos +++ b/extras/repos/dave.lyrical.repos @@ -13,4 +13,3 @@ repositories: type: git url: https://github.com/IOES-Lab/dave.git version: ros2 - diff --git a/extras/ros-jazzy-gz-harmonic-install.sh b/extras/ros-lyrical-gz-jetty-install.sh old mode 100644 new mode 100755 similarity index 62% rename from extras/ros-jazzy-gz-harmonic-install.sh rename to extras/ros-lyrical-gz-jetty-install.sh index e2979095..8741b856 --- a/extras/ros-jazzy-gz-harmonic-install.sh +++ b/extras/ros-lyrical-gz-jetty-install.sh @@ -1,19 +1,24 @@ -#!/bin/bash -# Script to install development tools and libraries for robotics and simulation +#!/usr/bin/env bash +# Install the ROS 2 Lyrical / Gazebo Jetty development stack used by DAVE. +set -euo pipefail + +DIST="${ROS_DISTRO:-lyrical}" echo echo -e "\033[94m============================================================\033[0m" echo -e "\033[94m== One-liner Installation Script for ROS-Gazebo Framework ==\033[0m" echo -e "\033[94m============================================================\033[0m" -echo -e "Requirements: Ubuntu 24.04 LTS Noble" +echo -e "Target stack: ROS 2 Lyrical / Gazebo Jetty" +echo -e "Requirements: Ubuntu 26.04 LTS Resolute" echo -e "\033[94m============================================================\033[0m" echo -echo -e "\033[96m(1/4) ------------- Updating the System ----------------\033[0m" +echo -e "\033[96m(1/5) ------------- Updating the System ----------------\033[0m" echo "Performing full system upgrade (this might take a while)..." -sudo sudo apt update && apt full-upgrade -y +sudo apt-get update +sudo apt-get full-upgrade -y echo -echo -e "\033[96m(2/4) ------------ Install Dependencies ---------------\033[0m" +echo -e "\033[96m(2/5) ------------ Install Dependencies ---------------\033[0m" echo -e "\033[34mInstalling essential tools and libraries...\033[0m" sudo apt install -y \ build-essential \ @@ -38,34 +43,26 @@ sudo apt install -y \ wget echo -echo -e "\033[96m(3/4) ------------ Install Package Keys ---------------\033[0m" -echo -e "\033[34mInstalling Signing Keys for ROS and Gazebo...\033[0m" +echo -e "\033[96m(3/5) ------------ Install Package Keys ---------------\033[0m" +echo -e "\033[34mInstalling the ROS apt source...\033[0m" # Remove keyring if exists to avoid conflicts sudo rm -f /usr/share/keyrings/ros2-latest-archive-keyring.gpg && \ sudo rm -rf /etc/apt/sources.list.d/ros2-latest.list # Get Keys sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \ -o /usr/share/keyrings/ros-archive-keyring.gpg -sudo wget https://packages.osrfoundation.org/gazebo.gpg \ - -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg - sudo apt update && sudo apt install -y jq -UBUNTU_CODENAME=noble && \ +UBUNTU_CODENAME="$(. /etc/os-release && echo "${UBUNTU_CODENAME:-${VERSION_CODENAME}}")" && \ ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | jq -r '.tag_name') && \ curl -L -o /tmp/ros2-apt-source.deb \ "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.${UBUNTU_CODENAME}_all.deb" && \ sudo apt-get install -y /tmp/ros2-apt-source.deb && \ rm -f /tmp/ros2-apt-source.deb -sudo curl https://packages.osrfoundation.org/gazebo.gpg --output /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" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null - echo -echo -e "\033[96m(4/4) ------------ Install ROS-Gazebo ---------------\033[0m" -DIST=jazzy -GAZEBO=gz-harmonic +echo -e "\033[96m(4/5) ------------ Install ROS-Gazebo ---------------\033[0m" -echo -e "\033[34mInstalling ROS Gazebo framework...\033[0m" +echo -e "\033[34mInstalling ROS 2 ${DIST}; ros-${DIST}-ros-gz supplies Gazebo Jetty vendor packages...\033[0m" sudo apt update && sudo apt install -y \ python3-rosdep \ python3-catkin-pkg \ @@ -73,45 +70,39 @@ sudo apt update && sudo apt install -y \ python3-colcon-core \ python3-colcon-common-extensions \ python3-vcstool \ - $GAZEBO \ ros-$DIST-desktop-full \ ros-$DIST-ros-gz \ ros-$DIST-gz-ros2-control \ - ros-$DIST-effort-controllers \ - ros-$DIST-geographic-info \ - ros-$DIST-joint-state-publisher \ - ros-$DIST-joy-teleop \ - ros-$DIST-key-teleop \ - ros-$DIST-moveit-planners \ - ros-$DIST-moveit-simple-controller-manager \ - ros-$DIST-moveit-ros-visualization \ - ros-$DIST-robot-localization \ - ros-$DIST-ros2-controllers \ - ros-$DIST-teleop-tools \ - ros-$DIST-urdfdom-py \ ros-$DIST-marine-acoustic-msgs \ - ros-dev-tools \ - && rosdep init + ros-dev-tools + +sudo rosdep init 2>/dev/null || true +rosdep update --rosdistro "$DIST" echo -echo -e "\033[96m(4/4) ------------ Install Ardusub ---------------\033[0m" +echo -e "\033[96m(5/5) ------------ Install ArduSub ---------------\033[0m" sudo apt update && sudo apt install -y \ - libgz-sim8-dev rapidjson-dev libopencv-dev \ + rapidjson-dev libopencv-dev \ libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \ gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-gl \ ffmpeg python3-venv python3-websockets \ ros-${DIST}-joy-linux gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base \ gstreamer1.0-plugins-ugly python3-gi python3-gst-1.0 \ libfuse2 libxcb-xinerama0 libxkbcommon-x11-0 libxcb-cursor-dev \ - cython3 python3-dev python3-future python3-lxml + cython3 python3-dev python3-lxml -# Install ardusub(local) +# Install ArduSub. The helper sources the Lyrical environment so the +# ardupilot_gazebo build resolves Jetty's vendored CMake packages. sudo mkdir -p /opt/ardusub_ws && cd /opt/ardusub_ws || exit -sudo wget https://raw.githubusercontent.com/IOES-Lab/dave/ros2/extras/ardusub-ubuntu-install.sh +if [[ -n "${DAVE_EXTRAS_DIR:-}" && -f "${DAVE_EXTRAS_DIR}/ardusub-ubuntu-install.sh" ]]; then + sudo cp "${DAVE_EXTRAS_DIR}/ardusub-ubuntu-install.sh" ./ardusub-ubuntu-install.sh +else + sudo wget https://raw.githubusercontent.com/IOES-Lab/dave/ros2/extras/ardusub-ubuntu-install.sh +fi sudo chmod +x ardusub-ubuntu-install.sh && sudo bash ./ardusub-ubuntu-install.sh # Mavros install -sudo apt-get -y install ros-jazzy-mavros* +sudo apt-get -y install "ros-${DIST}-mavros" "ros-${DIST}-mavros-msgs" sudo mkdir -p /opt/mavros_ws && cd /opt/mavros_ws || exit sudo wget https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh sudo chmod +x install_geographiclib_datasets.sh && sudo bash ./install_geographiclib_datasets.sh @@ -130,17 +121,17 @@ ENV_DIR="$TARGET_HOME/.ros_ardusub_env" ENV_FILE="$ENV_DIR/env" mkdir -p "$ENV_DIR" -cat > "$ENV_FILE" <<'EOF' -if [ -n "$ZSH_VERSION" ]; then - source /opt/ros/jazzy/setup.zsh +cat > "$ENV_FILE" </dev/null; then @@ -153,5 +144,5 @@ chown "$TARGET_USER:$TARGET_USER" "$RC_FILE" 2>/dev/null || true echo echo -e "\033[32m============================================================\033[0m" echo -e "\033[32mROS-Gazebo Framework (w mavros and Ardusub) Installation completed. Awesome! ๐Ÿค˜๐Ÿš€ \033[0m" -echo -e "You may check ROS, and Gazebo version installed with \033[33mprintenv ROS_DISTRO\033[0m and \033[33mecho \$GZ_VERSION\033[0m" +echo -e "Check the installed stack with \033[33mprintenv ROS_DISTRO\033[0m and \033[33mgz sim --versions\033[0m" echo diff --git a/gazebo/dave_gz_model_plugins/CMakeLists.txt b/gazebo/dave_gz_model_plugins/CMakeLists.txt index 91d27666..e4be1cf3 100644 --- a/gazebo/dave_gz_model_plugins/CMakeLists.txt +++ b/gazebo/dave_gz_model_plugins/CMakeLists.txt @@ -3,26 +3,27 @@ project(dave_gz_model_plugins) # Find required packages find_package(ament_cmake REQUIRED) -find_package(Boost REQUIRED COMPONENTS system) -find_package(gz-cmake3 REQUIRED) -find_package(gz-plugin2 REQUIRED COMPONENTS register) +find_package(tinyxml2 CONFIG REQUIRED) +find_package(Boost REQUIRED) +find_package(gz-cmake 5 REQUIRED) +find_package(gz-plugin 4 REQUIRED COMPONENTS register) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) -find_package(gz-common5 REQUIRED COMPONENTS profiler) -find_package(gz-sim8 REQUIRED) +find_package(gz-common 7 REQUIRED COMPONENTS profiler) +find_package(gz-sim 10 REQUIRED) find_package(geometry_msgs REQUIRED) find_package(dave_interfaces REQUIRED) find_package(Protobuf REQUIRED) -find_package(gz-msgs10 REQUIRED) +find_package(gz-msgs 12 REQUIRED) find_package(dave_gz_world_plugins REQUIRED) # Set version variables -set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR}) -set(GZ_COMMON_VER ${gz-common5_VERSION_MAJOR}) -set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR}) -set(GZ_MSGS_VER ${gz-msgs10_VERSION_MAJOR}) +set(GZ_PLUGIN_VER "") +set(GZ_COMMON_VER "") +set(GZ_SIM_VER "") +set(GZ_MSGS_VER "") -message(STATUS "Compiling against Gazebo Harmonic") +message(STATUS "Compiling against Gazebo Jetty") add_library(OceanCurrentModelPlugin SHARED src/OceanCurrentModelPlugin.cc) @@ -33,12 +34,14 @@ target_link_libraries(OceanCurrentModelPlugin ) # Specify dependencies for ocean_current_plugin using ament_target_dependencies -ament_target_dependencies(OceanCurrentModelPlugin - rclcpp - std_msgs - geometry_msgs - dave_interfaces - dave_gz_world_plugins +target_link_libraries(OceanCurrentModelPlugin + rclcpp::rclcpp + ${std_msgs_TARGETS} + ${geometry_msgs_TARGETS} + ${dave_interfaces_TARGETS} + dave_gz_world_plugins::gauss_markov_process + dave_gz_world_plugins::tidal_oscillation + dave_gz_world_plugins::dave_gz_world_plugins-msgs ) # Install targets diff --git a/gazebo/dave_gz_multibeam_sonar/README.md b/gazebo/dave_gz_multibeam_sonar/README.md index 98f62cec..da89591c 100644 --- a/gazebo/dave_gz_multibeam_sonar/README.md +++ b/gazebo/dave_gz_multibeam_sonar/README.md @@ -1,6 +1,6 @@ # DAVE Multibeam Sonar Plugin -The DAVE multibeam sonar plugin, adapted for ROS 2 Jazzy and Gazebo Harmonic, uses a ray-based multibeam model that simulates phase, reverberation, and speckle noise through a point scattering approach. It generates realistic intensity-range (A-plot) data while accounting for time and angular ambiguities as well as speckle noise. +The DAVE multibeam sonar plugin, adapted for ROS 2 Lyrical and Gazebo Jetty, uses a ray-based multibeam model that simulates phase, reverberation, and speckle noise through a point scattering approach. It generates realistic intensity-range (A-plot) data while accounting for time and angular ambiguities as well as speckle noise. > **System Requirement**: > An **NVIDIA graphics card with CUDA compatibility** is required to use the sonar plugin. This enables GPU-accelerated simulation for real-time performance. diff --git a/gazebo/dave_gz_multibeam_sonar/multibeam_sonar/CMakeLists.txt b/gazebo/dave_gz_multibeam_sonar/multibeam_sonar/CMakeLists.txt index c5a1d2d0..1f01ac18 100644 --- a/gazebo/dave_gz_multibeam_sonar/multibeam_sonar/CMakeLists.txt +++ b/gazebo/dave_gz_multibeam_sonar/multibeam_sonar/CMakeLists.txt @@ -23,11 +23,13 @@ if(CUDAToolkit_FOUND) message(STATUS "CUDA found, enabling CUDA support.") include_directories(${CUDA_INCLUDE_DIRS}) set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -arch=sm_${CUDA_ARCHITECTURE}") - find_package(gz-cmake3 REQUIRED) - find_package(gz-sim8 REQUIRED) - find_package(gz-sensors8 REQUIRED) - find_package(gz-rendering8 REQUIRED OPTIONAL_COMPONENTS ogre ogre2) - find_package(gz-transport13 REQUIRED) + find_package(tinyxml2 CONFIG REQUIRED) + find_package(gz-cmake 5 REQUIRED) + find_package(gz-sim 10 REQUIRED) + find_package(gz-sensors 10 REQUIRED) + find_package(gz-rendering 10 REQUIRED OPTIONAL_COMPONENTS ogre ogre2) + find_package(gz-transport 15 REQUIRED) + find_package(gz-msgs 12 REQUIRED) find_package(rclcpp REQUIRED) find_package(sensor_msgs REQUIRED) find_package(geometry_msgs REQUIRED) @@ -36,21 +38,13 @@ if(CUDAToolkit_FOUND) find_package(marine_acoustic_msgs REQUIRED) find_package(cv_bridge REQUIRED) - set(GZ_MSGS_VER ${gz-msgs10_VERSION_MAJOR}) - set(GZ_RENDERING_VER ${gz-rendering8_VERSION_MAJOR}) - set(GZ_SENSORS_VER ${gz-sensors8_VERSION_MAJOR}) - set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR}) - set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR}) - - if(TARGET gz-rendering${GZ_RENDERING_VER}::ogre) + if(TARGET gz-rendering::ogre) set(HAVE_OGRE TRUE) - set(GZ_RENDERING_TARGET gz-rendering${GZ_RENDERING_VER}-ogre) add_definitions(-DWITH_OGRE) endif() - if(TARGET gz-rendering${GZ_RENDERING_VER}::ogre2) + if(TARGET gz-rendering::ogre2) set(HAVE_OGRE2 TRUE) - set(GZ_RENDERING_TARGET gz-rendering${GZ_RENDERING_VER}-ogre2) add_definitions(-DWITH_OGRE2) endif() @@ -67,12 +61,12 @@ if(CUDAToolkit_FOUND) target_include_directories(${PROJECT_NAME} PUBLIC - ${gz-sensors${GZ_SENSORS_VER}_INCLUDE_DIRS} - ${gz-rendering${GZ_RENDERING_VER}_INCLUDE_DIRS} - ${gz-msgs${GZ_MSGS_VER}_INCLUDE_DIRS} + ${gz-sensors_INCLUDE_DIRS} + ${gz-rendering_INCLUDE_DIRS} + ${gz-msgs_INCLUDE_DIRS} ${CUDA_INCLUDE_DIRS} - ${gz-transport${GZ_TRANSPORT_VER}_INCLUDE_DIRS} - ${gz-sim${GZ_SIM_VER}_INCLUDE_DIRS} + ${gz-transport_INCLUDE_DIRS} + ${gz-sim_INCLUDE_DIRS} ) find_library(CUBLAS_LIB cublas @@ -87,21 +81,25 @@ if(CUDAToolkit_FOUND) endif() target_link_libraries(${PROJECT_NAME} + gz-sim::gz-sim + gz-sensors::gz-sensors + gz-msgs::gz-msgs + gz-transport::gz-transport + gz-rendering::gz-rendering ${CUDA_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CUBLAS_LIB} ) + if(TARGET gz-sensors::gz-sensors-rendering) + target_link_libraries(${PROJECT_NAME} gz-sensors::gz-sensors-rendering) + endif() + install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME} ) ament_target_dependencies(${PROJECT_NAME} - gz-sensors${GZ_SENSORS_VER} - ${GZ_RENDERING_TARGET} - gz-msgs${GZ_MSGS_VER} - gz-transport${GZ_TRANSPORT_VER} - gz-sim${GZ_SIM_VER} rclcpp sensor_msgs rosidl_default_generators diff --git a/gazebo/dave_gz_multibeam_sonar/multibeam_sonar_system/CMakeLists.txt b/gazebo/dave_gz_multibeam_sonar/multibeam_sonar_system/CMakeLists.txt index 7bdb72c5..a601f6a1 100644 --- a/gazebo/dave_gz_multibeam_sonar/multibeam_sonar_system/CMakeLists.txt +++ b/gazebo/dave_gz_multibeam_sonar/multibeam_sonar_system/CMakeLists.txt @@ -5,28 +5,21 @@ find_package(ament_cmake REQUIRED) find_package(CUDAToolkit QUIET) if(CUDAToolkit_FOUND) - find_package(gz-cmake3 REQUIRED) - find_package(gz-common5 REQUIRED COMPONENTS profiler) - find_package(gz-plugin2 REQUIRED COMPONENTS register) - find_package(gz-rendering8 REQUIRED OPTIONAL_COMPONENTS ogre ogre2) - find_package(gz-sim8 REQUIRED) - find_package(gz-sensors8 REQUIRED) - - set(GZ_COMMON_VER ${gz-common5_VERSION_MAJOR}) - set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR}) - set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR}) - set(GZ_RENDERING_VER ${gz-rendering8_VERSION_MAJOR}) - set(GZ_SENSORS_VER ${gz-sensors8_VERSION_MAJOR}) - - if(TARGET gz-rendering${GZ_RENDERING_VER}::ogre) + find_package(tinyxml2 CONFIG REQUIRED) + find_package(gz-cmake 5 REQUIRED) + find_package(gz-common 7 REQUIRED COMPONENTS profiler) + find_package(gz-plugin 4 REQUIRED COMPONENTS register) + find_package(gz-rendering 10 REQUIRED OPTIONAL_COMPONENTS ogre ogre2) + find_package(gz-sim 10 REQUIRED) + find_package(gz-sensors 10 REQUIRED) + + if(TARGET gz-rendering::ogre) set(HAVE_OGRE TRUE) - set(GZ_RENDERING_TARGET gz-rendering${GZ_RENDERING_VER}-ogre) add_definitions(-DWITH_OGRE) endif() - if(TARGET gz-rendering${GZ_RENDERING_VER}::ogre2) + if(TARGET gz-rendering::ogre2) set(HAVE_OGRE2 TRUE) - set(GZ_RENDERING_TARGET gz-rendering${GZ_RENDERING_VER}-ogre2) add_definitions(-DWITH_OGRE2) endif() @@ -34,25 +27,16 @@ if(CUDAToolkit_FOUND) add_library(${PROJECT_NAME} SHARED MultibeamSonarSystem.cc) target_link_libraries(${PROJECT_NAME} - gz-common${GZ_COMMON_VER}::gz-common${GZ_COMMON_VER} - gz-plugin${GZ_PLUGIN_VER}::gz-plugin${GZ_PLUGIN_VER} - gz-sim${GZ_SIM_VER}::gz-sim${GZ_SIM_VER} - gz-sensors${GZ_SENSORS_VER}::gz-sensors${GZ_SENSORS_VER} + gz-common::gz-common + gz-plugin::gz-plugin + gz-sim::gz-sim + gz-sensors::gz-sensors multibeam_sonar ) target_include_directories(${PROJECT_NAME} PUBLIC ../multibeam_sonar ) - - ament_target_dependencies(${PROJECT_NAME} - gz-common${GZ_COMMON_VER} - ${GZ_RENDERING_TARGET} - gz-plugin${GZ_PLUGIN_VER} - gz-sim${GZ_SIM_VER} - gz-sensors${GZ_SENSORS_VER} - ) - # Install targets install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME} diff --git a/gazebo/dave_gz_sensor_plugins/CMakeLists.txt b/gazebo/dave_gz_sensor_plugins/CMakeLists.txt index 675fdcd6..06ee9345 100644 --- a/gazebo/dave_gz_sensor_plugins/CMakeLists.txt +++ b/gazebo/dave_gz_sensor_plugins/CMakeLists.txt @@ -3,28 +3,29 @@ project(dave_gz_sensor_plugins) # Find required packages find_package(ament_cmake REQUIRED) -find_package(gz-cmake3 REQUIRED) -find_package(gz-plugin2 REQUIRED COMPONENTS register) +find_package(tinyxml2 CONFIG REQUIRED) +find_package(gz-cmake 5 REQUIRED) +find_package(gz-plugin 4 REQUIRED COMPONENTS register) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) -find_package(gz-common5 REQUIRED COMPONENTS profiler) -find_package(gz-sim8 REQUIRED) +find_package(gz-common 7 REQUIRED COMPONENTS profiler) +find_package(gz-sim 10 REQUIRED) find_package(geometry_msgs REQUIRED) find_package(dave_interfaces REQUIRED) find_package(sensor_msgs REQUIRED) find_package(Protobuf REQUIRED) -find_package(gz-msgs10 REQUIRED) +find_package(gz-msgs 12 REQUIRED) find_package(OpenCV REQUIRED) # Set version variables -set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR}) -set(GZ_COMMON_VER ${gz-common5_VERSION_MAJOR}) -set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR}) -set(GZ_MSGS_VER ${gz-msgs10_VERSION_MAJOR}) +set(GZ_PLUGIN_VER "") +set(GZ_COMMON_VER "") +set(GZ_SIM_VER "") +set(GZ_MSGS_VER "") include_directories(${OpenCV_INCLUDE_DIRS}) -message(STATUS "Compiling against Gazebo Harmonic") +message(STATUS "Compiling against Gazebo Jetty") add_library(UsblTransceiver SHARED src/UsblTransceiver.cc) add_library(UsblTransponder SHARED src/UsblTransponder.cc) @@ -54,30 +55,30 @@ target_link_libraries(UnderwaterCamera ) # Specify dependencies for FullSystem using ament_target_dependencies -ament_target_dependencies(UsblTransceiver - dave_interfaces - sensor_msgs - rclcpp - geometry_msgs - std_msgs +target_link_libraries(UsblTransceiver + ${dave_interfaces_TARGETS} + ${sensor_msgs_TARGETS} + rclcpp::rclcpp + ${geometry_msgs_TARGETS} + ${std_msgs_TARGETS} ) -ament_target_dependencies(UsblTransponder - dave_interfaces - rclcpp - std_msgs +target_link_libraries(UsblTransponder + ${dave_interfaces_TARGETS} + rclcpp::rclcpp + ${std_msgs_TARGETS} ) -ament_target_dependencies(sea_pressure_sensor - rclcpp - std_msgs - sensor_msgs - geometry_msgs +target_link_libraries(sea_pressure_sensor + rclcpp::rclcpp + ${std_msgs_TARGETS} + ${sensor_msgs_TARGETS} + ${geometry_msgs_TARGETS} ) -ament_target_dependencies(UnderwaterCamera - rclcpp - sensor_msgs +target_link_libraries(UnderwaterCamera + rclcpp::rclcpp + ${sensor_msgs_TARGETS} ) # Install targets diff --git a/gazebo/dave_gz_world_plugins/CMakeLists.txt b/gazebo/dave_gz_world_plugins/CMakeLists.txt index 1d43d4d9..117cec47 100644 --- a/gazebo/dave_gz_world_plugins/CMakeLists.txt +++ b/gazebo/dave_gz_world_plugins/CMakeLists.txt @@ -10,29 +10,30 @@ add_compile_options(-Wno-psabi) add_definitions(-DBOOST_BIND_GLOBAL_PLACEHOLDERS) find_package(ament_cmake REQUIRED) -find_package(Boost REQUIRED COMPONENTS system) -find_package(gz-cmake3 REQUIRED) -find_package(gz-plugin2 REQUIRED COMPONENTS register) +find_package(tinyxml2 CONFIG REQUIRED) +find_package(Boost REQUIRED) +find_package(gz-cmake 5 REQUIRED) +find_package(gz-plugin 4 REQUIRED COMPONENTS register) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) -find_package(gz-common5 REQUIRED COMPONENTS profiler) -find_package(gz-sim8 REQUIRED) +find_package(gz-common 7 REQUIRED COMPONENTS profiler) +find_package(gz-sim 10 REQUIRED) find_package(geometry_msgs REQUIRED) find_package(dave_interfaces REQUIRED) find_package(sensor_msgs REQUIRED) find_package(Protobuf REQUIRED) -find_package(gz-msgs10 REQUIRED) +find_package(gz-msgs 12 REQUIRED) find_package(ament_index_cpp REQUIRED) -# Set version variables with gazebo Harmonic -set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR}) -set(GZ_COMMON_VER ${gz-common5_VERSION_MAJOR}) -set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR}) -set(GZ_MSGS_VER ${gz-msgs10_VERSION_MAJOR}) -message(STATUS "compiling against Gazebo Harmonic") +# Use the unversioned Gazebo Jetty vendor targets +set(GZ_PLUGIN_VER "") +set(GZ_COMMON_VER "") +set(GZ_SIM_VER "") +set(GZ_MSGS_VER "") +message(STATUS "Compiling against Gazebo Jetty") # Define a variable 'GZ_MSGS_VER' holding the version number -set(GZ_MSGS_VER ${gz-msgs10_VERSION_MAJOR}) +set(GZ_MSGS_VER "") # Define a variable 'MSGS_PROTOS' listing the .proto files # cmake-lint: disable=C0301 @@ -94,27 +95,27 @@ target_link_libraries(tidal_oscillation gz-sim${GZ_SIM_VER}::gz-sim${GZ_SIM_VER} ) -ament_target_dependencies(OceanCurrentWorldPlugin - rclcpp - std_msgs - geometry_msgs - dave_interfaces - ament_index_cpp - gz-msgs${GZ_MSGS_VER} +target_link_libraries(OceanCurrentWorldPlugin + rclcpp::rclcpp + ${std_msgs_TARGETS} + ${geometry_msgs_TARGETS} + ${dave_interfaces_TARGETS} + ament_index_cpp::ament_index_cpp + gz-msgs::gz-msgs ) -ament_target_dependencies(gauss_markov_process - rclcpp - std_msgs - geometry_msgs - dave_interfaces +target_link_libraries(gauss_markov_process + rclcpp::rclcpp + ${std_msgs_TARGETS} + ${geometry_msgs_TARGETS} + ${dave_interfaces_TARGETS} ) -ament_target_dependencies(tidal_oscillation - rclcpp - std_msgs - geometry_msgs - dave_interfaces +target_link_libraries(tidal_oscillation + rclcpp::rclcpp + ${std_msgs_TARGETS} + ${geometry_msgs_TARGETS} + ${dave_interfaces_TARGETS} ) # Install targets @@ -139,11 +140,11 @@ install(DIRECTORY include/ ament_export_include_directories("include/${PROJECT_NAME}") ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET) ament_export_dependencies( - gz-cmake3 - gz-plugin2 - gz-msgs10 - gz-common5 - gz-sim8 + gz-cmake + gz-plugin + gz-msgs + gz-common + gz-sim geometry_msgs sensor_msgs std_msgs diff --git a/gazebo/dave_ros_gz_plugins/CMakeLists.txt b/gazebo/dave_ros_gz_plugins/CMakeLists.txt index a3469b39..8e356488 100644 --- a/gazebo/dave_ros_gz_plugins/CMakeLists.txt +++ b/gazebo/dave_ros_gz_plugins/CMakeLists.txt @@ -3,23 +3,24 @@ project(dave_ros_gz_plugins) # Find required packages find_package(ament_cmake REQUIRED) -find_package(gz-cmake3 REQUIRED) -find_package(gz-plugin2 REQUIRED COMPONENTS register) +find_package(tinyxml2 CONFIG REQUIRED) +find_package(gz-cmake 5 REQUIRED) +find_package(gz-plugin 4 REQUIRED COMPONENTS register) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) -find_package(gz-common5 REQUIRED COMPONENTS profiler) -find_package(gz-sim8 REQUIRED) +find_package(gz-common 7 REQUIRED COMPONENTS profiler) +find_package(gz-sim 10 REQUIRED) find_package(geometry_msgs REQUIRED) find_package(dave_interfaces REQUIRED) find_package(dave_gz_world_plugins REQUIRED) -find_package(Boost REQUIRED COMPONENTS system) +find_package(Boost REQUIRED) # Set version variables -set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR}) -set(GZ_COMMON_VER ${gz-common5_VERSION_MAJOR}) -set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR}) +set(GZ_PLUGIN_VER "") +set(GZ_COMMON_VER "") +set(GZ_SIM_VER "") -message(STATUS "Compiling against Gazebo Harmonic") +message(STATUS "Compiling against Gazebo Jetty") # Libraries add_library(SphericalCoords SHARED src/SphericalCoords.cc) @@ -50,24 +51,27 @@ target_link_libraries(OceanCurrentPlugin ) # Specify dependencies using ament_target_dependencies -ament_target_dependencies(SphericalCoords - dave_interfaces - rclcpp - geometry_msgs - std_msgs +target_link_libraries(SphericalCoords + ${dave_interfaces_TARGETS} + rclcpp::rclcpp + ${geometry_msgs_TARGETS} + ${std_msgs_TARGETS} ) -ament_target_dependencies(DVLBridge - dave_interfaces - rclcpp - geometry_msgs - std_msgs +target_link_libraries(DVLBridge + ${dave_interfaces_TARGETS} + rclcpp::rclcpp + ${geometry_msgs_TARGETS} + ${std_msgs_TARGETS} ) -ament_target_dependencies(OceanCurrentPlugin - rclcpp - std_msgs - geometry_msgs - dave_interfaces - dave_gz_world_plugins +target_link_libraries(OceanCurrentPlugin + rclcpp::rclcpp + ${std_msgs_TARGETS} + ${geometry_msgs_TARGETS} + ${dave_interfaces_TARGETS} + dave_gz_world_plugins::OceanCurrentWorldPlugin + dave_gz_world_plugins::gauss_markov_process + dave_gz_world_plugins::tidal_oscillation + dave_gz_world_plugins::dave_gz_world_plugins-msgs ) # Install targets @@ -93,10 +97,10 @@ install( ament_export_include_directories("include/${PROJECT_NAME}") ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET) ament_export_dependencies( - gz-cmake3 - gz-plugin2 - gz-common5 - gz-sim8 + gz-cmake + gz-plugin + gz-common + gz-sim geometry_msgs std_msgs dave_interfaces diff --git a/gazebo/dave_ros_gz_plugins/src/SphericalCoords.cc b/gazebo/dave_ros_gz_plugins/src/SphericalCoords.cc index 2145a8d7..72aceed2 100644 --- a/gazebo/dave_ros_gz_plugins/src/SphericalCoords.cc +++ b/gazebo/dave_ros_gz_plugins/src/SphericalCoords.cc @@ -114,13 +114,20 @@ bool SphericalCoords::TransformFromSphericalCoord( const std::shared_ptr request, std::shared_ptr response) { - gz::math::Vector3d scVec = - gz::math::Vector3d(request->latitude_deg, request->longitude_deg, request->altitude); + gz::math::Angle lat, lon; + lat.SetDegree(request->latitude_deg); + lon.SetDegree(request->longitude_deg); + auto scVec = gz::math::CoordinateVector3::Spherical(lat, lon, request->altitude); - gzmsg << "Called FROM and latitude: " << scVec.X() << std::endl; + gzmsg << "Called FROM and latitude: " << request->latitude_deg << std::endl; auto coords = this->dataPtr->world.SphericalCoordinates(*this->dataPtr->ecm); - gz::math::Vector3d cartVec = coords->LocalFromSphericalPosition(scVec); + gz::math::Vector3d cartVec = gz::math::Vector3d::Zero; + auto cartOpt = coords->LocalFromSphericalPosition(scVec); + if (cartOpt && cartOpt->AsMetricVector()) + { + cartVec = *cartOpt->AsMetricVector(); + } response->output.x = cartVec.X(); response->output.y = cartVec.Y(); @@ -133,17 +140,17 @@ bool SphericalCoords::TransformToSphericalCoord( const std::shared_ptr request, std::shared_ptr response) { - gz::math::Vector3d cartVec = - gz::math::Vector3d(request->input.x, request->input.y, request->input.z); + auto cartVec = + gz::math::CoordinateVector3::Metric(request->input.x, request->input.y, request->input.z); - gzmsg << "Called TO and X: " << cartVec.X() << std::endl; + gzmsg << "Called TO and X: " << request->input.x << std::endl; auto coords = this->dataPtr->world.SphericalCoordinates(*this->dataPtr->ecm); - gz::math::Vector3d scVec = coords->SphericalFromLocalPosition(cartVec); + auto scOpt = coords->SphericalFromLocalPosition(cartVec); - response->latitude_deg = scVec.X(); - response->longitude_deg = scVec.Y(); - response->altitude = scVec.Z(); + response->latitude_deg = (scOpt && scOpt->Lat()) ? scOpt->Lat()->Degree() : 0.0; + response->longitude_deg = (scOpt && scOpt->Lon()) ? scOpt->Lon()->Degree() : 0.0; + response->altitude = (scOpt && scOpt->Z()) ? *scOpt->Z() : 0.0; return true; } From d5b509467f72b5e8952d594556d47b255be6b46c Mon Sep 17 00:00:00 2001 From: yeseorizi <172019512+yeseorizi@users.noreply.github.com> Date: Wed, 9 Sep 2026 12:28:00 +0900 Subject: [PATCH 2/9] Fix installer ShellCheck findings --- extras/ardusub-ubuntu-install-local.sh | 2 +- extras/ardusub-ubuntu-install.sh | 2 +- extras/ros-lyrical-gz-jetty-install.sh | 16 +++++++++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/extras/ardusub-ubuntu-install-local.sh b/extras/ardusub-ubuntu-install-local.sh index f5e4e762..db9e8b6d 100755 --- a/extras/ardusub-ubuntu-install-local.sh +++ b/extras/ardusub-ubuntu-install-local.sh @@ -2,8 +2,8 @@ set -euo pipefail # Source Ros and Gazebo -# shellcheck source=/dev/null ROS_DISTRO="${ROS_DISTRO:-lyrical}" +# shellcheck disable=SC1090 source "/opt/ros/${ROS_DISTRO}/setup.bash" USER_NAME=$(logname 2>/dev/null || echo "${SUDO_USER:-$USER}") diff --git a/extras/ardusub-ubuntu-install.sh b/extras/ardusub-ubuntu-install.sh index 5374d9c5..298cf69e 100755 --- a/extras/ardusub-ubuntu-install.sh +++ b/extras/ardusub-ubuntu-install.sh @@ -2,8 +2,8 @@ set -euo pipefail # Source Ros and Gazebo -# shellcheck source=/dev/null ROS_DISTRO="${ROS_DISTRO:-lyrical}" +# shellcheck disable=SC1090 source "/opt/ros/${ROS_DISTRO}/setup.bash" # Commit used by the verified Lyrical / Python 3.14 build. diff --git a/extras/ros-lyrical-gz-jetty-install.sh b/extras/ros-lyrical-gz-jetty-install.sh index 8741b856..bff04db5 100755 --- a/extras/ros-lyrical-gz-jetty-install.sh +++ b/extras/ros-lyrical-gz-jetty-install.sh @@ -52,8 +52,10 @@ sudo rm -f /usr/share/keyrings/ros2-latest-archive-keyring.gpg && \ sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \ -o /usr/share/keyrings/ros-archive-keyring.gpg sudo apt update && sudo apt install -y jq -UBUNTU_CODENAME="$(. /etc/os-release && echo "${UBUNTU_CODENAME:-${VERSION_CODENAME}}")" && \ - ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | jq -r '.tag_name') && \ +# shellcheck disable=SC1091 +. /etc/os-release +UBUNTU_CODENAME="${UBUNTU_CODENAME:-${VERSION_CODENAME}}" +ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | jq -r '.tag_name') && \ curl -L -o /tmp/ros2-apt-source.deb \ "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.${UBUNTU_CODENAME}_all.deb" && \ sudo apt-get install -y /tmp/ros2-apt-source.deb && \ @@ -70,10 +72,10 @@ sudo apt update && sudo apt install -y \ python3-colcon-core \ python3-colcon-common-extensions \ python3-vcstool \ - ros-$DIST-desktop-full \ - ros-$DIST-ros-gz \ - ros-$DIST-gz-ros2-control \ - ros-$DIST-marine-acoustic-msgs \ + "ros-${DIST}-desktop-full" \ + "ros-${DIST}-ros-gz" \ + "ros-${DIST}-gz-ros2-control" \ + "ros-${DIST}-marine-acoustic-msgs" \ ros-dev-tools sudo rosdep init 2>/dev/null || true @@ -86,7 +88,7 @@ sudo apt update && sudo apt install -y \ libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \ gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-gl \ ffmpeg python3-venv python3-websockets \ - ros-${DIST}-joy-linux gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base \ + "ros-${DIST}-joy-linux" gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base \ gstreamer1.0-plugins-ugly python3-gi python3-gst-1.0 \ libfuse2 libxcb-xinerama0 libxkbcommon-x11-0 libxcb-cursor-dev \ cython3 python3-dev python3-lxml From 4d0dec55478b817ed9f3d3d909b10fb705214dc2 Mon Sep 17 00:00:00 2001 From: yeseorizi <172019512+yeseorizi@users.noreply.github.com> Date: Wed, 9 Sep 2026 12:29:19 +0900 Subject: [PATCH 3/9] Run and deduplicate pull request CI --- .github/workflows/docker-amd64.yml | 4 ++++ .github/workflows/docker-arm64v8.yml | 4 ++++ .github/workflows/lint.yml | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-amd64.yml b/.github/workflows/docker-amd64.yml index 17c96db0..c9382f67 100644 --- a/.github/workflows/docker-amd64.yml +++ b/.github/workflows/docker-amd64.yml @@ -24,6 +24,10 @@ env: IMAGE_NAME: ioeslab/dave ROS_DISTRO: lyrical +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: build-and-push-to-docker-hub: # Never execute untrusted fork code on a self-hosted runner. diff --git a/.github/workflows/docker-arm64v8.yml b/.github/workflows/docker-arm64v8.yml index f581b797..bc6d434a 100644 --- a/.github/workflows/docker-arm64v8.yml +++ b/.github/workflows/docker-arm64v8.yml @@ -24,6 +24,10 @@ env: IMAGE_NAME: ioeslab/dave ROS_DISTRO: lyrical +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: build-and-push-to-docker-hub: # Never execute untrusted fork code on a self-hosted runner. diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 677c35bc..d0bb4803 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,7 +8,7 @@ on: branches: - ros2 pull_request: - types: [opened, reopened] + types: [opened, synchronize, reopened] jobs: # ament_lint: From 21773f60af8101612297e4a04aedd804748b143d Mon Sep 17 00:00:00 2001 From: yeseorizi <172019512+yeseorizi@users.noreply.github.com> Date: Wed, 9 Sep 2026 12:45:43 +0900 Subject: [PATCH 4/9] Source ROS setup safely with nounset --- extras/ardusub-ubuntu-install-local.sh | 2 ++ extras/ardusub-ubuntu-install.sh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/extras/ardusub-ubuntu-install-local.sh b/extras/ardusub-ubuntu-install-local.sh index db9e8b6d..cb9ce927 100755 --- a/extras/ardusub-ubuntu-install-local.sh +++ b/extras/ardusub-ubuntu-install-local.sh @@ -3,8 +3,10 @@ set -euo pipefail # Source Ros and Gazebo ROS_DISTRO="${ROS_DISTRO:-lyrical}" +set +u # shellcheck disable=SC1090 source "/opt/ros/${ROS_DISTRO}/setup.bash" +set -u USER_NAME=$(logname 2>/dev/null || echo "${SUDO_USER:-$USER}") export USER="$USER_NAME" diff --git a/extras/ardusub-ubuntu-install.sh b/extras/ardusub-ubuntu-install.sh index 298cf69e..3d40e098 100755 --- a/extras/ardusub-ubuntu-install.sh +++ b/extras/ardusub-ubuntu-install.sh @@ -3,8 +3,10 @@ set -euo pipefail # Source Ros and Gazebo ROS_DISTRO="${ROS_DISTRO:-lyrical}" +set +u # shellcheck disable=SC1090 source "/opt/ros/${ROS_DISTRO}/setup.bash" +set -u # Commit used by the verified Lyrical / Python 3.14 build. ARDUPILOT_COMMIT="${ARDUPILOT_COMMIT:-30257f01185471ab4c1ac544e47d1b4437e44c98}" From 3aaa1d7e56dc91df22713281b0bd9f19b9312ad1 Mon Sep 17 00:00:00 2001 From: yeseorizi <172019512+yeseorizi@users.noreply.github.com> Date: Wed, 9 Sep 2026 13:08:00 +0900 Subject: [PATCH 5/9] Allow containerized ArduSub prerequisite setup --- extras/ardusub-ubuntu-install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/extras/ardusub-ubuntu-install.sh b/extras/ardusub-ubuntu-install.sh index 3d40e098..676aa063 100755 --- a/extras/ardusub-ubuntu-install.sh +++ b/extras/ardusub-ubuntu-install.sh @@ -33,6 +33,12 @@ export DO_AP_STM_ENV=0 # Do not activate the Ardupilot venv by default export DO_PYTHON_VENV_ENV=0 sed -i 's/ python-argparse//g' Tools/environment_install/install-prereqs-ubuntu.sh +# This system-wide helper is invoked by the root-owned Docker build. The pinned +# ArduPilot prerequisite script rejects EUID 0 before using sudo for the same +# package operations, so remove only that guard in this container installer. +# shellcheck disable=SC2016 +sed -i '/^if \[ \$EUID == 0 \]; then$/,/^fi$/d' \ + Tools/environment_install/install-prereqs-ubuntu.sh Tools/environment_install/install-prereqs-ubuntu.sh -y # Build ArduSub From a7ae2a422291b3f8cca984f0fafd0b4cbfdb2d54 Mon Sep 17 00:00:00 2001 From: yeseorizi <172019512+yeseorizi@users.noreply.github.com> Date: Wed, 9 Sep 2026 13:30:31 +0900 Subject: [PATCH 6/9] Complete ArduSub and Jetty installer migration --- .docker/lyrical.arm64v8.dockerfile | 10 +++++++++- extras/ardusub-ubuntu-install-local.sh | 10 ++++++++-- extras/ardusub-ubuntu-install.sh | 11 +++++++++-- extras/ros-lyrical-gz-jetty-install.sh | 6 +++++- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/.docker/lyrical.arm64v8.dockerfile b/.docker/lyrical.arm64v8.dockerfile index 833ef044..2f2d0a2d 100644 --- a/.docker/lyrical.arm64v8.dockerfile +++ b/.docker/lyrical.arm64v8.dockerfile @@ -95,6 +95,7 @@ EXPOSE 22/tcp # --- ROS 2 Lyrical + Gazebo Jetty --- ARG ROS_DISTRO="lyrical" +ENV GZ_VERSION=jetty RUN apt update && apt full-upgrade -y && apt autoremove -y @@ -133,6 +134,7 @@ RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ # Pinned to the commit used by the verified Ubuntu 26.04 / Python 3.14 build. USER root ARG ARDUSUB_COMMIT="30257f01185471ab4c1ac544e47d1b4437e44c98" +ARG ARDUPILOT_GAZEBO_COMMIT="082a0fe231f6e63bc8d1598f1cba461d9e2ea7f5" WORKDIR /home/$USER RUN git clone --recurse-submodules https://github.com/ArduPilot/ardupilot.git && \ cd ardupilot && git fetch --tags && git checkout --detach "$ARDUSUB_COMMIT" && \ @@ -150,14 +152,20 @@ ENV PIP_BREAK_SYSTEM_PACKAGES=1 RUN chown -R $USER:$USER /home/$USER/ardupilot /home/$USER/imp_shim && \ cd /home/$USER/ardupilot && \ sed -i "s/ python-argparse//g" Tools/environment_install/install-prereqs-ubuntu.sh && \ + sed -i 's/-U pip setuptools wheel/-U pip "setuptools<80" wheel/' \ + Tools/environment_install/install-prereqs-ubuntu.sh && \ su $USER -c "git config --global --add safe.directory /home/$USER/ardupilot" && \ su $USER -c "cd /home/$USER/ardupilot && Tools/environment_install/install-prereqs-ubuntu.sh -y" && \ - su $USER -c "cd /home/$USER/ardupilot && ./waf configure --board sitl && ./waf sub" && \ + su $USER -c "cd /home/$USER/ardupilot && python3 modules/waf/waf-light configure --board sitl" && \ + su $USER -c "cd /home/$USER/ardupilot && python3 modules/waf/waf-light build --target bin/ardusub" && \ cp /home/$USER/ardupilot/build/sitl/bin/ardusub /usr/local/bin/ardusub # Build the Gazebo Jetty ArduPilot plugin against the ROS vendor packages. RUN git clone --depth 1 https://github.com/ArduPilot/ardupilot_gazebo.git \ /home/$USER/ardupilot_gazebo && \ + cd /home/$USER/ardupilot_gazebo && \ + git fetch --depth 1 origin "$ARDUPILOT_GAZEBO_COMMIT" && \ + git checkout --detach "$ARDUPILOT_GAZEBO_COMMIT" && \ chown -R $USER:$USER /home/$USER/ardupilot_gazebo && \ mkdir -p /home/$USER/ardupilot_gazebo/build && \ cd /home/$USER/ardupilot_gazebo/build && \ diff --git a/extras/ardusub-ubuntu-install-local.sh b/extras/ardusub-ubuntu-install-local.sh index cb9ce927..2bbe4acf 100755 --- a/extras/ardusub-ubuntu-install-local.sh +++ b/extras/ardusub-ubuntu-install-local.sh @@ -7,11 +7,13 @@ set +u # shellcheck disable=SC1090 source "/opt/ros/${ROS_DISTRO}/setup.bash" set -u +export GZ_VERSION="${GZ_VERSION:-jetty}" USER_NAME=$(logname 2>/dev/null || echo "${SUDO_USER:-$USER}") export USER="$USER_NAME" ARDUPILOT_COMMIT="${ARDUPILOT_COMMIT:-30257f01185471ab4c1ac544e47d1b4437e44c98}" +ARDUPILOT_GAZEBO_COMMIT="${ARDUPILOT_GAZEBO_COMMIT:-082a0fe231f6e63bc8d1598f1cba461d9e2ea7f5}" mkdir -p "/home/$USER/ardusub_ws" && cd "/home/$USER/ardusub_ws" || exit git clone https://github.com/ArduPilot/ardupilot.git --recurse-submodules cd "/home/$USER/ardusub_ws/ardupilot" || exit @@ -33,15 +35,19 @@ export DO_AP_STM_ENV=0 # Do not activate the Ardupilot venv by default export DO_PYTHON_VENV_ENV=0 sed -i 's/ python-argparse//g' Tools/environment_install/install-prereqs-ubuntu.sh +sed -i 's/-U pip setuptools wheel/-U pip "setuptools<80" wheel/' \ + Tools/environment_install/install-prereqs-ubuntu.sh Tools/environment_install/install-prereqs-ubuntu.sh -y # Build ArduSub -modules/waf/waf-light configure --board sitl \ - && modules/waf/waf-light build --target bin/ardusub +python3 modules/waf/waf-light configure --board sitl +python3 modules/waf/waf-light build --target bin/ardusub # Clone ardupilot_gazebo code cd "/home/$USER/ardusub_ws" || exit git clone https://github.com/ArduPilot/ardupilot_gazebo.git +cd "/home/$USER/ardusub_ws/ardupilot_gazebo" || exit +git checkout --detach "$ARDUPILOT_GAZEBO_COMMIT" # Install ardupilot_gazebo plugin # Check if the directory creation was successful diff --git a/extras/ardusub-ubuntu-install.sh b/extras/ardusub-ubuntu-install.sh index 676aa063..25ac681d 100755 --- a/extras/ardusub-ubuntu-install.sh +++ b/extras/ardusub-ubuntu-install.sh @@ -7,9 +7,11 @@ set +u # shellcheck disable=SC1090 source "/opt/ros/${ROS_DISTRO}/setup.bash" set -u +export GZ_VERSION="${GZ_VERSION:-jetty}" # Commit used by the verified Lyrical / Python 3.14 build. ARDUPILOT_COMMIT="${ARDUPILOT_COMMIT:-30257f01185471ab4c1ac544e47d1b4437e44c98}" +ARDUPILOT_GAZEBO_COMMIT="${ARDUPILOT_GAZEBO_COMMIT:-082a0fe231f6e63bc8d1598f1cba461d9e2ea7f5}" mkdir -p "/opt/ardusub_ws" && cd "/opt/ardusub_ws" || exit git clone https://github.com/ArduPilot/ardupilot.git --recurse-submodules cd "/opt/ardusub_ws/ardupilot" || exit @@ -33,6 +35,9 @@ export DO_AP_STM_ENV=0 # Do not activate the Ardupilot venv by default export DO_PYTHON_VENV_ENV=0 sed -i 's/ python-argparse//g' Tools/environment_install/install-prereqs-ubuntu.sh +# Keep the ROS 2 Lyrical colcon requirement (setuptools < 80) intact. +sed -i 's/-U pip setuptools wheel/-U pip "setuptools<80" wheel/' \ + Tools/environment_install/install-prereqs-ubuntu.sh # This system-wide helper is invoked by the root-owned Docker build. The pinned # ArduPilot prerequisite script rejects EUID 0 before using sudo for the same # package operations, so remove only that guard in this container installer. @@ -42,12 +47,14 @@ sed -i '/^if \[ \$EUID == 0 \]; then$/,/^fi$/d' \ Tools/environment_install/install-prereqs-ubuntu.sh -y # Build ArduSub -modules/waf/waf-light configure --board sitl \ - && modules/waf/waf-light build --target bin/ardusub +python3 modules/waf/waf-light configure --board sitl +python3 modules/waf/waf-light build --target bin/ardusub # Clone ardupilot_gazebo code cd "/opt/ardusub_ws" || exit git clone https://github.com/ArduPilot/ardupilot_gazebo.git +cd "/opt/ardusub_ws/ardupilot_gazebo" || exit +git checkout --detach "$ARDUPILOT_GAZEBO_COMMIT" # Install ardupilot_gazebo plugin # Check if the directory creation was successful diff --git a/extras/ros-lyrical-gz-jetty-install.sh b/extras/ros-lyrical-gz-jetty-install.sh index bff04db5..6f0eff6c 100755 --- a/extras/ros-lyrical-gz-jetty-install.sh +++ b/extras/ros-lyrical-gz-jetty-install.sh @@ -110,7 +110,10 @@ sudo wget https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts sudo chmod +x install_geographiclib_datasets.sh && sudo bash ./install_geographiclib_datasets.sh # Environment variables setup (write to ~/.dave/env and source from shell rc) -TARGET_USER="${SUDO_USER:-$USER}" +TARGET_USER="${SUDO_USER:-${USER:-}}" +if [[ -z "$TARGET_USER" ]]; then + TARGET_USER="$(id -un)" +fi TARGET_HOME="$(getent passwd "$TARGET_USER" | cut -d: -f6)" TARGET_SHELL="$(getent passwd "$TARGET_USER" | cut -d: -f7)" @@ -132,6 +135,7 @@ fi export PATH=/opt/ardusub_ws/ardupilot/Tools/autotest:\$PATH export PATH=/opt/ardusub_ws/ardupilot/build/sitl/bin:\$PATH export GEOGRAPHICLIB_GEOID_PATH=/usr/share/GeographicLib/geoids +export GZ_VERSION=jetty export GZ_SIM_SYSTEM_PLUGIN_PATH=/opt/ardusub_ws/ardupilot_gazebo/build:\${GZ_SIM_SYSTEM_PLUGIN_PATH:-} export GZ_SIM_RESOURCE_PATH=/opt/ardusub_ws/ardupilot_gazebo/models:/opt/ardusub_ws/ardupilot_gazebo/worlds:\${GZ_SIM_RESOURCE_PATH:-} EOF From 36cc99823c923f7f3c3dca8d12384de39ab51000 Mon Sep 17 00:00:00 2001 From: yeseorizi <172019512+yeseorizi@users.noreply.github.com> Date: Thu, 10 Sep 2026 17:03:53 +0900 Subject: [PATCH 7/9] ci: use native Docker driver on ARM64 runner Signed-off-by: yeseorizi <172019512+yeseorizi@users.noreply.github.com> --- .github/workflows/docker-arm64v8.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/docker-arm64v8.yml b/.github/workflows/docker-arm64v8.yml index bc6d434a..8488b9b1 100644 --- a/.github/workflows/docker-arm64v8.yml +++ b/.github/workflows/docker-arm64v8.yml @@ -46,6 +46,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + with: + # On a macOS launchd runner, the docker-container driver can try to + # open Docker Desktop's interactive Keychain credential helper. + # The native driver avoids that dependency for this single-platform + # ARM64 build and works with Docker Desktop's containerd image store. + driver: docker - name: Log in to Docker Hub if: github.event_name != 'pull_request' From 68b7598fb72482e22c7b6be0cdf5d4e1763b0b07 Mon Sep 17 00:00:00 2001 From: yeseorizi <172019512+yeseorizi@users.noreply.github.com> Date: Thu, 10 Sep 2026 17:23:44 +0900 Subject: [PATCH 8/9] fix: add ARM64 ArduPilot GStreamer headers --- .docker/lyrical.arm64v8.dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/.docker/lyrical.arm64v8.dockerfile b/.docker/lyrical.arm64v8.dockerfile index 2f2d0a2d..491b95e1 100644 --- a/.docker/lyrical.arm64v8.dockerfile +++ b/.docker/lyrical.arm64v8.dockerfile @@ -73,6 +73,7 @@ RUN apt-get update && \ xterm vim net-tools \ curl wget git build-essential cmake cppcheck \ gnupg libeigen3-dev libgles2-mesa-dev \ + libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \ lsb-release pkg-config protobuf-compiler \ python3-pip python3-venv \ nano xauth htop libtool \ From 169018c780e833b23dd714f3b19ba22d15921c95 Mon Sep 17 00:00:00 2001 From: yeseorizi <172019512+yeseorizi@users.noreply.github.com> Date: Thu, 10 Sep 2026 22:02:28 +0900 Subject: [PATCH 9/9] fix: complete ARM64 tutorial runtime dependencies Signed-off-by: yeseorizi <172019512+yeseorizi@users.noreply.github.com> --- .docker/lyrical.arm64v8.dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.docker/lyrical.arm64v8.dockerfile b/.docker/lyrical.arm64v8.dockerfile index 491b95e1..a833ee72 100644 --- a/.docker/lyrical.arm64v8.dockerfile +++ b/.docker/lyrical.arm64v8.dockerfile @@ -108,6 +108,7 @@ RUN export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-inf apt update && \ apt install -y --no-install-recommends \ ros-${ROS_DISTRO}-desktop ros-${ROS_DISTRO}-ros-gz \ + ros-${ROS_DISTRO}-image-view \ python3-rosdep python3-vcstool python3-colcon-common-extensions # --- DAVE workspace --- @@ -187,6 +188,8 @@ RUN apt-get update && \ gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly python3-gi python3-gst-1.0 \ libfuse2 libxcb-xinerama0 libxkbcommon-x11-0 libxcb-cursor-dev gstreamer1.0-qt6 \ gstreamer1.0-gl libqt6qml6 qml6-module-qtquick qml6-module-qtquick-window && \ + /opt/ros/${ROS_DISTRO}/lib/mavros/install_geographiclib_datasets.sh && \ + test -r /usr/share/GeographicLib/geoids/egm96-5.pgm && \ rm -rf /var/lib/apt/lists/* USER $USER