Drone: Rapport de force des boucles

Bonsoir à tous ! :)

Me revoilà. Je me suis rendu compte d'un petit problème qui va, je présume, être rapidement réglé. Je suis en train de faire un drone moi-même, en codant tout sur Arduino (Vive l'Open source :)!), et j'ai un soucis au niveau du "rapport de forces" des boucles. En gros, la valeur du joystick est reçue par un signal radio, et cette valeur (qui a été préalablement mappée aux valeurs du moteur bien sûr) est envoyée aux moteurs. J'ai donc défini la valeur des moteurs, en fonction des coordonnées lues des 2 Joysticks. Monter, Descendre, Aller à droite, gauche, avancer, reculer, ... Sauf que j'embarque évidemment une stabilisation avec un PID. Même si j'ai des problèmes avec la lecture du gyro et de l'acceleromètre, je vois bien que cette stabilisation n'est pas active du tout à cause des if qui fixent les valeurs des moteurs.

Voici mon code:

 ////|A|//|B|////
//////I//I/////
///////II//////
////////o//////
///////II//////
//////I//I/////
////|C|//|D|///

void loop() {


  xFin1 = nombres[0];
  yFin1 = nombres[1];
  xFin2 = nombres[2];
  yFin2 = nombres[3]; 
  
  timePrev = time;
  time = millis();
  elapsedTime = (time - timePrev) / 1000;  

  uint8_t Buf[14];
  I2Cread(MPU9250_ADDRESS,0x3B,14,Buf);
  
  // Gyroscope
  int16_t Acc_rawX = -(Buf[8]<<8 | Buf[9]);
  int16_t Acc_rawY = -(Buf[10]<<8 | Buf[11]);
  int16_t Acc_rawZ = Buf[12]<<8 | Buf[13];
  
  // Accelerometer
  int16_t Gyr_rawX = -(Buf[0]<<8 | Buf[1]);
  int16_t Gyr_rawY = -(Buf[2]<<8 | Buf[3]);
  int16_t Gyr_rawZ = Buf[4]<<8 | Buf[5];

  lcd.setCursor(0,1);
  lcd.print(Gyr_rawX, DEC);
  lcd.setCursor(10,1);
  lcd.print(Gyr_rawY, DEC);
  
  /*---X---*/
  Acceleration_angle[0] = atan((Acc_rawY/16384.0)/sqrt(pow((Acc_rawX/16384.0),2) + pow((Acc_rawZ/16384.0),2)))*rad_to_deg;
  /*---Y---*/
  Acceleration_angle[1] = atan(-1*(Acc_rawX/16384.0)/sqrt(pow((Acc_rawY/16384.0),2) + pow((Acc_rawZ/16384.0),2)))*rad_to_deg;

  /*---X---*/
  Gyro_angle[0] = Gyr_rawX/131.0; 
  /*---Y---*/
  Gyro_angle[1] = Gyr_rawY/131.0;

  /*---X axis angle---*/
  Total_angle[0] = 0.98 *(Total_angle[0] + Gyro_angle[0]*elapsedTime) + 0.02*Acceleration_angle[0];
  /*---Y axis angle---*/
  Total_angle[1] = 0.98 *(Total_angle[1] + Gyro_angle[1]*elapsedTime) + 0.02*Acceleration_angle[1];

  lcd.setCursor(0,0);
  lcd.print(Total_angle[0], 1);
  lcd.setCursor(10,0);
  lcd.print(Total_angle[1], 1);
  
  //Activer ou non le PID
  if (yFin2 >= 85 && yFin2 <= 95 && xFin2 >= 85 && xFin2 <= 95) {
  PIDcorrection();
  }
  
  if (yFin1 >=90 && yFin1 <= 95) {
    valMotA = valStable;
    valMotB = valStable;
    valMotC = valStable;
    valMotD = valStable;
  }
  //Monter
  if (yFin1 > 95) {
    valMotA = yFin1; //Gestion des gaz
    valMotB = yFin1;
    valMotC = yFin1;
    valMotD = yFin1;
  }
  //Descendre
  if (yFin1 < 90) {
    valMotA = yFin1; //Gestion des gaz
    valMotB = yFin1;
    valMotC = yFin1;
    valMotD = yFin1;
  }
  //Aller en avant
  if (yFin2 > 95) {
    valMotA = yFin2 - CoeffDeltaVit * yFin2;
    valMotB = yFin2 - CoeffDeltaVit * yFin2;
    valMotC = yFin2;
    valMotD = yFin2;
  }
  //Aller en arrière
  if (yFin2 < 85) {
    valMotA = 180 - yFin2;
    valMotB = 180 - yFin2;
    valMotC = 180 - (yFin2 + CoeffDeltaVit * (180 - yFin2));
    valMotD = 180 - (yFin2 + CoeffDeltaVit * (180 - yFin2));
  }
  //Aller à droite
  if (xFin2 > 95) {
    valMotA = xFin2;
    valMotB = xFin2 - CoeffDeltaVit * xFin2;
    valMotC = xFin2;
    valMotD = xFin2 - CoeffDeltaVit * xFin2;
  }
  //Aller à gauche
  if (xFin2 < 85) {
    valMotA = 180 - (xFin2 + CoeffDeltaVit * (180 - xFin2));
    valMotB = 180 - xFin2;
    valMotC = 180 - (xFin2 + CoeffDeltaVit * (180 - xFin2));
    valMotD = 180 - xFin2;
  }
  //Tourner à droite
  if (xFin1 > 95) {
    valMotA = xFin1 - CoeffDeltaVit * xFin1;
    valMotB = xFin1;
    valMotC = xFin1;
    valMotD = xFin1 - CoeffDeltaVit * xFin1;
  }
  //Tourner à gauche
  if (xFin1 < 85) {
    valMotA = 180 -  xFin1;
    valMotB = 180 - (xFin1 + CoeffDeltaVit * (180 - xFin1));
    valMotC = 180 - (xFin1 + CoeffDeltaVit * (180 - xFin1));
    valMotD = 180 -  xFin1;
  }
  
  if (valMotA > 180) {
    valMotA = 180;
  }
  if (valMotB > 180) {
    valMotB = 180;
  }
  if (valMotC > 180) {
    valMotC = 180;
  }
  if (valMotD > 180) {
    valMotD = 180;
  }
  if (valMotA <= 1) { //On ne met pas 0 car il y a des "rebonds", à la position basse, le joystick affiche 0 ou 1 (pas bon pour le démarrage)
    valMotA = 0;
  }
  if (valMotB <= 1) {
    valMotB = 0;
  }
  if (valMotC <= 1) {
    valMotC = 0;
  }
  if (valMotD <= 1) {
    valMotD = 0;
  }
  
  motA.write(valMotA);
  motB.write(valMotB);
  motC.write(valMotC);
  motD.write(valMotD);
    
Serial.print("Mot A: "); Serial.print(valMotA); Serial.print(" | Mot B: "); Serial.print(valMotB); Serial.print(" | Mot C: "); Serial.print(valMotC); Serial.print(" | Mot D: "); Serial.println(valMotD);

lcd.setCursor(0,2);
lcd.print(valMotA);
lcd.setCursor(4,2);
lcd.print(valMotB);
lcd.setCursor(8,2);
lcd.print(valMotC);
lcd.setCursor(12,2);
lcd.print(valMotD);

delay(50);
lcd.clear();

}

