Controllo PID

lesto:
ciao, allora, il PID è sufficiente, ho visto tantissimi progettini come il tuo usarlo.

I first used the rectangle method for integration but now I've preferred the trapezoid method to minimize the error: what I've found out is that most of the error comes from (1) the sensor and (2) ADC approximation.

Anyone going to replicate this robot should use an angle sensor (maybe I2C based) instead of a gyroscope; integration is bringing avoidable error.




a quanto piare lui usa http://it.wikipedia.org/wiki/Regola_del_trapezio , ma visto che tu hai una IMU non ti serve.

edit: come non detto
Lui sta mettendo in stato un pò di valori; posiszione stimata? velocità lineare, e un paio di altre cose, poi le moltoplica con il fattore K (quindi è la P di un pid) e le somma per ottenere la forza finale.. non ho idea da che csa sia partito per fare ciò, che io sappia basta un pid sull'angolazione, ma magari lui ha voluto aggiungere robe per poter controllare la posizione, e la cosa mi sfugge

Posto il codice del PID che sputa fuori una velocità (da passare ai due motori) e valuta l'errore come differenza tra il setpoint e il valore rilevato dalla IMU.

La procedura standard è questa?
Quali migliorie potete consigliarmi?
Mi sono sfuggiti errori?
ben accetto qualsiasi consiglio!

//DEFINIZIONE VARIABILI                            
double output;
double input;

double setpoint = 0; //da correggere

double P = 0;
double I = 0;
double D = 0;
//Coefficienti del regolatore
double kP = 10;
double kI = 0;
double kD = 0;
//
double error;
double ITerm;
double DTerm; 
double Ki, Kp, Kd;
float currentValue=0;
float lastInput=0;
int vel=0;
int equilibrio=0;

float x=0;
float rpy_rol=0;
float rpy_pit=0;
float rpy_yaw=0;
float ADegX=0;
float ADegY=0;

int updatePid(int setpoint, float x) { // compute PWM value
 float time = millis();
 float previousTime = time;                                            // Salva il tempo al ciclo precedente
 float interval = time - previousTime;                                 // Calcola il tempo impiegato per eseguire un ciclo
                   
         error =(double)(abs(setpoint) - abs(x));
	  
         P = error * kP;                                                                                                    // Calcola la variabile proporzionale 
         I =(double) I + interval * kI * P;                                                                    // Calcola la variabile integrativa
         D =(double) kD * (abs(currentValue - lastInput) / interval);            // Calcola la variabile derivativa	
         lastInput=currentValue;
        
         vel =(int) P + I + D;
        
        //elimino le micro correzioni      
        if(vel <= 1 && vel > 0) vel = 0;                                
        if(vel >= -1 && vel < 0) vel = 0;                               
        
        //if( vel >= 255/2 )  vel = 255/2;                                // da usare se ancora in fase di test  per evitare la vel max e distruggere tutto
                
        constrain(vel, 0, 255);
        return vel;
}

// dentro al LOOP
 vel = updatePid(setpoint, x);
        
             if(setpoint == x)  {equilibrio = 0;}-->motori fermi
             if(ADegX > 246)    {equilibrio = 1;}---> senso orario ruote
             if(ADegX < 246)    {equilibrio = 2;}---> senso antiorario ruote

ps: ADegX è uno dei valori rilevati dalla mia IMU: lo uso per semplicità (perchè non mi sn venute in mente altre soluzioni per andicare l'inclinazione e quindi in quale delle due casistiche ricadere). empiricamente ho visto che il valore della stabilità è 246.