Skip to content

Migrate WGPU sonar backend from DAVE #44 - #6

Draft
yeseorizi wants to merge 36 commits into
mainfrom
port/dave-pr44-wgpu
Draft

yeseorizi wants to merge 36 commits into
mainfrom
port/dave-pr44-wgpu

Conversation

@yeseorizi

Copy link
Copy Markdown
Collaborator

Purpose and provenance

Continue the WGPU sonar work in POSIM without replacing the current main tree.

  • Original contribution and discussion: IOES-Lab/dave#44, opened by Naitik Pahwa (@naitikpahwa18).
  • Source head: ca60ba63dcdf60cb76d231255570106e43024862.
  • POSIM baseline merged into that branch: e05a9fb7d25ec21399f897e9bddfcabc4493b703.
  • All 21 commits listed by the source PR remain in the ancestry with their original SHAs and author metadata, including subsequent contributions by Woen-Sug Choi and Yeseol Gwon. Original comments and reviews remain linked in DAVE; they are not recreated under another author's name.

What is carried over

The WGPU Rust/vendor package, compute shaders, C++ backend integration, optional CUDA support, BlueView model settings, demo guides, and existing range-axis validation assets. The current code includes later changes beyond the original PR description; this migration does not claim CPU fallback or new cross-platform runtime results.

POSIM integration decisions

  • Keep POSIM's main-based workflows, ioeslab/posim image naming, repository manifests, documentation and installer fallback URL.
  • Do not reintroduce the DAVE-only PR-image publisher or Pages deployment.
  • Resolve the workflow conflicts in favor of POSIM's current policy; combine the source installer/Docker changes with POSIM branding and repository paths.
  • Result: 38 changed files against the pinned POSIM baseline. The 36 source feature files outside the two workflows, ARM64 Dockerfile and installer are byte-identical to the source PR head.

Checks and remaining work

  • Original source head and every listed source PR commit are ancestors of this branch.
  • Current POSIM baseline is an ancestor; POSIM workflows and repository manifests are unchanged.
  • git diff --check, changed Python syntax and installer Bash syntax pass.
  • Four changed package XML files parse. The unchanged BlueView SDF uses the existing gz: extension; a generic XML parser reports an unbound-prefix warning. SDF/runtime validation is still required.
  • Resolve integration with POSIM #5. A non-mutating merge preview finds an ARM64 Dockerfile conflict between the inherited ArduPilot retry block and fix: handle invalid camera frames and preserve Gazebo signal handling #5's runtime-image changes. Neither branch has been overwritten.
  • Build and validate the POSIM-integrated sonar on the intended backends; retained validation assets are historical evidence, not a new test run.

Draft / CI note: migration commits use [skip ci] to avoid automatically starting long self-hosted builds before the imported code is reviewed. Repository CI/publication settings were not changed. Before marking this ready, push a follow-up commit without the skip marker and run the required CI/runtime checks. This PR is not a merge-ready or image-publication claim.

The original DAVE PR remains open until the migration is reviewed and closure is coordinated.

naitikpahwa18 and others added 26 commits March 17, 2026 02:03
Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
Signed-off-by: Yeseol Gwon <172019512+yeseorizi@users.noreply.github.com>
Signed-off-by: Yeseol Gwon <172019512+yeseorizi@users.noreply.github.com>
Updated Docker configuration step for better clarity and error handling.
ci: fix Node 20, lint permission, and formatting annotations
Signed-off-by: Yeseol Gwon <172019512+yeseorizi@users.noreply.github.com>
Publish macOS loader paths for both sonar libraries and replace the two byte-copy cv_bridge conversions with a local ROS image copy. This avoids unnecessary OpenCV ABI coupling while preserving BGR8 and RGB8 message output.

Signed-off-by: Yeseol Gwon <172019512+yeseorizi@users.noreply.github.com>
Preserve the original wgpu_integration commits and authors, and merge POSIM main e05a9fb. Retain POSIM workflows, manifests and branding; exclude DAVE-only PR-image publishing and Pages deployment. This is a draft migration, not runtime validation. Source: IOES-Lab/dave#44
@naitikpahwa18

