Three weeks ago already I participated in the Mediamatic Social RFID Hackers Camp at Picnic 08 in Amsterdam. At Hackers Camp, in about five days time, an excellent group of designers, tinkerers, builders and hackers built eight Social RFID installations to be enjoyed by the Picnic’ers.
Together with Erik Borra, Eelco Wagenaar, Martijn Pannevis and Adriaan Wormgoor I built Vbird. Vbird is a flightless bird, equipped with a wireless camera and Arduino BT powered RFID reader and accelerometer. Since Vbird can’t fly, you have to throw it to each other to make it fly! It continuously records video, and if you let it scan your Picnic RFID tag, the next video will be uploaded to your profile. In all, pretty awesome. You can see some videos here: http://www.justlol.net/vbird/.
Unfortunately Vbird did not last very long. Every piece of hardware inside the bird that could fail, failed. It worked briefly at the end of Wednesday, the first Picnic conference day. It consistently broke down on Thursday, at the end of which day we finally gave up. No more Vbird.
I primarily worked on making Vbird interface with anyMeta, the community management system created by Mediamatic Lab and used to drive the Picnic website. This involved setting up the video processing infrastructure with Martijn and some help from Robin Gareus. The video processing ran on a MacBook Pro – converted to a Ubuntu machine – hooked up to a analogue to MPEG video converter. (We had it working on an EEE PC, and figured it’d be faster to install Ubuntu on the MacBook than figuring out how to do the video processing on OS X.) We used ffserver to set up a Flash video stream we could display live, and used ffmpeg to make video segments encoded in Flash video. This then was controlled using OSC messages from a second MacBook Pro, which did the main anyMeta interactions, handled Arduino communication, and drove the UI.
The second MacBook Pro did all this using Physical.js, which is an open source library, by yours truly, for doing physical computing in JavaScript. It runs inside Rhino, which is a JavaScript-interpreter written in Java. The big advantage of Rhino is that you can use the Java libraries, and still write lovely JavaScript.
Physical.js builds upon Dojo, which makes it easy to separate the code into modules, has a fantastic event system, and even a Twisted-like Deferred implementation. Now, Dojo hasn’t really focused on its Rhino support, but that’s something I hope to change going forward, by contributing code from Physical.js back to Dojo.
In any case, Dojo’s event system leads to some interesting “Action Oriented” code. For example, the code reading the output from the Arduino BT is encapsulated in a ArduinoReader class:
dojo.require('picnic.ArduinoReader');
reader = new picnic.ArduinoReader('/dev/tty.Arduino_bt121-Bluetooth-1');
Then, we simply hook up a few events:
reader.onOpenComplete = function() {
// …
};
reader.onOpenError = function(e) {
// …
};
reader.onAcceleration = function() {
// …
};
reader.onDeceleration = function() {
// …
};
reader.onTagEnter = function(evt) {
// …
};
(Admittedly, perhaps I should have used dojo.connect() instead of directly overwriting the event callbacks, but hey.)
From a programming perspective, it’s quite awesome that you can simplify the input stream to a few events, to which you can hook up other actions. Having such a framework available, and being able to clearly express the actions, helped a lot in creating Vbird.
And, when the onboard RFID reader died, it was easy to hook up a physically connected RFID reader:
dojo.require('picnic.OSCReader');
reader2 = new picnic.OSCReader(7007);
dojo.connect(reader2, 'onTagEnter', reader, 'onTagEnter');
Here picnic.OSCReader implements the ph.rfid.Reader interface, just like picnic.ArduinoReader. It receives OSC messages from the Tikitag reader we used, through the RFID-to-OSC gateway written by Mediamatic. (Ironically, we had no Java software available for the Tikitag reader.) It’s simply a matter of connecting the two onTagEnter handlers to use a second RFID input with the original code.
Another incredibly useful thing was automatically generating an API for anyMeta. A slightly older version of the code I used can be seen in the Flickr API implementation in Physical.js. It uses dojo.getObject() and the __noSuchMethod__ method to dynamically set up an API. In the Flickr API example, there’s an API declaration for people, which lets you use all people.* methods, without explicitly declaring them.
anyMeta uses OAuth to control access to API methods. The API implementation I wrote – and which has yet to be ported to Physical.js – automatically signs API calls before sending them to the server. This, then, lets us do:
dojo.require('picnic.anyMeta.anyMeta');
api = new picnic.anyMeta.anyMeta(OAUTH, ANYMETA_ENDPOINT);
profile = api.picnic.persons.get({rfid: 'urn:rfid:1AA037EF'});
Which gives us the profile corresponding to a specific RFID tag.
The API code takes care of serializing to and from JSON, as well, which made it incredibly easy to interact with anyMeta.
The UI Adriaan built for Vbird was a small Flash movie, served and updated straight from the Physical.js code. See, the Jetty web server is included in Physical.js, making it easy to serve-up static files, and register handlers for specific URLs:
dojo.require('jetty.Server');
server = new jetty.Server(8080, jettyResources);
server.register('/stream/latest.js', function(request, response) {
response.type = 'text/javascript';
response.body = dojo.toJson({
latest: 'Latest data here…'
});
});
server.start();
This then is a far more elegant solution than writing data to a file, accessed via a separate web server. Breathlyzer, created by Matt Cottam and Jasper Speicher of Tellart also used Physical.js for this purpose.
In all, using Physical.js at Picnic was great fun, and it’s definitely cool to use JavaScript for something completely different than web programming. Let me know what you think of Vbird and Physical.js!



holy cow, that’s freaking awesome!
If you cc me on patches you file at bugs.dojotoolkit.org against the Rhino support, I’ll be happy to review/commit. I’d love to see stronger Rhino packages for 1.3.
Regard
Certainly!