Autobilanciamento meccanico (Arduino equilibrista)

Salve a tutti,
ho iniziato un nuovo esperimento, e cioè voglio creare un sistema di autobilanciamento su un bilico per arduino.
1 prova)

Componenti:
1 potenziometro da 2.2k
1 mini servo mg90
1 bullone esagonale (pesante)
1 vite lunga con altri pesi montati in cima.
1 psu 7805 per il servo

Montaggio:
ho montato il potenziomatro (contatti verso l’alto) , su una base in legno, con l’albero sporgente ed ho fissato in maniera solidale all’albero un braccio con un peso che lo tiene a metà corsa (il bullone esagonale).
dal lato opposto della base in legno ho fissato il servo, ed alla sua crociera ho fissato la vite con i pesi scorrevoli (tutti in cima per la prima prova).

Software:
L’esempio servo knob :wink: K.I.S.S.

Prova sul campo:
posto il tutto su un bilico, muovendo la base con la mano il servo muove il peso in direzione opposta tentando di controbilanciare la pressione della mano.
direi che è l’effetto che volevo…
Ma andiamo oltre…

2 prova)
Componenti:
2 sensori sharp GP2D12
1 solito servo
1 solita vite con pesi montati in cima
1 psu 7805 per il servo ed i sensori

Montaggio:
ho posizionato i due sensori a infrarossi sotto la base in legno, uno in testa ed uno in coda (come il robot di gbm).
il servo e montato come nella prova precedente.

Software:
Questa volta ho messo giù qualche riga di sw per leggere la distanza sei sensori dal suolo e istruire il servo a spostarsi in caso di sbilanciamento dalla posizione di 0 (90°).

#include <Servo.h>
#define IRFront          2
#define IRBack          3
int frontSense = 0; //sensore ir anteriore
int backSense = 0;  //sensore ir posteriore
Servo myservo;  // creo oggetto servo per il controllo  
int val ;    // variable per posizione servo

void setup() 
{ 
  Serial.begin(9600);
  val=90;                   //servo al centro, si parte paralleli al suolo
  myservo.attach(9);  // assegno il servo al pin 9
} 
 void getValues() {
  frontSense = 0;
  backSense = 0;
 for (int i = 0; i < 10; i++) {
  frontSense = analogRead(IRFront) + frontSense;
  backSense = analogRead(IRBack) + backSense;
  if (i == 9) {
   frontSense = frontSense / 10;
   backSense = backSense / 10;
    
  }}}

void loop() { 
  val=90;
  getValues();          //leggi i dati e posiziona il servo in base allo sbilanciamento
  if (frontSense > backSense) val++;
  if (frontSense < backSense) val--;
  if (frontSense == backSense) val=90;
  Serial.print("FS:");          //un pò di debugging
  Serial.println(frontSense);
  Serial.print("BS:");
  Serial.println(backSense);
  //val = map(val, 0, 1023, 0, 179);     // scalo o no? ci penserò dopo 
  myservo.write(val);   // posiziona il servo
  Serial.print("Servo_Pos:");
  Serial.println(val);

  delay(15);      // aspettiamo il servo...
  }

Prova sul campo:
Non riesco a leggere dei valori affidabili e coerenti dai sensori!
e non capisco perchè… dove sbaglio?

A parte la "divina commedia" (che non ho avuto la pazienza di leggere), non è che posteresti un disegnino sul "coso" che hai costruito e che vuoi controllare (con la posizione di attuatori e sensori previsti). Io riesco a ragionare meglio se "vedo" quello che faccio... ::)


aggiungo: per quel che posso aver intuito credo che per gestire cose come quella che stai facendo non sarebbe male rispolverare un pochino di fuzzy logic...

Provo ad aggiungere un'immagine:

i sensori sono sotto la base, che guardano il suolo ed il servo è sopra la base ed al centro (fra i due sensori) con il "braccio" che sporge dal lato dx. sul braccio del servo c'è una vite lunga più o meno 10cm, alla quale in cima ho messo un megacuscinetto a sfera, che pesa quasi quanto tutta la base.(sembra un martello)

