March 5, 2025

Most of today was focused on the aerialometer project, specifically to be able to visualize the rotation data using the window position from a phone. I had to do a lot to make this work!

A few things. I wanted to be able to deploy my app so that others could use the visualization data. I had a basic app already deployed to vercel, but since my app is now a monorepo with two apps (the controller, which collects data, and the display app, which displays data once the peer server is working), I needed to set up the deployments as two separate vercel projects.

A pretty key part of this set up is that the display app shows a QR code which embeds a URL to the controller app (along with a query parameter for the display app’s peer id). But, the URL for the controller app is different depending on whether the app is running locally or in the cloud, and depending on what network it’s running on. It uses the ssl setting from vite to be able to deploy locally to an https address, which is required to be able to collect the device data from the browser. So, I needed to write some code that allows storing that local address so the display app can look it up. In production, the display app just looks this up via an env var that’s set in the vercel project settings.

Once that was working, I wanted to figure out how to use the rotation data from the device to rotate the torus on the screen. This was not too tricky at first because I already had some working code to update the torus using useFrame() from the React Three Fiber framework. My first attempt used the DeviceOrientationEvent from the browser. This was a pretty straightforward way to display the rotation, because the data is more absolute. This meant no math was required to display the rotation (aside from converting the position in degrees to radians).

Ultimately, though, I’d like to be able to build these visualizations using data from an embedded device, not “just” a phone, and this device orientation data is not available. Instead, the device more likely uses a rotation rate which measures change in rotation rather than a more absolute value. That data is available from the mobile browser, too, using the DeviceMotionEvent. It just requires some math to get it working. In the end, the code I have stores a current rotation (starting at 0,0,0) and updates the rotation by applying the delta time from useFrame and the new rotation rate reading. FWIW, this article was really helpful for understanding the difference between the two device readings, and some AI help was helpful in understanding how to code up the math.

I’m pretty happy with where I ended up as a stopping point for today. The app is deployed successfully at aerial3d.vercel.app and has some hidden parameters for being able to switch between displaying rotation by reading the orientation or the rotation rate. It also has a hidden parameter for displaying the torus’s position, but that needs a bit more work.

Up next, I think I want to go back to visualizing the data from the hardware device and see how well this new approach translates. That should be interesting.