Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

Flubi

28. September 2012

Flubi ist ein interaktiver "Gummiball" welcher über 4 Infrarot-Distanz-Messer gesteuert wird. Durch schnellere Handbewegungen richtung Flubi wird er Physikalisch im Raum herumgeschleudert. Durch feine Bewegungen kann er verformt werden. Mit mehreren Personen kann er sogar zusammengedrückt werden bis er blau wird und keine Luft mehr bekommt. Die Farben ändern sich je nach Beschleunigung oder Presswerte.

Die Schwierigkeit bei dieser Aufgabe lag darin die schwankenden Werte zu regulieren. Auch das kleine Spektrum der Sensoren sind schwierig zu kontrollieren und führten Anfangs immer zu Fehlern

CODE

import processing.serial.*;  // Import the Processing Serial Library for communicating with arduino
Serial myPort;               // The used Serial Port

int left, right, front, back;

int sizeX = 1024;
int sizeY = 786;

int coords[] = new int[4];
int coordsOld[] = new int[4];
int distanceX[] = new int[4];
int distanceY[] = new int[4];
int distanceXOld[] = new int[4];
int distanceYOld[] = new int[4];

PVector position = new PVector(0, 0);
PVector positionOld = new PVector(0, 0);

PVector movement = new PVector(0,0); //Bewegung über den Bildschirm

int flubberWidth;
int flubberHeight;

float newMulti = 0.05;
float oldMulti = 0.95;
float magnetStrength = 0.4;

void setup()
{
  size(sizeX, sizeY);
  background(255);

  //println(Serial.list()); // Prints the list of serial available devices (Arduino should be on top of the list)
  myPort = new Serial(this, Serial.list()[0], 9600); // Open a new port and connect with Arduino at 9600 baud
  
  //frameRate(20);
  randomSeed(millis() * 1024 ^ 16);

  positionOld.x = position.x = sizeX/2;
  positionOld.y = position.y = sizeY/2;

}

void draw()
{ 

  navigate();
  
  flubber();
  
}

void navigate() {

  int coordsChange[] = new int[4]; //Veraenderung der Koordinatenposition

  flubberWidth = coords[1] + coords[0] - 20;
  flubberHeight = coords[3] + coords[2] - 20;

  println(flubberWidth);

  coordsChange[0] = coordsOld[0] - coords[0];
  if(coordsChange[0] <= 2) coordsChange[0] = 0;
  coordsChange[1] = coordsOld[1] - coords[1];
  if(coordsChange[1] <= 2) coordsChange[1] = 0;
  coordsChange[2] = coordsOld[2] - coords[2];
  if(coordsChange[2] <= 2) coordsChange[2] = 0;
  coordsChange[3] = coordsOld[3] - coords[3];
  if(coordsChange[3] <= 2) coordsChange[3] = 0;

  /*** Magnet ***/

  if(coordsChange[0] == 0 && coordsChange[1] == 0 && coordsChange[2] == 0 && coordsChange[3] == 0) {

    if(position.x < sizeX/2) position.x += magnetStrength;
    else position.x -= magnetStrength;

    if(position.y < sizeY/2) position.y += magnetStrength;
    else position.y -= magnetStrength;

  }

  movement.add(6 * (coordsChange[0] - coordsChange[1]), 6 * (coordsChange[2] - coordsChange[3]), 0);

  movement.mult(oldMulti);

  position = PVector.add(position, movement);


  if(position.x - flubberWidth/2 < 0) {

    movement.x *= -1;
    position.x = flubberWidth/2;

  } else if(position.x + flubberWidth/2 > sizeX) {

    movement.x *= -1;
    position.x = sizeX - flubberWidth/2;

  }


  if(position.y - flubberHeight/2 < 0) {

    movement.y *= -1;
    position.y = flubberHeight/2;

  } else if(position.y + flubberHeight/2 > sizeY) {

    movement.y *= -1;
    position.y = sizeY - flubberHeight/2;

  }

  //position = PVector.add(PVector.mult(position, newMulti), PVector.mult(positionOld, oldMulti));

  /*position.x = sizeX/2;
  position.y = sizeY/2;*/

}