Copy link
Copy Markdown
Collaborator

Hi @woensug-choi, could I get write access to IOES-Lab/POSIM so I can push the conflict fixes and test results for #6? Thanks!

Rename the runtime backend selector DAVE_SONAR_COMPUTE_BACKEND to
POSIM_SONAR_COMPUTE_BACKEND in MultibeamSonarSensor.cc and the demo
launch file, and the compile definition DAVE_HAS_CUDA_BACKEND to
POSIM_HAS_CUDA_BACKEND. Update the wgpu_vendor package description.
No compatibility alias is kept for the old variable.

Tested on Ubuntu 26.04.1 / ROS 2 Lyrical / gz-sim 10.5.0, RTX 4060:
clean colcon build with and without CUDA, wgpu and cuda smoke runs,
15-minute wgpu soak (no memory growth), and range-axis and
single-scene numerics matching the DAVE reference data.

Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
Select the compute backend before creating the GpuRays sensor. If
sensor setup fails, destroy the GpuRays and reset the backend, and
return no rendering sensors. MultibeamSonarSystem now removes a sensor
that failed to initialize instead of attaching a null rendering sensor.

Previously a missing or unusable backend (e.g. cuda with no visible
device) left an unconfigured GpuRays in the scene and Ogre aborted the
whole server on the next render.

Tested on Ubuntu 26.04.1 / ROS 2 Lyrical / gz-sim 10.5.0, RTX 4060:
cuda with CUDA_VISIBLE_DEVICES='' keeps the server running and logs a
single error; wgpu, cuda and cpu still publish point clouds.

Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
WgpuComputeBackend::Initialize() returned true even when the adapter
probe failed, then silently ran every frame on an internal CPU backend
while the logs reported the WGPU backend. The CPU backend uses a
different model, so the output was wrong as well as slow, and auto
could never reach its own CPU branch.

Initialize() now returns false when no adapter is usable, letting the
factory fail an explicit wgpu request or move auto on to CPU. The
internal CPU fallback is removed; a failed GPU frame makes Compute()
return false, as the CUDA backend does.

Tested on Ubuntu 26.04.1 / ROS 2 Lyrical / gz-sim 10.5.0, RTX 4060:
with no Vulkan ICD, wgpu fails cleanly with the server running and
auto selects and reports CPU; wgpu, cuda and cpu still publish point
clouds with a working GPU.

Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
CreateComputeBackend() fell through to the CPU backend for any value it
did not recognise, so a typo in POSIM_SONAR_COMPUTE_BACKEND or
compute_backend silently produced CPU output. Unknown values now log
the valid choices and fail the sensor, leaving the server running. An
empty value is treated as auto, and auto's CPU fallback is an explicit
branch.

Tested on Ubuntu 26.04.1 / ROS 2 Lyrical / gz-sim 10.5.0, RTX 4060:
bogus fails cleanly, an empty value selects auto, and wgpu, cuda and
cpu still publish point clouds.

Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
sonar_wgpu_compute and sonar_wgpu_free dereference caller-supplied raw
pointers, so declare them unsafe extern "C" and document their safety
requirements. The exported C ABI is unchanged.

Also apply clippy's div_ceil and is_none_or suggestions, turn the file
header into a module doc comment, and run cargo fmt. cargo clippy with
-D warnings and cargo fmt --check now pass.

Tested on Ubuntu 26.04.1 / ROS 2 Lyrical / gz-sim 10.5.0, RTX 4060:
WGPU output is bit-identical to the previous build, and a missing
Vulkan adapter still fails the backend cleanly.

Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
The shared GPU context held a single set of persistent buffers. With
two sonars of different dimensions in one world, every frame from the
other sonar freed and reallocated the whole set (about 1000 times in a
30 s run). Keep a buffer set per (beams, rays, freq) instead, with a
cap of 8 sets.

Tested on Ubuntu 26.04.1 / ROS 2 Lyrical / gz-sim 10.5.0, RTX 4060:
- one sonar: WGPU and CUDA output byte-identical to the previous build
  (80/80 frames each)
