gbm
Image scanner con sensore ERER, tilt/pan e Processing
Tutorials -
Mercoledì 29 Giugno 2011 00:00
Scritto da gbm

Dopo aver visto il tutorial di Alegiaco sul robot diffidente ho deciso di provare anche io il sistema di Tilt Pan con due microservi, e trovarne un'applicazione sperimentale interessante. Essendo appassionato di fotografia, di tecniche di rappresentazione come l'HDR ho sempre sognato costruire una macchina fotografica, e da quando lavoro con Arduino, il sensore fondamentalmente. Per puro caso, qualche anno fa, sperimentando con la robotica di base mi sono imbattuto nel semplice tutorial Arduino LED sensor, cioè un LED ir utilizzato come sensore di luce. Dopo alcuni test ho capito le potenzialità di questo sistema e ho creato un semplice sensore di prossimità che sfrutta la proprietà fisica del LED di variare la sua capacitanza in rapporto alla quantità di luce che lo colpisce insieme a un semplicissimo algoritmo basato sull'analisi di due letture per ottenere un preciso valore di distanza in mm. Qui trovate il tutorial Sensore di prossimità LED (il codice è vecchio e poco elegante vi consiglio di utilizzare quello che troverete piu' avanti nel codice di questo tutorial). 

 

 

 

Cos'è Image Scanner

Questo programma permette di sperimentare la multirilevazione sensoriale, espandendo cosi' le capacità percettive di un qualsiasi sistema di misurazione con Arduino. In parole povere grazie a questo applicativo è possibile rappresentare con un immagine il flusso di dati in arrivo da Arduino durante una misurazione con un sistema di Tilt Pan. Di conseguenza ogni pixel rappresenta una rilevazione e grazie all'algoritmo da entrambi i lati, Arduino e Processing, è possibile posizionare questi in modo da costruire un'immagine di cio' che si trova davanti al sistema di rilevamento. Ecco uno dei primi scan effettuati con Image Scanner:

 

Image Scanner GUI

 

Image Scanner esempio

 

 

Come funziona

Con Arduino spediamo a Image Scanner le informazioni necessarie alla costruzione dell'immagine:

 

    Serial.print(distance); 
    Serial.print("/"); 
    Serial.print(panvalue); 
    Serial.print("/"); 
    Serial.print(index);  
    Serial.print("/"); 
    Serial.println(mode);

Come vedete spediamo come primo valore quello di distanza percepita (che ricordo puo' essere qualsiasi cosa, per esempio la temperatura percepita, oppure il suono percepito da un piezo, lascio spazio alla vostra fantasia), il secondo valore rappresentail valore di Pan, quindi di inclinazione verticale del nostro sensore, il terzo valore l'indice, cioè una variabile che contiene il numero di rilevazioni effettuate attualmente e la variabile mode, che indica se il sistema di Tilt sta ruotando da destra verso sinistra o viceversa. Image Scanner riceve la stringa con buffer ogni a capo e la suddivide in 4 valori suddivisi da /. Ottenuti i valori e correttamente trasformati in interi questi vengono utilizzati per rappresentare i pixel dell'immagine. La variabile distance contiene l'informazione che verrà trasformata in colore (in questo caso, 2m sarà nero e contatto o 0cm sarà bianco) con un semplice map. La variabile index rappresenta la x dei nostri pixel, la variabile panvalue invece la y. La variabile mode viene utilizzata per indicare a Image Scanner quando siamo arrivati a uno dei lati dell'immagine e quindi quando iniziare a tornare verso il lato opposto (esattamente come funziona una stampante o certi scanner a due assi).

 

Vediamo il codice lato Arduino completo (inserire la libreria servo.h perchè tutto funzioni correttamente):

Servo tiltservo; 
Servo panservo;  
 
int hometilt = 80;
int maxtilt = 109;
int homepan = 5;
int tiltvalue = 25;
int panvalue = 20;
// SENSORE ERER
#define irEmitter 13   // polo positivo emettitore - positive emitter pin
#define irReceiverN 3  // polo negativo ricevitore - negative receiver pin
volatile long ambient = 0;
volatile long emission = 0;
volatile long distance = 0;
volatile long lightTime = 0;
volatile int currentInit = 0;
volatile long gain = 4;       //gain crescita valore distanza
volatile long maxRangeValue = 666666;  //valore range massimo
volatile long maxRange = 2000; //distanza range massimo in mm
int advisor = 0;
int index = 0;
int mode = 1;




 
void setup() { 
  tiltservo.attach(9);
  panservo.attach(10);
  Serial.begin(9600);
} 

///////////////////////////SENSORE ERER////////////////////////////////////////
void focus() { 
 if(currentInit == 0){if(digitalRead(irReceiverN) == LOW){ ambientLightCheck();}}
 if(currentInit == 1){if(digitalRead(irReceiverN) == LOW){ reflectionLightCheck();}}
}

void ambientLightCheck() {
 ambient = micros() - lightTime;
 init(1);
}

void reflectionLightCheck() {
 emission = micros() - lightTime;
 distance = emission * (ambient / (ambient - emission));
 distance = map(distance, 0, maxRangeValue, 0, maxRange);
 if(distance <= 0) distance = 0;
 if(distance > 15) distance = sqrt(distance) * gain;
 advisor++;
 emission = 0; 
 ambient = 0;
 init(0);
}

void init(int emitter) {
 if(emitter == 0)digitalWrite(irEmitter, LOW);   
 if(emitter == 1)digitalWrite(irEmitter, HIGH); 
 lightTime = micros();
 pinMode(irReceiverN, OUTPUT);
 digitalWrite(irReceiverN, HIGH); //carico ricevitore di induttanza
 pinMode(irReceiverN, INPUT);
 digitalWrite(irReceiverN, LOW);
 if(emitter == 1) currentInit = 1;
 if(emitter == 0) currentInit = 0;
}
//////////////////////////////LOOP////////////////////////////////////////////////

void loop() { 
    focus(); // effettua rilevamento
    tiltservo.write(tiltvalue); //tilta
    panservo.write(panvalue);   //panna :P
    if(advisor == 1) {          //se la rilevazione è finita
    Serial.print(distance);     //manda distanza
    Serial.print("/"); 
    Serial.print(panvalue);     //manda y
    Serial.print("/"); 
    Serial.print(index);        //manda x
    Serial.print("/"); 
    Serial.println(mode);       //manda mode
    if(mode == 1){ tiltvalue = tiltvalue + 1;  index++; }  
    if(mode == 0){ tiltvalue = tiltvalue - 1;  index--;} 
    advisor = 0;
    if(index == 0 && mode == 0) { mode = 1; panvalue++;  panservo.write(panvalue); } 
    if(index == maxtilt) { mode = 0; panvalue++;  panservo.write(panvalue); }
  }
}

 

L'eseguibile

Come potete vedere dalla screenshot qui sotto in Image Scanner è presente una comoda GUI bar che vi permette innanzittutto di iniziare o stoppare lo scan, di salvare l'immagine ottenuta, o di cancellarla in previsione di una rappresentazione. Seguendo il consiglio di Lesto ho creato il file image.txt che contiene tutto il log dei dati ottenuti, suddivisi da a capo. Ogni linea contiene rilevazione (quindi colore), x, y e mode. Da questo file potremo in futuro lavorare su algoritmi di correzione dell'emisfericità intrinseca nella rappresentazione ed eventuale miglioramento / interpretazione dell'immagine ottenuta. In qualsiasi caso un datalogging fa comodo quindi l'ho aggiunto. Le immagini salvate dal programma vengono create nella directory principale di Image Scanner in formato png.

 

Image Scanner GUI

 

Sorgente ed eseguibile Linux32

Sorgente ed eseguibile Macosx

Sorgente ed eseguibile win32

Sorgente ed eseguibile win64

 

Gioblu Robotics © 2010 - 2012 · Sitemap · privacy

gioscarab@gmail.com

Gioblu BOTServer è online dal 10 Aprile 2010 - 319.232 Visite - 1.027.175 Pagine visualizzate - 182.309 Visitatori unici - 536 utenti attivi