« Micro contrôleurs AVR/Travail pratique/Utilisation d'un Accéléromètre MPU6050 » : différence entre les versions
Contenu supprimé Contenu ajouté
Dépeuplement de Catégorie:Pages utilisant des balises source obsolètes |
|||
Ligne 25 :
* un capteur accéléromètre 3 axes (x,y et z) qui mesure une [[w:accélération|accélération]] ;
* un capteur gyroscope 3 axes qui mesure une [[w:vitesse angulaire|vitesse angulaire]] ;
* un «
[[Fichier:Accelerometre 1.png|thumb|300px|Utiliser Processing pour visualiser des données d'un accéléromètre et d'un gyroscope.]]
Ligne 39 :
[[w:Attitude_%28astronautique%29|L'attitude]] en robotique (et en astronautique) désigne la direction des axes de la pièce mobile du robot ; généralement caractérisée par trois angles ([[w:Roulis|roulis]], [[w:Tangage|tangage]] et cap ou [[w:Lacet_%28mouvement%29|lacet]]).
Ce mot «
La notion d'attitude est très liée aux rotations en trois dimensions. Nous allons donc commencer par examiner ces rotations d'un point de vue mathématique.
Ligne 57 :
Voici un code SCILAB permettant de définir ces trois matrices pour des valeurs particulières d'angle :
<
//******* SCILAB
phi=%pi/4;
Ligne 68 :
roty=[cos(theta) 0 -sin(theta);0 1 0;sin(theta) 0 cos(theta)];
rotz=[cos(psi) sin(psi) 0;-sin(psi) cos(psi) 0;0 0 1];
</syntaxhighlight>
=== Euler 123 ===
Ligne 82 :
Le code SCILAB permettant de réaliser le calcul de la matrice d'Euler 123 est :
<
//******* SCILAB
// construction matrice de rotation Euler 123
Ligne 88 :
// construction matrice de rotation Euler 321
R2=rotz*roty*rotx;
</syntaxhighlight>
Une rotation en dimension 3 peut aussi être définie par un axe de rotation et un angle (soit à priori 4 paramètres). Les quatre paramètres sont naturellement les trois composantes du vecteur qui définit l'axe et l'angle de rotation. Il est en fait possible d'économiser un paramètre en définissant l'axe à partir du centre d'une sphère ainsi que la longitude et latitude du point de rencontre de l'axe avec la sphère. Une autre manière d'économiser une donnée est de définir l'axe de rotation par un vecteur unitaire pour lequel trois coordonnées suffisent. '''Bref seulement 3 paramètres suffisent à définir une rotation'''.
Ligne 105 :
Le code SCILAB permettant le calcul d'angle est donc :
<
//******* SCILAB
// matrice R de rotation 3x3
angle= acos((trace(R)-1)/2)
</syntaxhighlight>
=== Axe de rotation ===
L'axe de rotation est plus difficile à calculer si l'on ne dispose pas d'une puissance de calcul suffisante. Sur notre PC ce n’est pas un problème : il faut chercher le vecteur invariant par cette rotation. Techniquement cela revient à chercher le seul et unique vecteur propre associé à la valeur propre +1. Plutôt que d’en faire la théorie, nous préférons donner le code de SCILAB qui permet facilement ce genre de calcul :
<
//******* SCILAB
// premiere maniere
[Ab,X]=bdiag(R)
</syntaxhighlight>
affiche :
<pre>
Ligne 134 :
Il existe une autre méthode avec SCILAB :
<
//******* SCILAB
//deuxième manière
[al,be]=spec(R)
</syntaxhighlight>
qui donne
<pre>
Ligne 171 :
'''Exemple en SCILAB'''
<
//******* SCILAB
// recupération de l'axe : troisième colonne de X
Ligne 183 :
Z=[0 -axis(3) axis(2);axis(3) 0 -axis(1);-axis(2) axis(1) 0];
R3=expm(angle*Z); // redonne R2
</syntaxhighlight>
redonne exactement la même matrice que R pour les deux techniques de construction de R2 et R3.
Ligne 282 :
==== Axe de rotation du vecteur g ====
Le script suivant :
<
//******* SCILAB
// réalisation du produit vectoriel
Ligne 294 :
// calcul de l'axe à partir du produit vectoriel : IL EST MONTRE PLUS LOIN QUE CETTE IDÉE SIMPLE EST FAUSSE
axis2=CrossProd(g0,g1);
</syntaxhighlight>
nécessite l’utilisation de CrossProd.sci qui doit contenir :
<
//******* SCILAB
function [p] = CrossProd(u,v)
Ligne 314 :
p = [px, py, pz]
//end function
</syntaxhighlight>
[[Fichier:Accelerometer3.png|thumb|L'axe de rotation d'une rotation 3D ne peut pas être retrouvé à l'aide d'un produit vectoriel]]
{{attention|
Ligne 362 :
L'utilisation de SCILAB nous a permis cependant de trouver une relation entre les deux. En effet le code :
<
anglex=%pi/4; //phi
angley=-%pi/4; //theta
Ligne 381 :
erreurx = (anglex-phi)*180/%pi
erreury= (angley-rho)*180/%pi
</syntaxhighlight>
donne :
<pre>
Ligne 458 :
1°) Nous allons commencer par le programme tout simple :
<
// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
Ligne 489 :
delay(333);
}
</syntaxhighlight>
Essayez ce programme sur la liaison série.
Ligne 518 :
{{Solution|contenu=
<
#include<Wire.h>
const int MPU=0x68; // I2C address of the MPU-6050
Ligne 554 :
delay(333);
}
</syntaxhighlight>
{{Remarque|contenu=
Ce code pose problème dans le cas où les composantes de g sont nulles sur les deux axes X et Z (cela peut arriver : accéléromètre sur la tranche). Dans ce cas, ce qui est retourné par atan2 est NaN (Not a Number) et ne peut pas être interprété par un logiciel de visualisation. Il vous faut donc gérer cette situation sauf si vous vous interdisez de mettre l'accéléromètre dans cette situation.
Ligne 575 :
'''<u>Indication</u>''' : Voici un programme capable de récupérer la chaîne "Phi = -0.67" envoyée par l'Arduino et de la transformer en nombre réel :
<
import processing.serial.*;
Ligne 605 :
}
}
</syntaxhighlight>
{{Solution|contenu=
<
import processing.serial.*;
Ligne 649 :
}
}
</syntaxhighlight>
}}
À partir de maintenant, la partie processing sera fournie. Elle sera bien plus sophistiquée que ce que l’on vient de faire puisqu'elle sera destinée à recevoir les données de notre capteur et d’en faire plusieurs représentations 3D.
Ligne 656 :
Soit le programme Processing suivant :
{{Boîte déroulante|titre=Programme Processing pour visualisation|contenu=
<
/**
* Show GY521 Data.
Ligne 881 :
}
}
</syntaxhighlight>
}}
C'est le programme que l’on utilisera systématiquement par la suite. Il peut être trouvé dans la partie [http://www.geekmomprojects.com/gyroscopes-and-accelerometers-on-a-chip/ à télécharger de cette page].
Ligne 887 :
Ce programme est sensible au type de liaison série utilisé et particulièrement au système d'exploitation. La ligne en début de programme :
<
String portName = "/dev/ttyACM0"; // parfois "/dev/ttyACM1" chez moi
</syntaxhighlight>
est propre à Linux et devra donc être adaptée !
Ligne 895 :
{{remarque|contenu=
Ce programme utilise la représentation d'Euler des rotations. Ceci peut être vu avec l'extrait de code
<
rotateX(radians(-x_fil - x_rotation));
rotateY(radians(-y_fil));
</syntaxhighlight>
La rotation autour de l'axe Z est donc supposée être nulle. Ceci semble assez normal pour l'accéléromètre mais on peut faire mieux pour les rotations (gyroscope). Nous serons donc éventuellement amenés à modifier ceci.
}}
Ligne 910 :
{{Solution|contenu=
<
float accel_angle_x=0.0,accel_angle_y=0.0,accel_angle_z=0.0;
Ligne 950 :
delay(300);
}
</syntaxhighlight>
}}
2°) Construire ensuite le même programme en vous intéressant maintenant à la position de l'accélération de pesanteur. Pour simplifier commencez par faire fonctionner le programme Processing avec la résolution 2D que vous avez réalisé dans l'exercice précédant. Les données que vous allez envoyer au programme processing seront maintenant liées à votre position de l'accéléromètre par rapport à l'axe x. L'angle doit être fourni en ° et non en radians !
{{Solution|contenu=
<
#include<Wire.h>
const int MPU=0x68; // I2C address of the MPU-6050
Ligne 1 012 :
delay(30);
}
</syntaxhighlight>
}}
Ligne 1 031 :
{{Solution|contenu=
L'utilisation des deux premières formules peut laisser croire que le problème est résolu... mais une étude expérimentale attentive peut nous conduite à de fortes divergences entre la position de l'accéléromètre dans notre main et sa visualisation 3D avec Processing.
<
#include<Wire.h>
const int MPU=0x68; // I2C address of the MPU-6050
Ligne 1 098 :
delay(30);
}
</syntaxhighlight>
}}
[[Fichier:Accelerometre 3.png|thumb|300px|Améliorer les données de l'accéléromètre avec un filtrage]]
Ligne 1 111 :
}}
{{Solution|contenu=
<
#include<Wire.h>
const int MPU=0x68; // I2C address of the MPU-6050
Ligne 1 176 :
//delay(30);
}
</syntaxhighlight>
}}
Ligne 1 185 :
{{Boîte déroulante|titre=Code pour retrouver l'attitude avec l'accéléromètre|contenu=
<
#include<Wire.h>
const int MPU=0x68; // I2C address of the MPU-6050
Ligne 1 301 :
delay(5);
}
</syntaxhighlight>
Le calcul de la matrice de rotation R doit être amélioré : tel qu’il est écrit ici il fait appel plusieurs fois à des cosinus et sinus identiques.
}}
Ligne 1 323 :
On donne :
<
// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
Ligne 1 356 :
delay(333);
}
</syntaxhighlight>
==== Exercice 6 ====
Ligne 1 377 :
ii) La sortie sera réalisée par quelque chose comme :
<
// Send the data to the serial port
Serial.print(F("DEL:")); //Delta T
Ligne 1 400 :
Serial.print(0.0, 2);
Serial.println(F(""));
</syntaxhighlight>
si l’on veut rester compatible avec Processing.
Ligne 1 406 :
iv) L'obtention de la vitesse en °/s se fait par <u>une division</u> à l'aide d'une valeur
<
// Convert gyro values to degrees/sec
float FS_SEL = 131;
</syntaxhighlight>
{{Solution|contenu=
<
#include<Wire.h>
const int MPU=0x68; // I2C address of the MPU-6050
Ligne 1 500 :
delay(30);
}
</syntaxhighlight>
}}
Ligne 1 510 :
Voici donc un nouveau programme qui respecte les mathématiques des rotations 3D. Il est destiné à comparer l'intégration naïve ci-dessus à celle que l’on est sensé faire.
{{solution|contenu=
<
#include<Wire.h>
Ligne 1 723 :
delay(30);
}
</syntaxhighlight>
Il a été testé avec le programme Processing très légèrement modifié pour l’occasion :
<
/**
* Show GY521 Data.
Ligne 1 959 :
}
}
</syntaxhighlight>
L'objectif a été de départager expérimentalement les deux méthodes. On bouge pendant environ 5s et on revient à la position de départ. Le gagant est celui qui s'est alors le moins éloigné de la position de départ et le gagnant n'a pas vraiement pu être départagé !
}}
Ligne 1 978 :
Nous donnons un programme très simple qui relève les donnée de l'accéléromètre et celles du gyroscope. Remarquez que vous avez en bonus la température.
<
// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
Ligne 2 019 :
delay(333);
}
</syntaxhighlight>
Si vous avez suivi jusque là, vous pouvez facilement déduire de ce programme qu’il n’est pas prévu pour des visualisations de données avec processing. En effet il fonctionne à 9600 bauds (au lieu des 38400 exigées). Les données ne peuvent être visibles qu’à l'aide du moniteur série.
Ligne 2 030 :
1°) Si nous mélangeons les données de l'accéléromètre et du gyroscope, nous aurons une sortie comme :
<
// Send the data to the serial port
Serial.print(F("DEL:")); //Delta T
Ligne 2 053 :
Serial.print(0.0, 2);
Serial.println(F(""));
</syntaxhighlight>
On vous demande de réaliser un sous-programme appelé "envoiAProcessing()" ayant un paramètre de type :
<
struct data
{
Ligne 2 066 :
int z_gyro;
};
</syntaxhighlight>
qui regroupe donc toutes les données importantes et un autre paramètre de type float pour envoyer dt.
Ligne 2 073 :
{{solution|contenu=
Voici une version sans sous-programme :
<
#include<Wire.h>
const int MPU=0x68; // I2C address of the MPU-6050
Ligne 2 185 :
}
</syntaxhighlight>
}}
Ligne 2 200 :
{{solution|contenu=
Voici une version d'essai qui ne fonctionne pas correctement, en tout cas pas mieux que la solution de l'exercice 6. '''Cette solution doit être corrigée au plus vite'''.
<
#include<Wire.h>
const int MPU=0x68; // I2C address of the MPU-6050
Ligne 2 321 :
}
</syntaxhighlight>
}}
Ligne 2 344 :
Elles nécessitent l’utilisation des vecteurs sous forme de tableau.
{{Boîte déroulante|titre=Routines mathématiques pour le calcul sur vecteurs|contenu=
<
#ifndef VECTOR3D__H
#define VECTOR3D__H
Ligne 2 409 :
}
#endif
</syntaxhighlight>
}}
Ligne 2 416 :
Les matrices sont supposées être des tableaux à une seule dimension dans les routines proposées ci-dessous.
{{Boîte déroulante|titre=Routines mathématiques pour les matrices 3x3|contenu=
<
#ifndef MATRIX_H
#define MATRIX_H
Ligne 2 553 :
}
#endif
</syntaxhighlight>
}}
Pour ceux qui seraient frustrés d’utiliser un tableau à une dimension pour les matrices, on vous présente maintenant un autre code.
Ligne 2 561 :
{{Boîte déroulante|titre=Routines mathématiques pour les matrices 3x3 (avec classe objet)|contenu=
<
/*
* matrixtools.h
Ligne 2 626 :
};
#endif /* MATRIXTOOLS_H_ */
</syntaxhighlight>
}}
Et maintenant le code (Merci à Loïc Kaemmerlen et Pascal Madesclair)
{{Boîte déroulante|titre=Routines mathématiques pour les matrices 3x3|contenu=
<
/*
* matrixtools.cpp
Ligne 2 890 :
}
}
</syntaxhighlight>
}}
Ligne 2 897 :
Voici un ensemble de routines utilisant les quaternions proposé par Jeff Rowberg.
{{Boîte déroulante|titre=Routines mathématiques pour Quaternions|contenu=
<
// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class, 3D math helper
// 6/5/2012 by Jeff Rowberg <jeff@rowberg.net>
Ligne 3 114 :
#endif /* _HELPER_3DMATH_H_ */
</syntaxhighlight>
}}
Ligne 3 121 :
Dans les codes d'exemple d'utilisation de l'accéléromètre, vous pouvez trouver des lignes du genre :
<
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(220);
Ligne 3 127 :
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
</syntaxhighlight>
et votre problème consiste à trouver toutes les valeurs correspondants à votre MPU6050. Pour cela vous pouvez utiliser du code que l'on trouve sur Internet.
{{Boîte déroulante|titre=Code de calibration trouvé sur Internet (luisrodenas)|contenu=
[https://www.i2cdevlib.com/forums/topic/96-arduino-sketch-to-automatically-calculate-mpu6050-offsets/ article de '''luisrodenas''']
<
// Arduino sketch that returns calibration offsets for MPU6050 // Version 1.1 (31th January 2014)
// Done by Luis Ródenas <luisrodenaslorda@gmail.com>
Ligne 3 244 :
}
}
</syntaxhighlight>
Remplacer
<
Serial.println("...");
</syntaxhighlight>
par
<
Serial.print(mean_ax);
Serial.print("\t");
Ligne 3 263 :
Serial.print("\t");
Serial.println(mean_gz);
</syntaxhighlight>
pour avoir des données lisibles.
}}
|