Ciao Brain. Leggi pvt. hehehe queste soluzioni tecniche mi ricordano qualcosa ::). Senti ma stai utilizzando sensori SHARP? Occhio perchè nell'esempio: http://www.gioblu.com/index.php?option=com_content&view=article&id=100:self-balancing-robot-per-noobs-p&catid=36:robotica&Itemid=34 Come ha specificato Guiott' nel important thread robotica, i valori dei due sensori sotto i 3cm semplicemente si invertono (cioè la luce riflessa è inversamente proporzionale alla distanza sotto i 3cm, di conseguenza il dato scende invece che salire), questo potrebbe darti qualche noia. Posta qualche foto sarei curioso di vedere la realizzazione!!!! ;)

Azz! la storia dei sensori l'avevo vista ma non sapevo che fosse lineare ed usabile :) questo spiega molte cose.... Adesso riguardando il sw. mi sono accorto che è profondamente sbagliato! e che forse dovrei usare un pò di trigonometria e tirare fuori l'angolo di inclinazione dalla distanza del sensore (anche uno solo) dal suolo, per darlo al servo invece della schifezza che ho pensato in prima battuta. o no? ;D

Sì, la faccenda dell'inversione della lettura del sensore SHARP è roba vecchia... già nel 2008 proprio in questo forum al post:http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1200939322/3 tra le altre cose scrivevo:

... se effettui una misura con il sensore e la confronti con la successiva puoi chiaramente determinare a che distanza è dall'ostacolo. Così, se l'ostacolo è a + di 20cm, avvicinandoti la distanza diminuisce, ma se invece la distanza (avanzando) aumenta (se guardi le specifiche del GP2Y0A02YK0F capisci cosa voglio dire), allora vuol dire che il sensore rileva un oggetto più vicino di 20cm. Così, con un semplice calcolo, è possibile determinare con discreta precisione anche distanze inferiori estendendo di fatto la portata del sensore.

E proprio su questa semplice intuizione (confrontare due letture) ho anche pubblicato sul mio blog un tutorial (vedi qui: http://kokiua.wordpress.com/tutorial/servo-a-rotazione-continua/ ) per creare con costi irrisori un buon encoder assoluto adatto ad un servo modificato per non fermarsi mai (così come avevo promesso avrei fatto recentemente in un altro post ;) )

Grazie per le risposte :slight_smile:
avevo fatteo delle ricerche ed avevo anche visto il post di kokiua ma siccome ero in cerca di info precise non ho approfondito perchè riguardava il GP2Y0A02YK0F ed io ho il gp2d12… :stuck_out_tongue:
P.S.
ho visto anche l’encoder per servi a rotazione continua… geniale!
sopratutto perchè e semplice come concetto!
considerazioni a posteriori: quanto dura lo slider usato così? e la resistenza opposta dal potenziometro non incide sul servo? se ne monti due, per due ruote, poi queste gireranno alla stessa velocità? ::slight_smile:

non ho approfondito perchè riguardava il GP2Y0A02YK0F ed io ho il gp2d12..

Iil sistema di rilevamento è identico, cambia solo il sistema ottico, quindi il "giochetto" vale per entrambi ;) Sul discorso dell'encoder invece: la resistenza meccanica (sia come opposizione al moto che come durata di vita) di un potenziometro a slitta è uguale a quella di uno a rotazione se sono costruiti entrambi con materiale di qualità ;) Se pensi ai mixer audio e video, esistono slider molto robusti...

se ne monti due, per due ruote, poi queste gireranno alla stessa velocità?

se lo slider è di ottima qualità non dovrebbe avere diverso attrito... certo che se si usano dei potenziometri a slitta di recupero e magari anche di tipo/lunghezza diversa tra loro (ivi compresa la rotellina), le cose si complicano di parecchio :-?