void flubber() {



  /*left = coords[0];
  right = coords[1];
  front = coords[2];
  back = coords[3];*/
  int distanceWidth = 1;
  int distanceTilt = int(random(0, 20));

  distanceX[0] = distanceTilt;
  distanceX[1] = distanceTilt;
  distanceX[2] = coords[2] * distanceWidth;
  distanceX[3] = coords[3] * distanceWidth;

  if(distanceXOld[0] != 0) distanceX[0] = int(distanceX[0] * newMulti + distanceXOld[0] * oldMulti);
  if(distanceXOld[1] != 0) distanceX[1] = int(distanceX[1] * newMulti + distanceXOld[1] * oldMulti);
  if(distanceXOld[2] != 0) distanceX[2] = int(distanceX[2] * newMulti + distanceXOld[2] * oldMulti);
  if(distanceXOld[3] != 0) distanceX[3] = int(distanceX[3] * newMulti + distanceXOld[3] * oldMulti);

  distanceXOld[0] = distanceX[0];
  distanceXOld[1] = distanceX[1];
  distanceXOld[2] = distanceX[2];
  distanceXOld[3] = distanceX[3];
  

  distanceY[0] = coords[0] * distanceWidth;
  distanceY[1] = coords[1] * distanceWidth;
  distanceY[2] = distanceTilt;
  distanceY[3] = distanceTilt;

  if(distanceYOld[0] != 0) distanceY[0] = int(distanceY[0] * newMulti + distanceYOld[0] * oldMulti);
  if(distanceYOld[1] != 0) distanceY[1] = int(distanceY[1] * newMulti + distanceYOld[1] * oldMulti);
  if(distanceYOld[2] != 0) distanceY[2] = int(distanceY[2] * newMulti + distanceYOld[2] * oldMulti);
  if(distanceYOld[3] != 0) distanceY[3] = int(distanceY[3] * newMulti + distanceYOld[3] * oldMulti);

  distanceYOld[0] = distanceY[0];
  distanceYOld[1] = distanceY[1];
  distanceYOld[2] = distanceY[2];
  distanceYOld[3] = distanceY[3];

  fill(0, 0, 100, 90);
  rect(0, 0, sizeX, sizeY);

  noStroke();

  pushMatrix();

  translate(position.x, position.y);
  /*rotate(radians(45));
  translate(-sizeX/2,-sizeY/2);*/

  colorMode(HSB, 100);

  fill(((coords[0] + coords[1] + coords[2] + coords[3]) / 5 + 50) % 100, 100, 50);

  beginShape();

  vertex(0, -coords[2]);

  bezierVertex(distanceX[2], -coords[2] + distanceY[2], coords[1] - distanceX[1], -distanceY[1], coords[1], 0);

  bezierVertex(coords[1] + distanceX[1], distanceY[1], distanceX[3], coords[3] + distanceY[3], 0, coords[3]);

  bezierVertex(-distanceX[3], coords[3] - distanceY[3], -coords[0] + distanceX[0], distanceY[0], -coords[0], 0);
  bezierVertex(-coords[0] - distanceX[0], -distanceY[0], -distanceX[2], - coords[2] - distanceY[2], 0, -coords[2]);

  endShape();

  /*line(0, -coords[2], distanceX[2], -coords[2] + distanceY[2]);

  line(coords[1] - distanceX[1], -distanceY[1], coords[1], 0);
  line(coords[1], 0, coords[1] + distanceX[1], distanceY[1]);

  line(distanceX[3], coords[3] + distanceY[3], 0, coords[3]);
  line(0, coords[3], -distanceX[3], coords[3] - distanceY[3]);

  line(-coords[0] + distanceX[0], distanceY[0], -coords[0], 0);
  line(-coords[0], 0, -coords[0] - distanceX[0], -distanceY[0]);

  line(-distanceX[2], - coords[2] - distanceY[2], 0, -coords[2]);*/

  coordsOld[0] = coords[0];
  coordsOld[1] = coords[1];
  coordsOld[2] = coords[2];
  coordsOld[3] = coords[3];

  popMatrix();

}


void serialEvent(Serial myPort) // Is called everytime there is new data to read
{
  if (myPort.available() > 0)
  {
    String completeString = myPort.readStringUntil(10); // Read the Serial port until there is a linefeed/carriage return
    if (completeString != null) // If there is valid data insode the String
    {
      trim(completeString); // Remove whitespace characters at the beginning and end of the string
      String seperateValues[] = split(completeString, ";"); // Split the string everytime a delimiter is received

      //println(seperateValues.length);

      for(int j = 0; j < seperateValues.length-1; j++) {
        
        if(j < 4) coords[j] = round(1.5 * int(seperateValues[j]));
        //println(j);
        
      }
      
      //if(seperateValues.length == 4) println(coords[0] + "   " + coords[1] + "   " + coords[2] + "   " + coords[3]);
    }
  }
}

