Monthly Archive for February, 2009

DizzyCat Proposal

DizzyCat is a toy designed to make my cat active again, as she is getting fatter every day and needs to exercise. I unfortunately cannot play with her on a daily basis since moving to New York, and since she is alone for the most part of the day, she spends all her time eating and sleeping.

DizzyCat is a little toy on wheels that has four basic behaviours:

  • If the cat is not moving, it slowly creeps towards her.
  • If the cat is moving towards the toy, it moves away from her.
  • If the cat is moving away from the toy, ¬†it moves towards her.
  • If the toy bumps into something, it moves in the opposite direction.

The idea is to make an autonomous toy that will keep her entertained for hours. As any cat owner will tell you, it is very difficult to find a good toy because cats expect whatever they are playing with to react to them, either by fighting back or running away. A weight at the end of a string just does not cut it because it quickly becomes boring, even for an animal. Any good cat toy needs to be interactive; it needs to taunt the cat to play with it and offer it some sort of challenge.

Special attention will be brought in the design to make DizzyCat as quiet as possible, as I have noticed that my cat tends to stay away from noisy things. It should also be built strong as it will probably be thrown around a lot, but should feel soft like a small, helpless animal.

The body of the toy will be made out of blue foam, because it is a very light and fairly solid material. This will be covered with a furry or feathery material so that it feels good to the bite. The moving mechanism will consist of a battery-powered DC motor attached to the wheels, using a system of gears to achieve appropriate speed and torque. The behaviours will be achieved by simply turning the motor in either direction using an H-bridge. Proximity between the cat and DizzyCat will be measured using XBee modules. One XBee will be placed on DizzyCat, and the other will be attached to a custom cat collar. An Arduino board will take care of the logic, polling the distance between the XBees, judging if both objects are getting closer or futher away from each other, and choosing a direction and speed to spin the motor based on this information.

View the PDF

flora Vine Tests

The following two sketches are vine tests for the flora project. The final design will probably have to incorporate elements from both these applets.

This first sketch is a curve fitting example. It draws a path following the mouse movements, adding a point whenever the mouse moves far enough in a direction different enough from the previous point.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
ArrayList pts;
PVector lastPt, beforeLastPt;
int distThreshold = 50;
float slopeThreshold = 0.5;
 
void setup() {
  size(400, 400);
  smooth();
 
  pts = new ArrayList();
  lastPt = new PVector();
  beforeLastPt = new PVector();
}
 
void draw() {
  // clear the screen
  background(255);
 
  // draw a path through all key points
  beginShape();
  for (int i=0; i < pts.size(); i++) {
    PVector currPt = (PVector)pts.get(i);
    // draw the key point
    noStroke();
    fill(0);
    ellipse(currPt.x, currPt.y, 5, 5);
    // add the vertex to the path
    noFill();
    stroke(255, 0, 0);
    curveVertex(currPt.x, currPt.y);
  }
  endShape();
 
}
 
void mouseDragged() {
  // if the new point is far enough from the last key point...
  if (dist(mouseX, mouseY, lastPt.x, lastPt.y) > distThreshold) {
    // ...and there are less than 2 key points total
    // OR
    // ...the slope between the new point and the last key point is
    //    different enough from the slope between the last 2 key points...
    if (pts.size() < 2 ||
        abs(slope(mouseX, mouseY, lastPt.x, lastPt.y) - slope(lastPt.x, lastPt.y, beforeLastPt.x, beforeLastPt.y)) > slopeThreshold) {
      // ...add a new key point
      beforeLastPt = lastPt;
      lastPt = new PVector(mouseX, mouseY);
      pts.add(lastPt);
    }
  }
}
 
float slope(float x1, float y1, float x2, float y2) {
  if (x2-x1 == 0) return 0;  // avoid division by 0!
  return (y2-y1)/(x2-x1);
}
 
void keyPressed() {
  if (key == ' ') {
    // reset all the key points
    pts.clear();
    lastPt = new PVector();
    beforeLastPt = new PVector();
  }
}

This second sketch draws a vine using circles on a bezier path. These have varying diameters which results in a tapering effect. It also adds leaves at regular intervals on the curve.

taperedBranch 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
int ax1 = 385;
int ay1 = 20;
int cx1 = 10;
int cy1 = 10;
 
int ax2 = 15;
int ay2 = 380;
int cx2 = 390;
int cy2 = 390;
 
void setup() {
  size(400, 400);
  smooth();
}
 
void draw() {
  background(255);
 
  ax1 = mouseX;
  ay1 = mouseY;
 
  noFill();
  stroke(128);
  bezier(ax1, ay1, cx1, cy1, cx2, cy2, ax2, ay2);
  stroke(128, 0, 0);
  //line(ax1, ay1, cx1, cy1);
  //line(cx2, cy2, ax2, ay2);
 
  noStroke();
  int steps = 300;
  int leafSteps = 6;
  boolean leafDir = true;
  float px = 0;
  float py = 0;
  for (int i = 0; i <= steps; i++) {
    float t = i / float(steps);
    float x = bezierPoint(ax1, cx1, cx2, ax2, t);
    float y = bezierPoint(ay1, cy1, cy2, ay2, t);
    float s = sin(i*PI/(steps*2))*10;
    fill(#743632);
    noStroke();
    ellipse(x, y, s, s);
 
    if (i%leafSteps == 1) {
      float a = atan2(y - py, x - px);
      leaf(x, y, leafDir? a+PI*3/4 : a+PI*1/4, leafDir? s*3 : -s*3);
      leafDir = !leafDir;
    }
 
    px = x;
    py = y;
  }
}
 
void leaf(float x, float y, float r, float s) {
  stroke(#07903D);
  fill(#1AEA11);
 
  pushMatrix();
    translate(x, y);
    rotate(r);
    beginShape();
      curveVertex(0, 0);
      curveVertex(0, 0);
      curveVertex(s/2, -s/4);
      curveVertex(s, 0);
      curveVertex(s, 0);
      curveVertex(s/2, s/4);
      curveVertex(0, 0);
      curveVertex(0, 0);
    endShape();
    line(s/4, 0, s*3/4, 0);
  popMatrix();
}

Zoetrope Early Tests

After presenting my zoetrope toy idea to class last Tuesday, I realized that I had completely forgot to add a lens to the design. A lens would be necessary for the projection, so that the image on the wall is bigger than 2″ wide. I ran some quick tests today to see what sort of setup is possible.

I had many lenses to try: an acrylic half-sphere from Canal Plastics and a bunch of lenses Matt pulled off a projector. 

IMG_1546 IMG_1553 

I made a tube out of sheet metal and placed a piece of acetate with a drawing on it between two pieces of acrylic at one end. I attached a super-bright LED to the end of a wooden stick, which I put in the tube from the other end. Using the stick, I could move the light back and forth to see what  distance would work best. 

IMG_1551 IMG_1552 IMG_1548 IMG_1547 

Only one lens worked properly, but my whole setup was a bit too loose to calculate any distances. I’ll have to build a second prototype where the lens, drawing, and light are all mobile to get more concrete results.

 IMG_1535

Interview on Ça manque à ma culture

Hugues (aka smallfly) and I did an interview last Monday for an online show on Télé-Québec called Ça manque à ma culture. I’m impressed at how well it turned out considering that we were mumbling and going off on tangents for the entire duration of the interview.

Watch it here.

Dick Johnson at Nuit Blanche next Saturday

Next Saturday (Feb 28) is Nuit Blanche in Montreal, and Spasm will be part of the party, playing shorts all night. It kicks off at 9PM with Trailer, a compilation of fake movie trailers featuring my very own Dick Johnson: No Strings Attached. So check it out!

Doors: 8PM / Movies: 9PM
Caf?© Cl?©op?¢tre /¬†1230 St-Laurent
FREE

Mousetrap Race Car

Here is the mousetrap race car I built with Karla. The frame is built out of LEGOs, the back wheels are an electric wire spindle cut in two, and we used a rubber band connected to the mouse trap as the engine.

IMG_1529 IMG_1531 IMG_1532 IMG_1530 

It goes pretty fast, but we over-wound the rubber band for the official race and came out in 3rd place.

flora Technical Document

Software
We are aiming to code the front-end of the piece (graphics and animation) in Processing/Java and the back-end (blob detection and tracking) in openFrameworks/OpenCV, and have both components communicate with each other using the OSC protocol. The information to be transmitted will be very minimal: a list of blob IDs and xy-coordinates. If Processing turns out to be too slow, we will convert the front-end to openFrameworks/OpenGL code and have both components running in the same application.

Computer Graphics
The growth algorithm will consist of a central vine which follows the path drawn by the fingers. The direction of the growth is determined by generating a path following a finger as it travels on the surface. In order to keep the path as smooth as possible, the following algorithm is used to register the least amount of control points, using threshold values for the distance and slope between the last few points.

IF (the new point is far enough from the last key point) {
    IF (there are less than 2 key points total) {
        add a new key point at the end of the list;
    }
    ELSE IF (the slope between the new point and the last key point is
             different enough from the slope between the last 2 key points) {
        add a new key point at the end of the list;
    }
}

The leafs/flowers particles will be created in an external graphics program, and imported as SVG graphics into flora. These will be placed along the central vine, rotated and scaled depending on their position in the overall plant. The particle animations will be computed automatically based on keyframes for the birth, alive, and dead states. Pre-rendered animations cannot be used because of the initial growth and nurturing features, which require being able to stop at any intermediate state between the birth, alive, and dead states. The keyframes will consist of positions for a fixed number of control points which determine the shape of the particle. Each control point will have a birth, alive, and dead position, and will tween from its current position to one of these targets depending on the triggered animation.

Surface
We will use a single horizontal surface as the touch interface and the display, which will be cut to custom shape as represented in the design document. This surface will consist of a sheet of acrylic covered with a thin film such as vellum or mylar. The purpose of the film is twofold:
• It will make the surface more pleasant to touch and will allow the fingers to move smoothly across it.
• It will act as a diffuser for the IR light if we end up using the Diffused Illumination technique for touch detection (see Sensing Device section).

Display Device
The application will be projected on the touch/display surface using a projector. Depending on the setup used (see Sensing Device section), the image will either be front-projected or rear-projected.

Sensing Device
Touch detection can be achieved using one of the two following options.
The first is to build a touch interface following the Diffused Illumination technique. This works by shining infrared light using IR emitters below the screen, which is covered by a diffuser such as vellum or mylar. When the finger touches the surface, it reflects more light than the diffuser, and can therefore be detected by the camera. The camera and projector used to display the software are both also placed below the screen. The advantage of using this technique is that we can accurately detect points of contact on the touch surface, and that we do not have to worry about shadows covering the projected image. The disadvantage is that the table needs to be built, and this will cost time and money.

The second option is to use the pre-existing setup at ITP. Because the projector and camera are on top of the surface, the user’s entire arm will be tracked and not just the point of contact with the screen. One solution to this problem would be to track from which edge the arm enters the tracked area and to assume the finger is on the opposite end. For example, if the arm comes in from the right, we know that the fingers are at the leftmost edge of the tracked blob. This however does not solve the problem of the shadows covering the projected image. We also cannot detect the moment when the finger touches or releases the screen, which is necessary for our interface. This can be solved by installing a contact mic on the surface, which could set a flag in the software whenever it “hears” the finger tapping the surface.

Computer Sensing
The computer will identify blobs using a background subtraction algorithm. The blobs will be tracked and identified so that their movement can be followed from frame to frame. This will be done using a customized version of Stefan Hechenberger’s extension to the openFrameworks OpenCV libraries. The way the tracker works is by comparing the current list of blobs with the list from a previous frame, and assigning the same ID to those that are near each other. This is limited by a maximum distance a blob can travel per frame, and inconsistencies are resolved by using more than one previous frame when performing the comparison. Once the blobs are identified, their position will be transmitted to the front-end software, which will generate graphics.

Points of Failure
• The background subtraction could stop functioning properly if the light conditions in the room change. If this is the case, we would need to research adaptive background subtraction techniques.
• The blob detection could be imprecise if the blobs and the background have similar colour. This potential bug can be eliminated if we use the Diffused Illumination setup.
• The software may lag if there are many input points and/or growths at the same time. If this happens using Processing, we can switch to openFrameworks for a speed increase. If the problem is still not solved, we may have to revert to OpenGL vertex buffers and display lists to perform more processing on the graphics card.
• The way the directions will be conveyed may not be as clear as we want it to be. User-testing and multiple iterations will eventually solve this problem.

View the PDF

Manners, Please

Invited your boss for dinner to wow him into giving you that new promotion?
Need to persuade your mother-in-law that you are good enough for her daughter?
Having your dentist over for brunch to solicit capital for your latest great movie script?

Then Manners, Please is the dining table enhancement for you!

Manners, Please is a projection system that overlays the dining room table, reminding you of good dining etiquette. This intelligent system will give you subtle hints throughout the meal, which will help impress your guests with your impeccable table manners.

Don’t know which fork to use?
Manners, Please will highlight the fork, spoon, or glass you should use corresponding to the food or drink you are currently consuming.

whichFork moreWine

Is one of the guests low on wine?
As the host, it is your duty to make sure everyone’s glass is always full, and Manners, Please helps you always be on your toes by projecting a faint halo around the wine bottle when someone finishes their glass.

Done eating?
Manners, Please will place guides on your plate, helping you place your utensils properly, parallel to one another in the position of ten o’clock to four o’clock.

whenDone

More than a projection
Manners, Please is also a state-of-the-art table, incorporating sophisticated haptic feedback technology, which gently vibrates under your elbows if you carelessly rest them on the table, or under your napkin if you’ve got food on your face and need to wipe it off.

How it works
The Manners, Please hardware consists of a projector and colour camera installed on the ceiling, both facing down and covering the entire dining table area. The table looks like a regular dining table, but it is equipped with vibrating motors along the perimeter hidden underneath the surface, which are used for haptic feedback.

All sensing is done using the camera. Manners, Please uses pattern recognition to determine where objects are placed on the dining room table. In training mode, the system prompts the user to place the items under the camera one at a time, so that their shape and colour can be determined and added to the internal database. When it is active, the system can then recognize tableware, and can tell if glasses or plates are empty based on colour analysis.

View the PDF

iFlora Design Document

A flourishing interactive experience at the Brooklyn Botanic Garden.

iFlora is a kiosk located in the main hall of the Steinhardt Conservatory at the Brooklyn Botanic Garden. The interactive environment is an introduction to the 4 main pavilions of the Conservatory; a digital representation of what you will experience as you walk through each area.

iFlora is a tabletop touch screen that is divided into 4 zones for each of the pavilions. It is shaped like a rounded square, with each edge facing the direction of the pavilion it represents. As you drag your finger in each zone, you trigger a particle-based growth animation representative of the type of flora that is found in each area: Sandstorms and cactii for the Desert Pavilion, thick deep-green vines for the Tropical Pavilion, ferns and wild flowers for the Warm Temperate Pavilion, and finally, lily pads and schools of fish for the Aquatic House.

When you place your finger on an empty space on the screen, you give birth to a plant. The longer you hold your finger down, the longer it will grow and the longer it will live. If you drag your finger along the screen, the plant will grow following your path. When you let go, the plant slowly starts dying, but you can help it live longer by touching it and dragging some more to nurture its growth.

If iFlora is idle for several minutes, an animation of a finger tapping appears on screen, indicating to any viewers how to interact with the table. The iconic finger appears in a random position on the screen, generating the growth animation corresponding to its location. As all it does is tap briefly, the generated plant will have a very short life span, enticing any viewers to help it grow by interacting with the table.

iFlora is a playful installation meant to encourage you to visit each pavilion. As no screen-based experience can rival viewing these environments face-to-face, it is not designed using photorealistic visuals, but with highly stylized graphics and animation that are better suited for the screen. It is not meant to be a replacement or a catalog of the Conservatory, but more of an addendum, a teaser of all the awe-inspiring areas surrounding you.

View the PDF (14.3 MB!)

Hoods.fm Proposal

Your Last.fm connections as an evolving city.

Using the neighbours, friends, and groups data from your profile, Hoods.fm gradually builds a city, placing you at the center and other users around, clustering the ones with similar tastes together, and placing the ones with very compatible taste closer to you. The visualization evolves over time, so you can see the rise, development, and fall of your city from when you first joined Last.fm until the present day.

The style of each user‚Äôs house represents their listening habits: rock as suburban bungalows, hip hop as brownstones, country as farmhouses, etc. The more music listened to, the higher the building. Since most people mix up what they listen to, the resulting houses will be a patchwork of styles – a superbly bizarre architecture.¬†

If you click on any dwelling, an extra layer of information appears to give details on that specific user and what their connection to you is. The ground under all related users highlights, so you can see how your neighbours are connected to each other. An extra click will take you to that user’s profile page on Last.fm, where you will be able to get all the available details.

View the poster