J'ai déjà posté il y a quelques jours pour un problème de définition de période pour intégrer et dériver mes vitesses angulaires. J'ai résolu ce problème mais j'en ai un nouveau concernant la dérivée.
J'arrive à calculer un angle en degrés à partir de la vitesse angulaire fournie par le gyroscope par intégration.
Vos formules de dérivation ne sont certainement pas les bonnes....
Si je veux calculer une estimation de la dérivée temporelle de Truc, c'est le quotient:
(Truc[t] - Truc[t -deltaT]) / (deltaT)
et une façon de la calculer (un peu moins folklorique) est
if (MISSING != trucPrecedent) { // au debut, il n'y a pas de précedent, dirait Lpalisse
DerivTruc = Truc - trucPrecedent;
} else DEricTruc = 0;
trucPrecedent = Truc; // dans tous les cas
Je vous l'ai ecrit précedemment:
au debut, il n'est pas defini (et le plus sain est de mettre une "dérivée" nulle)
Après, c'est Gyro(t) qui devient GyroPrecedent....
Il vous faut attendre un (tout petit moment ) au démarrage pour avoir la valeur précedente.
Nota: au vu de vos courbes, votre "dérivée" a l'air très bruitée....
MISSING est une valeur que votre gyro ne sortira jamais.... (valeur manquante: en toute logique, au demarrage, on n'a pas de valeur precedente : il faut initialiser à manquante.... -ça peut servir aussi à gérer les cas de panne; peut être que ça servira, à terme, avec l'usure des capteurs- ).
Une façon simple de la définir est
#define MISSING 123456789.0
une façon un peu plus belle est :
const float MISSING = 123456789.0 ;
(tout reel en dehors de la plage de sortie de votre gyroscope peut faire l'affaire: j'avoue que j'ai eu la main lourde)
edit
a) c(++) fait la difference entre les majuscules et les minuscules; j'ai écrit en majuscules MISSING pour en faire une "defined macro" -convention de lecture assz courante- , et , un peu par abus, je vous ai laissé le choix d'en faire une "const" What is the difference between a macro and a const in C++? - Stack Overflow explique pourquoi c'est plus beau....
b) mes bouts de code sont donnés à titre indicatif (vu les typos, ils ne peuvent pas compiler tels quels); l'essentiel est que vous compreniez le principe.
Pour calculer une dérivée, tu divises l'accroissement de ta variable par la durée sur laquelle cet accroissement est mesuré.
En français, tu stockes quelque part la valeur précédemment mesurée. Puis à chaque nouvelle mesure tu calcules la différence entre cette nouvelle mesure et la valeur précédente stockée et tu divises le résultat par le temps écoulé entre ces deux mesures. Puis pour préparer le prochain calcul de dérivée, tu remplaces la valeur précédente, stockée quelque part, par la nouvelle valeur.
Oui, comme je le disais précédemment j'ai bien compris le principe mais je ne parviens pas à le mettre en application.
J'ai pour l'instant ceci, mais la courbe en sortie a la même forme que celle de la vitesse...
Je met un bout de code "condensé", je pourrai mettre l'intégralité si besoin.
// Variables globales
float GyroY; // où je stocke ma vitesse angulaire en Y après avoir soustrait les offsets
float GyroYPrec = 0; // pour stocker ma vitesse "précédente" pour l'intégration, je l'initialise à 0
GyroAccelY; // Accélération angulaire (ce que je souhaite déterminer)
void setup(){blabla}
void loop (){
imu.readsensor();
GyroY=IMU.getGyroY_rads();
GyroAccel();
}
void GyroAccel(){
// première boucle
if (GyroYPrec==0){
GyroAccelY = GyroY / 0.005;
}
// boucles suivantes
else{
GyroAccelY = (GyroY-GyroYPrec) / 0.005;
GyroYPrec = GyroY;
}
}
@dbrion
Il y a quelque chose qui m'échappe avec missing : si je lui affecte une valeur improbable, la condition n'est jamais remplie (Trucprecedent toujours différent de la valeur).
Fais simple. Initialise la première valeur précédente à zéro, ça te donnera une première dérivée fausse mais ce n'est pas bien grave...
Et fais simplement le calcul sans t'encombrer d'un test
Il y a deux doctrines possibles:
a) que des données manquantes peuvent se rencontrer de temps en temps, avec le vieillissement des capteurs et, pour certains, la possibilité de detecter que la mesure n'est pas valide. Autant le prévoir dans les codes dès le départ (un test d'une ligne). La façon classique de traiter une panne detectée est de coder à une valeur impossible (en dehors du domaine de mesure)
b) que, sauf pour le démarrage (que l'on peut régler en mettant la valeur precedente à zero), il n'y aura jamais de mesure detectée comme aberrante.
Les deux sont valables, et, pour sortir un dessin, la seconde est plus simple..... (à terme, je n'en sais rien).
la courbe en sortie a la même forme que celle de la vitesse...
Comme votre grandeur à dériver a de grandes plages où elle est nulle (et donc constante), vous verrez que la dérivée, sur de grandes plages, est nulle aussi... Au premier regard, ce sera vrai.
Ensuite, il faudrait donner les deux courbes, pour vérifier (les codes que vous affichez semblent bons: comme c'est une version adaptée et simplifiée de ce que j'ai donné, je ne peux pas les critiquer) que vos calculs sont vraisemblables..... Déjà, la grandeur à dériver semble affectée de discontinuités (chocs?). Sa "dérivée" sera encore plus bruitée....
Et regardant tes courbes, j'ai l'impression que c'est l'intégration qui est fausse, c'est à dire la courbe de l'angle en degrés. J'ai du mal à croire, en voyant la vitesse angulaire, que l'angle revient pile à zéro, et d'autre part que les courbes d'angle et d'accélération soient aussi semblables.
Que l'angle revienne "pile à zero" ne me choque pas (les échelles ont une grande dynamique, et j'ai fait le pari que le gyromètre ait été très bien compensé/étalonné au préalable).
Mais je serais curieux de voir les courbes avec les nouvelles moutures de logiciel, d'autant plus que le choix du logiciel qui trace les courbes m'a l'air judicieux.
Une chose qui est moins judicieuse, c'est le fait que la vitesse du port serie soit à 9600 bauds : si on veut sortir 3 reels toutes les 50 ms, ça fait, une fois converti en ASCII, environ 30 caractères par mesure (et donc 600 caractères par seconde). C'est tolérable, mais si on rajoute d'autres voies, on va créer un goulet d'étranglement avec la voie de ...debugging... Autant se mettre à 115200 bauds, pour ne pas créer de blocage, à terme.
Je vous remercie pour le temps que vous prenez pour m'aider. Je ne suis plus très loin de la vérité.
Je répond un peu dans le désordre :
C'est normal que mon angle revienne pile à 0. Le capteur est posé sur une touche de piano et mesure la vitesse angulaire de celle-ci à l'enfoncement et au relâchement. La touche revient à son état de "repos" après le relâchement.
L'angle mesuré est correct. En utilisant ma longueur de touche, je trouve un enfoncement de la touche (arc) cohérent.
Le gyroscope est calibré au préalable.
Sur les graphiques que j'ai posté, il y a effectivement un problème de "paliers" qui était dû à Excel et que j'ai corrigé en renvoyant le timer en ms plutôt qu'en s. Je met ci-dessous les graphiques que j'obtiens actuellement.
La vitesse est à 128000 bauds, c'est le plus rapide que le logiciel (PLX-DAQ) propose.
J'essayerai de l'améliorer pour l'initialiser correctement.
La courbe retournée a la bonne forme (même forme que celle retournée lorsque je dérive avec Excel), mais pas la bonne échelle (à un coefficient de 1000 près).
Courbes :
Vitesse angulaire
Angle
Accélération angulaire (Arduino)
Accélération angulaire (Excel)
Il me reste donc à comprendre pourquoi pour intégrer j'utilise une valeur en s alors que pour dériver j'ai besoin d'une valeur en ms, mais je ne doute pas d'y parvenir.
Bon, votre choix de 128000 bauds n'est pas standard. Je pense que 115200 bauds feraient l'affaire (c'est à 10% : je proposais de transmettre 10 fois plus vite que 9600 bauds, sans rentrer dans les details).
Votre façon de travailler (test sous excel et sous arduino) fait que je n'ai aucune inquiétude quant à la détection de l'effet d'un changement d'unités -nécessaire pour éviter des underflows? par faute de frappe?) sur les echelles...