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.