Resta il fatto però che questo sistema lo si può adottare anche nel caso di motori cc pilotati tramite PWM, nel qual caso puoi compensare la velocità garantendoti che il tutto vada davvero dove desideri.. (per questo io non monterei mai dei servo per muovere delle ruote... ;) )

hai ragione, anche se gli slider "serii" possono costare più dei servi... per il montaggio sui motori dc invece ho ancora qualche dubbio... quando vai molto veloce, l'attrito dei contatti striscianti potrebbe riscaldare il layer di carbone falsando la lettura ::). adesso che mel'hai detto, ho letto tutto il post :P , a volte la fretta....

quando vai molto veloce, l'attrito dei contatti striscianti potrebbe riscaldare il layer di carbone falsando la lettura

noooo ... non puoi/devi considerare la soluzione del potenziometro con della velocità in gioco.. e che te ne fai di sapere la posizione esatta se devi correre???

Infatti anche i servi non possono lavorare in continuazione a piena velocità, perchè anche li c'è un potenziometro che può subire il problema che hai ricordato (il riscaldamento). Non a caso se lo noti i servi che lavorano di continuo sono soggetti o a modificare la precisione del posizionamento, o ad iniziare una sorta di parknison incontrollabile :o

Io ho pensato al classico robottino che deve gironzolare per un ambiente seguendo/tracciando una mappa.. non ha bisogno certo di correre, o no?

non avevo capito che la soluzione era solo per "andamenti lenti" ;D però questo è un limite che coincide con la definizione di "veloce" e quindi non è universalmente applicabile (come avevo capito io).

Dubbio: per avere l'angolo di inclinazione dalla base avendo la distanza letta dal sensore al suolo devo fare arctan(distanza) ? o ricordo male?

Mi fa piacere che la mia intuizione utilizzata qui: http://www.gioblu.com/index.php?option=com_content&view=article&id=100:self-balancing-robot-per-noobs-p&catid=36:robotica&Itemid=34

abbia ispirato il tutorial di kokuia, in effetti è un utilizzo molto intelligente del sistema logico utilizzato per far stare in piedi PICO.

Sarebbe carina una citazione, vista la licenza di creative commons che puoi ben leggere sotto ;). (grazie)

L'idea è carina. Trovo che visto che esistono gli encoder ottici, e che la tecnologia ferroviaria è ormai datata :D, sia un sistema ottimo per spiegare la teoria della "misurazione differenziale data da due input" come mi sono permesso di chiamarla, ma è decisamente poco applicabile, calcolando la quantità di attrito e consumo del sistema. In piu' rende piu' complesso un sistema che puo' essere optoelettronico e non meccanico. Se riuscite è sempre meglio eliminare punti di giunzione meccanici con soluzioni prive di attriti. (come puo' esserlo la luce infrarossa).

X brain credo tu stia andando un po' oltre, utilizza il principio KIS se riesci (keep it simple), dai un occhio al codice del link sopra. Non c'è bisogno di calcolare l'effettiva inclinazione, ma basta sapere la differenza tra le due letture. Calcola che cambiamento di opacità (imperfezioni o irregolarità) nella superficie sottostante falsano decisamente la lettura. Vista la bassa precisione del sistema è inutile studiare un modo per ottenere l'effettiva inclinazione (almeno secondo me).

Se proprio devi, si puoi utilizzare le trigonometria, un esempio lo puoi trovare qui: http://www.gioblu.com/index.php?option=com_content&view=article&id=98:filtro-di-kalman-con-arduino&catid=38:programmazione&Itemid=7

nel codice a linea 133.

@gbm grazie della risposta, ho dato un'occhiata al kalman riga 133 ma lì vedo 2 termini, io pensavo che ne bastasse uno :o cioè in teoria potrei anche usare un solo sensore per sapere l'angolo di inclinazione.. o no?

Si ma in modo molto meno preciso!! Se hai due sensori e la opacità della superficie riflettente cambia solo su uno dei due, avrai un impatto sulla stabilità del sistema molto piu' basso!! In parole povere con una misurazione differenziale ottieni un dato molto piu' pulito ed affidabile rispetto che affidandoti a un solo sensore, in piu' dovresti calcolare qual'è lo 0 del sensore unico che utilizzi (valore che varierà in rapporto alla tensione in ingresso e alla superficie riflettente), invece se utilizzi due sensori e sottrai una lettura all'altra, otterrai lo 0 automaticamente senza dovertelo calcolare!!! Credo che sia principalmente questo il punto di forza del mio semplicissimo algoritmo!!! ;)

vedi la funzione getOrientation linea 33 primo codice: http://www.gioblu.com/index.php?option=com_content&view=article&id=100:self-balancing-robot-per-noobs-p&catid=36:robotica&Itemid=34

ho capito quello che intendi, ma il giochino non deve camminare, deve solo stare in equilibrio statico. per quello camminante aspetto di avere i materiali ;) per il momento tolgo un pò di ruggine dai neuroni e rispolvero un pò di matematica... ;D tornando all'angolo, adesso per curiosità, ricordavo giusto allora quando dicevo angolo=arctan(distanza)?

