I’ve been hacking on the software for the projector quite a bit this week- mostly on the code responsible for importing and converting vector graphics data.
In a typical laser projector, you have a high-speed DAC connecting a pair of analog servo amplifiers to a computer. The computer reads samples out of an ILDA file, maybe applies some effects in real-time, then sprays them out of the DAC. In my projector, I wanted a more sophisticated approach- mostly because of the relatively low-bandwidth Bluetooth link that exists between my projector and the PC.
My solution was to create a simple vector graphics virtual machine. The virtual machine runs on the projector’s microcontroller, in lockstep with the servo loops. It has three registers- a position register, a first-order accumulator, and a second-order accumulator. It isn’t turing-complete, but there are instructions to load these registers, wait for a number of samples to elapse, etc. It can interpolate quadratic Bézier curves in hardware. The VM also supports instructions like “jump”, and “increment counter”. This lets it support fairly complex queueing and double-buffering systems.
So far, I have code to:
- Load paths from an SVG file
- Convert those paths (lines, quadratic Bézier curves, and cubic Bézier curves) into my “VectorMachine” instructions.
- Simulate the VectorMachine, and display a visual representation of the samples that the hardware will generate.
- Queue up instructions for completed frames, using both a local and remote (in the firmware’s memory) queue. The queue has bounded latency, and it lets me flawlessly stream animated vector graphics over Bluetooth to the device.
There are some areas for improvement, like automatically optimizing the path the laser takes when it’s blanked. This could be fun- it’s actually a travelling salesman problem. I also don’t have a good way to get animation, or programatically generated graphics into it. But, it loads simple SVG files, and it does an okay job at it. It does a decent job at rendering Kirby at a blazing fast 8 FPS.
I think it’s time to take a break from this project while I figure out what to do with it next. Maybe music visualization, or Flash animations?