Drone Quadcopter Arduino : Stabilisateur avec le capteur Mpu6050

Bonjour ,
Je m'appelle Olivier , c'est la première fois que je demande de l'aide sur un forum , je suis ici parce que je me suis mit dans la tête dès le début des vacances d'été de réaliser un drone avec une carte Arduino.
Cela fait déjà 1 mois que je travaille sur ce projet . Mon drone est composé d'une carte Arduino Mega 2560 , de 4 moteurs Brushless (4 hélices ...) et 4 esc et d'un module Mpu6050 (je n'utilise que l'accéléromètre ).

Je vous remets mon programme ci dessous :

#include <Servo.h> 
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"



Servo moteur1;
Servo moteur2;Servo moteur3;Servo moteur4;

MPU6050 accelgyro;

int16_t ax, ay, az;
int16_t gx, gy, gz;

int vxp = 60; 
int vxn=60; 
int vpynx =60;
int vnypx =60;
int vpyx =60;
int vnyx =60;
int vyp =60;
int vyn =60;

void setup() {
Wire.begin();
Serial.begin(115200);

Serial.println("Initialisation I2C ...");
accelgyro.initialize();
Serial.println(accelgyro.testConnection() ? "MPU6050 connection réussi" : "erreur de connection");

moteur1.attach(52);
moteur2.attach(50);moteur3.attach(48);moteur4.attach(46);
ini();
delay(5000);
int v;
for(v=10;v<=60;v +=5){

mot(v);
delay(1000);
}
Serial.println("Moteur ok");

}

void loop(){

vxp<=70;vxn<=70;vpynx <=70;vnypx <= 70;vpyx<=70;vnyx<=70;vyp<=70;vyn<=70;
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

int x = map(ax,-17000,17000,-90,90);

int y = map(ay,-17000,17000,-90,90);
Serial.print(x);
Serial.print(" ");
Serial.print(y);
   Serial.println(" ");

if(x >0){
 xp(vxp++);
 delay(100);
if(y<0){
nypx(vnypx++);
delay(100);}
if(y>0){
pyx(vpyx++);
delay(100);}

}
if(x<0){
xn(vxn++);
delay(100);
if(y<0){
nyx(vnyx++);
delay(100);
}
if(y>0){
pynx(vpynx++);
delay(100);
}
}
if(y<0){yn(vyn++);
delay(100);

if(x<0){
nyx(vnyx++);
delay(100);}

if(x>0){nypx(vnypx++);
delay(100);}}

if(y>0){
yp(vyp++);
delay(100);
if(x>0){pyx(vpyx++);
delay(100);}
if(x<0){
pynx(vpynx++);
delay(100);
}

}

}
void ini(){
mot(0); 

}


void mot(int v){
int angle3 = map(v, 0, 100, 0, 180);
moteur1.write(angle3);
moteur2.write(angle3);
moteur3.write(angle3);
moteur4.write(angle3);

}

void xp (int vxp){//x>0
int vx1 = map(vxp,0,100,0,180);
moteur3.write(vx1);
moteur4.write(vx1);
}
void xn(int vxn){//x<0
int vx2 = map(vxn,0,100,0,180);
moteur1.write(vx2);
moteur2.write(vx2);}

void pynx(int vpynx){//y>0, x<0
int vxy1 = map(vpynx,0,100,0,180);
moteur1.write(vxy1);
moteur2.write(vxy1);
moteur3.write(vxy1);}

void nypx (int vnypx){//y<0, x>0
int vxy2 = map(vnypx,0,100,0,180);
moteur1.write(vxy2);
moteur3.write(vxy2);
moteur4.write(vxy2);
}
void pyx (int vpyx){//y>0 x >0
int vyx3 = map(vpyx,0,100,0,180);
moteur3.write(vyx3);
moteur2.write(vyx3);
moteur4.write(vyx3);
}
void nyx(int vnyx){// y<0 x<0
int vyx4 = map(vnyx,0,100,0,180);
moteur4.write(vyx4);
moteur1.write(vyx4);
moteur2.write(vyx4);}

void yp(int vyp){// y>0
int vy1 = map(vyp,0,100,0,180);
moteur3.write(vy1);
moteur2.write(vy1);
}
void yn (int vyn){//y<0
int vy2 = map(vyn,0,100,0,180);
moteur4.write(vy2);
moteur1.write(vy2);}