- two sonars (512x300 + 256x600): WGPU output byte-identical (9/9 run
  pairs); reallocations drop from about 1000 to 3 per run. Per-frame
  time and throughput are unchanged within run-to-run noise.

Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
The WGPU backend hard-coded its backend list and the high-performance
adapter, so the standard wgpu environment variables had no effect and
the GPU could only be chosen through the Vulkan loader. On Linux the
fallback "all" attempt also tried OpenGL, whose EGL setup always panics
inside Gazebo.

- WGPU_BACKEND, if set, replaces the default backend list.
- WGPU_ADAPTER_NAME picks the first adapter whose name contains it
  (case-insensitive). If none matches, the available adapters are
  logged and initialization fails cleanly.
- WGPU_POWER_PREF is honoured; the default stays high-performance.
- Linux now tries Vulkan only. Windows and macOS are unchanged.
- Log messages no longer mention a CPU fallback that no longer exists.

Tested on Ubuntu 26.04.1 / ROS 2 Lyrical / gz-sim 10.5.0, RTX 4060 +
Intel RPL-S iGPU:
- default settings: WGPU and CUDA output byte-identical to the previous
  build (80/80 frames each); per-frame time unchanged
- WGPU_ADAPTER_NAME=Intel runs on the iGPU; output matches the NVIDIA
  run to within 1.4e-4 of the peak, with the same range accuracy
- bogus adapter name, WGPU_BACKEND=gl, or no Vulkan driver: the sensor
  is removed and the server keeps running
- cargo fmt --check and cargo clippy -D warnings pass

Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
@naitikpahwa18

Copy link
Copy Markdown
Collaborator

I tested this PR on the POSIM target (Ubuntu 26.04.1, ROS 2 Lyrical, gz-sim 10.5.0, RTX 4060 + Intel iGPU) and pushed fixes for what I found.

DAVE -> POSIM: the port didn't change the sonar output.

  • WGPU and CPU output are bit-identical to DAVE.
  • CUDA matches within its normal run-to-run noise.
  • Range accuracy (panel at 2–8 m, 0–45°) is within 1–2 range bins (2.5 cm each): WGPU about 0.03–0.05 m, CUDA about 0.03–0.06 m, the same as in DAVE.

What I changed (7 commits):

  1. Renamed the env var and compile flag to POSIM_SONAR_COMPUTE_BACKEND / POSIM_HAS_CUDA_BACKEND.
  2. A backend that fails to start (e.g. CUDA with no working CUDA) now removes only that sensor, instead of crashing Gazebo.
  3. WGPU without a GPU now reports the failure, instead of silently running on the CPU and claiming it ran on the GPU.
  4. Unknown backend names are rejected with a clear message, instead of silently using the CPU.
  5. Rust cleanup: the FFI functions are marked unsafe, and cargo fmt and clippy are clean.
  6. Multi-sonar runs: all sonars share one GPU context. With two sonars of different sizes, each frame from the other sonar threw away and rebuilt the shared GPU buffers (about 1000 times per run). Each sonar size now keeps its own buffer set, so they are built only 3 times per run.
  7. WGPU_ADAPTER_NAME / WGPU_BACKEND / WGPU_POWER_PREF now work, and Linux no longer tries OpenGL, which crashes inside Gazebo.

Numerical check:

  • Before vs after the fixes: the sonar output is exactly the same, for both WGPU and CUDA. Multi-sonar runs on WGPU are unchanged too.
  • WGPU vs CUDA: they still match.

The results are acceptable. The WGPU backend from DAVE works on POSIM and gives the same results, testing on POSIM is complete.

@woensug-choi

Copy link
Copy Markdown
Contributor

@naitikpahwa18 Thank you for confirming! The PR conflicts are probably mostly due to filename changes of removing 'dave' and replacing to 'posim'. Would you look into that too?

naitikpahwa18 and others added 3 commits October 13, 2026 06:59
Resolve dave_* -> posim_* rename and ARM64 Dockerfile conflicts.

Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>
Signed-off-by: Naitik Pahwa <naitikpahwa11@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants