Tuesday, October 21, 2008
Inverse Kinematics and Processing
Basic inverse kinematics code rewritten for processing from Keith Peters of bit-101. The idea is to replicate the motion of your shoulder, upper arm, elbow, lower arm, and hand in two dimensions. The angular value of the "shoulder" and "elbow" will be written to corresponding servo motors that are being controlled by Arduino.
Here is the code:
int sx,sy,ex,ey,hx,hy;
int armLength,ua,la;
float uad, lad;
void setup(){
size(500,500);
background(255, 224, 150);
sx = width/2;
sy = height/2;
armLength = int(width/5);
}
void draw(){
fill(255);
rect(0,0,width,height);
upperArm();
}
void upperArm(){
int dx = mouseX - sx;
int dy = mouseY - sy;
float distance = sqrt(dx*dx+dy*dy);
int a = armLength;
int b = armLength;
float c = min(distance, a + b);
float B = acos((b*b-a*a-c*c)/(-2*a*c));
float C = acos((c*c-a*a-b*b)/(-2*a*b));
float D = atan2(dy,dx);
float E = D + B + PI + C;
ex = int((cos(E) * a)) + sx;
ey = int((sin(E) * a)) + sy;
print("UpperArm Angle= "+degrees(E)+" ");
hx = int((cos(D+B) * b)) + ex;
hy = int((sin(D+B) * b)) + ey;
println("LowerArm Angle= "+degrees((D+B)));
stroke(255,0,0,100);
fill(240,0,0,200);
ellipse(sx,sy,10,10);
ellipse(ex,ey,8,8);
ellipse(hx,hy,6,6);
stroke(0);
line(sx,sy,ex,ey);
line(ex,ey,hx,hy);
}
Awesome Data Visualization Site
My friend Loren Klein sent me a link to a site called Very Small Array. The specific page shows the map of the five boroughs. Instead of the borough names, the names of States with the closest equivalent in population are used. I really recommend checking out the rest of the site.
Money Map
Multi-Value Serial Communication
I want to thank Meredith for writing this post. I merely changed my name to her's.
I worked with Meredith Hasson on the serial communication lab for this week. We followed the lab instructions and did the first basic serial circuit using a flex sensor, a photo cell and a switch. We were able to get it working and thus, began to play with moving the ball around the screen.
We then changed both the Arduino and Processing code up a bit and went for snow. We made the background color change based on how much light the photocell was receiving. When it was getting lots of light, it would be a light background and when it was not receiving any light, it was a black background. The white balls were moving around based off of random numbers, but we utilized the flex sensor to decide how many balls would be present. When bent one way there were lots of balls and when bent the other there were fewer balls.
Here is our code:
Arduino:
int analogOne = 0; // analog input
int analogTwo = 1; // analog input
int digitalOne = 2; // digital input
int sensorValue = 0; // reading from the sensor
void setup() {
// configure the serial connection:
Serial.begin(9600);
// configure the digital input:
pinMode(digitalOne, INPUT);
}
void loop() {
// read the sensor:
sensorValue = analogRead(analogOne);
// print the results:
Serial.print(sensorValue, DEC);
Serial.print(”,”);
// read the sensor:
sensorValue = analogRead(analogTwo);
// print the results:
Serial.print(sensorValue, DEC);
Serial.print(”,”);
// read the sensor:
sensorValue = digitalRead(digitalOne);
// print the last sensor value with a println() so that
// each set of four readings prints on a line by itself:
Serial.println(sensorValue, DEC);
}
Processing:
import processing.serial.*; // import the Processing serial library
Serial myPort; // The serial port
float bgcolor; // Background color
float fgcolor; // Fill color
float xpos, ypos; // Starting position of the ball
void setup() {
size(640,480);
myPort = new Serial(this, Serial.list()[2], 9600);
// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil(’\n’);
}
void draw() {
//background(xpos);
fill(xpos, 50);
rect(0, 0, width, height);
fill(fgcolor);
// Draw the shape
for(int i = 0; i <= ypos; i++){
// ellipse(i*10, height/2, 10, 10);
ellipse(random(width), random(height), 10, 10);
}
}
// serialEvent method is run automatically by the Processing applet
// whenever the buffer reaches the byte value set in the bufferUntil()
// method in the setup():
void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil('\n');
// if you got any bytes other than the linefeed:
if (myString != null) {
myString = trim(myString);
// split the string at the commas
// and convert the sections into integers:
int sensors[] = int(split(myString, ','));
// print out the values you got:
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
}
// add a linefeed after all the sensor values are printed:
println();
if (sensors.length > 1) {
xpos = map(sensors[0], 190,900,1,255);
ypos = map(sensors[1], 220,540,1,200);
fgcolor = sensors[2] * 255;
}
}
}
I worked with Meredith Hasson on the serial communication lab for this week. We followed the lab instructions and did the first basic serial circuit using a flex sensor, a photo cell and a switch. We were able to get it working and thus, began to play with moving the ball around the screen.
We then changed both the Arduino and Processing code up a bit and went for snow. We made the background color change based on how much light the photocell was receiving. When it was getting lots of light, it would be a light background and when it was not receiving any light, it was a black background. The white balls were moving around based off of random numbers, but we utilized the flex sensor to decide how many balls would be present. When bent one way there were lots of balls and when bent the other there were fewer balls.
Here is our code:
Arduino:
int analogOne = 0; // analog input
int analogTwo = 1; // analog input
int digitalOne = 2; // digital input
int sensorValue = 0; // reading from the sensor
void setup() {
// configure the serial connection:
Serial.begin(9600);
// configure the digital input:
pinMode(digitalOne, INPUT);
}
void loop() {
// read the sensor:
sensorValue = analogRead(analogOne);
// print the results:
Serial.print(sensorValue, DEC);
Serial.print(”,”);
// read the sensor:
sensorValue = analogRead(analogTwo);
// print the results:
Serial.print(sensorValue, DEC);
Serial.print(”,”);
// read the sensor:
sensorValue = digitalRead(digitalOne);
// print the last sensor value with a println() so that
// each set of four readings prints on a line by itself:
Serial.println(sensorValue, DEC);
}
Processing:
import processing.serial.*; // import the Processing serial library
Serial myPort; // The serial port
float bgcolor; // Background color
float fgcolor; // Fill color
float xpos, ypos; // Starting position of the ball
void setup() {
size(640,480);
myPort = new Serial(this, Serial.list()[2], 9600);
// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil(’\n’);
}
void draw() {
//background(xpos);
fill(xpos, 50);
rect(0, 0, width, height);
fill(fgcolor);
// Draw the shape
for(int i = 0; i <= ypos; i++){
// ellipse(i*10, height/2, 10, 10);
ellipse(random(width), random(height), 10, 10);
}
}
// serialEvent method is run automatically by the Processing applet
// whenever the buffer reaches the byte value set in the bufferUntil()
// method in the setup():
void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil('\n');
// if you got any bytes other than the linefeed:
if (myString != null) {
myString = trim(myString);
// split the string at the commas
// and convert the sections into integers:
int sensors[] = int(split(myString, ','));
// print out the values you got:
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
}
// add a linefeed after all the sensor values are printed:
println();
if (sensors.length > 1) {
xpos = map(sensors[0], 190,900,1,255);
ypos = map(sensors[1], 220,540,1,200);
fgcolor = sensors[2] * 255;
}
}
}
Tags:
arduino,
physical computing,
processing,
serial input
Subscribe to:
Posts (Atom)