Saturday, May 17, 2014

Lorenz in Living Color: Part 5 - Calculating the LED States

With the solution of the Lorenz system in place, the next task was to figure out how to define the color state for each of the 50 LEDs I'm using.  The first task: how to figure out which LED corresponds to the latest solution.

Assuming I'm projecting the 3-D solution space onto a 2-D plane (the X-Z plane in this case), I decided to divide the dual-lobed solution space radially into octants.  Based on the X and Z coordinates of the solution, I should be able to figure out which half of the attractor I'm in. Once I know that, I can pretend each lobe of the attractor is a circle and calculate the angle of the latest solution.  Using that angle, I can then determine which LED to light up. I planned on arranging the LEDs in the shape of a butterfly and with a little bit of work came up with this pattern.  (The numbers shown are the LED number.)




Each half of the butterfly shape the LEDs will be arranged in will have 23 LEDS (excluding the common center of 4 LEDs) and this angle will define which one of these LEDs corresponds to the latest solution to the Lorenz system.

But those four common LEDs that make up the body of the butterfly, those are a little tricky. They need to be considered in their own special way.  Once the solution is in this region, it could be taking a path as a part of either lobe in the attractor. Rather than try to figure out which half it is in, I decided to make a special rectangular region right down the middle.  If the solution landed in this area, I didn't decide which half it was in, I just figured out which of the four LEDs best matched the vertical position of the solution.

To keep it all straight I made a diagram.  I have referred to this often, especially as the development of this project has spanned multiple years and I've need to remind myself what all this means.  What you see below is the 3-D solution projected onto the X-Z plane along with all my annotations to remind me what was going on.


To increase the aesthetics of the project, I wanted to do more than just light up the LED corresponding to the current solution.  As I've already said, the LED was going to be colored based on the X, Y, and Z values of the solution.  But his solution would not necessarily progress smoothly from one LED to another.  To create that smooth transition, I needed to light up all the LEDs between the LED that was going to light up and the LED that was currently lit up, filling in any gaps with a gradual shift in color between the two. Looking at the butterfly pattern above, this works out neatly because most of the time, the path the solution takes is corresponds to an increase in the LED number.  If the current solution lights up LED 11 and the next solution lights up LED 15, I know that I need to also light up 12, 13, and 14.

Except for that center body portion.  If the solution is running around the left-hand lobe, it regularly needs to progress from LED 26 to LED 0.  Similarly, in the right-hand lobe from 50 to 23.  I realized the solution to this problem is that if the difference between the current LED and the next LED is negative, I'm dealing with the center section.  It took some trial and error but I figured out how to handle this special case.

To test out this portion of the code, since I didn't have the LED strands mounted in the butterfly pattern, I once again used Processing.  I had my Arduino program take a set of solutions for the Lorenz system (solved off-line in Excel) and, using the program I had just written, figure out the brightness and color for each of LEDs in the butterfly pattern.  Rather driving these LEDs directly, I had them written out and saved to a file.  Processing then used this file to create an animation simulating what I could expect the final project to look like.

Here's what that animation showed:


This is more or less what I was hoping for. The animation should proceed smoothly around either half of the butterfly and it is clear there are some glitches how the Arduino calculates all of this but it will work for a prototype.

No comments:

Post a Comment