Difference between revisions of "Software"

From FabLabGenovaWiki
Jump to: navigation, search
(Replaced content with "preliminary python code")
Line 1: Line 1:
preliminary python code
+
processing code for the conversion from the image file to the pen tip path
 +
 
 +
import toxi.geom.*;
 +
 
 +
// tsp variables
 +
int particleRouteLength;
 +
Vec2D[] particles;
 +
int[] particleRoute;
 +
int maxParticles;
 +
 
 +
// image variable
 +
PImage img;
 +
 
 +
float millisLastFrame = 0;
 +
float frameTime = 0;
 +
// scale of the drawing
 +
float s = 2.0;
 +
 
 +
void setup() {
 +
 
 +
  maxParticles = 15000;
 +
  //img = loadImage("lenna-lg_BW_loRes.png");
 +
  //img = loadImage("test.png");
 +
  img = loadImage("lenna_BW_loRes2.png");
 +
  size(img.width*(int)s, img.height*(int)s);
 +
  //size(400, 600);
 +
  // count black pixels
 +
  int i;
 +
  maxParticles = 0;
 +
  for ( int x = 0; x < img.width; x++ ) {
 +
    for ( int y = 0; y < img.height; y++ ) {
 +
      i = ( ( y * img.width ) + x ); // getting pixel index
 +
      if ( img.pixels[i] == color( 0, 0, 0 ) ) {
 +
        maxParticles++;
 +
      }
 +
    }
 +
  }
 +
 
 +
  println("black dots: " + maxParticles);
 +
  // allocate and fill points vector
 +
  particles = new Vec2D[maxParticles];
 +
  i = 0;
 +
  int j = 0;
 +
  for ( int x = 0; x < img.width; x++ ) {
 +
    for ( int y = 0; y < img.height; y++ ) {
 +
      i = ( ( y * img.width ) + x );
 +
      if ( img.pixels[i] == color( 0, 0, 0 ) ) {
 +
        Vec2D p1 = new Vec2D(x, y);
 +
        particles[j] = p1;
 +
        j++;
 +
      }
 +
    }
 +
  }
 +
  millisLastFrame = millis();
 +
  initPath();    // initialize path (NN heuristic)
 +
  for (int l = 0; l < 5; l++ ) {
 +
    // optimize path with 2-opt heuristic
 +
    for (int k = 0; k < 5000; k++ ) optimizePath();
 +
    // profiling ...
 +
    frameTime = (millis() - millisLastFrame)/1000;
 +
    millisLastFrame = millis();
 +
    println("Frame time: " + millisLastFrame);
 +
  }
 +
  noLoop();
 +
}
 +
 
 +
void initPath()
 +
{
 +
  int temp;
 +
  println("initializing path (NN)");
 +
  Vec2D p1, p2;
 +
  particleRouteLength = maxParticles;
 +
  // array of free ramaining particles to be queried
 +
  boolean freeParticles[] = new boolean[maxParticles];
 +
  particleRoute = new int[particleRouteLength];
 +
  int closestParticle;
 +
  float distMin;
 +
  p1 = particles[0];
 +
  freeParticles[0] = true;
 +
  particleRoute[0] = 0;
 +
  // Nearest neighbor ("Simple, Greedy") algorithm path optimization:
 +
  int i = 0, j;
 +
  float dx, dy, distance;
 +
  while (i < particleRouteLength) {
 +
    distMin = Float.MAX_VALUE; // re-initialize mimimun distance value
 +
    closestParticle = 0;      // re-initialize closest particle
 +
    for (j = 0; j < particleRouteLength; j++) {
 +
      if (freeParticles[j] == false) {
 +
        p2 = particles[j];  // get next particle to calculate distance
 +
        dx = p1.x - p2.x;
 +
        dy = p1.y - p2.y;
 +
        distance = (float) (dx*dx+dy*dy);  // Only looking for closest; do not need sqrt factor!
 +
        if (distance < distMin) {
 +
          closestParticle = j;  // update the closest particle index
 +
          distMin = distance;  // update the minimum distance value
 +
        }
 +
      }
 +
    }
 +
    freeParticles[closestParticle] = true; // remove the particle from the ones to be queried
 +
    particleRoute[i] = closestParticle; //set the next particle in the path
 +
    i++; // increment while counter
 +
  }
 +
  // Initial routing is complete
 +
  frameTime = (millis() - millisLastFrame)/1000;
 +
  millisLastFrame = millis();
 +
  println("Frame time: " + millisLastFrame);
 +
}
 +
 
 +