boolean sketchFullScreen() {
  return true;
}
import processing.serial.*;  // Import the Processing Serial Library for communicating with arduino
Serial myPort;               // The used Serial Port

int left, right, front, back;

int sizeX = 1024;
int sizeY = 786;

int coords[] = new int[4];
int coordsOld[] = new int[4];
int distanceX[] = new int[4];
int distanceY[] = new int[4];
int distanceXOld[] = new int[4];
int distanceYOld[] = new int[4];

PVector position = new PVector(0, 0);
PVector positionOld = new PVector(0, 0);

PVector movement = new PVector(0,0); //Bewegung über den Bildschirm

int flubberWidth;
int flubberHeight;

float newMulti = 0.05;
float oldMulti = 0.95;
float magnetStrength = 0.4;

void setup()
{
  size(sizeX, sizeY);
  background(255);

  //println(Serial.list()); // Prints the list of serial available devices (Arduino should be on top of the list)
  myPort = new Serial(this, Serial.list()[0], 9600); // Open a new port and connect with Arduino at 9600 baud
  
  //frameRate(20);
  randomSeed(millis() * 1024 ^ 16);

  positionOld.x = position.x = sizeX/2;
  positionOld.y = position.y = sizeY/2;

}

void draw()
{ 

  navigate();
  
  flubber();
  
}

void navigate() {

  int coordsChange[] = new int[4]; //Veraenderung der Koordinatenposition

  flubberWidth = coords[1] + coords[0] - 20;
  flubberHeight = coords[3] + coords[2] - 20;

  println(flubberWidth);

  coordsChange[0] = coordsOld[0] - coords[0];
  if(coordsChange[0] <= 2) coordsChange[0] = 0;
  coordsChange[1] = coordsOld[1] - coords[1];
  if(coordsChange[1] <= 2) coordsChange[1] = 0;
  coordsChange[2] = coordsOld[2] - coords[2];
  if(coordsChange[2] <= 2) coordsChange[2] = 0;
  coordsChange[3] = coordsOld[3] - coords[3];
  if(coordsChange[3] <= 2) coordsChange[3] = 0;

  /*** Magnet ***/

  if(coordsChange[0] == 0 && coordsChange[1] == 0 && coordsChange[2] == 0 && coordsChange[3] == 0) {

    if(position.x < sizeX/2) position.x += magnetStrength;
    else position.x -= magnetStrength;

    if(position.y < sizeY/2) position.y += magnetStrength;
    else position.y -= magnetStrength;

  }

  movement.add(6 * (coordsChange[0] - coordsChange[1]), 6 * (coordsChange[2] - coordsChange[3]), 0);

  movement.mult(oldMulti);

  position = PVector.add(position, movement);


  if(position.x - flubberWidth/2 < 0) {

    movement.x *= -1;
    position.x = flubberWidth/2;

  } else if(position.x + flubberWidth/2 > sizeX) {

    movement.x *= -1;
    position.x = sizeX - flubberWidth/2;

  }


  if(position.y - flubberHeight/2 < 0) {

    movement.y *= -1;
    position.y = flubberHeight/2;

  } else if(position.y + flubberHeight/2 > sizeY) {

    movement.y *= -1;
    position.y = sizeY - flubberHeight/2;

  }

  //position = PVector.add(PVector.mult(position, newMulti), PVector.mult(positionOld, oldMulti));

  /*position.x = sizeX/2;
  position.y = sizeY/2;*/

}