Mon problème est celui-ci : Je ne sais pas si mon programme est adapté afin de stabiliser mon drone , malheureusement je ne peux pas le tester car j'ai cramé un esc le temps que le colis soit livré je voudrais optimiser mon programme c'est pourquoi je suis ici :slight_smile: .
(J'utilise l’accéléromètre pour calculer la rotation du drone sur l'axe x et y).

Le but de ce projet est de réaliser un drone qui communiquera directement avec mon smartphone Android via le bluetooth (programme terminé), ainsi je donnerai au drone la faculté de discuté avec son utilisateur grâce au "text to speech" mais aussi de recevoir une commande par l’intermédiaire de la commande vocale .

(Je ne sais pas si cela est utile de dire ça mais si l'un d'entre vous me demander pourquoi faire un drone .)

A+ et Help me! :sweat_smile:

Ps : Je vous envoie un croquis avec ses 2 axes x et y mais aussi le positionnement des moteurs par rapport aux axes pour mieux comprendre le code .

Bonjour,
Regarde le point 6 de Bienvenue mais les autres points sont également importants
@+

Ah , Merci ^^

Bonjour :slight_smile:

Moi pareil que toi, j'en suis à la stabilisation du drone mais je galère grave :frowning: ...je ne sais pas comment faire pour que la sensibilité du MPU6050 soit parfaitement calibrée au niveau du code...je pensais à étudier les valeurs du MPU6050 et faire des if(x>valeur1) etc etc mais bon il faudrait pas mal de valeurs pour que ce soit assez fluide...désolé je ne peux pas t'aider ...en tout cas ça m’intéresse ! :slight_smile:
D'ailleur as-tu réussi à extirpé les valeurs du MPU6050 en appliquant les filtres complémentaires ou filtre de Kalman?

Salut :slight_smile:
Comme tu peux le voir
j'utilise la méthode fourni par la librairie Mpu6050:

accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

int x = map(ax,-17000,17000,-90,90);

int y = map(ay,-17000,17000,-90,90);