void optimizePath() {
 +
  // 2-opt heuristic optimization:
 +
  // Identify a pair of edges that would become shorter by reversing part of the tour.
 +
  int temp;
 +
  //println("optimizing path (2-opt) " );
 +
  for (int i = 0; i < 5000; ++i) {  // 1000 tests per frame; you can edit this number.
 +
    int indexA = floor(random(particleRouteLength - 1));
 +
    int indexB = floor(random(particleRouteLength - 1));
 +
    if (Math.abs(indexA  - indexB) < 2)
 +
      continue;
 +
    if (indexB < indexA) {  // swap A, B.
 +
      temp = indexB;
 +
      indexB = indexA;
 +
      indexA = temp;
 +
    }
 +
 
 +
    Vec2D a0 = particles[particleRoute[indexA]];
 +
    Vec2D a1 = particles[particleRoute[indexA + 1]];
 +
    Vec2D b0 = particles[particleRoute[indexB]];
 +
    Vec2D b1 = particles[particleRoute[indexB + 1]];
 +
 
 +
    // Original distance:
 +
    float  dx = a0.x - a1.x;
 +
    float  dy = a0.y - a1.y;
 +
    float  distance = (float) (dx*dx+dy*dy);  // only a comparison; do not need sqrt factor!
 +
    dx = b0.x - b1.x;
 +
    dy = b0.y - b1.y;
 +
    distance += (float) (dx*dx+dy*dy);  //  only a comparison; do not need sqrt factor!
 +
    // Possible shorter distance?
 +
    dx = a0.x - b0.x;
 +
    dy = a0.y - b0.y;
 +
    float distance2 = (float) (dx*dx+dy*dy);  //  only a comparison; do not need sqrt factor!
 +
    dx = a1.x - b1.x;
 +
    dy = a1.y - b1.y;
 +
    distance2 += (float) (dx*dx+dy*dy);  // only a comparison; do not need sqrt factor!
 +
 
 +
    if (distance2 < distance) { // Reverse tour between a1 and b0. 
 +
      int indexhigh = indexB;
 +
      int indexlow = indexA + 1;
 +
      while (indexhigh > indexlow) {
 +
        temp = particleRoute[indexlow];
 +
        particleRoute[indexlow] = particleRoute[indexhigh];
 +
        particleRoute[indexhigh] = temp;
 +
        indexhigh--;
 +
        indexlow++;
 +
      }
 +
    }
 +
  }
 +
}
 +
 
 +
 
 +
void draw() {
 +
  //image(img, 0, 0);
 +
  image(img, width*s, height*s);
 +
  int i = 0;
 +
  stroke(128, 128, 255);    // Stroke color (blue)
 +
  strokeWeight (.5);        // stroke weight
 +
  println("in draw, n.part : " + particleRouteLength);
 +
 
 +
  // loop the particles drawing a line between successive points
 +
  for ( i = 0; i < (particleRouteLength - 1); ++i) {
 +
    Vec2D p1 = particles[particleRoute[i]];
 +
    Vec2D p2 = particles[particleRoute[i + 1]];
 +
    line(p1.x*s, p1.y*s, p2.x*s, p2.y*s);
 +
  }
 +
}
 +
 
 +
 
 +
preliminary python code for the low level controller
 +
 
 +
from time import sleep
 +
from math import pi
 +
import RPi.GPIO as GPIO
 +
 
 +
# systems parameters
 +
r_p = 18.0 #............... pulley radius [mm]
 +
d_p = 1500.0 #............. pulley distance [mm]
 +
d_p05 = dp * 0.5 #......... half pulley distance [mm]
 +
s_a = 3.5 * (2*pi/360) #... step angle [rad]
 +
 
 +
# drawing parameters
 +
s = 2.0 #.................. drawing scale [-]
 +
 
 +
# initialize output pins
 +
GPIO.setup(13, GPIO.OUT)
 +
#GPIO.setup(15, GPIO.OUT)
 +
#GPIO.setup(16, GPIO.OUT)
 +
#GPIO.setup(15, GPIO.OUT)
 +
#GPIO.setup(16, GPIO.OUT)
 +
