thunderrobot

 #MAKE 

 14/01/14 

Un robot omnidirezionale derivato da quelli che usavamo per la RoboCup

Questo robot è derivato dai robot che avevamo fatto per partecipare alla RoboCup, con i quali avevamo vinto il campionato italiano e ci eravamo qualificati per i mondiali del Messico 2012.
Questo robot presenta molte caratteristiche tipiche dei nostri robot che giocavano a calcio, ovvero: la forma cilindrica per non incastrarsi negli angoli del campo di gioco, le ruote omnidirezionali per muoversi in qualsiasi direzione; i 24 ricevitori infrarossi per seguire la pallina da gioco, il modulo bluetooth per comunicare con il compagno di squadra, i sensori ultrasuoni e la bussola per orientarsi nel campo.
Oltre a tutto ciò, in questo robot abbiamo montato un LCD grafico con risoluzione 128x64 e una tastiera per poter scegliere le varie funzioni da far fare al robot, di tarare i sensori e di leggere i valori provenienti da essi.
Tutto questo sistema è controllato da un Arduino Mega2560 e da tre ATMEGA328 (Per intenderci sono i microcontrollori che sono usati nell'Arduino UNO, cioè praticamente ci sono quattro Arduino). L'Arduino Mega2560 ha il compito di gestire tutto il sistema in generale, quindi i motori, il display, la tastiera, la connessione bluetooth con l'altro robot e la comunicazione con gli altri microcontrollori. Contemporaneamente due dei tre ATmega328 montati sul robot vengono utilizzati per leggere i dati relativi ai ricevitori infrarossi; mentre l'altro ATmega ha la funzione di individuare la posizione nello spazio del robot tramite la lettura dei quattro sensori di distanza ad ultrasuoni e del sensore di bussola. La motivazione della scelta di un sistema formato da più microcontrollori è semplice e intuitiva: i sensori che vengono gestiti dagli ATmega328 hanno bisogno di letture continue per ridurre al minimo gli errori e, inoltre, questo permette di avere un sistema multitasking che velocizza tutte le operazioni.
Per quanto riguarda i movimenti, il robot sfrutta quattro motori DC totalmente indipendenti l'uno dall'altro e posizionati su due assi perpendicolari tra loro. I motori usati sono piuttosto potenti e veloci: possono ruotare fino a 500 RPM e hanno una coppia di 5 kg-cm. Dunque richiedono molta energia e, infatti, per controllarli sono stati usati quattro potenti ponti ad H integrati che permettono di controllare la velocità e il senso di rotazione dei motori mediante segnali PWM generati da un microcontrollore.
Per l'alimentazione dei robot viene usata una batteria LiPo da tre celle e 2000mAh perché è un ottimo compromesso tra peso, dimensioni e la potenza erogabile.

Come funziona?

In questa descrizione ci limiteremo alla spiegazione di come gestire i motori e le combinazioni delle relative velocità per muovere il robot in qualsiasi direzione, perché se dovessimo parlare di tutto il sistema sarebbe una descrizione infinita, dove la maggior parte del testo sarebbe codice che interesserebbe a pochi.
Dunque, facendo riferimento alla nostra guida su come utilizzare i nostri modelli di ruote omnidirezionali, proviamo a immaginare quali sono le combinazioni che servono per fare i movimenti basilari. Considerando che i motori sono tutti collegati con la stessa polarità, numeriamo per comodità i motori partendo da quello in alto a destra e procedendo in senso orario. Vediamo che se vogliamo muovere in avanti il robot dobbiamo far girare i motori di destra in avanti e i motori di sinistra all'indietro, mentre se vogliamo farlo andare 45° a destra basta che i motori 1 e 3 stiano fermi, con il motore 2 vada in avanti e il 3 che va indietro. Se invece vogliamo farlo andare a destra di 90° dobbiamo far ruotare i motori davanti all'indietro e quelli dietro in avanti. Per far andare il robot a 45° a destra all'indietro dobbiamo tenere fermi i motori 2 e 4, far girare in avanti il motore 3 e nel senso opposto il numero 1.
Gli altri movimenti rettilinei sono molto simili a quelli appena descritti e non ci dilunghiamo nella loro spiegazione, mentre passiamo a vedere i movimenti rotatori che sono molto semplici: se si vuole far ruotare il robot in senso orario tutti i motori devono ruotare all'indietro; al contrario, per ruotare in senso antiorario tutti i motori devono ruotare in avanti.
Dunque abbiamo visto quanto semplice sia gestire un robot che monti le nostre ruote omnidirezionali e come basti un po' di ragionamento per riuscire a muoverlo in ogni direzione.
Un'ultima cosa da notare è che la velocità massima raggiungibile dal robot muovendosi in modo rettilineo dipende da quanti motori si usano per il movimento: chiaramente quando va in diagonale usando solo due motori ha una velocità massima minore in confronto a quella ottenibile quando si muove utilizzando 4 motori.
Con questi ragionamenti si evidenzia che ogni motore deve essere gestito individualmente, dunque la prossima domanda a cui rispondere è: come gestire questi quattro motori?

Hardware

Per pilotare ogni motore singolarmente ognuno deve avere il suo circuito di controllo composto da dei driver, ecco perché nel nostro robot ci sono quattro VNH2SP30, che sono dei ponti ad H integrati prodotti dalla STMicroelectronics. Questi hanno la particolarità di essere SMD e di poter erogare fino a 30A sul carico senza surriscaldarsi, grazie anche alle adeguate zone di dissipazione del calore che gli sono state progettate nelle schede.
Nello schema sottostante si può vedere il circuito dedicato a ciascuno di questi integrati, per comodità consideriamo solo un VNH2SP30 poiché il circuito relativo agli altri driver è identico, cambiano solo i pin di comando provenienti dall'Arduino. Si nota che dal microcontrollore arrivano solo due linee di comando, una che va a finire sul pin denominato PWM e che serve per gestire la velocità di rotazione del motore e che è in comune per tutti i motori. Mentre l'altro pin dell'Arduino serve per controllare il senso di rotazione del motore: questa linea va diretta all'ingresso A dell'integrato, mentre arriva all'ingresso B attraverso una porta NOT, così che i due ingressi del ponte ad H abbiano sempre livelli logici opposti. Questo è molto comodo perchè permette di risparmiare un'uscita del microcontrollore.



Passando al circuito specifico dell'integrato si notano i pin di alimentazione di GND e di VCC, che in questo integrato può essere al massimo di 41V; poi c'è il pin di Current Sensing (CS) che fornisce un'uscita analogica proporzionale alla corrente che sta assorbendo il carico, nel nostro caso è stato lasciato libero perché non c'era interesse particolare per questo dato. Ci sono inoltre due pin un po' particolari che si chiamano "enable/diagnostic" e hanno due funzioni: normalmente sono degli input che abilitano o meno il funzionamento dei semi ponti ad H relativi agli ingressi e alle uscite A e B (funzione enable); mentre se ci sono dei problemi sull'integrato fungono da segnalatori del guasto (funzione diagnostic). In questo circuito sono stati usati solo come enable collegandoli ad una resistenza di pull-up, visto che l'applicazione è piuttosto semplice e nel caso ci fossero problemi sarebbero comunque facilmente individuabili. Arriviamo dunque alla parte finale di questa spiegazione sull'uso del VNH2SP30: il collegamento delle uscite con i motori. Infatti, c'è da prestare molta attenzione a quei diodi che vanno a VCC e a GND, a prima vista magari potrebbero sembrare inutili, ma in realtà sono fondamentali per evitare grossi problemi. Come forse saprete, i motori hanno una componente induttiva e, quindi, ad ogni variazione di corrente a cui sono sottoposti, producono delle tensioni inverse che possono danneggiare il resto dei componenti elettronici presenti nel circuito. Quei diodi servono dunque a "tagliare" questi picchi di tensione così da evitare danni al driver e agli altri integrati. In genere per svolgere questa funzione vengono usati diodi schottky che si polarizzano con una tensione più massa e dunque più velocemente degli altri. Ora non ci resta che capire che segnali dobbiamo dare in pasto ai nostri potentissimi ponti ad H e come produrli dal nostro programma.

Software

Di seguito descriveremo la parte di codice utilizzata per gestire i 10 movimenti basilari, più precisamente la funzione che viene usata per gestire tali movimenti.
I valori di m1, m2, m3 e m4 indicano la percentuale del duty cycle del segnale PWM.

/*
 La variabile speed può assumere valori da 0 a 255 e va a regolare
 la velocità di rotazione di tutti i motori. 

 La variabile direction può assumere i seguenti valori:
 - 0 per far star fermo il robot;
 - 1 per far muovere il robot in avanti rispetto all'asse 0;
 - 2 per far muovere il robot in avanti rispetto all'asse a 45°;
 - 3 per far muovere il robot in avanti rispetto all'asse a 90°;
 - 4 per far muovere il robot in avanti rispetto all'asse a 135°;
 - 5 per far muovere il robot indietro rispetto all'asse 0;
 - 6 per far muovere il robot indietro rispetto all'asse a 45°;
 - 7 per far muovere il robot indietro rispetto all'asse a 90°;
 - 8 per far muovere il robot indietro rispetto all'asse a 135°;
 - 9 per fare ruotare il robot su se stesso in senso orario;
 - 10 per fare ruotare il robot su se stesso in senso antiorario.
*/

void Move(byte direction, byte speed)
{ 
  // Controlla che il valore di speed richiesto non sia sopra il limite
  speed=speed>100?100:speed;
  
  // Il pin 39 è un ingresso usato per abilitare o disabilitare il limitatore di velocità
  // se è a livello basso dimezza la velocità
  speed=digitalRead(39)==0?speed/2:speed; 
  
  // Aggiorna il valore della velocità
  motor.setPWM(2,speed);
  
  byte m1,m2,m3,m4;

  // Sceglie quale movimento fare in base al valore di direction inserito
  switch(direction){
  
  // Direzione 1 -> i motori 1 e 2 girano in avanti e i motori 3 e 4 all'indietro  
  case 1:{  
      m1=100; 
      m2=100; 
      m3=0; 
      m4=0; 
    }
    break;

  // Direzione 2 -> i motori 1 e 3 stanno fermi, il motore 2 gira in avanti e il 4 all'indietro
  case 2:{  
      m1=50; 
      m2=100; 
      m3=50; 
      m4=0; 
    }
    break;

  // Direzione 3 -> i motori 2 e 3 girano in avanti e i motori 1 e 4 all'indietro
  case 3:{  
      m1=0; 
      m2=100; 
      m3=100; 
      m4=0; 
    }
    break;
  
  // Direzione 4 -> i motori 2 e 4 stanno fermi, il motore 3 gira in avanti e l'1 all'indietro
  case 4:{  
      m1=0; 
      m2=50; 
      m3=100; 
      m4=50; 
    }
    break;

  // Direzione 5 -> i motori 3 e 4 girano in avanti e i motori 1 e 2 all'indietro
  case 5:{  
      m1=0; 
      m2=0; 
      m3=100; 
      m4=100; 
    }
    break;
    
  // Direzione 6 -> i motori 1 e 3 stanno fermi, il motore 4 gira in avanti e il 2 all'indietro
  case 6:{  
      m1=50; 
      m2=0; 
      m3=50; 
      m4=100; 
    }
    break;

  // Direzione 7 -> i motori 1 e 4 girano in avanti e i motori 2 e 3 all'indietro
  case 7:{  
      m1=100; 
      m2=0; 
      m3=0; 
      m4=100; 
    }
    break;

  // Direzione 8 -> i motori 2 e 4 stanno fermi, il motore 1 gira in avanti e il 3 all'indietro
  case 8:{  
      m1=100; 
      m2=50; 
      m3=0; 
      m4=50; 
    }
    break;
  
  // Direzione 9 -> tutti i motori girano all'indietro
  case 9:{  
      m1=0; 
      m2=0; 
      m3=0; 
      m4=0; 
    }
    break;

  // Direzione 10 -> tutti i motori girano in avanti
  case 10:{ 
      m1=100; 
      m2=100; 
      m3=100; 
      m4=100; 
    }
    break;

  // Tutti i motori fermi
  case 0:
  default:{  
      m1=50; 
      m2=50; 
      m3=50; 
      m4=50; 
    }
    break;
  }

  // Aggiorno i segnali PWM
  motor.setPWM(3,m1);
  motor.setPWM(4,m2);
  motor.setPWM(5,m3);
  motor.setPWM(6,m4); 
}

Risultato

Dunque cosa si ottiene facendo tutto quello che abbiamo descritto finora? La risposta è semplice e basta guardare un video a caso dei tanti presenti su YouTube del nostro ThunderRobot o le foto presenti sulla nostra pagina facebook negli album "Working on ThunderRobot" e "ThunderRobot".


CONTATTI

Al momento non abbiamo un uffico,
ma siamo spesso tra Padova e Vicenza.
Se avete bisogno di incontrarci,
contattateci e ci organizzeremo.

Di solito rispondiamo rapidamente, se non ricevete
alcuna risposta basta che mi rimandiate l'email
o che proviate un altro metodo.
Info@VicenzaThunders.com

Attenzione: se avete bisogno di chiamarci, vi
suggeriamo di spedirci un'email o un SMS prima
perché non siamo sempre disponibili.
Potete anche utilizzare WhatsApp se volete.
+393484808073
+393494548359

Potete trovarci su molti social network,
quando abbiamo tempo ci piace condividere
i nostri lavori e le nostre esperienze!