pour pouvoir déterminer les valeur d'inclinaison du Mpu6050 j'utilise l'outil map afin de convertir l'intervalle de données reçut en un intervalle angulaire [-90,90]
et j'ai dit au code de faire fluctuer les valeurs prisent par x et par y en augmentant plus ou moins la vitesse de certains moteurs en fonction des circonstances .
Je ne sais pas si c'est la bonne technique pour convertir les données reçut par le capteur et stabiliser le drone avec le plus de précision possible (c'est pourquoi je suis sur ce forum ^^ )
Et comme toi j'utilise des conditions pour pouvoir stabiliser mon drone avec toutes les combinaisons d'inclinaison possible sur x et (ou) y , (regarde mon schéma que j'ai mit à ta disposition ) .
Par contre je serrais content d'en savoir un plus sur ce filtre de Kalman ... les conditions ne suffisent pas ?
A+ :smiley:

Hmm je vois...je n'ai pas encore épluché la librairie du mpu, ton code peut peut-être marcher..

Alors pour le filtre de Kalman il faut que tu saches que c'est la même chose que les filtres complémentaires mais en beaucoup plus compliqué ^^
Quand j'ai essayé mon MPU6050 avec Processing (je sais pas si tu connais ce logiciel, ça permet de visualiser les informations envoyées par le gyroscope et là c'était avec un modèle d'avion' j'ai remarqué qu' au fur et à mesure que je bouger le gyroscope, la position de l'avion perdait en précision jusqu'à ce que ça devienne vraiment n'importe quoi, disons que la position initiale est tout droit, et bien après quelques temps la position tout droit est devenue position à 90°. Ceci est apparemment dû aux constantes d'intégration accumulées par le DMP (Digital Motion Processor je crois) (dans le MPU6050) car pour obtenir la position le MPU intégré une fois l'accélération et une autres fois la vitesse. Du coup ça te fait 2 constantes en plus à chaque fois.

Les filtres complémentaires ou filtres de Kalman sont parfait pour contrer ce problème. Ils arrivent à faire en sorte que ça marche mais je crois qu'il utilise un algorithme particulier qui permet d'atténuer les trop fortes variations. Enfin c'est compliqué quoi ^^". Je n'ai toujours pas fait la programmation car j'essaie encore de comprendre le code fournit par le MIT (mon niveau en C est pas terrible pour l'instant ^^" )

Ah! Je vais me renseigner d'avantage . Bon courage ! :wink:

Merci, à toi aussi :slight_smile:

Personne d'autre ne peut m'aider ? :confused:

Bonjour à tous,

Comme je comprends pas bien quels sont les questions, je vais juste dire ce que je sais à ce sujet :

Je l'ai testé le MPU6050 avec un 328P, la librairie Arduino et le petit programme Processing avec l'avion, et chez moi c'était très stable :

  • Les axes X & Y sont quasi parfait
  • J'ai constaté un léger drift constant sur l'axe Z qui était auto-compensé au bout de 30 secondes maximum, si le capteur ne bouge pas trop

Pour gérer ce drift je ne connais que 2 possibilités :

  • Attendre 30 secondes sans bouger
  • Envoyer des valeurs d'initialisation au MPU pour limiter le drift durant l'initialisation

Je ne savais pas que le filtre Kalmann pouvait gérer ça.

Ensuite oui, je pense que c'est la bonne technique que de corriger la vitesses moteurs en fonction de l'assiette (X,Y) pour stabiliser le drone, c'est en fait un asservissement par consigne.
En revanche, ton action sur les moteurs doit être régulée, on appelle ça la régulation PID.

Ensuite je te déconseille (si possible) de faire du MAP pour avoir une valeur entre 90 & -90.
Tu pers en précision juste pour simplifier ta compréhension... mais la machine n'a pas besoin d'avoir des valeurs "humainement logiques", à la limite ça peut te servir pour débugger uniquement.

EDIT : Il existe un truc tout fait qui s'appelle MultiWii, et même si vous voulez construire le programme vous-même, c'est peut-être une bonne source d'inspiration.

Salut,

Je tenais tout d'abord à vous remercier d'avoir prit du temps à me venir en aide et à répondre au Topic ,

Je suis content de savoir que je suis sur la bonne voie afin de stabiliser mon drone mais ce problème de PID m'intrigue ...

Je me suis renseigné sur le net plus particulièrement sur ce blog "Implémenter un PID sans faire de calculs ! » Sciences et Techniques"

et j'ai comprit à quoi sert le PID mais je ne sais pas comment représenter ce calcule dans mon code:

Tous les x millisecondes, faire :
    erreur = consigne - mesure;
    somme_erreurs += erreur;
    variation_erreur = erreur - erreur_précédente;
    commande = Kp * erreur + Ki * somme_erreurs + Kd * variation_erreur;
    erreur_précédente = erreur

plus précisément je ne sais pas comment faire pour obtenir :

-Kp le coefficient de proportionnalité de l'erreur
-Ki le coefficient de proportionnalité de la somme des erreurs.
-Kd le coefficient de proportionnalité de la variation de l'erreur.

à bientôt :slight_smile:

Ton lien mène à un autre lien qui parait répondre à tes questions :
http://www.ferdinandpiette.com/blog/2012/04/asservissement-en-vitesse-dun-moteur-avec-arduino/

LOL je n'avais même pas remarqué ^^ Je te remercie . Je te tiendrais au courant par rapport à l'avancement du programme :slight_smile:

A+ et encore Merci :wink:

Salut
j 'ai besoin d 'un programme d'une drone quadrirotor avec arduino mega 2560 vous pouvez m'aider svp

Bonsoir,

Je suis aussi depuis quelques temps sur un projet de quadricoptère qui sera stabilisé à l'aide d'un MPU_6050 et de son DMP qui fournit à une fréquence de 100 HZ les valeurs de cap, roulis et tangage. Je pense me servir a priori de ces trois valeurs, mais dans la pratique, peut-être que je serai obligé d'introduire les accélérations et le rotations.

A l'aide de ces données, il faut piloter les moteurs qui entrainent les hélices. Cela représente plusieurs chaînes d'asservissement qu'il faudra régler. En ce qui me concerne, je vais chercher à calculer un maximum de choses pour ne pas avoir à faire de réglages au pif. Cela nécessite donc de connaître les fonctions de transfert de chaque élément concernant la chaîne d'asservissement. Deux éléments sont indispensables : les gains du transfert commande -> moteur -> Hélice -> Poussée et les moments d'inertie des trois axes du drone. Après ça, reste plus qu'à peaufiner les PID.

Cordialement.

Pierre