#GPIO.setup(15, GPIO.OUT)
 +
#GPIO.setup(16, GPIO.OUT)
 +
#GPIO.setup(15, GPIO.OUT)
 +
 
 +
 
 +
pos = [240, 240] #.... set initial position vector (x,Y)
 +
len_curr = getStringsLen(pos_init, d_p05, s) # get initial string
 +
 
 +
for i in list
 +
pos_next = path[i]
 +
len_next = getStringsLen(pos_next, d_p05, s)
 +
dl = len_next - len_curr
 +
ds = dl/s_a
 +
 +
 
 +
def getStringsLen(pos_xy, halfPullDist, scale)
 +
x2 = (pos_xy[0] * scale)**2
 +
x2b2 = (halfPullDist - pos_xy[0] * scale)**2
 +
y2 = (pos_xy[1] * scale)**2
 +
return [sqrt(x2+y2) , sqrt(x2b2+y2)]

Revision as of 17:32, 12 February 2013

processing code for the conversion from the image file to the pen tip path

import toxi.geom.*;

// tsp variables int particleRouteLength; Vec2D[] particles; int[] particleRoute; int maxParticles;

// image variable PImage img;

float millisLastFrame = 0; float frameTime = 0; // scale of the drawing float s = 2.0;

void setup() {

 maxParticles = 15000;
 //img = loadImage("lenna-lg_BW_loRes.png");
 //img = loadImage("test.png");
 img = loadImage("lenna_BW_loRes2.png");
 size(img.width*(int)s, img.height*(int)s);
 //size(400, 600);
 // count black pixels
 int i;
 maxParticles = 0;
 for ( int x = 0; x < img.width; x++ ) {
   for ( int y = 0; y < img.height; y++ ) { 
     i = ( ( y * img.width ) + x ); // getting pixel index
     if ( img.pixels[i] == color( 0, 0, 0 ) ) {
       maxParticles++;
     }
   }
 }
 println("black dots: " + maxParticles);
 // allocate and fill points vector
 particles = new Vec2D[maxParticles];
 i = 0;
 int j = 0;
 for ( int x = 0; x < img.width; x++ ) {
   for ( int y = 0; y < img.height; y++ ) { 
     i = ( ( y * img.width ) + x );
     if ( img.pixels[i] == color( 0, 0, 0 ) ) {
       Vec2D p1 = new Vec2D(x, y);
       particles[j] = p1;
       j++;
     }
   }
 }
 millisLastFrame = millis();
 initPath();    // initialize path (NN heuristic)
 for (int l = 0; l < 5; l++ ) {
   // optimize path with 2-opt heuristic
   for (int k = 0; k < 5000; k++ ) optimizePath();
   // profiling ...
   frameTime = (millis() - millisLastFrame)/1000;
   millisLastFrame = millis();
   println("Frame time: " + millisLastFrame);
 }
 noLoop();

}

void initPath() {

 int temp;
 println("initializing path (NN)");
 Vec2D p1, p2;
 particleRouteLength = maxParticles;
 // array of free ramaining particles to be queried
 boolean freeParticles[] = new boolean[maxParticles]; 
 particleRoute = new int[particleRouteLength]; 
 int closestParticle;
 float distMin;
 p1 = particles[0];
 freeParticles[0] = true;
 particleRoute[0] = 0;
 // Nearest neighbor ("Simple, Greedy") algorithm path optimization:
 int i = 0, j;
 float dx, dy, distance; 
 while (i < particleRouteLength) {
   distMin = Float.MAX_VALUE; // re-initialize mimimun distance value
   closestParticle = 0;      // re-initialize closest particle
   for (j = 0; j < particleRouteLength; j++) {
     if (freeParticles[j] == false) {
       p2 = particles[j];  // get next particle to calculate distance
       dx = p1.x - p2.x;
       dy = p1.y - p2.y;
       distance = (float) (dx*dx+dy*dy);  // Only looking for closest; do not need sqrt factor!
       if (distance < distMin) {
         closestParticle = j;  // update the closest particle index
         distMin = distance;  // update the minimum distance value
       }
     }
   }
   freeParticles[closestParticle] = true; // remove the particle from the ones to be queried
   particleRoute[i] = closestParticle; //set the next particle in the path
   i++; // increment while counter
 }
 // Initial routing is complete
 frameTime = (millis() - millisLastFrame)/1000;
 millisLastFrame = millis();
 println("Frame time: " + millisLastFrame);

}

