Bonjour,
Je suis actuellement en terminale SI et dans le cadre de cette matière, je dois réaliser un stabilisateur de drone "simplifié" c’est-à-dire ça : https://www.youtube.com/watch?v=w2hZoZQyRw8&t=28s
L’une des problématiques de ce projet est donc l’asservissement grâce au PID.
Notre cahier des charges nous impose de considérer que le drone n’est plus stabilisé lorsque ses oscillations dépassent de plus ou moins 5degrés de 90degrés.
Nous avons réaliser un programme comprenant la mesure de l’angle (qui fonctionne) et l’asservissement par PID mais nous rencontrons 2 problèmes avec celui-ci :
- La consigne renvoyer est parfois négative
- Nous pouvons avoir une consigne de 200 pour un angle de 40degrés mais de 100 pour un angle de 30…
Voici le programme en question :
////////////////////////////////////
// Les bibliothèques nécessaires //
////////////////////////////////////
#include <Wire.h>
#include <ADXL345.h>
double pitch = 0.00;
ADXL345 adxl; //variable adxl en relation avec la bibliothèque ADXL345
const int ecart = 5;
float erreur = 0;//consigne - mesure
float consigne = 90;
float Kp = 10;
float Ki = 0.4;
float Kd = 20;
float erreur_precedente = 0;
float somme_erreurs = 0;
float variation_erreur = 0;
float mesure_ecart = 0;
float mesure = 0;
float commande = 0;
void setup(){
Serial.begin(9600);
adxl.powerOn();
}
void loop(){
int x,y,z;
adxl.readXYZ(&x, &y, &z); //Lecture des valeurs issues de l'accéléromètre et stockage dans les variables x,y,z
// Valeurs de sorties x,y,z
double x_Buff = float(x);
double y_Buff = float(y);
double z_Buff = float(z);
pitch = atan2((- x_Buff) , sqrt(y_Buff * y_Buff + z_Buff * z_Buff)) * 63;
mesure = pitch;
if((mesure < (consigne - (consigne * ecart / 100))) || (mesure > (consigne + (consigne * ecart / 100)))){
erreur = consigne - abs(mesure);
somme_erreurs += erreur;
variation_erreur = erreur - erreur_precedente;
commande = (Kp * erreur) + (Ki * somme_erreurs) + (Kd * variation_erreur);
erreur_precedente = erreur;
delay(500);
} else {
//Rénitialisation des variables
erreur_precedente = 0 ;
somme_erreurs = 0 ;
variation_erreur = 0 ;
commande = (Kp * erreur) + (Ki * somme_erreurs) + (Kd * variation_erreur); //Remettre à 0 la commande
}
erreur = 0 ;
}
Est-ce une méthode correcte ? Si oui, comment faire pour résoudre ces problèmes ?
Cordialement et Merci d’avance !
PS :
- Pour l’instant nous n’avons pas de moteurs, nous réalisons donc nos tests "à la main" avec une équerre
- Les valeurs du PID sont rentrés au hasard.
+0
-0