Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d655441
Add vendor-agnostic wgpu compute backend
naitikpahwa18 Mar 16, 2026
bbf0a1e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 16, 2026
e812a99
add CUDA backend with runtime selection, rustfft migration
naitikpahwa18 Mar 18, 2026
4f9ad66
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 18, 2026
494b0df
Add Zero-Padding & Remove CPU Fallback
naitikpahwa18 Apr 13, 2026
e74f7f5
Merge branch 'ros2' into wgpu_integration
woensug-choi Apr 21, 2026
b15574d
Add Demo Guide to run Multi-Backend
naitikpahwa18 May 20, 2026
7402f0c
working update for macosx
woensug-choi May 22, 2026
6aef91c
debugFlag wgpu + Fix formatting
naitikpahwa18 May 25, 2026
9a08fa9
fix: preserve range axis after padded WGPU FFT
yeseorizi Sep 8, 2026
050244d
docs: record WGPU range-axis validation
yeseorizi Sep 8, 2026
12a4272
ci: fix runtime, permission, and formatting annotations
woensug-choi Sep 23, 2026
56311df
Refactor Docker connection and credentials setup
woensug-choi Sep 29, 2026
cfae083
ci: fetch pinned ArduPilot sources with bounded retries
woensug-choi Sep 29, 2026
94557df
Merge pull request #74 from IOES-Lab/ci/node24-actions-20260923
woensug-choi Sep 29, 2026
e5ee371
Merge ros2 into WGPU integration for Lyrical and Jetty
yeseorizi Sep 18, 2026
cc2fd14
Make WGPU sonar runtime portable on macOS
yeseorizi Sep 18, 2026
bb5c8ee
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 18, 2026
e388e9f
fix: resolve multibeam sonar CMake lint failures
woensug-choi Sep 23, 2026
f7def31
ci: run Docker builds for all ros2 pull requests
woensug-choi Sep 23, 2026
156e429
fix: order sonar builds and export the installed WGPU library
woensug-choi Sep 23, 2026
5487157
ci: use Ubuntu 26.04 and publish PR-number Docker images
woensug-choi Sep 23, 2026
9b39c5f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 23, 2026
ac85508
fix: make ROS bootstrap downloads deterministic in Docker builds
woensug-choi Sep 23, 2026
ca60ba6
ci: reconcile PR runners with merged Node 24 updates
woensug-choi Sep 29, 2026
909f400
Migrate DAVE PR #44 to the POSIM baseline [skip ci]
yeseorizi Sep 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions .docker/lyrical.arm64v8.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# 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.
# - The sonar uses the portable WGPU backend when CUDA is unavailable on ARM64.
# - ArduSub SITL includes the Python 3.14 compatibility shims validated on Ubuntu 26.04
# (imp/pipes modules, python-argparse removal, and PEP 668 handling).

Expand Down Expand Up @@ -96,13 +96,15 @@ EXPOSE 22/tcp

# --- ROS 2 Lyrical + Gazebo Jetty ---
ARG ROS_DISTRO="lyrical"
ARG ROS_APT_SOURCE_VERSION="1.3.0"
ENV GZ_VERSION=jetty

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 \
# Pin the bootstrap package to avoid unauthenticated GitHub API rate limits.
RUN curl --fail --show-error --location --retry 5 --retry-delay 2 \
-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 && \
Expand Down Expand Up @@ -141,9 +143,25 @@ 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" && \
git submodule update --init --recursive
# Fetch only the pinned revision before its submodules, avoiding a full-history
# clone of the default branch. Retry interrupted transfers without changing pins.
RUN set -eu; \
retry() { \
for attempt in 1 2 3; do \
if "$@"; then return 0; fi; \
if [ "$attempt" -lt 3 ]; then \
echo "Git transfer failed (attempt $attempt/3); retrying..." >&2; \
sleep "$((attempt * 5))"; \
fi; \
done; \
return 1; \
}; \
git init ardupilot; \
cd ardupilot; \
git remote add origin https://github.com/ArduPilot/ardupilot.git; \
retry git fetch --depth 1 --no-tags origin "$ARDUSUB_COMMIT"; \
git checkout --detach "$ARDUSUB_COMMIT"; \
retry git submodule update --init --recursive --depth 1

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 && \
Expand Down
6 changes: 4 additions & 2 deletions extras/ros-lyrical-gz-jetty-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ sudo apt update && sudo apt install -y jq
# 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 \
# Use a known release instead of a rate-limited unauthenticated API lookup.
ROS_APT_SOURCE_VERSION="${ROS_APT_SOURCE_VERSION:-1.3.0}"
curl --fail --show-error --location --retry 5 --retry-delay 2 \
-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
Expand Down
84 changes: 84 additions & 0 deletions gazebo/DEMO_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Multibeam Sonar Demo Guide

