diff --git a/.devcontainer/nouveau/Dockerfile b/.devcontainer/nouveau/Dockerfile
index d362c8b2..8bd6c389 100644
--- a/.devcontainer/nouveau/Dockerfile
+++ b/.devcontainer/nouveau/Dockerfile
@@ -1,9 +1,9 @@
-FROM ghcr.io/robotic-decision-making-lab/blue:rolling-desktop
+FROM ghcr.io/robotic-decision-making-lab/blue:jazzy-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..8a4daeb0 100644
--- a/.devcontainer/nvidia/Dockerfile
+++ b/.devcontainer/nvidia/Dockerfile
@@ -1,9 +1,9 @@
-FROM ghcr.io/robotic-decision-making-lab/blue:rolling-desktop-nvidia
+FROM ghcr.io/robotic-decision-making-lab/blue:jazzy-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..951d1bf9
--- /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=jazzy
+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..a4fe3600
--- /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": "jazzy"
+ }
+ },
+ "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..07d3ca30 100644
--- a/.docker/Dockerfile
+++ b/.docker/Dockerfile
@@ -1,5 +1,5 @@
-ARG ROS_DISTRO=rolling
-FROM ros:$ROS_DISTRO-ros-base as ci
+ARG ROS_DISTRO=jazzy
+FROM ros:$ROS_DISTRO-ros-base AS ci
ENV DEBIAN_FRONTEND=noninteractive
@@ -18,6 +18,7 @@ RUN apt-get -q update \
clang-tools \
python3-pip \
python3-dev \
+ python3-venv \
lsb-release \
wget \
gnupg \
@@ -26,7 +27,8 @@ RUN apt-get -q update \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
-# Install all ROS dependencies
+# Install all ROS dependencies for _just_ blue
+# (we have not imported other repos from .repos files)
RUN apt-get -q update \
&& apt-get -q -y upgrade \
&& rosdep update \
@@ -36,16 +38,24 @@ RUN apt-get -q update \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
-FROM ci as robot
-
-# Configure a new non-root user
-ARG USERNAME=blue
+# This stage includes
+# - Switching to the non-root user
+# - Copying 'blue' source from this repo into the non-root user's workspace
+# - Installing blue deps using pip, apt and rosdep
+# - Installs the remaining blue dependencies from blue_robot.repos
+# - Installs deps from rosdep for all src dependencies
+# - colcon build
+#
+FROM ci AS robot
+
+#
+# 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 +66,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 \
@@ -81,58 +101,100 @@ RUN sudo apt-get -q update \
gstreamer1.0-plugins-ugly \
gstreamer1.0-plugins-bad \
gstreamer1.0-libav \
+ libgstreamer1.0-dev \
+ gstreamer1.0-gl \
+ 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/
+ARG MAVROS_RELEASE=ros2
+# mavlink-gdp-release has not been released for Jazzy, so we use the Rolling release
+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
RUN sudo apt-get -q update \
&& sudo apt-get -q -y upgrade \
+ && vcs import src < src/blue/blue.repos \
&& rosdep update \
&& rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} \
&& sudo apt-get autoremove -y \
&& sudo apt-get clean -y \
&& sudo rm -rf /var/lib/apt/lists/*
+# Actually build workspace
+RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" \
+ && colcon build
+
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
+FROM robot AS desktop
ENV DEBIAN_FRONTEND=noninteractive
-ENV GZ_VERSION=garden
-
-# 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 \
- && sudo apt-get -q update \
- && sudo apt-get -y --quiet --no-install-recommends install \
- gz-garden \
- && sudo apt-get autoremove -y \
- && sudo apt-get clean -y \
- && sudo rm -rf /var/lib/apt/lists/*
-
-# Install ArduPilot and ardupilot_gazebo dependencies
-RUN sudo apt-get -q update \
- && sudo apt-get -q -y upgrade \
- && sudo apt-get -q install --no-install-recommends -y \
+ENV GZ_VERSION=harmonic
+
+# 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 \
python3-wxgtk4.0 \
+ python3-future \
rapidjson-dev \
xterm \
- && sudo apt-get autoremove -y \
- && sudo apt-get clean -y \
- && sudo rm -rf /var/lib/apt/lists/*
+ rapidjson-dev \
+ libopencv-dev \
+ && apt-get autoremove -y \
+ && apt-get clean -y \
+ && rm -rf /var/lib/apt/lists/*
+USER $USERNAME
# Clone ArduSub
# ArduSub is installed for simulation purposes ONLY
# When deployed onto hardware, the native installation of ArduSub
# (on the FCU) will be used.
WORKDIR /home/$USERNAME
-RUN git clone https://github.com/ArduPilot/ardupilot.git --recurse-submodules
+# Really should do version pinning but Sub-4.5 is waaaay behind master
+# (e.g. it doesn't know about "noble" yet)
+ARG ARDUPILOT_RELEASE=master
+RUN git clone -b ${ARDUPILOT_RELEASE} 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
@@ -155,7 +217,7 @@ RUN [ "/bin/bash" , "-c" , " \
WORKDIR $USER_WORKSPACE
RUN sudo apt-get -q update \
&& sudo apt-get -q -y upgrade \
- && vcs import src < src/blue/blue.repos \
+ && vcs import src < src/blue/sim.repos \
&& rosdep update \
&& rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} \
&& sudo apt-get autoremove -y \
@@ -171,7 +233,7 @@ RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" \
# Setup the simulation environment variables
RUN echo "source ${USER_WORKSPACE}/src/blue/.docker/entrypoints/sim.sh" >> /home/$USERNAME/.bashrc
-FROM desktop as desktop-nvidia
+FROM desktop AS desktop-nvidia
# Install NVIDIA software
RUN sudo apt-get update \
diff --git a/.docker/compose/nouveau-desktop.yaml b/.docker/compose/nouveau-desktop.yaml
index f18588de..3783b19d 100644
--- a/.docker/compose/nouveau-desktop.yaml
+++ b/.docker/compose/nouveau-desktop.yaml
@@ -1,7 +1,7 @@
version: "3"
services:
blue:
- image: ghcr.io/robotic-decision-making-lab/blue:rolling-desktop
+ image: ghcr.io/robotic-decision-making-lab/blue:jazzy-desktop
environment:
- DISPLAY=${DISPLAY}
- XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}
diff --git a/.docker/compose/nvidia-desktop.yaml b/.docker/compose/nvidia-desktop.yaml
index da240d51..ebc6777f 100644
--- a/.docker/compose/nvidia-desktop.yaml
+++ b/.docker/compose/nvidia-desktop.yaml
@@ -1,7 +1,7 @@
version: "3"
services:
blue:
- image: ghcr.io/robotic-decision-making-lab/blue:rolling-desktop-nvidia
+ image: ghcr.io/robotic-decision-making-lab/blue:jazzy-desktop-nvidia
environment:
- DISPLAY=${DISPLAY}
- XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}
diff --git a/.docker/compose/robot.yaml b/.docker/compose/robot.yaml
new file mode 100644
index 00000000..66c3607b
--- /dev/null
+++ b/.docker/compose/robot.yaml
@@ -0,0 +1,21 @@
+services:
+ blue:
+ image: ghcr.io/robotic-decision-making-lab/blue:jazzy-robot
+ build:
+ dockerfile: .docker/Dockerfile
+ target: robot
+ context: ../../
+ network_mode: host
+ privileged: true
+ cap_add:
+ - SYS_PTRACE
+ security_opt:
+ - seccomp:unconfined
+ - apparmor:unconfined
+ volumes:
+ - /dev:/dev
+ - /run/user/1000:/run/user/1000
+ - type: bind
+ source: ../../
+ target: /home/blue/ws_blue/src/blue
+ command: tail -f /dev/null
diff --git a/.dockerignore b/.dockerignore
index 211fad8d..ae633710 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -7,5 +7,6 @@
!blue_description
!blue_demos
!blue.repos
+!sim.repos
!.docker/entrypoints
!requirements-build.txt
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 8c56c7f7..987d2f90 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
@@ -28,7 +28,7 @@ jobs:
submodules: recursive
- name: Log into registry
- uses: docker/login-action@v3.1.0
+ uses: docker/login-action@v3.3.0
with:
registry: ghcr.io
username: ${{ github.actor }}
diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml
index c93452a5..c7dab62c 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
@@ -33,7 +33,7 @@ jobs:
- name: Log into registry
if: env.PUSH == 'true'
- uses: docker/login-action@v3.1.0
+ uses: docker/login-action@v3.3.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -49,7 +49,7 @@ jobs:
type=raw,value=${{ matrix.ROS_DISTRO }}-${{ github.job }}
- name: Build and push Docker image
- uses: docker/build-push-action@v5.3.0
+ uses: docker/build-push-action@v6.5.0
with:
context: .
file: .docker/Dockerfile
@@ -63,7 +63,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- ROS_DISTRO: [rolling]
+ ROS_DISTRO: [jazzy]
runs-on: ubuntu-latest
permissions:
packages: write
@@ -73,14 +73,14 @@ jobs:
uses: actions/checkout@v4
- name: Set up QEMU
- uses: docker/setup-qemu-action@v3.0.0
+ uses: docker/setup-qemu-action@v3.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log into registry
if: env.PUSH == 'true'
- uses: docker/login-action@v3.1.0
+ uses: docker/login-action@v3.3.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -96,7 +96,7 @@ jobs:
type=raw,value=${{ matrix.ROS_DISTRO }}-${{ github.job }}
- name: Build and push Docker image
- uses: docker/build-push-action@v5.3.0
+ uses: docker/build-push-action@v6.5.0
with:
context: .
file: .docker/Dockerfile
@@ -105,13 +105,14 @@ 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:
fail-fast: false
matrix:
- ROS_DISTRO: [rolling]
+ ROS_DISTRO: [jazzy]
runs-on: ubuntu-latest
permissions:
packages: write
@@ -122,7 +123,7 @@ jobs:
- name: Log into registry
if: env.PUSH == 'true'
- uses: docker/login-action@v3.1.0
+ uses: docker/login-action@v3.3.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -138,7 +139,7 @@ jobs:
type=raw,value=${{ matrix.ROS_DISTRO }}-${{ github.job }}
- name: Build and push Docker image
- uses: docker/build-push-action@v5.3.0
+ uses: docker/build-push-action@v6.5.0
with:
context: .
file: .docker/Dockerfile
@@ -152,7 +153,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- ROS_DISTRO: [rolling]
+ ROS_DISTRO: [jazzy]
runs-on: ubuntu-latest
permissions:
packages: write
@@ -163,7 +164,7 @@ jobs:
- name: Log into registry
if: env.PUSH == 'true'
- uses: docker/login-action@v3.1.0
+ uses: docker/login-action@v3.3.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -179,7 +180,7 @@ jobs:
type=raw,value=${{ matrix.ROS_DISTRO }}-${{ github.job }}
- name: Build and push Docker image
- uses: docker/build-push-action@v5.3.0
+ uses: docker/build-push-action@v6.5.0
with:
context: .
file: .docker/Dockerfile
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
diff --git a/blue.repos b/blue.repos
index ca3abd91..20a32377 100644
--- a/blue.repos
+++ b/blue.repos
@@ -1,10 +1,5 @@
repositories:
- ros_gz:
- type: git
- url: https://github.com/gazebosim/ros_gz
- version: ros2
-
hydrodynamics:
type: git
url: https://github.com/Robotic-Decision-Making-Lab/hydrodynamics.git
diff --git a/blue_bringup/launch/bluerov2_heavy/bluerov2_heavy.launch.yaml b/blue_bringup/launch/bluerov2_heavy/bluerov2_heavy.launch.yaml
index 28819c61..93897099 100644
--- a/blue_bringup/launch/bluerov2_heavy/bluerov2_heavy.launch.yaml
+++ b/blue_bringup/launch/bluerov2_heavy/bluerov2_heavy.launch.yaml
@@ -43,7 +43,7 @@ launch:
- arg:
name: mavros_file
- default: $(find-pkg-share blue_description)/config/mavros.yaml
+ default: $(find-pkg-share blue_description)/config/ardusub/mavros.yaml
- arg:
name: manager_file
diff --git a/blue_bringup/launch/bluerov2_heavy_reach/bluerov2_heavy_reach.launch.yaml b/blue_bringup/launch/bluerov2_heavy_reach/bluerov2_heavy_reach.launch.yaml
index d4c01132..d16e459b 100644
--- a/blue_bringup/launch/bluerov2_heavy_reach/bluerov2_heavy_reach.launch.yaml
+++ b/blue_bringup/launch/bluerov2_heavy_reach/bluerov2_heavy_reach.launch.yaml
@@ -43,7 +43,7 @@ launch:
- arg:
name: mavros_file
- default: $(find-pkg-share blue_description)/config/mavros.yaml
+ default: $(find-pkg-share blue_description)/config/ardusub/mavros.yaml
- arg:
name: manager_file
diff --git a/blue_demos/control_integration/launch/bluerov2_controllers.launch.py b/blue_demos/control_integration/launch/bluerov2_controllers.launch.py
index a3f6345f..b4e6d059 100644
--- a/blue_demos/control_integration/launch/bluerov2_controllers.launch.py
+++ b/blue_demos/control_integration/launch/bluerov2_controllers.launch.py
@@ -21,12 +21,7 @@
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, RegisterEventHandler
from launch.event_handlers import OnProcessExit
-from launch.substitutions import (
- Command,
- FindExecutable,
- LaunchConfiguration,
- PathJoinSubstitution,
-)
+from launch.substitutions import PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
@@ -52,29 +47,6 @@ def generate_launch_description() -> LaunchDescription:
),
]
- robot_description_content = Command(
- [
- PathJoinSubstitution([FindExecutable(name="xacro")]),
- " ",
- PathJoinSubstitution(
- [
- FindPackageShare("blue_demos"),
- "control_integration",
- "description",
- "urdf",
- "bluerov2.config.xacro",
- ]
- ),
- " ",
- "prefix:=",
- LaunchConfiguration("prefix"),
- " ",
- "use_sim:=",
- LaunchConfiguration("use_sim"),
- ]
- )
- robot_description = {"robot_description": robot_description_content}
-
# The ISMC expects state information to be provided in the FSD frame
mobile_to_maritime_velocity_state = Node(
package="mobile_to_maritime",
@@ -95,7 +67,6 @@ def generate_launch_description() -> LaunchDescription:
executable="ros2_control_node",
output="both",
parameters=[
- robot_description,
PathJoinSubstitution(
[
FindPackageShare("blue_demos"),
@@ -105,6 +76,9 @@ def generate_launch_description() -> LaunchDescription:
]
),
],
+ remappings=[
+ ("/controller_manager/robot_description", "/robot_description"),
+ ],
)
velocity_controller_spawner = Node(
diff --git a/blue_demos/control_integration/launch/bluerov2_heavy_controllers.launch.py b/blue_demos/control_integration/launch/bluerov2_heavy_controllers.launch.py
index 9e196b7c..5e367672 100644
--- a/blue_demos/control_integration/launch/bluerov2_heavy_controllers.launch.py
+++ b/blue_demos/control_integration/launch/bluerov2_heavy_controllers.launch.py
@@ -21,12 +21,7 @@
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, RegisterEventHandler
from launch.event_handlers import OnProcessExit
-from launch.substitutions import (
- Command,
- FindExecutable,
- LaunchConfiguration,
- PathJoinSubstitution,
-)
+from launch.substitutions import PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
@@ -51,29 +46,6 @@ def generate_launch_description() -> LaunchDescription:
),
]
- robot_description_content = Command(
- [
- PathJoinSubstitution([FindExecutable(name="xacro")]),
- " ",
- PathJoinSubstitution(
- [
- FindPackageShare("blue_demos"),
- "control_integration",
- "description",
- "urdf",
- "bluerov2_heavy.config.xacro",
- ]
- ),
- " ",
- "prefix:=",
- LaunchConfiguration("prefix"),
- " ",
- "use_sim:=",
- LaunchConfiguration("use_sim"),
- ]
- )
- robot_description = {"robot_description": robot_description_content}
-
# The ISMC expects state information to be provided in the FSD frame
mobile_to_maritime_velocity_state = Node(
package="mobile_to_maritime",
@@ -94,7 +66,6 @@ def generate_launch_description() -> LaunchDescription:
executable="ros2_control_node",
output="both",
parameters=[
- robot_description,
PathJoinSubstitution(
[
FindPackageShare("blue_demos"),
@@ -104,6 +75,9 @@ def generate_launch_description() -> LaunchDescription:
]
),
],
+ remappings=[
+ ("/controller_manager/robot_description", "/robot_description"),
+ ],
)
velocity_controller_spawner = Node(
diff --git a/blue_description/package.xml b/blue_description/package.xml
index 0eca687e..e176cb73 100644
--- a/blue_description/package.xml
+++ b/blue_description/package.xml
@@ -16,6 +16,8 @@
ament_cmake
+ xacro
+
ament_cmake
diff --git a/docs/docs/tutorials/teleop.mdx b/docs/docs/tutorials/teleop.mdx
index 0171bcb4..c1519576 100644
--- a/docs/docs/tutorials/teleop.mdx
+++ b/docs/docs/tutorials/teleop.mdx
@@ -138,10 +138,12 @@ inputs, press and release the left trigger.
## USB/IP gamepad teleoperation
-This tutorial describes how to configure [USB/IP](https://www.kernel.org/doc/html/latest/usb/usbip_protocol.html)
+This tutorial describes how to configure [USB/IP](https://usbip.sourceforge.net/)
so that you can teleoperate a remote vehicle connected to a topside computer
-via a tether with a gamepad connected to your topside machine. In this
+via tether with a gamepad connected to your topside machine. In this
configuration, we recommend using a [Logitech F310 Gamepad](https://www.logitechg.com/en-us/products/gamepads/f310-gamepad.940-000110.html).
+Additional USB/IP tutorials can be found on the [RidgeRun Developer Wiki](https://developer.ridgerun.com/wiki/index.php?title=How_to_setup_and_use_USB/IP)
+and in the [Linux Magazine](https://www.linux-magazine.com/Issues/2018/208/Tutorial-USB-IP).
### Dependencies
diff --git a/docs/package-lock.json b/docs/package-lock.json
index 6af2feaa..a75032d3 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -4904,11 +4904,11 @@
}
},
"node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dependencies": {
- "fill-range": "^7.0.1"
+ "fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@@ -8266,9 +8266,9 @@
}
},
"node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dependencies": {
"to-regex-range": "^5.0.1"
},
diff --git a/sim.repos b/sim.repos
new file mode 100644
index 00000000..91c14acd
--- /dev/null
+++ b/sim.repos
@@ -0,0 +1,11 @@
+#
+# Note this is _in addition to_ blue.repos
+# (i.e. you need to vcs import both files independently)
+#
+repositories:
+
+ # ROS-Gazebo integration
+ ros_gz:
+ type: git
+ url: https://github.com/gazebosim/ros_gz
+ version: ros2