Show Posts
Pages: 1 [2] 3 4 ... 7
16  Topics / Robotics / Re: AutoBalance - PID Controller on: January 17, 2013, 12:40:42 pm
I have another question, which are the equations of the P, I and D?
Mine are right? I have to limit the I?

I'm trying to tune it but seems that there is something wrong...
17  Topics / Robotics / Re: AutoBalance - PID Controller on: January 16, 2013, 04:13:33 pm
Try a Google search for: balancing robot PID tuning
Hehehe I'll read some stuff for sure!  smiley-grin

My principal worry is how understand where is the problem!
I don't know about the code for these things, but there is a good resource on balancing bots
here, and 40-50 additional links, so someone in there probably talks about these matters.

http://www.geology.smu.edu/~dpa-www/robo/nbot/
Thank you very much!
I found a similar project there, but unfortunately the link doesn't work... (and with the web search of that project i don't find nothing)
However it's very interesting (and more professional than mine)


Thank you all for the answers!

Soon i'll make a video while it works!
18  International / Software / Re: AutoBalance - Controllo PID on: January 16, 2013, 05:26:39 am
Grazie mille per la risposta!  smiley-grin

Se ti posso chiedere una cosa, le formule che hai usato per il calcolo del PID, sono uguali a quelle che ho usato io?
E come invii il valore del PID ai motori? sempre nello stesso modo?

Ok!
Come rimonto il tutto farò un video!  smiley

E grazie per i consigli su come regolare i coefficienti!
Non sapevo proprio come fare, come posso rifaccio qualche prova, e provo a regolarli imitando il tuo metodo  smiley-mr-green


edit. Mi interessa particolarmente il calcolo della I (del pid)  smiley-grin
La I assume valori troppo grandi, penso che ci sia qualche errore nel suo calcolo..

Per fargli assumere un valore nell'ordine delle centinaia ho dovuto mettere un kI = 0.00005;  o.o'

edit.2 Pensandoci, una cosa che mi darebbe un grande aiuto sarebbe conoscere quale ordine di grandezza assumo P, I e D durante il funzionamento smiley-grin (P suppongo 10 o 10², gli altri due?)
Ed un'ultima cosa, il valore di I và limitato in qualche modo? O deve essere libero di salire o scendere di qualsiasi valore? (in alcuni esempi trovati online ho visto che veniva limitato)
19  Topics / Robotics / Re: AutoBalance - PID Controller on: January 16, 2013, 05:21:54 am
PID loops require tuning so I suspect that your first guesses for kP, kI, and kD are not optimal.
I tried to do some tuning... but, How can i tune it?  It has to be adjusted only with experimental tests?
20  Topics / Robotics / AutoBalance - PID Controller on: January 14, 2013, 01:39:28 pm
Hi all!  smiley-grin
I'm building an AutoBalance Robot, one of those robots that are able to maintain the balance with two wheels.

The goal of this project, for now, is only to maintain the balance on a plan.
Without climbs, descents, external forces and without the control of the movement.

The mechanical part is done.
Unfortunately I do not have a photo on hand, so I put a render to give you an idea of how it's made:

http://oi47.tinypic.com/2le303k.jpg