Build and run the GPU multibeam sonar demo. The plugin supports wgpu (Vulkan), CUDA (NVIDIA), and CPU backends—pick one at launch without recompiling.

## Setup

**Prerequisites:**
- Ubuntu 24.04
- ROS 2 Rolling
- Gazebo Jetty (gz-sim 10)
- Rust/Cargo
- Vulkan driver
- CUDA 12+ (if using the CUDA backend)

Clone and check out the branch:
```bash
git clone https://github.com/naitikpahwa18/dave.git
cd dave
git checkout wgpu_integration
```

## Build

Build in two steps on a fresh clone (the Rust library must be ready before the plugin can link to it):

```bash
source /opt/ros/rolling/setup.bash

# Step 1: build and install the Rust library
colcon build --packages-select wgpu_vendor
source install/setup.bash

# Step 2: build the plugin and everything else
colcon build --packages-select dave_demos dave_worlds dave_interfaces multibeam_sonar multibeam_sonar_system dave_multibeam_sonar_demo dave_sensor_models
source install/setup.bash
```

On subsequent builds, you can run all packages in one command.

## Run

```bash
ros2 launch dave_multibeam_sonar_demo multibeam_sonar_demo.launch.py compute_backend:=wgpu
```

Use `compute_backend:=cuda` for CUDA, `compute_backend:=cpu` for CPU, or `compute_backend:=auto` to pick the best available (tries wgpu -> cuda -> cpu).

You'll see RViz2 launch with a point cloud display. The sonar fan should update in real time. Check the terminal for initialization messages and per-frame timing.

## Troubleshooting

**`Could not find wgpu_vendorConfig.cmake`** -> You skipped Step 1. Build `wgpu_vendor` first, source install, then build the rest.

**`Another world of the same name is running`** -> Kill stale Gazebo with `pkill -9 -f gz` and try again.

**CUDA backend won't initialize** -> Run `nvidia-smi` to check if the driver is loaded. If not, reinstall or reload with `sudo modprobe nvidia`.


## How It Works

Each frame, Gazebo renders depth and surface normals. The sonar plugin reads these and runs acoustic physics on your selected backend. The wgpu backend dispatches four compute shaders: backscatter (acoustic return per ray), convert (fixed-point i32 -> f32), matmul (beam correction), and FFT (range compression). Output goes to ROS 2 topics as a point cloud and sonar image via ros_gz_bridge. The Rust library compiles to a static library linked into the C++ Gazebo plugin via C FFI.

## Data Flow

**Pipeline stages:**

1. **Input Buffers** - CPU writes depth, normal maps, reflectivity, window function, beam correction matrix
2. **backscatter.wgsl** - Computes acoustic return per ray using Lambert model, outputs to atomic accumulators
3. **convert.wgsl** - Converts fixed-point i32 results to f32
4. **matmul.wgsl** - Applies beam correction matrix to each beam
5. **fft.wgsl** - Performs in-place FFT with zero-padding to power-of-2 for range compression
6. **Readback** - CPU reads first n_freq bins from staging buffers
7. **Output** - Results published to ROS 2 as point cloud and sonar image

**Buffer details:**

| Buffer | Dimensions | Type | Usage |
|--------|-----------|------|-------|
| depth_buf, normal_buf, refl_buf | n_beams × n_rays | f32 | Input from Gazebo |
| out_re_i32, out_im_i32 | n_beams × n_freq | i32 | Atomic accumulators (zeroed each frame) |
| mm_re_in, mm_im_in | n_beams × n_freq | f32 | After convert pass |
| mm_re_out, mm_im_out | n_beams × n_freq | f32 | After beam correction |
| p_re_buf, p_im_buf | n_beams × fft_len | f32 | FFT input/output (zero-padded) |
| stg_re, stg_im | n_beams × fft_len | f32 | Staging for CPU readback |
88 changes: 88 additions & 0 deletions gazebo/DEMO_GUIDE_AppleSilicon_MacOSX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Multibeam Sonar Demo Guide
Build and run the GPU multibeam sonar demo. The plugin supports wgpu (Vulkan), and CPU backends—pick one at launch without recompiling.

![Multibeam Sonar Demo](https://github.com/user-attachments/assets/8fbe8a3f-e917-42af-a51d-c49f133da882)

## Setup

### Native Installation of ROS2 Jazzy and Gazebo Harmonic
- Follow the instructions in this guide to set up ROS2 Jazzy and Gazebo Harmonic natively on Apple Silicon: https://github.com/IOES-Lab/ROS2_Jazzy_MacOS_Native_AppleSilicon

### ROS_GZ for Mac
- Install ROS_GZ following the instructions here: https://github.com/IOES-Lab/ROS_GZ_MacOS_Native_AppleSilicon

### RUST and Cargo
- Install Rust and Cargo using the official installer: https://www.rust-lang.org/tools/install
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

### Vulkan SDK
- Install with brew:
```bash
brew install vulkan-tools
```

## Build

Build in two steps on a fresh clone (the Rust library must be ready before the plugin can link to it):

```bash
source /opt/ros/jazzy/setup.bash

# Step 1: build and install the Rust library
colcon build --packages-select wgpu_vendor
source install/setup.bash

# Step 2: build the plugin and everything else
colcon build --packages-select dave_demos dave_worlds dave_interfaces multibeam_sonar multibeam_sonar_system dave_multibeam_sonar_demo dave_sensor_models
source install/setup.bash
```

On subsequent builds, you can run all packages in one command.

## Run

```bash
ros2 launch dave_multibeam_sonar_demo multibeam_sonar_demo.launch.py compute_backend:=wgpu
```

Use `compute_backend:=cuda` for CUDA, `compute_backend:=cpu` for CPU, or `compute_backend:=auto` to pick the best available (tries wgpu -> cuda -> cpu).

You'll see RViz2 launch with a point cloud display. The sonar fan should update in real time. Check the terminal for initialization messages and per-frame timing.

## Troubleshooting

**`Could not find wgpu_vendorConfig.cmake`** -> You skipped Step 1. Build `wgpu_vendor` first, source install, then build the rest.

**`Another world of the same name is running`** -> Kill stale Gazebo with `pkill -9 -f gz` and try again.

**CUDA backend won't initialize** -> Run `nvidia-smi` to check if the driver is loaded. If not, reinstall or reload with `sudo modprobe nvidia`.


## How It Works

Each frame, Gazebo renders depth and surface normals. The sonar plugin reads these and runs acoustic physics on your selected backend. The wgpu backend dispatches four compute shaders: backscatter (acoustic return per ray), convert (fixed-point i32 -> f32), matmul (beam correction), and FFT (range compression). Output goes to ROS 2 topics as a point cloud and sonar image via ros_gz_bridge. The Rust library compiles to a static library linked into the C++ Gazebo plugin via C FFI.

## Data Flow

**Pipeline stages:**

1. **Input Buffers** - CPU writes depth, normal maps, reflectivity, window function, beam correction matrix
2. **backscatter.wgsl** - Computes acoustic return per ray using Lambert model, outputs to atomic accumulators
3. **convert.wgsl** - Converts fixed-point i32 results to f32
4. **matmul.wgsl** - Applies beam correction matrix to each beam
5. **fft.wgsl** - Performs in-place FFT with zero-padding to power-of-2 for range compression
6. **Readback** - CPU reads first n_freq bins from staging buffers
7. **Output** - Results published to ROS 2 as point cloud and sonar image

**Buffer details:**

| Buffer | Dimensions | Type | Usage |
|--------|-----------|------|-------|
| depth_buf, normal_buf, refl_buf | n_beams × n_rays | f32 | Input from Gazebo |
| out_re_i32, out_im_i32 | n_beams × n_freq | i32 | Atomic accumulators (zeroed each frame) |
| mm_re_in, mm_im_in | n_beams × n_freq | f32 | After convert pass |
| mm_re_out, mm_im_out | n_beams × n_freq | f32 | After beam correction |
| p_re_buf, p_im_buf | n_beams × fft_len | f32 | FFT input/output (zero-padded) |
| stg_re, stg_im | n_beams × fft_len | f32 | Staging for CPU readback |
Loading