Skip to content

feat: WASM modules based simulation in Companion#6435

Merged
pfeerick merged 69 commits intomainfrom
wasi
Mar 20, 2026
Merged

feat: WASM modules based simulation in Companion#6435
pfeerick merged 69 commits intomainfrom
wasi

Conversation

@raphaelcoeffic
Copy link
Copy Markdown
Member

@raphaelcoeffic raphaelcoeffic commented Jul 11, 2025

This is a conversion of libsimulator plug-ins to WASM / WASI-threads.

Also included:

  • streamline simulator plug-in to depend only on threads and file system operations (no SDL dependency).
  • remove Qt fully from radio/src.
  • Companion macOS is now built with universal binaries.

@raphaelcoeffic raphaelcoeffic force-pushed the wasi branch 11 times, most recently from 1ece51b to 1a897e4 Compare July 12, 2025 10:13
@raphaelcoeffic raphaelcoeffic force-pushed the wasi branch 5 times, most recently from f7646c4 to f748394 Compare July 21, 2025 10:17
@raphaelcoeffic raphaelcoeffic added the needs: rebase A git rebase on top of the latest destination branch version is required label Jul 26, 2025
@raphaelcoeffic raphaelcoeffic force-pushed the wasi branch 9 times, most recently from f792fe0 to ae5c598 Compare August 21, 2025 18:46
@raphaelcoeffic raphaelcoeffic removed the needs: rebase A git rebase on top of the latest destination branch version is required label Aug 21, 2025
raphaelcoeffic and others added 14 commits March 19, 2026 06:49
Release m_mutex before emitting lcdChange(true) — the connected slot
onLcdChange() calls lcdFlushed() which needs to re-acquire the same
non-recursive QMutex, causing a deadlock on the main thread. This
froze the UI entirely; the most visible symptom was button blink
timers never firing so buttons stayed red permanently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The pre-built SDL2 framework has install name
@rpath/SDL2.framework/Versions/A/SDL2, so the entire .framework
directory must be copied into Contents/Frameworks — not just the
bare binary.  Detect when IMPORTED_LOCATION points inside a
.framework and copy the framework root instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace manual SDL2 bundling with CMake 3.21's
install(IMPORTED_RUNTIME_ARTIFACTS) which handles .framework dirs,
.dylib, and .dll automatically.  Bump cmake_minimum_required to 3.21.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CMake 3.21 treats missing source files as errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
install(IMPORTED_RUNTIME_ARTIFACTS) with FRAMEWORK destination
doesn't work for the imported SDL2 target. Revert macOS to the
proven get_target_property + regex + file(INSTALL) approach while
keeping IMPORTED_RUNTIME_ARTIFACTS for Windows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…l rename

Set OUTPUT_NAME on the companion target so CMake creates the bundle as
"EdgeTX Companion 3.0.app" directly, eliminating the fragile
file(RENAME) hack that caused install ordering issues with SDL2 bundling
and other post-install steps.

Also switches macOS SDL2 bundling to install(IMPORTED_RUNTIME_ARTIFACTS)
which now works correctly since install() ordering is no longer broken
by the rename.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Firmware side:
- getLuxSensorValue() reads from ADC input instead of hardcoded 1024
- simu_start_conversion() reads all ADC inputs including LUX

Companion side:
- Add AIT_LUX enum and "LUX" mapping to input type lookup table
- Recognize AIT_LUX inputs as available pots in the simulator UI
- Remove hardcoded TX16S MK3 "LIGHT" fallback, use JSON-defined LUX
  input with default "Ambient light" label

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…M simulator

The WASM simulator interface was missing backlight state reporting (always
hardcoded to true) and function switch RGB LED color updates. This caused
three issues: LCD backlight ON/OFF not working for mono/gray radios, OLED
displays showing white text on light background instead of black, and
customisable switch RGB colours not updating on TX15/GX12.

Add simuGetBacklightState, simuGetNumFuncSwitches, simuGetFSLedColor, and
simuGetFSSwitchIndex WASM exports, and wire them into the Companion WASM
interface. Also fix build-wasm-modules.sh to not nuke the entire build/
directory on each run.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
raphaelcoeffic and others added 2 commits March 19, 2026 07:00
The capability check ran during the constructor before the WASM module
was loaded, so getCapability always returned 0 and the button stayed
disabled. Defer the check to the started() signal when the module is
ready.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix v4 SimulatorOptions deserializer reading flags into simulatorId
- Always use profile's fwType() and sdPath() as authoritative source
  instead of stale copies in stored simulatorOptions