The "robot" is composed of a Arduino ONE, two analog sensors SHARP (GP2Y0A21YK0F), two gearmotors (SBGM9) and a driver motor made ​​by me (if you want  i will put the circuit diagram).
The first floor is empty for now, there will be the batteries. (For now I'm doing the tests with flying leads)

The problem is... the robot does not maintains the balance! smiley-grin

I copied the part of the PID controller from here: http://schianorobotics.altervista.org/SISTEMI_DI_CONTROLLO_MULTIVARIABILE.pdf (at the end of the document there is the skecth), the rest is made by me...

I don't know if the problem is in the sketch, or that I'm not able of handling a PID or that the two gear motors are not suitable (with a very low value of PWM they don't move...), and i must change them with two servomotors... (I hope not...)

Here there is the Sketch:

Main Program:
Code:
// Define sensors pins
#define sensore1 A0                           // Define pin sensor 1
#define sensore2 A1                           // Define pin sensor 2

// Define motors pins
#define motore1 3                             // Define the PWM pin of motor 1
#define motore2 5                             // Define the PWM pin of motor 2

// Variables for distances front and rear
int distanzas1 = 0;                             // Value read from sensor 1
int distanzas2 = 0;                             // Value read from sensor 2

// Counters support
int C;                                             // Counter support
int J;                                             // Counter support

// Variables for the filtering of the measures
int arrays1[10];                            
int arrays2[10];              
int n = 20;                                     // number of measurements
int somma = 0;                              // Variable for the calculation of the sum
int appoggio;                                 // Variable support for sorting the array

// Variables to calculate the orientation
int orientamento = 0;                      // Orientation
int previousorientamento = 0;           // Previous orientation

// variables for the calculation of the PID
float time = 0;                               // Current time
float previousTime = 0;                   // Previous time
float interval = 0;                           // Time taken for the execution of a program cycle

//  PID Variables
float P = 0;                                  
float I = 0;                              
float D = 0;                            
float PID = 0;                                

// Gains of the PID coefficients
float kP = 12;                                
float kI = 430;                            
float kD = 20;                            

void setup()
{
    Serial.begin( 9600 );                  
    pinMode( motore1, OUTPUT );          
    pinMode( motore2, OUTPUT );              
}

void loop()                                
{  
  controllomotori( getPID() );
  
  Serial.print( "Distanza S1 =  " );                        // Print to the  monitor all data
  Serial.print(  analogRead( sensore1 ));                      
  Serial.print( "  DS1 Filtrata =  " );    
  Serial.print( distanzas1 );  
  Serial.print( "  Distanza S2 =  " );    
  Serial.print(  analogRead( sensore2 ));                      
  Serial.print( "  DS2 Filtrata =  " );    
  Serial.print( distanzas2 );
  Serial.print( "  Orientamento =  " );    
  Serial.print( orientamento );
  Serial.print( "  P =  " );    
  Serial.print( P );
  Serial.print( "  I =  " );    
  Serial.print( I );
  Serial.print( "  D =  " );    
  Serial.print( D );
  Serial.print( "  PID =  " );    
  Serial.print( PID );
  Serial.print( "  To Motori =  " );
  Serial.println( ( 255 / 2 ) + PID );
  
  previousorientamento = orientamento;         // Previous orientation  
}

Data Acquisition:
Code:
int getdistanzas1()                             // Algorithm for the acquisition of the distance s1
{
  for ( C = 1; C <= n; C++ )                          // Read  20 values ​​from sensor 1, and writes them in an array
  {
    arrays1[C] = analogRead( sensore1 );
  }  
    
  for ( C = 1; C <= n; C++ )                         // Sorts the array in ascending order
  {
    for ( J = (C + 1); J <= n; J++ )
    {
      if ( arrays1[C] > arrays1[J] )
      {
        appoggio = arrays1[C];
       arrays1[C] = arrays1[J];
arrays1[J] = appoggio;
      }
    }
  }
  
  somma = 0;
  
  for ( C = 6; C <= ( n - 5 ); C++ )                 // Does not consider the highest and the lowest values
  {
    somma = somma + arrays1[C];
  }
  
  distanzas1 = somma / ( n - 10 );                // Make the average of the values
  
  return( distanzas1 );                          
}  




int getdistanzas2()                                    // Algorithm for the acquisition of the distance s2 ( as the sensor 1)
{
  for ( C = 1; C <= n; C++ )                    
  {
    arrays2[C] = analogRead( sensore2 );
  }  
    
  for ( C = 1; C <= n; C++ )                    
  {
    for ( J = (C + 1); J <= n; J++ )
    {
      if ( arrays2[C] > arrays2[J] )
      {
        appoggio = arrays2[C];
       arrays2[C] = arrays2[J];
arrays2[J] = appoggio;
      }
    }
  }
  
  somma = 0;
  
  for ( C = 6; C <= ( n - 5 ); C++ )          
  {
    somma = somma + arrays2[C];
  }
  
  distanzas2 = somma / ( n - 10 );          
  
  return( distanzas2 );                          
}

PID Controller, and Orientation:
Code:
int getPID()                                                 // Algorithm for the calculation of the PID
{
  getorientation();                                                // Invokes the function to obtain the orientation  
  previousTime = time;                                           // Save the time of the previous cycle
  time = millis();
  float interval = time - previousTime;                      // Calculate the time it takes to run a cycle
  
  P = orientamento * kP;                                          
  I = I + interval * kI * P;                              
  D = kD * ( orientamento - previousorientamento ) / interval;  
  
  PID = P + I + D;                                            
  
  if( PID >= 255/2 ) PID = 255/2;                              // If the value exceeds 255/2, the value is set to 255/2
  if( PID <= -255/2 ) PID = -255/2;                           // If the value is less than -255 / 2, the value is set to -255 / 2

  
  if(PID <= 1 && PID > 0) PID = 0;                            // Approximates the PID to 0
  if(PID >= -1 && PID < 0) PID = 0;                              
  
  return( PID );                                                  
}

void getorientation()                                              // Algorithm for calculating the orientation
{
  orientamento = getdistanzas1() - getdistanzas2();    // Difference between the distances detected by the two sensors

}

Motors Control:
Code:
void controllomotori ( int PID )                        // Algorithm for controlling two motors
{
  analogWrite( motore1, ( 255 / 2 ) + PID );          
  analogWrite( motore2, ( 255 / 2 ) + PID );        
}

The data acquisition works well enough, but i'm going to optimize it.

The robot try to get the balance, but absolutely does not maintain it...

What do you think?
Where can be the problem? The PID? The Gear Motors? Some problems in the Sketch?

Thanks very much in advance. smiley-grin


p.s. Sorry for my english, i hope it is understandable smiley
21  International / Software / Re: AutoBalance - Controllo PID on: January 13, 2013, 03:55:04 pm
Vi allego lo Sketch: (L'ho diviso in schede per comodità)

Main Program:
Code:
// Definizione dei pin utilizzati dai sensori
#define sensore1 A0                           // Definisce il pin del sensore1
#define sensore2 A1                           // Definisce il pin del sensore2

// Definizione dei pin utilizzati dai motori
#define motore1 3                             // Definisce il pin PWM a cui il motore1 è collegato
#define motore2 5                             // Definisce il pin PWM a cui il motore2 è collegato

// Variabile per le distanze anteriore e posteriore
int distanzas1 = 0;                           // Valore letto dal sensore1
int distanzas2 = 0;                           // Valore letto dal sensore2

// Contatori d'appoggio
int C;                                        // Contatore d'appoggio
int J;                                        // Contatore d'appoggio

// Variabili per il filtraggio delle misure
int arrays1[10];                              // Array di appoggio per la rilevazione della distanza1
int arrays2[10];                              // Array di appoggio per la rilevazione della distanza2
int n = 20;                                   // Numero di volte che si deve effettuare la misura, per il calcolo della media
int somma = 0;                                // Variabile di appoggio per il calcolo della media
int appoggio;                                 // Variabie di appoggio per l'ordinamento degli array

// Variabili per il calcolo dell'orientamento
int orientamento = 0;                         // Inclinazione dell'AutoBalance, in funzione delle distanze rilevate
int previousorientamento = 0;

// Variabili temporali, per il calcolo del PID
float time = 0;                               // Tempo auttuale, dall'accensione del dispositivo
float previousTime = 0;                       // Tempo del precedente ciclo
float interval = 0;                           // Tempo impiegato per l'esecuzione di un ciclo di programma

// Variabili PID
float P = 0;                                  // Variabile PROPORZIONALE  del PID
float I = 0;                                  // Variabile INTEGRATIVA del PID
float D = 0;                                  // Variabile DERIVATIVA del PID
float PID = 0;                                // Parametro PID

// Guadagni dei coefficenti PID
float kP = 12;                                // Variabile PID PROPORZIONALE
float kI = 430;                               // Variabile PID INTEGRATIVA
float kD = 20;                                // Variabile PID DERIVATRIVA

void setup()
{
    Serial.begin( 9600 );                     // Avvia la comunicazzione seriale
    pinMode( motore1, OUTPUT );               // Imposta il pin del motore1 come uscita
    pinMode( motore2, OUTPUT );               // Imposta il pin del motore2 come uscita
}

void loop()                                   //  In Debug
{  
  controllomotori( getPID() );
  
  Serial.print( "Distanza S1 =  " );    
  Serial.print(  analogRead( sensore1 ));                      
  Serial.print( "  DS1 Filtrata =  " );    
  Serial.print( distanzas1 );  
  Serial.print( "  Distanza S2 =  " );    
  Serial.print(  analogRead( sensore2 ));                      
  Serial.print( "  DS2 Filtrata =  " );    
  Serial.print( distanzas2 );
  Serial.print( "  Orientamento =  " );    
  Serial.print( orientamento );
  Serial.print( "  P =  " );    
  Serial.print( P );
  Serial.print( "  I =  " );    
  Serial.print( I );
  Serial.print( "  D =  " );    
  Serial.print( D );
  Serial.print( "  PID =  " );    
  Serial.print( PID );
  Serial.print( "  To Motori =  " );
  Serial.println( ( 255 / 2 ) + PID );
  
  previousorientamento = orientamento;         // Orientamento al ciclo precedente  
}


Acquisizione Dati:
Code:
int getdistanzas1()                              // Algoritmo per l'acquisizione della distanza s1
{
  for ( C = 1; C <= n; C++ )                     // Legge 20 valori dal sensore1, e li trascrive in un array
  {
    arrays1[C] = analogRead( sensore1 );
  }  
    
  for ( C = 1; C <= n; C++ )                     // Ordina l'array in modo crescente
  {
    for ( J = (C + 1); J <= n; J++ )
    {
      if ( arrays1[C] > arrays1[J] )
      {
        appoggio = arrays1[C];
       arrays1[C] = arrays1[J];
arrays1[J] = appoggio;
      }
    }
  }
  
  somma = 0;
  
  for ( C = 6; C <= ( n - 5 ); C++ )             // Non considera gli estremi
  {
    somma = somma + arrays1[C];
  }
  
  distanzas1 = somma / ( n - 10 );               // Effettua la media dei valori
  
  return( distanzas1 );                          // Ritorna il valore distanzas2 oppurtunamente filtrato
}  




int getdistanzas2()                              // Algoritmo per l'acquisizione della distanza s2
{
  for ( C = 1; C <= n; C++ )                     // Legge 20 valori dal sensore2, e li trascrive in un array
  {
    arrays2[C] = analogRead( sensore2 );
  }  
    
  for ( C = 1; C <= n; C++ )                     // Ordina l'array in modo crescente
  {
    for ( J = (C + 1); J <= n; J++ )
    {
      if ( arrays2[C] > arrays2[J] )
      {
        appoggio = arrays2[C];
       arrays2[C] = arrays2[J];
arrays2[J] = appoggio;
      }
    }
  }
  
  somma = 0;
  
  for ( C = 6; C <= ( n - 5 ); C++ )             // Non considera gli estremi
  {
    somma = somma + arrays2[C];
  }
  
  distanzas2 = somma / ( n - 10 );               // Effettua la media dei valori
  
  return( distanzas2 );                          // Ritorna il valore distanzas2 oppurtunamente filtrato
}


Calcolo PID:
Code:
int getPID()                                                      // Algoritmo per il calcolo del PID
{
  getorientation();                                               // Richiama la funzione per ottenere l'orientamento
  
  previousTime = time;                                            // Salva il tempo al ciclo precedente
  time = millis();
  interval = time - previousTime;                           // Calcola il tempo impiegato per eseguire un ciclo
  
  P = orientamento * kP;                                          // Calcola la variabile proporzionale
  I = I + interval * kI * P;                                      // Calcola la variabile integrativa
  D = kD * ( orientamento - previousorientamento ) / interval;    // Calcola la variabile derivativa
  
  PID = P + I + D;                                                // Calcola il PID
  
  if( PID >= 255/2 ) PID = 255/2;                                 // Se il valore supera 255/2, il valore è impostato a 255/2  
  if( PID <= -255/2 ) PID = -255/2;                               // Se il valore è minore di -255/2, il valore è impostato a -255/2  
  
  if(PID <= 1 && PID > 0) PID = 0;                                // Approssima il PID a 0
  if(PID >= -1 && PID < 0) PID = 0;                               // Approssima il PID a 0
  
  return( PID );                                                  // Ritorna il valore del PID
}

void getorientation()                                             // Algoritmo per il calcolo dell'orientamento
{
  orientamento = getdistanzas1() - getdistanzas2();               // Differenza fra le distanze rilevate dai due sensori
}



Controllo motori:
Code:
void controllomotori ( int PID )                      // Algoritmo per il controlla i due motori DC
{
  analogWrite( motore1, ( 255 / 2 ) + PID );          // Controlla il motore1 in base al PID
  analogWrite( motore2, ( 255 / 2 ) + PID );          // Controlla il motore2 in base al PID
}


Quello di cui sono abbastanza sicuro è che la parte di acquisizione dati funziona "bene".
Non avevo idea di come farla, cosi ho deciso di prendere n valori, metterli in un tabella, ordinarla, togliere gli estremi e fare la media con i restanti.
Non ho idea se questo sia un metodo efficace oppure no, ma sembra fare il suo dovere...

Il problema è il resto  smiley-sweat

Togliendo la parte integrativa dal PID da accenni di funzionamento, ma non riesce assolutamente a tenersi in equilibrio...

Qualcuno ha qualche idea / consiglio su quello che posso fare?  smiley-sweat

L'obiettivo è portarlo come progetto d'esame  smiley
Grazie a tutti in anticipo.
22  International / Software / AutoBalance - Controllo PID on: January 13, 2013, 03:54:50 pm
Salve a tutti smiley-grin
Mi sto cimentando nella costruzione di un AutoBalance, uno di quei sistemi con due ruote che riescono a tenersi in equilibrio da soli.

Per ora, il mio unico obbiettivo è mantenere l'equilibrio su una superficie piana.
Quindi niente salite, discese, forze esterne, o controllo del movimento.

La parte meccanica, in pratica è finita.
Purtroppo non ho una foto a portata di mano, quindi vi metto un rendering per darvi un'idea di come è fatto:

http://oi47.tinypic.com/2le303k.jpg

Il "robot" è composto da un Arduino UNO, due sensori SHARP analogici ( GP2Y0A21YK0F ), due motoriduttori ( SBGM9) ed un driver motore fatto da me ( se volete poi allego anche lo schema elettrico di questo).
Il primo piano per ora è vuoto, in seguito ci andranno le batterie. (Per ora faccio le prove con dei fili volanti)

--

Allora, il problema è, ovviamente, che non si tiene in equilibrio  smiley-mr-green

La parte della gestione del PID l'ho copiata da un esempio trovato online (per la precisione quì: http://schianorobotics.altervista.org/SISTEMI_DI_CONTROLLO_MULTIVARIABILE.pdf), il resto l'ho scritto io..

Non sò se il problema sia dovuto ad un problema software, al fatto che non sono capace di gestire un PID oppure (la cosa che temo di più) che i due motoriduttori non sono adatti, e che dovrò cambiarli con dei servo 360° (cosa che vorrei, ovviamente, evitare...)

Continuo nel post successivo che non fà postare più 9500 caratteri  smiley-red
23  International / Hardware / Re: Dubbio alimentazione Arduino on: October 20, 2012, 01:31:12 pm
Grazie mille!

Allora penso che userò i +5V, usando appunto il piedino +5V  smiley-mr-green
24  International / Hardware / Dubbio alimentazione Arduino on: October 20, 2012, 11:41:30 am
Salve, ho un dubbio riguardo l'alimentazione di arduino...

Allora, tramite il Jack va alimentato 7-12V
Ma tramite il piedino Vin?

C'è un modo per alimentarlo con 5 v?
25  International / Generale / Re: Nuova Votazione on: June 27, 2012, 03:38:02 pm
Si, anche se non partecipo molto al forum...  smiley
26  International / Hardware / Re: Motori con arduino!!! on: May 28, 2012, 10:25:25 am
Aaah dimenticavo una cosa importante! Come detto qui, contrariamente al tutorial, non dovresti agire sul pin "enable" dell'integrato con un impulso pwm.
Quindi tu diresti: come faccio a controllare la velocità?  
Ah boh, mi sono scordato di chiederlo quindi attendi qualcuno smiley-grin

Allora tempo fà chiesi anch'io aiuto su questo argomento!  smiley-lol
Per controllare la velocità dei motori, il metodo più efficiente è l'utilizzo di due segnali complementari PWM agli input di comando motori dell'integrato.
Si può fare questo tramite software ( difficile ) o tramite porte NOT ( soluzione semplice smiley )

Ho anche realizzato uno schema, sempre con il grandissimo aiuto del forum, per il controllo di 4 motori DC con 2 integrati SN754410 ( supportano fino ad 1.1 A per linea ).
Testato su Bread Board, senza diodi di protezione,con dei motoriduttori da 5V come carico, basetta in fase di realizzazione, perfettamente funzionante smiley-grin

Allego i file Eagle dello schema elettrico e dello sbroglio, non sia mai vi siano utili  smiley

p.s. Ho pensato questa basetta un pò come tutto fare, quindi, anche se l'SN754410 ha già i diodi di protezione integrati, ho preferito metterli esterni. Perchè mi è stato detto che per pilotare motori passo-passo ( un integrato può comandare un passo passo o due dc ) alla massima corrente servivano.
I diodi che userò sono dei: UF2003 ( diodi FAST, 2 A min, 50V min più economici che ho trovato su RS), e non quelli indicati nello schema.
27  International / Generale / Re: Consiglio sensore di distanza on: May 25, 2012, 12:48:12 pm
Mi rendo contro di essere stressante, ma è la prima volta che mi cimento nell'acquisto di componenti elettronici e in mini-progetti  smiley-sweat
I sensori Sharp li vedo meno complicati che gestire l'ERER... (ho fatto qualche prova...smiley )

Ha 3 piedini, due sono l'alimentazione ed uno và sull'entrata analogica di Arduino... giusto?
Avete qualche consiglio in particolare?

Altrimenti prenderei questo: http://it.rs-online.com/web/p/sensori-fotoelettrici/6666564/

Mi servirebbe per fare un robottino autobalance, quindi dovrebbero avere un range basso...
28  International / Generale / Re: Costruire driver motore on: May 20, 2012, 03:30:33 pm
Ok, sono finalmente riuscito a rimediare dei diodi veloci, 2A, 200V

http://it.rs-online.com/web/p/products/6882293/

Vanno bene come protezione, giusto? smiley-lol
29  International / Generale / Re: Consiglio sensore di distanza on: May 19, 2012, 11:39:28 am
esattamente, funziona da pannello solare. La sensibilità del led dipende dalla frequenza d'onda, più è simile alle frequenze d'nda emesse dalle lampade/sole, più viene "ingannato".
però come vedi dal codice di gioblu se ne può tenere conto.

Figo  smiley-lol
E come và collegato per ricevere un valore analogico con arduino?
gnd su catodo e l'anodo su un input analogico?
Mentre l'altro su A1 e A2, seguendo l'algoritmo erer...

Con due normali LED rossi non funziona smiley-grin
30  International / Generale / Re: Consiglio sensore di distanza on: May 19, 2012, 11:08:59 am
Sensore di distanza intendi un sensore on/off se c'é un oggetto alla distanza 0-10cm tipo il GP2Y0D810Z0F o vuoi misurare la distanza di un oggetto?
Ciao Uwe
Vorrei proprio misurare la distanza di un oggetto...
Girando su internet ho trovato:

http://www.gioblu.com/prodotti?page=shop.product_details&flypage=flypage_images.tpl&product_id=184&category_id=63

http://www.gioblu.com/prodotti?page=shop.product_details&flypage=flypage_images.tpl&product_id=139&category_id=63
due led bastano e avanzano, a parte il 0cm che è un pò un casino con qualsiasi sensore non a contatto.
uso lo usi come emettitore, con l'altro misuri la luce di ritorno (in pratica lo usi come pannello solare smiley )

ma tutto in realtà dipende dal materiale dell'oggetto che vuoi misurare!
Non ho capito  smiley-grin
Con due led come posso misurare la distanza di un oggetto?
Un led non alimentato, ma illuminato, produce una tensione ai suoi capi?
Questo sistema sarebbe molto sensibile alla luce ambientale...? 


Grazie mille smiley
Pages: 1 [2] 3 4 ... 7