void flubber() {



  /*left = coords[0];
  right = coords[1];
  front = coords[2];
  back = coords[3];*/
  int distanceWidth = 1;
  int distanceTilt = int(random(0, 20));

  distanceX[0] = distanceTilt;
  distanceX[1] = distanceTilt;
  distanceX[2] = coords[2] * distanceWidth;
  distanceX[3] = coords[3] * distanceWidth;

  if(distanceXOld[0] != 0) distanceX[0] = int(distanceX[0] * newMulti + distanceXOld[0] * oldMulti);
  if(distanceXOld[1] != 0) distanceX[1] = int(distanceX[1] * newMulti + distanceXOld[1] * oldMulti);
  if(distanceXOld[2] != 0) distanceX[2] = int(distanceX[2] * newMulti + distanceXOld[2] * oldMulti);
  if(distanceXOld[3] != 0) distanceX[3] = int(distanceX[3] * newMulti + distanceXOld[3] * oldMulti);

  distanceXOld[0] = distanceX[0];
  distanceXOld[1] = distanceX[1];
  distanceXOld[2] = distanceX[2];
  distanceXOld[3] = distanceX[3];
  

  distanceY[0] = coords[0] * distanceWidth;
  distanceY[1] = coords[1] * distanceWidth;
  distanceY[2] = distanceTilt;
  distanceY[3] = distanceTilt;

  if(distanceYOld[0] != 0) distanceY[0] = int(distanceY[0] * newMulti + distanceYOld[0] * oldMulti);
  if(distanceYOld[1] != 0) distanceY[1] = int(distanceY[1] * newMulti + distanceYOld[1] * oldMulti);
  if(distanceYOld[2] != 0) distanceY[2] = int(distanceY[2] * newMulti + distanceYOld[2] * oldMulti);
  if(distanceYOld[3] != 0) distanceY[3] = int(distanceY[3] * newMulti + distanceYOld[3] * oldMulti);

  distanceYOld[0] = distanceY[0];
  distanceYOld[1] = distanceY[1];
  distanceYOld[2] = distanceY[2];
  distanceYOld[3] = distanceY[3];

  fill(0, 0, 100, 90);
  rect(0, 0, sizeX, sizeY);

  noStroke();

  pushMatrix();

  translate(position.x, position.y);
  /*rotate(radians(45));
  translate(-sizeX/2,-sizeY/2);*/

  colorMode(HSB, 100);

  fill(((coords[0] + coords[1] + coords[2] + coords[3]) / 5 + 50) % 100, 100, 50);

  beginShape();

  vertex(0, -coords[2]);

  bezierVertex(distanceX[2], -coords[2] + distanceY[2], coords[1] - distanceX[1], -distanceY[1], coords[1], 0);

  bezierVertex(coords[1] + distanceX[1], distanceY[1], distanceX[3], coords[3] + distanceY[3], 0, coords[3]);

  bezierVertex(-distanceX[3], coords[3] - distanceY[3], -coords[0] + distanceX[0], distanceY[0], -coords[0], 0);
  bezierVertex(-coords[0] - distanceX[0], -distanceY[0], -distanceX[2], - coords[2] - distanceY[2], 0, -coords[2]);

  endShape();

  /*line(0, -coords[2], distanceX[2], -coords[2] + distanceY[2]);

  line(coords[1] - distanceX[1], -distanceY[1], coords[1], 0);
  line(coords[1], 0, coords[1] + distanceX[1], distanceY[1]);

  line(distanceX[3], coords[3] + distanceY[3], 0, coords[3]);
  line(0, coords[3], -distanceX[3], coords[3] - distanceY[3]);

  line(-coords[0] + distanceX[0], distanceY[0], -coords[0], 0);
  line(-coords[0], 0, -coords[0] - distanceX[0], -distanceY[0]);

  line(-distanceX[2], - coords[2] - distanceY[2], 0, -coords[2]);*/

  coordsOld[0] = coords[0];
  coordsOld[1] = coords[1];
  coordsOld[2] = coords[2];
  coordsOld[3] = coords[3];

  popMatrix();

}


void serialEvent(Serial myPort) // Is called everytime there is new data to read
{
  if (myPort.available() > 0)
  {
    String completeString = myPort.readStringUntil(10); // Read the Serial port until there is a linefeed/carriage return
    if (completeString != null) // If there is valid data insode the String
    {
      trim(completeString); // Remove whitespace characters at the beginning and end of the string
      String seperateValues[] = split(completeString, ";"); // Split the string everytime a delimiter is received

      //println(seperateValues.length);

      for(int j = 0; j < seperateValues.length-1; j++) {
        
        if(j < 4) coords[j] = round(1.5 * int(seperateValues[j]));
        //println(j);
        
      }
      
      //if(seperateValues.length == 4) println(coords[0] + "   " + coords[1] + "   " + coords[2] + "   " + coords[3]);
    }
  }
}

boolean sketchFullScreen() {
  return true;
}
VIDEO