- Fix simulator dropdown empty: resolve simulatorId through
  SimulatorLoader::findSimulatorByName() to match registered names
  (WASM modules register without "edgetx-" prefix)
- Fix data file dialog using getSaveFileName instead of getOpenFileName
- Copy WASM modules to both companion and simulator app bundles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@pfeerick
Copy link
Copy Markdown
Member

Ah nice, I was just in the process of fixing the changed simulator naming issue when I realised you'd pushed the changes. Initial look on windows looks good... I'll give it a proper look in the morning and hopefully merge.

@pfeerick
Copy link
Copy Markdown
Member

Right, so repeat testing on Windows, Linux and MacOS(!!) everything seems to be generally working. I may need your help in re-building windows build environment as with the changes to wasm it is completely broken now, but I'll see how that goes.

There does seem to be one universal regression - volume for sound is a lot lower than it used to be... perhaps half the prior volume or one-third. Not worth holding this up, at least everything seems to be back to how it should be! :)

@pfeerick pfeerick merged commit 04a2231 into main Mar 20, 2026
49 checks passed
@pfeerick pfeerick deleted the wasi branch March 20, 2026 02:19
@philmoz
Copy link
Copy Markdown
Collaborator

philmoz commented Mar 20, 2026

How do I build simulator libraries on MacOS with this????

My build setup is now completely broken stopping any work I was doing on EdgeTX.

@raphaelcoeffic
Copy link
Copy Markdown
Member Author

raphaelcoeffic commented Mar 20, 2026

How do I build simulator libraries on MacOS with this????

My build setup is now completely broken stopping any work I was doing on EdgeTX.

I use this:

FLAVOR="tx16s;t12max" ./tools/build-wasm-modules.sh

You could also use the usual:

# Configure "super build"
cmake -S . -B build -DPCB=X10 -DPCBREV=TX16S -DENABLE_WASM=yes
# Compile WASM module
cmake --build build --target wasi-module

As usual, the plugins need to be copied into the Companion / Simulator app:

cp output/*.wasm "build/companion/simulator.app/Contents/MacOS/"
cp output/*.wasm "build/companion/EdgeTX Companion 3.0.app/Contents/MacOS/"

@pfeerick pfeerick mentioned this pull request Mar 23, 2026
@wimalopaan
Copy link
Copy Markdown
Contributor

Looks like the serial ports aren't working anymore???

raphaelcoeffic added a commit that referenced this pull request Apr 11, 2026
PR #6435 ported the simulator plug-ins to WASM but did not bridge the
aux serial ports across the WASM boundary, leaving AUX1/AUX2 backed by
a no-op driver. Lua serialWrite() and any other code touching the aux
serials was silently dropped, breaking host serial integration in
Companion's simulator (#7283).

Add a host bridge driver in simulib.cpp that forwards TX through new
WASM imports (simuAuxSerialStart/Stop/SetBaudrate/SendBuffer) and serves
RX from per-port mutex-protected queues, populated by a new
simuAuxSerialReceive export. On the Companion side, register native
callbacks that re-emit the existing SimulatorInterface aux serial
signals so HostSerialConnector (already wired up in
SimulatorMainWindow) drives the real host port, and implement
WasmSimulatorInterface::receiveAuxSerialData() to push host bytes back
into the firmware.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
raphaelcoeffic added a commit that referenced this pull request Apr 11, 2026
PR #6435 ported the simulator plug-ins to WASM but did not bridge the
aux serial ports across the WASM boundary, leaving AUX1/AUX2 backed by
a no-op driver. Lua serialWrite() and any other code touching the aux
serials was silently dropped, breaking host serial integration in
Companion's simulator (#7283).

Add a host bridge driver in simulib.cpp that forwards TX through new
WASM imports (simuAuxSerialStart/Stop/SetBaudrate/SendBuffer) and serves
RX from per-port mutex-protected queues, populated by a new
simuAuxSerialReceive export. On the Companion side, register native
callbacks that re-emit the existing SimulatorInterface aux serial
signals so HostSerialConnector (already wired up in
SimulatorMainWindow) drives the real host port, and implement
WasmSimulatorInterface::receiveAuxSerialData() to push host bytes back
into the firmware.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

companion Related to the companion software simulator

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants