Archive for May, 2009

Real World Haskell: Chapter 3

Saturday, May 16th, 2009

Real World Haskell Chapter 3 is your introduction to the real syntax of Haskell programs.  It’s not entirely complete yet (you need modules and a few other things), but it’s enough to write one-purpose scripts, which is a huge step.

Again, there wasn’t all that much new to me in Chapter 3 here.  The important thing to takeaway was a review of the difference between data and type: data is struct, type is typedef (with type safety).  Other than that, the coverage of guards was nice, and the exercises were good for reinforcing knowledge and expanding horizons a little bit. Ending with the Graham scan algorithm is a little intense, but it’s significantly less evil than some of Knuth’s high-numbered problems.

However, in the exercises, be wary of number 4: there was a ++ operator introduced in the context of strings.  Don’t forget that it exists.  Number 5 is also a bit gnarly; I feel like they’ve totally screwwed the pooch on it.  If you don’t get it within 10 minutes, give up and read the comments on the website (or, if you know a bit about the performance of Lists in functional languages, just accept that your solution is O(n2)).

Wiimote: Robust IR filters on the cheap

Friday, May 15th, 2009

One thing I learned from Perceptron was that interactive art is a lot like engineering: it’s all about coping when plans fall through.  For instance, one of my goals was to have a neat IR-based camera system in the final product.  It didn’t gel by our first installation, and has kind of fallen by the wayside for Perceptron Mk II (I’ve also mostly bowed out, in favor of another project or two).  However, I’m still rather interested in IR sensing in general.  There’s just something about having cameras that can see something humans can’t that makes me smile.

The goal wasn’t to see heat, but instead to see people.  Perceptron uses a video feed to detect people and their movement.  This is then fed into something that generates video, which we wanted to project onto a wall behind the person.  Now, most people-detection algorithms use motion detection as part of their process.  If you’re projecting a moving image up, then trying to find a person moving on top of that… it’s going to get really confused.  To get around this, I wanted to use an IR camera and flood the video display surface with IR light.

Getting the IR light is easy: remote controls use IR, so there are a lot of IR LEDs on the market.  A quick email to the noisebridge mailing list (“High-output IR LEDs?“), and I had a few suggestions for IR LEDs from Mitch Altman, the guy behind TV-B-Gone.  A quick mouser order and the IR light part was done, but where to get an IR camera?

Thankfully, most cheap webcams are actually sensitive to IR!  The technology they use to collect light for an image (charge-coupled devices, CCDs) is actually pretty sensitive to everything from IR to just above the visible spectrum.  If you don’t believe me, get out a digital camera, point a remote control at it and hit some buttons.  You should see a pink-ish flash from the LED on the front on the screen of the camera: that’s IR getting into the red-sensing bit of the camera.

So, we can use cheap webcams: great!  I have four of them just lying around, and between us, we had something like a dozen of them.  But allowing IR into a camera is problematic: it blows out the reds, so they put a filter in to stop it.  On nicer webcams, you can get in and remove that filter, but on the cheapest ones, it’s basically part of the sensor itself.  Did I mention that I had four cheap webcams?  To get four, they’re going to be real cheap.  So cheap that the filter is on the sensor itself.  They still see IR, but not very well: it gets drowned out by the visible light.  Admittedly, this is what most people want, but I found it rather frustrating.  To overcome this, you can put in a visible light filter, which blocks visible light, rendering the camera nearly blind.  You can use lots of things for this: exposed 35mm film, floppy disk material, etc, but they’re all a little hacky and fragile.  I wanted a proper filter, but real filters are damned expensive (and still a bit fragile, not something you want in a project that might wind up at Burning Man).

A week after the showing, Jean emailed me a link detailing how to use the Wii controller’s IR sensor to track IR points.  It isn’t quite what we want, but it made me realize something: the Wiimote is a great source of cheap, robust IR filters.  I have a couple Wiimotes lying around at home, so I ordered a tri-wing screwdriver from DealExtreme (85¢US, shipped, par avion, from Hong Kong) and tonight, popped open my second Wiimote.  The IR filter works stunningly, and now I have a dedicated “data acquisition device” Wiimote.  3-axis accelerometer, lots of buttons, and a light-source tracker that works in visible and IR now: this thing is quite great!

(The SICKmods Wiimote disassembly tutorial has good pictures of the disassembly process.  In particular, you’ll want to be careful with the two tabs at the top of the device.  I used my vinyl pry tools, part of the kit to change an original iPod battery… As for getting accelerometer, on linux, I’m using CWiid, but will just be using wmdemo to pipe data out for now.  There’s a gotcha with building it in its current state, documented in a bug report: hci_remote_name should be hci_read_remote_name.  The change described there worked for me.)

Hack of the day: LED HSV wheel

Thursday, May 14th, 2009

I recently worked on an art project called Perceptron, an interactive dance floor (it’s cool, check it out).  The kind folks at Langton Labs hosted our build process for a while, and it was there that I met the lamp of my dreams.

It was a sphere made out of pipette covers, which are a nice milky, translucent plastic, and diffuse light wonderfully.  In the center was an array of RGB LEDs, which would cycle through colors.  There were these gorgeous blues and reds in there that you just don’t see very often: they’re probably beyond what LCD technologies can produce, so it’s a redder red and a bluer blue than you’re used to seeing.

Tonight, while killing time waiting for something, I swung by my neighborhood Radio Shack and picked up an RGB LED.  When I got home, I plugged it into my arduino and got to hacking.  I now have a one-LED version of that lamp, which makes me really happy.  It’s a gorgeous thing to behold, and involves a fun little bit of code and math.  So, of course, I’m going to share it with you.

Color-wheel arduino video

