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..af151c79 100644 --- a/.devcontainer/nouveau/devcontainer.json +++ b/.devcontainer/nouveau/devcontainer.json @@ -2,9 +2,9 @@ "name": "Nouveau Dev Container", "dockerFile": "Dockerfile", "context": "../..", - "workspaceMount": "source=${localWorkspaceFolder},target=/home/blue/ws_blue/src/blue,type=bind", - "workspaceFolder": "/home/blue/ws_blue/src/blue", - "remoteUser": "blue", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/ubuntu/ws_blue/src/blue,type=bind", + "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..c8500eda 100644 --- a/.devcontainer/nvidia/devcontainer.json +++ b/.devcontainer/nvidia/devcontainer.json @@ -2,9 +2,9 @@ "name": "NVIDIA Dev Container", "dockerFile": "Dockerfile", "context": "../..", - "workspaceMount": "source=${localWorkspaceFolder},target=/home/blue/ws_blue/src/blue,type=bind", - "workspaceFolder": "/home/blue/ws_blue/src/blue", - "remoteUser": "blue", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/ubuntu/ws_blue/src/blue,type=bind", + "workspaceFolder": "/home/ubuntu/ws_blue/src/blue", + "remoteUser": "ubuntu", "runArgs": [ "--network=host", "--cap-add=SYS_PTRACE", diff --git a/.devcontainer/robot/Dockerfile b/.devcontainer/robot/Dockerfile new file mode 100644 index 00000000..cd3d2818 --- /dev/null +++ b/.devcontainer/robot/Dockerfile @@ -0,0 +1,31 @@ +# +# Dockerfile for *-robot development container +# +ARG BLUE_GITHUB_REPO=Robotic-Decision-Making-Lab/blue +ARG ROS_DISTRO=rolling +FROM ${BLUE_GITHUB_REPO}:${ROS_DISTRO}-robot + +# 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=ubuntu +ENV USER_WORKSPACE=/home/$USERNAME/ws_blue +WORKDIR $USER_WORKSPACE + +COPY --chown=$USER_UID:$USER_GID . src/blue +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} --skip-keys="gz-transport12 gz-sim7 gz-math7 gz-msgs9 gz-plugin2" \ + && sudo apt-get autoremove -y \ + && sudo apt-get clean -y \ + && sudo rm -rf /var/lib/apt/lists/* + +# Install debugging/linting Python packages +RUN python3 -m pip install \ + pre-commit \ + mypy + +# Disable the setuputils installation warning +# This prevents us from needing to pin the setuputils version (which doesn't always work) +ENV PYTHONWARNINGS="ignore" diff --git a/.devcontainer/robot/devcontainer.json b/.devcontainer/robot/devcontainer.json new file mode 100644 index 00000000..2fe816b2 --- /dev/null +++ b/.devcontainer/robot/devcontainer.json @@ -0,0 +1,40 @@ +{ + "name": "Robot Dev Container", + "build": { + "dockerfile": "Dockerfile", + "context": "../..", + "args": { + "BLUE_GITHUB_REPO": "ghcr.io/robotic-decision-making-lab/blue", + "ROS_DISTRO": "rolling" + } + }, + "workspaceMount": "source=${localWorkspaceFolder},target=/home/ubuntu/ws_blue/src/blue,type=bind", + "workspaceFolder": "/home/ubuntu/ws_blue/src/blue", + "remoteUser": "ubuntu", + "runArgs": [ + "--network=host", + "--cap-add=SYS_PTRACE", + "--security-opt=seccomp:unconfined", + "--security-opt=apparmor:unconfined", + "--volume=/dev:/dev", + "--privileged", + "--volume=/run/user/1000:/run/user/1000" + ], + "containerEnv": {}, + "customizations": { + "vscode": { + "extensions": [ + "ms-azuretools.vscode-docker", + "ms-python.python", + "njpwerner.autodocstring", + "redhat.vscode-xml", + "redhat.vscode-yaml", + "smilerobotics.urdf", + "esbenp.prettier-vscode", + "charliermarsh.ruff", + "josetr.cmake-language-support-vscode", + "unifiedjs.vscode-mdx" + ] + } + } +} diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 5a8289e3..2295d107 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 \ @@ -38,14 +39,14 @@ RUN apt-get -q update \ FROM ci as robot -# Configure a new non-root user -ARG USERNAME=blue +# +# Ubuntu 24.04 "Noble", which is used as the base image for +# jazzy and rolling images, 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,6 +57,16 @@ ENV DEBIAN_FRONTEND=noninteractive USER $USERNAME ENV USER=$USERNAME +# Python in Ubuntu is now marked as a "Externally managed environment", +# Per best practice, create a venv for local python packages +# +# These two ENVs effectively "activate" the venv for subsequent calls to +# python/pip in the Dockerfile +WORKDIR /home/$USERNAME +ENV VIRTUAL_ENV=/home/$USERNAME/.venv/blue +RUN python3 -m venv --system-site-packages --symlinks $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + # Install MAVROS dependencies WORKDIR /home/$USERNAME RUN wget https://raw.githubusercontent.com/mavlink/mavros/ros2/mavros/scripts/install_geographiclib_datasets.sh \ @@ -85,6 +96,29 @@ RUN sudo apt-get -q update \ && sudo apt-get clean -y \ && sudo rm -rf /var/lib/apt/lists/* +<<<<<<< HEAD +======= +# Manually install MAVROS from source in the ws_blue/ workspace +WORKDIR $USER_WORKSPACE/src/ +ARG MAVROS_RELEASE=ros2 +ARG MAVLINK_RELEASE=release/rolling/mavlink +RUN git clone --depth 1 -b ${MAVROS_RELEASE} https://github.com/mavlink/mavros.git +RUN git clone --depth 1 --recursive -b ${MAVLINK_RELEASE} https://github.com/mavlink/mavlink-gbp-release.git mavlink +# - mavgen uses future.standard_library for backwards compatibility with Python2; +# However, this caused issues with Python 3.12 installed in "noble". +# Comment those lines out in mavlink. +# +# - Fix linkage for yaml-cpp in mavros_extra_plugins +RUN sed -i -e 's/^from future import standard_library/#from future import standard_library/' \ + -e 's/standard_library.install_aliases()/#standard_library.install_aliases()/' \ + mavlink/pymavlink/generator/mavgen.py && \ + sed -i -e 's/^# find_package(yaml_cpp REQUIRED)/find_package(yaml-cpp REQUIRED)/' \ + -e '/^ament_target_dependencies(mavros_extras_plugins$/i target_link_libraries(mavros_extras_plugins yaml-cpp::yaml-cpp)' \ + -e '/^ament_target_dependencies(mavros_extras$/i target_link_libraries(mavros_extras yaml-cpp::yaml-cpp)' \ + mavros/mavros_extras/CMakeLists.txt + +WORKDIR $USER_WORKSPACE +>>>>>>> fe3861d (Rolling ROS image is now based on "noble" (#220)) RUN sudo apt-get -q update \ && sudo apt-get -q -y upgrade \ && rosdep update \ @@ -94,13 +128,16 @@ RUN sudo apt-get -q update \ && 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 + && echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> /home/$USERNAME/.bashrc \ + && echo "source $VIRTUAL_ENV/bin/activate" >> /home/$USERNAME/.bashrc \ + && echo "\n# Ensure colcon is run in the venv\nalias colcon='python3 -m colcon'" >> /home/$USERNAME/.bashrc FROM robot as desktop ENV DEBIAN_FRONTEND=noninteractive ENV GZ_VERSION=garden +<<<<<<< HEAD # Install Gazebo Garden: https://gazebosim.org/docs/garden/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 \ @@ -115,6 +152,21 @@ 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 \ +======= +# Install Gazebo Harmonic: https://gazebosim.org/docs/harmonic/install_ubuntu +# Per DL3004, use "USER root" rather than "sudo" +# https://github.com/hadolint/hadolint/wiki/DL3004 +USER root +# Install custom rosdep list +ADD --chown=root:root --chmod=0644 https://raw.githubusercontent.com/osrf/osrf-rosdep/master/gz/00-gazebo.list /etc/ros/rosdep/sources.list.d/00-gazebo.list +RUN 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" | tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null \ + && apt-get -q update \ + && apt-get -y --quiet --no-install-recommends install \ + cppzmq-dev \ + gz-${GZ_VERSION} \ + python3-pexpect \ +>>>>>>> fe3861d (Rolling ROS image is now based on "noble" (#220)) python3-wxgtk4.0 \ rapidjson-dev \ xterm \ @@ -132,7 +184,12 @@ RUN git clone https://github.com/ArduPilot/ardupilot.git --recurse-submodules # Install ArduSub dependencies WORKDIR /home/$USERNAME/ardupilot ENV SKIP_AP_EXT_ENV=1 SKIP_AP_GRAPHIC_ENV=1 SKIP_AP_COV_ENV=1 SKIP_AP_GIT_CHECK=1 -RUN Tools/environment_install/install-prereqs-ubuntu.sh -y +# Do not install the STM development tools +ENV DO_AP_STM_ENV=0 +# Do not activate the Ardupilot venv by default +ENV DO_PYTHON_VENV_ENV=0 +RUN echo "\n# Below from ardupilot script \"install-prereqs-ubuntu.sh\"\n" >> /home/$USERNAME/.bashrc && \ + Tools/environment_install/install-prereqs-ubuntu.sh -y # Build ArduSub WORKDIR /home/$USERNAME/ardupilot diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index c93452a5..9445d19d 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -105,7 +105,8 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} push: ${{ env.PUSH }} - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64 + #platforms: linux/amd64,linux/arm64 desktop: strategy: diff --git a/.vscode/settings.json b/.vscode/settings.json index f6d45d50..354d88bb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -42,6 +42,7 @@ }, "editor.defaultFormatter": "charliermarsh.ruff" }, + "python.defaultInterpreterPath": "${workspaceFolder}/.venv/blue/bin/python", "[dockerfile]": { "editor.quickSuggestions": { "strings": true