diff --git a/.devcontainer/nouveau/Dockerfile b/.devcontainer/nouveau/Dockerfile index d362c8b2..8122286a 100644 --- a/.devcontainer/nouveau/Dockerfile +++ b/.devcontainer/nouveau/Dockerfile @@ -3,7 +3,7 @@ FROM ghcr.io/robotic-decision-making-lab/blue:rolling-desktop # Install ROS dependencies # This is done in a previous stage, but we include it again here in case anyone wants to # add new dependencies during development -ENV USERNAME=blue +ENV USERNAME=ubuntu ENV USER_WORKSPACE=/home/$USERNAME/ws_blue WORKDIR $USER_WORKSPACE diff --git a/.devcontainer/nouveau/devcontainer.json b/.devcontainer/nouveau/devcontainer.json index 5dbcef35..bae72b58 100644 --- a/.devcontainer/nouveau/devcontainer.json +++ b/.devcontainer/nouveau/devcontainer.json @@ -3,8 +3,8 @@ "dockerFile": "Dockerfile", "context": "../..", "workspaceMount": "source=${localWorkspaceFolder},target=/home/blue/ws_blue/src/blue,type=bind", - "workspaceFolder": "/home/blue/ws_blue/src/blue", - "remoteUser": "blue", + "workspaceFolder": "/home/ubuntu/ws_blue/src/blue", + "remoteUser": "ubuntu", "runArgs": [ "--network=host", "--cap-add=SYS_PTRACE", diff --git a/.devcontainer/nvidia/Dockerfile b/.devcontainer/nvidia/Dockerfile index 3135e7fa..1c55005d 100644 --- a/.devcontainer/nvidia/Dockerfile +++ b/.devcontainer/nvidia/Dockerfile @@ -3,7 +3,7 @@ FROM ghcr.io/robotic-decision-making-lab/blue:rolling-desktop-nvidia # Install ROS dependencies # This is done in a previous stage, but we include it again here in case anyone wants to # add new dependencies during development -ENV USERNAME=blue +ENV USERNAME=ubuntu ENV USER_WORKSPACE=/home/$USERNAME/ws_blue WORKDIR $USER_WORKSPACE diff --git a/.devcontainer/nvidia/devcontainer.json b/.devcontainer/nvidia/devcontainer.json index 9359454f..e58a5ed9 100644 --- a/.devcontainer/nvidia/devcontainer.json +++ b/.devcontainer/nvidia/devcontainer.json @@ -3,8 +3,8 @@ "dockerFile": "Dockerfile", "context": "../..", "workspaceMount": "source=${localWorkspaceFolder},target=/home/blue/ws_blue/src/blue,type=bind", - "workspaceFolder": "/home/blue/ws_blue/src/blue", - "remoteUser": "blue", + "workspaceFolder": "/home/ubuntu/ws_blue/src/blue", + "remoteUser": "ubuntu", "runArgs": [ "--network=host", "--cap-add=SYS_PTRACE", diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 5a8289e3..034eb66a 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -18,6 +18,7 @@ RUN apt-get -q update \ clang-tools \ python3-pip \ python3-dev \ + python3-venv \ lsb-release \ wget \ gnupg \ @@ -27,10 +28,11 @@ RUN apt-get -q update \ && rm -rf /var/lib/apt/lists/* # Install all ROS dependencies +# Don't try to resolve "mavros" or "mavros_extras", we will install those manually RUN apt-get -q update \ && apt-get -q -y upgrade \ && rosdep update \ - && rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} --as-root=apt:false \ + && rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} --as-root=apt:false --skip-keys="mavros mavros_extras" \ && rm -rf src \ && apt-get autoremove -y \ && apt-get clean -y \ @@ -39,13 +41,13 @@ RUN apt-get -q update \ FROM ci as robot # Configure a new non-root user -ARG USERNAME=blue +# +# ros image now includes a user "ubuntu" at UID 1000 +ARG USERNAME=ubuntu ARG USER_UID=1000 ARG USER_GID=$USER_UID -RUN groupadd --gid $USER_GID $USERNAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ - && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ +RUN echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ && chmod 0440 /etc/sudoers.d/$USERNAME \ && usermod -a -G dialout $USERNAME \ && echo "source /usr/share/bash-completion/completions/git" >> /home/$USERNAME/.bashrc @@ -56,11 +58,21 @@ ENV DEBIAN_FRONTEND=noninteractive USER $USERNAME ENV USER=$USERNAME -# Install MAVROS dependencies +# Python in Ubuntu is now marked as a "Externally managed environment", +# Per best practice, create a venv for local python packages +# Is there a more elegant way to handle this? +# +# These two ENVs effectively "activate" the venv for subsequent calls to +# python/pip in the Dockerfile WORKDIR /home/$USERNAME -RUN wget https://raw.githubusercontent.com/mavlink/mavros/ros2/mavros/scripts/install_geographiclib_datasets.sh \ - && chmod +x install_geographiclib_datasets.sh \ - && sudo ./install_geographiclib_datasets.sh +ENV VIRTUAL_ENV=/home/$USERNAME/.venv/blue +RUN python3 -m venv --system-site-packages --symlinks $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +# ROS must be activated before the venv (?) +RUN echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> /home/$USERNAME/.bashrc +RUN echo "source /home/$USERNAME/.venv/blue/bin/activate" >> /home/$USERNAME/.bashrc +RUN echo "\n# Ensure colcon is run in the venv\nalias colcon='python3 -m colcon'" >> /home/$USERNAME/.bashrc ENV USER_WORKSPACE=/home/$USERNAME/ws_blue WORKDIR $USER_WORKSPACE @@ -81,32 +93,50 @@ RUN sudo apt-get -q update \ gstreamer1.0-plugins-ugly \ gstreamer1.0-plugins-bad \ gstreamer1.0-libav \ + libgstreamer1.0-dev \ + libgstreamer-plugins-base1.0-dev \ && sudo apt-get autoremove -y \ && sudo apt-get clean -y \ && sudo rm -rf /var/lib/apt/lists/* +# Manually install MAVROS from source in the ws_blue/ workspace +WORKDIR $USER_WORKSPACE/src/ +RUN git clone --depth 1 -b ros2 https://github.com/mavlink/mavros.git +RUN git clone --depth 1 --recursive -b release/rolling/mavlink https://github.com/mavlink/mavlink-gbp-release.git mavlink + +# mavgen uses future.standard_library for backwards compatibility with Python2; +# However, this caused issues in Python3.12. Comment those lines out +RUN patch -d mavlink -p 1 < $USER_WORKSPACE/src/blue/.docker/patches/mavlink_standard_library.patch +WORKDIR $USER_WORKSPACE + RUN sudo apt-get -q update \ && sudo apt-get -q -y upgrade \ && rosdep update \ - && rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} \ + && rosdep install -y --from-paths src --ignore-src --as-root=pip:false --rosdistro ${ROS_DISTRO} \ && sudo apt-get autoremove -y \ && sudo apt-get clean -y \ && sudo rm -rf /var/lib/apt/lists/* -RUN echo "source ${USER_WORKSPACE}/install/setup.bash" >> /home/$USERNAME/.bashrc \ - && echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> /home/$USERNAME/.bashrc +# Install geographiclib datasets +# Scripts uses geographiclib-tools which is a rosdep dependency of mavros installed above +WORKDIR /tmp +RUN wget https://raw.githubusercontent.com/mavlink/mavros/ros2/mavros/scripts/install_geographiclib_datasets.sh \ + && chmod +x /tmp/install_geographiclib_datasets.sh \ + && sudo /tmp/install_geographiclib_datasets.sh + +RUN echo "if [ -f ${USER_WORKSPACE}/install/setup.bash ]; then source ${USER_WORKSPACE}/install/setup.bash; fi" >> /home/$USERNAME/.bashrc FROM robot as desktop ENV DEBIAN_FRONTEND=noninteractive -ENV GZ_VERSION=garden +ENV GZ_VERSION=harmonic -# Install Gazebo Garden: https://gazebosim.org/docs/garden/install_ubuntu +# Install Gazebo Harmonic: https://gazebosim.org/docs/harmonic/install_ubuntu RUN sudo wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg \ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null \ && sudo apt-get -q update \ && sudo apt-get -y --quiet --no-install-recommends install \ - gz-garden \ + gz-${GZ_VERSION} \ && sudo apt-get autoremove -y \ && sudo apt-get clean -y \ && sudo rm -rf /var/lib/apt/lists/* @@ -115,6 +145,8 @@ RUN sudo wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrin RUN sudo apt-get -q update \ && sudo apt-get -q -y upgrade \ && sudo apt-get -q install --no-install-recommends -y \ + cppzmq-dev \ + python3-pexpect \ python3-wxgtk4.0 \ rapidjson-dev \ xterm \ diff --git a/.docker/patches/mavlink_standard_library.patch b/.docker/patches/mavlink_standard_library.patch new file mode 100644 index 00000000..4f2360d8 --- /dev/null +++ b/.docker/patches/mavlink_standard_library.patch @@ -0,0 +1,15 @@ +diff --git a/pymavlink/generator/mavgen.py b/pymavlink/generator/mavgen.py +index ea62c961..35353184 100755 +--- a/pymavlink/generator/mavgen.py ++++ b/pymavlink/generator/mavgen.py +@@ -23,8 +23,8 @@ General process: + ''' + + from __future__ import print_function +-from future import standard_library +-standard_library.install_aliases() ++#from future import standard_library ++#standard_library.install_aliases() + from builtins import object + import os + import re diff --git a/.dockerignore b/.dockerignore index 211fad8d..62be0f94 100644 --- a/.dockerignore +++ b/.dockerignore @@ -8,4 +8,5 @@ !blue_demos !blue.repos !.docker/entrypoints +!.docker/patches !requirements-build.txt diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8c56c7f7..891d5898 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -19,8 +19,8 @@ jobs: fail-fast: false matrix: env: - - IMAGE: rolling-ci - ROS_DISTRO: rolling + - IMAGE: jazzy-ci + ROS_DISTRO: jazzy steps: - name: Checkout repository uses: actions/checkout@v4 @@ -37,7 +37,7 @@ jobs: - name: Run ROS Industrial CI uses: ros-industrial/industrial_ci@master env: - DOCKER_IMAGE: ghcr.io/robotic-decision-making-lab/blue:${{ matrix.env.IMAGE }} + DOCKER_IMAGE: ghcr.io/${{ github.repository }}:${{ matrix.env.IMAGE }} CXXFLAGS: >- -Wall -Wextra -Wpedantic -Wwrite-strings -Wunreachable-code -Wpointer-arith -Wredundant-decls CC: ${{ env.CLANG_TIDY && 'clang' }} diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index c93452a5..a00ed89a 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [rolling] + ROS_DISTRO: [jazzy] runs-on: ubuntu-latest permissions: packages: write @@ -63,7 +63,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [rolling] + ROS_DISTRO: [jazzy] runs-on: ubuntu-latest permissions: packages: write @@ -111,7 +111,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [rolling] + ROS_DISTRO: [jazzy] runs-on: ubuntu-latest permissions: packages: write @@ -152,7 +152,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [rolling] + ROS_DISTRO: [jazzy] runs-on: ubuntu-latest permissions: packages: write diff --git a/blue.repos b/blue.repos index ca3abd91..626b08d5 100644 --- a/blue.repos +++ b/blue.repos @@ -3,7 +3,7 @@ repositories: ros_gz: type: git url: https://github.com/gazebosim/ros_gz - version: ros2 + version: jazzy hydrodynamics: type: git