void optimizePath() {

 // 2-opt heuristic optimization:
 // Identify a pair of edges that would become shorter by reversing part of the tour.
 int temp;
 //println("optimizing path (2-opt) " );
 for (int i = 0; i < 5000; ++i) {   // 1000 tests per frame; you can edit this number.
   int indexA = floor(random(particleRouteLength - 1));
   int indexB = floor(random(particleRouteLength - 1));
   if (Math.abs(indexA  - indexB) < 2)
     continue;
   if (indexB < indexA) {  // swap A, B.
     temp = indexB;
     indexB = indexA;
     indexA = temp;
   }
   Vec2D a0 = particles[particleRoute[indexA]];
   Vec2D a1 = particles[particleRoute[indexA + 1]];
   Vec2D b0 = particles[particleRoute[indexB]];
   Vec2D b1 = particles[particleRoute[indexB + 1]];
   // Original distance:
   float  dx = a0.x - a1.x;
   float  dy = a0.y - a1.y;
   float  distance = (float) (dx*dx+dy*dy);  // only a comparison; do not need sqrt factor! 
   dx = b0.x - b1.x;
   dy = b0.y - b1.y;
   distance += (float) (dx*dx+dy*dy);  //  only a comparison; do not need sqrt factor! 
   // Possible shorter distance?
   dx = a0.x - b0.x;
   dy = a0.y - b0.y;
   float distance2 = (float) (dx*dx+dy*dy);  //  only a comparison; do not need sqrt factor! 
   dx = a1.x - b1.x;
   dy = a1.y - b1.y;
   distance2 += (float) (dx*dx+dy*dy);  // only a comparison; do not need sqrt factor! 
   if (distance2 < distance) { // Reverse tour between a1 and b0.   
     int indexhigh = indexB;
     int indexlow = indexA + 1;
     while (indexhigh > indexlow) {
       temp = particleRoute[indexlow];
       particleRoute[indexlow] = particleRoute[indexhigh];
       particleRoute[indexhigh] = temp;
       indexhigh--;
       indexlow++;
     }
   }
 }

}


void draw() {

 //image(img, 0, 0);
 image(img, width*s, height*s);
 int i = 0;
 stroke(128, 128, 255);    // Stroke color (blue)
 strokeWeight (.5);        // stroke weight
 println("in draw, n.part : " + particleRouteLength);
 // loop the particles drawing a line between successive points
 for ( i = 0; i < (particleRouteLength - 1); ++i) {
   Vec2D p1 = particles[particleRoute[i]];
   Vec2D p2 = particles[particleRoute[i + 1]];
   line(p1.x*s, p1.y*s, p2.x*s, p2.y*s);
 }

}


preliminary python code for the low level controller

from time import sleep from math import pi import RPi.GPIO as GPIO

  1. systems parameters

r_p = 18.0 #............... pulley radius [mm] d_p = 1500.0 #............. pulley distance [mm] d_p05 = dp * 0.5 #......... half pulley distance [mm] s_a = 3.5 * (2*pi/360) #... step angle [rad]

  1. drawing parameters

s = 2.0 #.................. drawing scale [-]

  1. initialize output pins

GPIO.setup(13, GPIO.OUT)

  1. GPIO.setup(15, GPIO.OUT)
  2. GPIO.setup(16, GPIO.OUT)
  3. GPIO.setup(15, GPIO.OUT)
  4. GPIO.setup(16, GPIO.OUT)
  5. GPIO.setup(15, GPIO.OUT)
  6. GPIO.setup(16, GPIO.OUT)
  7. GPIO.setup(15, GPIO.OUT)


pos = [240, 240] #.... set initial position vector (x,Y) len_curr = getStringsLen(pos_init, d_p05, s) # get initial string

for i in list pos_next = path[i] len_next = getStringsLen(pos_next, d_p05, s) dl = len_next - len_curr ds = dl/s_a


def getStringsLen(pos_xy, halfPullDist, scale) x2 = (pos_xy[0] * scale)**2 x2b2 = (halfPullDist - pos_xy[0] * scale)**2 y2 = (pos_xy[1] * scale)**2 return [sqrt(x2+y2) , sqrt(x2b2+y2)]