-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Comments
New SITL "TARGET": Webassembly (Experimental)#11282
New SITL "TARGET": Webassembly (Experimental) #11282Scavanger wants to merge 12 commits intoiNavFlight:maintenance-10.x from
Conversation
Merge 9.x to master
...into Webassembly
For my wasm build that runs in a browser / PWA, I used two different options to avoid a proxy.
Option 1:
MSP can be handled by just exporting Module.mspProcessCommand()
That's about 50X faster than messing with sockets on both ends.
Option 2:
The other technique I did was I added a small web socket function to SITL. No need to make Configurator speak raw TCP. SITL can easily strip off the web socket header, then pass the data as per a raw socket.
Scavanger
commented
Jan 24, 2026
Option 1: MSP can be handled by just exporting Module.mspProcessCommand() That's about 50X faster than messing with sockets on both ends.
Good idea, but it's not that simple, because the INAV main loop runs in a separate thread (web worker) and has to be synchronised, hence the queue and encapsulation in ‘serial_ex’ and only the configurator would have access to it.
Option 2: The other technique I did was I added a small web socket function to SITL. No need to make Configurator speak raw TCP. SITL can easily strip off the web socket header, then pass the data as per a raw socket.
The problem: You need a Websocket server and a client. Both the configurator and the SITL run in the browser, but a Websocket server in the browser is not possible.
And you had to rewrite the entire code for the simulators (X-Plane, Realflight), and the X-Plane plugin needs to be adapted.
I might be misreading your comment.
It almost sounds like you're saying why it's impossible for me to write and use the code that I already wrote and already use?
Scavanger
commented
Jan 24, 2026
Just show me :).
The approaches you described didn't work for me.
The simulators are native code, they can't run in the browser. No matter what anyone does with SITL, native code is absolutely required to run the sim. I don't see any big benefit of running SITL slowly in the browser while running a sim. So IMHO they aren't really relevant here.
Configurator can run in the browser, so for me, that's the use case for SITL in the browser. To run with Configurator. Which has been working for well for about six weeks.
Running SITL in the browser with a native code proxy for web sockets, with a native code sim, gets you 50X slower communication and what else?
On other words:
Option 1
sim.exe
SITL_proxy.exe
browser
Option 2
sim.exe
SITL.exe
What's the benefit to adding a browser on top of the native code? If you're going to run SITL_proxy.exe, why not run SITL.exe instead and skip the whole browser and web sockets and all of that entirely?
Scavanger
commented
Jan 24, 2026
Yes, you're right, the simulator interface is a nice gimmick, but more of an academic one.
I've built the corresponding proxy server into a test version of the INAV X-Plane plugin: it works really well, so there's no need for an extra programm here.
sensei-hacker
commented
Jan 24, 2026
Fyi I'm working on organizing my work into something I can actually show to someone else.
For comparison, here is the implementation I had done:
#11314
Scavanger's implentation is probably better overall
I put mine up mostly for comparison and there are a couple of things in the PR #11314 implementation that might be added to this PR.
Scavanger's handling of PGs looks significantly better (though I haven't actually tested his to see that it works). Also the pthread support may be better (I used ASYNCIFY).
The serial communication in my implementation is "interrupt driven", while this PR uses polling.
#11314 is more similar to how hardware is handled - the hardware triggers an interrupt when data is available. In my wasm implementation, that interrupt is of course triggered by software, but otherwise works the same as an interrupt coming from any FC.
The approach to rebooting used in this PR didn't work for me when I had tried it, so I used a different method for reboot.
Lastly, I added -gsource-map to wasm.cmake so that you can debug in the wasm code in the browser. This is very helpful for debugging and has no runtime cost. Any segfaults are just shown with a stack trace, you can put breakpoints, etc.
A couple observations / questions about this implementation:
-
Possible race condition in message serial queue? It uses volatile, is that safe with pthread? Or does it need a mutex?
-
Buffer size mismatch (inav_WASM.html:649)
- JavaScript allocates 64 bytes for the seriual buffer: Module._malloc(64)
- C defines 256 bytes: #define SERIAL_EX_MAX_MSG_SIZE 256
Is this intended?
- Updated C and C++ standards in .vscode/c_cpp_properties.json to C23 and C++23. - Introduced fix_wasm_build_files.cmake to consolidate WASM filename updates for both JS and HTML files. - Removed outdated fix_wasm_filename.cmake and fix_wasm_html.cmake scripts. - Enhanced wasm.cmake with new Emscripten linkage options for better modularization and environment support. - Modified serial_ex.c and serial_ex.h to implement a thread-safe message queue for inter-thread communication between C and JavaScript. - Updated target.c to improve socket proxy connection handling and added network function disable option.
Scavanger
commented
Feb 8, 2026
- Possible race condition in message serial queue? It uses volatile, is that safe with pthread? Or does it need a mutex?
The messagePendingPort operation is "atomic like", so no race conditions here. I used it a lot while debugging and works like a charme.
- Buffer size mismatch (inav_WASM.html:649)
- JavaScript allocates 64 bytes for the seriual buffer: Module._malloc(64)
- C defines 256 bytes: #define SERIAL_EX_MAX_MSG_SIZE 256
Is this intended?
No, inav_WASM.html is not actual, should be updared :)
Uh oh!
There was an error while loading. Please reload this page.
Yes, INAV in the Browser!
Intended to use with INAV-Configurator Web (PWA) iNavFlight/inav-configurator#2448
It works, inkl. TCP "UARTS" and Simulators, but due to limitations of the browser envoronment/emscripten some workarounds are mandatory:
Only a WebSocket client can run in the browser (no TCP/UDP), so a ‘serial_ex’ interface has been implemented for UART1. Emulates a serial connection via simple function calls.
Other UARTS and simulator interfaces require a locally running proxy that converts the WebSocket into a ‘real’ TCP/UDP socket.
I will integrate a proxy server into the X-Plane XITL plugin so that at least for X-Plane, the whole thing should be easy to use.
-A few more tricks and pull-ups are necessary (e.g. Config) because the emscripten API does not provide all the functions we need.
I'm marking the whole thing as experimental, as the communication Webassembly -> Proxy -> Application is a bit ‘backwards’ and runs a bit shakily.
The alternative would be to rewrite the entire network code (UART and Sims) and switch completely to Websockets, but it's probably not worth it.