@gbm: cito:

Mi fa piacere che la mia intuizione utilizzata qui: http://www.gioblu.com/index.php?option=com_content&view=article&id=100:self-bala... abbia ispirato il tutorial di kokuia, in effetti è un utilizzo molto intelligente del sistema logico utilizzato per far stare in piedi PICO. Sarebbe carina una citazione, vista la licenza di creative commons che puoi ben leggere sotto . (grazie)

A cosa diavolo ti riferisci?? Se proprio dobbiamo essere così fiscali credo sia tu a dovermi riconoscere qualcosa, visto che il tuo articolo è datato Martedì 29 Giugno 2010 00:17, mentre il mio post che parla dei sensori SHARP è del 2008... E poi di quale tutorial parli, di quello dei servo? E cosa c'entra con il tuo progetto??

gbm hai per caso dormito poco e fai confusione con i vari post che leggi??

questo articolo: http://www.gioblu.com/index.php?option=com_content&view=article&id=100:self-balancing-robot-per-noobs-p&catid=36:robotica&Itemid=34

il tuo tutorial http://kokiua.wordpress.com/tutorial/servo-a-rotazione-continua/ si basa palesemente sul mio, quindi ti richiedevo semplicemente una citazione ;) (come prevede la licenza con cui è rilasciato il mio articolo)

(cioè il calcolo differenziale di due dati input per ottenere un terzo valore di posizione) Nel tuo tutorial utilizi due potenziometri lineari (secondo me scelta abbastanza deprecabile, ma questo è il meno), io utilizzo due sensori ir, ma intellettualmente e logicamente è lo stesso sistema. E non si sta parlando a che distanza vengono utilizzati i sensori (e della loro eventuale inversione di tendenza) ma del MODO IN CUI VENGONO UTILIZZATI PER OTTENERE UN VALORE DI POSIZIONE.

Sono felice che cmq ti sia servito e spero possa tornare utile a molti altri. :D

Buona sperimentazione a te e a tutti gli altri! Buona fortuna e buon proseguimento per il tuo progetto di visione arduinica ;).

@gbm: chiunque può vedere che è il tuo progetto al link che indichi ad avere dei contenuti che possono essere stati una conseguenza di quanto scrissi nel 2008 a questo post: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1200939322/3

Quindi, se proprio insisti, diciamo che dovresti citare il mio post sul tuo articolo nel tuo sito ringraziandomi per la mia intuizione di allora che ti ha permesso di realizzare il tuo progetto.

Ok? ;)

(e spero che sta cosa non vada oltre perchè è palesemente OT)

dai, in questo caso "fra i due litiganti il terzo " non gode :( e poi le idee sono come i figli, se tu non puoi dargli un futuro le fai adottare da qualcun altro e speri che crescano :)