To get the color transitions to be smooth, you can’t just ramp through levels of red, green, and blue: it winds up being a bunch of peaks and valleys.  Instead, you really want to go around the HSV color wheel, changing the hue as you go.  It generates a really smooth transition, which is most pleasant.  Unfortunately, due to how crappily I’m driving the LED, it’s not as smooth as it could be: the arduino has only so much resolution in how finely it can control the level of these LEDs.  This makes for a few little jerky transitions in the blue to red return.

Here’s the code, in full:

// This assumes you're using a RadioShack #276-0028 RGB LED
// 2011-05-12: Note!  The anode is the really long pin.
// You'll need to bend it to get it into Digital8.
//
//          ||  ||  ||  ||
//          ||  ||  ||  ||
//          ||  ||  ||  ||
//          G   B   ||  ||
//                  ||  R
//                   A
//         D11 D10 D08 D09 

int common_anode = 8;
int red_pin = 9;
int blue_pin = 10;
int green_pin = 11;

int red_min = 150;
int red_max = 255;

int blue_min = 185;
int blue_max = 255;

int green_min = 195;
int green_max = 255;

void hsv_to_rgb(float h, float s, float v, unsigned char *rc, unsigned char *gc, unsigned char *bc) {
int h_i = ((int)(h/60)) % 6;

float f = (h/60) - (int)(h/60);

float r,g,b;

float p = v * (1.0 - s);
float q = v * (1.0 - f*s);
float t = (1.0 - (1.0 - f)*s);

switch(h_i) {
case 0:  r = v; g = t; b = p; break;
case 1:  r = q; g = v; b = p; break;
case 2:  r = p; g = v; b = t; break;
case 3:  r = p; g = q; b = v; break;
case 4:  r = t; g = p; b = v; break;
case 5:  r = v; g = p; b = q; break;
}

*rc = red_max - (char)((red_max - red_min)*r);
*gc = green_max - (char)((green_max - green_min)*g);
*bc = blue_max - (char)((blue_max - blue_min)*b);
}

void setup() {
pinMode(common_anode, OUTPUT);
digitalWrite(common_anode, HIGH);

pinMode(red_pin, OUTPUT);
digitalWrite(red_pin, HIGH);

pinMode(green_pin, OUTPUT);
digitalWrite(green_pin, HIGH);

pinMode(blue_pin, OUTPUT);
digitalWrite(blue_pin, HIGH);

Serial.begin(9600);
}

float h = 0.0;
float s = 1.0;
float v = 0.8;

void loop() {

unsigned char r,g,b;

h += 1;
if (h > 360.0)  h -= 360.0;

hsv_to_rgb(h,s,v, &r,&g,&b);
analogWrite(red_pin, r);
analogWrite(green_pin, g);
analogWrite(blue_pin, b);

delay(100);
}

Real World Haskell: Chapters 1 and 2

Wednesday, May 13th, 2009

Notes: not really anything noteworthy for me in these chapters.  I already speak a bit of Haskell.

Quotes:

Because the result of applying a pure function can only depend on its arguments, we can often get a strong hint of what a pure function does by simply reading its name and understanding its type signature. As an example, let’s look at not.

ghci> :type not
not :: Bool -> Bool

Even if we didn’t know the name of this function, its signature alone limits the possible valid behaviours it could have.

  • Ignore its argument, and always return either True or False.
  • Return its argument unmodified.
  • Negate its argument. 

We also know that this function can not do some things: it cannot access files; it cannot talk to the network; it cannot tell what time it is. 

Purity makes the job of understanding code easier. (emphasis mine) The behaviour of a pure function does not depend on the value of a global variable, or the contents of a database, or the state of a network connection. Pure code is inherently modular: every function is self-contained, and has a well-defined interface.

– pp39-40

As a formalist, I’m all about reasoning about type signatures for things.  When I design larger systems, I’m always looking for the type of information being passed around, then looking at how to turn one stage’s input format into the input format of the next stage.  This is partly based on my experience with functional languages, and partly based on an old programming maxim: “Show me your flowcharts and conceal your tales, and I shall continue to be mystified. Show me your tables, and I won’t usually need your flowcharts; it’ll be obvious.” (Brooks, The Mythical Man-Month, Ch9)

Takeaway:

Reading through the first two chapters of Real World Haskell reminded me just how bizarre learning OCaml was the first time around.

A new coworker recently mentioned Scala as something he enjoyed; I’ll probably give it a go soonish, to see how it fits.  I really like the feel of Haskell, and the community seems to be vibrant and growing.  About two years ago, I stopped using OCaml for anything, and started lurking around Haskell.  After a bit of prodding and coaching by my friend Evan, I mostly came to understand monads, but am still a little rough on the details.  Hopefully the process of reading through Real World Haskell will refine this, and let me knock out some interesting algorithmic code in Haskell.

What the heck does "hypomnemata" mean, anyway?

Tuesday, May 12th, 2009

Once again, I’m lowered to just quoting wikipedia for you:

Plato’s theory of anamnesis recognized the new status of writing as a device of artificial memory, and he developed the hypomnesic principles for his students to follow in the Academy. The hypomnemata constituted a material memory of things read, heard, or thought, thus offering these as an accumulated treasure for rereading and later meditation.

Wikipedia: Hypomnema

Basically, hypomnema is ancient Greek for “notes.”  Writing was relatively new, so it was kind of groundbreaking to crystallize your thoughts in a form to which you could return.  This allowed people to go from “Err, it seemed like a good idea at the time” to “We believed this to be true from the following evidences.”  Hypomnemata were thus the birthplace of the lab notebook and the primoridal stirrings of data, which is kind of incredible to think about.

In that tradition, this blog will contain my personal technical notes: reading notes, lab notes, etc.  Since it’s a collection of multiple different notebooks, I’m calling it the plural “hypomnemata” instead of “hypomnema.”