void PIDcorrection() {

  pitch_error = Total_angle[0] - desired_angle;
  roll_error = Total_angle[1] - desired_angle;
  //----------P---------//
  pitch_pid_p = pitch_kp*pitch_error;
  roll_pid_p = roll_kp*roll_error;

  //----------I---------//  
  if(-3 

J'ai du enlever la déclaration des variables et le setup vu que je n'ai pas assez de place pour le post.

Pour résumer, la stabilisation qui est sensée modifier la valeur des moteurs est inactive à cause des valeurs de joystick qui freezent la valeur de ces derniers

Merci beaucoup d'avance, une très bonne soirée à vous.

Les valeurs du joystick devraient donner l’objectif à atteindre par le biais du PID pas définir directement une valeur. Vous cherchez à maîtriser le roulis/lacet/tangage et vitesse et définir le comportement global remonter/descendre + tourner + vitesse sur l’axe) (image prise sur le lien github ci dessous de @lobodol)

Lisez des tutos comme celui ci ou inspirez vous des codes trouvés sur internet (en voici un pris au hasard)

Ah ! Donc le PID serait en permanence actif, c'est juste que le joystick place un point dans l'espace qui doit être atteint par le drone ?

Et le PID lui, fait tout pour atteindre ce point

Donc il faudra aussi intégrer un PID sur l'axe de lacet Merci beaucoup pour ces précisions ! J'ai une toute autre vision du drone maintenant !

Oui le(s) PID sont maîtres à bord

Non pas un point dans l’espace, le niveau d’abstration C’est plutôt si vous voulez monter ou descendre, tourner et à quelle vitesse. Comme vous n’avez pas de gouvernes de direction (volets) Les PIDs seront là pour piloter séparément chaque moteur afin d’obtenir le comportement voulu en minimisant les instabilités ou contrant les forces opposée à l’ordre qui seraient dues au vent par exemple ou à une resource brutale

Ensuite vous pouvez aussi dire que le joystick autorise le contrôle direct des roulis/lacet/tangage/vitesse et que vous stabilisez (lissez) le comportement mais même dans ce cas le PID a la main

Ok, j'ai à peu près compris, mais c'est juste le "niveau d'abstration" que je n'ai pas pigé et comment gérer alors cette vitesse ? Elle est proportionnelle aux PID ? Je veux dire, si par exemple on veut avancer, je vais définir avec le joystick un angle inclinaison bas pour que le drone se baisse, mais comment lui donner une vitesse proportionnelle en fonction du joystick ?

comment lui donner une vitesse proportionnelle en fonction du joystick

la vitesse est une conséquence de la vitesse individuelle des moteurs et de l’inclinaison de votre appareil

J-M-L: la vitesse est une conséquence de la vitesse individuelle des moteurs et de l'inclinaison de votre appareil

Donc le PID fait en sorte que plus le drone est orienté, et plus les moteurs vont aller vite ? Donc si je lui donne un angle très fort pour avancer, le PID va vouloir rapidement corriger ça et donc faire dépoter les moteurs ? Et donc le fait de garder le même angle va laisser les moteurs à leur plein régime, ce qui va faire avancer rapidement le drone?

le niveau d'abstraction ce sont les formules mathématiques qui disent à quoi correspondent les joystick

le niveau de base c'est ce qu'il y a dans le GitHub plus haut:

dans ce cas c'est à l'opérateur de garantir que la trajectoire se fait à altitude constante par exemple et il doit régler les angles roulis/lacet/tangage et vitesse

sinon vous pouvez dire que le joystick de gauche de haut en bas fait monter ou descendre, droite et gauche une translation à plat, et le joystick de droite de haut en bas règle la vitesse et de gauche à droite une rotation à plat

la notion de "rotation à plat" c'est un contrôle fin des des différents moteurs et le PID sert à maintenir cet objectif de "à plat"

J'opterais dans mon cas pour le mode 2 Merci pour vos précisions, et désolé du retard (le BAC est passé par là)

Admettons que je ne mette pas de stabilisation pour l'axe du lacet, et que le joystick contrôle directement les moteurs. Alors dans ce cas, il y aura le même problème que j'ai eu de "rapport de force des boucles", à part si je n'ai pas bien pigé vos explications ? De plus, l'axe de lacet ne doit pas être utilisable lorsque le drone effectue une translation, c'est à dire que sinon il va partir n'importe où ?