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.
There are several people who have built such a device before; for
example James Clar, who has as well
built a 5x5x5 cube and some larger ones that are documented on his homepage.
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:
(save-animation-file
#p"/home/mgr/stuff/cube-modeller/data/my-animation.data")
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.
Transformations
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
in Lisp). 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.
Eye candy
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!
Footnotes
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 :-)".