Bare bones JS port of OSQP

TL;DR: I put a bare bones JS port on Github and NPM.

Hi everyone and happy holidays,

First, I’d like to thank the creators of OSQP for such a nice-to-use, fast, and portable library.

I have lately been working on facial motion capture on the web and I needed a solver to solve the least squares problem to get the animation weights that move the 3D character using facial landmarks as input. These animation weights (known as morphtargets or blendshapes) say for example how much the character’s left eye is closed, right eye is closed, jaw is open, mouth smiling to the left, etc…

By the way, the very first thing I tried was using the pseudo-inverse but doing so yields nonsensical weights (like large negative numbers) and for the animations to look plausible the weights must be between 0 and 1.

The constraints led me to eventually finding this library and was pleasantly surprised to find how easy it was to use. What was even more pleasantly surprising was just how simple and portable the C code was and how little effort it took me to compile it to Webassembly using Emscripten. After that, I wrote a little wrapper in JS that hides the Webassembly stuff and then my mocap code just calls it and ta-da it works.

When I was first exploring this option to doing it on the web, I was quite apprehensive about how performance intensive this would be, especially given I am already running an expensive facial landmark neural network and my total budget cannot exceed 16ms per frame.

Turns out that the solver only takes around 0.3-0.4ms to run. Which is super cool given that basically every frame I update the q variable and then call solve. The only caveat is I do need to so some data prep to go from the input landmarks to the q variable, so really the total time is currently closer to 2ms although I have yet to sit down and optimize that data prep code (I just got it to work).

In any case, to thank you for the library, I took the liberty to putting the OSQP Javascript wrapper on Github and publishing it onto NPM under the same Apache 2.0 License of the original code. The wrapper is not well-tested and does not expose all of the functionality. It also just works on the Browser, I haven’t really tried using it on NodeJS. The code was written in Typescript and there are type annotations but I have not included any documentation.

I tried to follow the structure of the other interfaces, but could definitely be improved. There’s a setup static method which doubles as a constructor, there’s an update method (currently only supports updating q, l, and u) ,and there’s solve method. Finally, there’s a cleanup method because Javascript doesn’t have a way to automatically tell the C code to free memory when the solver gets garbage collected. It’s a bit annoying but you have to call cleanup manually when you’re done.

Please let me know what you think and where you’d want it to go from here. That I know of, I haven’t seen any JS versions of OSQP otherwise I would’ve used it. Given it is so lightweight and can comfortably run in real-time, I think this library is a great fit for the web.