LED Cube Modeller, 22C3 Edition
Last edited on October 11, 2006
Begun on the Chaos Communication Congress 2004 I have continued to work on my LED Cube Modeller on the 22C3 a few days ago in Berlin. It is a program written in Common Lisp to create animations for a cube of LEDs, a device that I have built together with Alex Wenger at our local computer club Entropia. For more information about the piece of hardware you might look at its page in the Entropia-Wiki or read the article 3d Baby Cube in Alex's weblog.
On the 21C3: The library and a simulator in OpenGL
A year ago I've written the LED Cube Library, that contains a data structure to represent the cube and sequences of them (animations), together with functions to initialize, modify, iterate over them as well as save them to and load them from files. With it you have already a quite comfortable means to write functions that produce animations, and there is also already an additional library to let straight lines gyrate in the cube.
Of course, this is not the most intuitive way to make animations. In order to address this problem I've added a GUI that draws the cube three-dimensional on the screen: You can turn and whirl it around using the mouse (holding the right mouse button) and just click on the spheres that represent the LEDs to enable or disable them. And if you have connected the hardware device to the serial port of your computer, the corresponding LEDs will lit instantaneously. It looks like this:
Or as a moviestrip:
I think this is the right place to thank Lisa. When I've started to write the application I didn't know anything about how to code in OpenGL. Just having heard a lecture on this as part of her studies, she had just the right code examples and documentation on her computer, and she kindly let me have a look on them. I've translated the C++ programs to Common Lisp, worked through them, and was then able to write my little simulator/modeller. On the third day I have had a working version.
On the 22C3: A toolbox window using McCLIM
To add new cubes, navigate through the animation and change the brightness level (the LEDs of the cube have five brightness levels in addition to having an LED switched off) you had to use keystrokes. This makes it harder to use the application right away. There was an even worse problem: Loading and storing animation files. It's not an option to expect the user to switch to the Lisp REPL (the shell of a Lisp environment) and enter something like:
No, you expect a nice file dialog. And isn't my File Selector for McCLIM nice? :-) To address these problems my hacking project of this year's congress has been to add a second GUI element: A toolbox window like the one of the image manipulation program The Gimp. Enjoy the beauty on the right.
Now you can just click on the buttons or move the slider to navigate through the animation. And if this is too slow for you it acts as a reference sheet for the keystrokes inside the 3-D viewport (the designators in parentheses on the buttons). Of course, I have been using the graphical über-toolkit Common Lisp Interface Manager (CLIM), an abstract and quite convenient way to write applications with graphical user interfaces. If you are interested in the source code, have a look at the file toolbox.lisp.
More interesting is the section in the bottom of the toolbox window, labelled "Transformation": With this element you can perform so called transformations, which are no more than the previously mentioned functions based on the LED Cube Library that change the current animation programatically. Right now only a handful of them are defined: They do things like mirroring the whole animation, appending a mirrored copy of the current animation, or inverting the LEDs of the currently displayed cube. It's quite easy to define a transformation; the code that mirrors the animation is for example:
(define-cube-transformation mirrored-animation () (save-undo) (setf *animation* (nreverse (mapcar #'copy-cube *animation*))))
That's all. (The macro define-cube-transformation does nothing more than just define an ordinary function and push its name onto a list so that the GUI knows about it.) You might notice the call to save-undo: Well, it does the obvious. If you call other transformations or functions of the LED cube library that would save undo points for themselves, you could enclose the body of your transformation by with-disabled-save-undo. This way it will only be one click on the undo-button (or a press of the key labelled "u") for the user to revoke the effects of the whole transformation.
A binary release
It would be nice to have users that happily clicked some nice animations together, and a harsh requirement to expect them to first install and set up a whole Lisp environment together with a handful of libraries (like CL-SDL) and McCLIM. Even for an experienced Lisper this is quite some work. You want an archive that the user can download, extract and just fire up.
In a typical Common Lisp implementation it is possible to call a function with a name that's similar to save-lisp, save-image, dumplisp, or save-lisp-and-die. It will write a core image of the running application to the disk — think of it as Hibernation or Suspend To File for the Common Lisp environment: The whole state, with all defined variables, functions and macros, loaded libraries and so on, will be written to a file, and you can later restart the whole application.
This doesn't sound like a small file, and you are right: For my little application this core image has a size of about 58 Megabytes. (You can find a current version in its release directory.) But this is of course not just my application, it is a whole and complete Lisp enviroment. It contains the complete Lisp compiler, a textual debugger and shell (the REPL in Lisp terms), a graphical debugger and shell, all of McCLIM, and much more. You could connect your Emacs to it and develop whatever you want in Common Lisp. Hey, I've just loaded my blog software into the same image to preview this entry here on my notebook while I'm on the train ride back home.
Okay, you probably don't want that if you just want to make some animations for the cube. Alas, I cannot give you something smaller right now. With some commercial Lisp compilers — like for example Lispworks or Allegro Common Lisp — you could have a small executable. But this work has only started for the free Lisps like SBCL, CMUCL, OpenMCL (on the PowerPC platform), etc. There is a proof-of-concept tree shaker1) for SBCL by Juho Snellman (source code), but it is also not more than a proof-of-concept implementation. At least the rather unoptimized image of the occupied RAM can be compressed to about 17 megabytes, which means quite a good compression ratio in my opinion.
It would also be possible to deliver a compressed image and decompress
it when the program starts (using Salza, an implementation of the GZIP algorithm
Juho has tried this before
as well.2) Sadly, this would introduce at least two problems: a) the
application would need quite some time to start, and b) forget
memory-mapping, the whole 60 megabytes would get loaded to your still
valuable main memory right away. We don't want that, do we? But, hey,
in times of DSL connections with two, four, even sixteen megabit per
second. . . (I'm sorry if you have only a slow internet connection.)
(Personally, I do not think that this is a big problem. At least it has not been and is not one for me. There are more important things than a small release. You need your libc for your C programs, a Java Virtual Machine for Java applications, a Perl and a Ruby interpreter for things that are written in those languages, and, finally, you need a Lisp compiler for your Lisp programs. (By the way, yes, it is usually a compiler for a couple of decades now, not an interpreter: SBCL produces native machine code for your central processing unit, although it may not be in the native executable format of your operating system. (Execuse me my use of that ambiguous term.)))
Okay, enough words on this topic! If you are interested in the code that produces the core image for the LED Cube Modeller have a look at the file save-cube-lisp.lisp. You can find the latest release of the source code in the release directory of the LED Cube Modeller, the same place where also the binary releases can be found.
And finally: Here is a screenshot of the whole application (sans File Selector) in action:
There is also a cute animation of the viewport, that is slued via the mouse while an animation is being played at the same time: The small, 200x200 pixel Animated GIF with its 38 frames has, in spite of optimization, got a size of 457 kB, and the larger, 500x500 pixel animation an actual prohibitive weight of 2 MB.
As we are already wasting bandwidth by the dozen: Alex has captured a video of the cube (3.1 MB) with his camera. It is not a handmade animation but the LED Cube Analyzer in action, a 3-D spectrum analyzer based on sanalyzer in form of a visualization plugin for XMMS. (See also JACK-Input-Plugin für XMMS.)
I would be glad if you had a try at the program. Even more, if you sent me some animations or a comment about the whole thing!
1) A tree shaker throws away all things that are not necessary for your application, hopefully leaving only a small image or executable.
2) Update on January 11, 2006, 00:30 (UTC):
I happened to misinterpret Juho's blog entry: He has made a core image that does GZIP compression via Salza but the image itself is not compressed. Confronted with my assertion he has actually commented: "the whole concept of compressing a core strikes me as a bit silly :-)".