BTS Mesure BTS Mesure
DébutTP 01TP 02Trouve NombreCourbesCTNPT100VISABT VISAArduinoNI6009ChenillardMétrologieRégulationMPUCodeurC2IEtalon

Régulation de position et de vitesse avec un codeur

Comment exploiter le codeur de notre robot gyropode ?

Pour aller plus loin que le simple maintien en équilibre du robot nous avons besoin d'un codeur.

Comment contrôler la position des roues et la position du robot ?
Réponse : le codeur et la régulation de position.

Comment maitriser la vitesse de déplacement du robot ?
Réponse : le codeur et la régulation de vitesse.

Réaliser système instrumenté permettant de déterminer la position, la vitesse et l’accélération d’un objet.

Cahier des charges :

  1. Analyser le fonctionnement du codeur à deux sorties à l'aide d'un oscilloscope
  2. Réaliser un programme Arduino qui exploite les 2 codeurs du robot afin de réaliser un codeur incrémental.
    Prévoir une structure facile à intégrer dans le programme gyropode avec régulation d'angle.
  3. Modifier la fonction compteur pour être sûr de ne manquer aucune impulsion.
  4. Réaliser une régulation de position.
  5. Réaliser une régulation de vitesse

1. Pourquoi 2 sorties A et B pour un codeur ?

Les moteurs de notre robot sont équipés d'un codeur incrémental à effet Hall.

Comme le montre la doc technique, le codeur offre 2 sorties CNTA1 (A) et CTNA2 (B).

Le capteur est placé sur l'axe du moteur, il est constitué :
- d'un rotor sur lequel est fixé 11 petits aimants ,
- d'un stator sur lequel on place
   2 capteurs à effet hall séparés d'un nombre entier de pas + un quart de pas .

Un tour moteur correspond à 11 impulsions.
Un tour de roue avec le réducteur correspond à 30 tours moteur.
Pour un tour de roue nous avons 30*11= 330 impulsions.

1. Placer les sondes de l'oscilloscope sur les sorties codeur :
    - Y1 sur Hall_D_A1 soit la patte D5 de l'Arduino
    - Y2 sur Hall_D_A2 soit la patte D2 de l'Arduino
    - relier les masses Arduino et oscillo ensemble

La fonction moteur que nous allons utiliser est disponible sur ce lien.

Faites tourner le moteur gauche à 100 (sur 255) :
Relever la fréquence f du signal.
Faites une capture 1 de l'écran d'oscilloscope à joindre au compte rendu.
Mettez en évidence l'état du signal A2 (voie 2) pour un front montant de A1.
Sens 1 : Pour un front montant de A1, A2 est à l'état ........

Avec un stroboscope mesurer la vitesse du moteur N en tr/s.
Etablir une relation entre N et f.
En déduire le nombre d'impulsions pour un tour de moteur.

Faites tourner le moteur gauche à -100 (sur -255) :
Relever la fréquence f du signal.
Faites une capture 2 de l'écran d'oscilloscope à joindre au compte rendu.
Notez l'état du signal A2 (voie 2) pour un front montant de A1.
Sens 2 : Pour un front montant de A1, A2 est à l'état ........

2. Pourquoi un codeur incrémental a 2 sorties ?

Appel 1 : Présenter oralement vos oscillogrammes et le fonctionnement du codeur.

2. Comment utiliser ces codeurs avec un Arduino ?

Le codeur génère des impulsions qu'il faudra compter pour obtenir la position relative.

Variables à utiliser  : Cd : compteur droit, Cg : compteur gauche

Durée de cycle : 20*dt  =20*5 = 100 ms      Cd0 : compteur droit cycle précédent...

3. En partant du programme ci-contre et des fonctions iniPin() disponible ici, concevoir les fonctions :

void compteur()

   - Elle doit détecter les fronts montants de  Hall_D_A1

            - Utiliser la fonction Had=digitalRead(Hall_D_A1);  et  son état précédent stocké dans Had0
           - selon l'état de  digitalRead(Hall_D_A2) elle doit incrémenter ou décrémenter le compteur Cd

    - Idem  pour les fronts montants de  Hall_G_A1 et son compteur associé Cg

    - appeler cette  fonction à l'endroit le plus opportun dans le programme loop()

    - Si (Compteur droit =Compteur droit précédent et Cg=Cg0) ne rien faire...

    - sinon affiche toutes les 100 ms Cd;Cg

Ajouter toutes les variables nécessaire pour faire tourner ce programme.

Vérifier que vos compteurs fonctionnent et détectent le sens de rotation.

Faites un repère sur les roues, combien d'impulsions détectez-vous pour un tour de roue ?

Le diamètre des roues est de 6,8 cm. Un tour de roue représente quelle distance d en cm ?
Déplacer votre robot de cette distance d. Cela représente combien d'impulsions ?
Quelle est la résolution du codeur (1 impulsion) Δθ (en °) , ΔL (en cm) ?

Pour pouvoir facilement associer la régulation de position et de vitesse à la régulation d'angle de tangage,
nous reprenons la boucle cadencée à dt=5ms.

Le compteur i compte le nombre de cycles de 5ms.
La fonction delay() est à proscrire dans un système dynamique comme celui-ci.

void setup() {
  Serial.begin(115200);      //Pour communiquer rapidement avec Labview 
  iniPin();                 //Initialisation pinMode du shield     
  digitalWrite(buz,HIGH);
  delay(10);
  digitalWrite(buz,LOW); 
}

void loop() {
  t0=micros();  // top départ boucle
  if (i%20==0) affiche();     // Affiche tous les 20*5=100ms
  if (!digitalRead(BP) && i-iBP>50) raz();
  if (i-recu>2)digitalWrite(buz,LOW);
  i++;
  while (micros()-t0<dt*1e6);
}
   

4. Que fait le bouton poussoir associé à la fonction void raz() ?
    On souhaite allumer les moteurs pendant une seconde lorsque Cd=0 et Cg=0.
    Ajouter les lignes de code pour répondre à ce cahier des charges.

               if (???) dep=i;  
              if
(???) moteur(255,255); else moteur(0,0);  

    Les résultats annoncés par le compteur vous semblent-ils cohérents ? 

Appel 2 : Monter le bon fonctionnement de votre compteur au professeur.

3. Sommes-nous sûr de compter toutes les impulsions ?

La plaque signalétique du moteur indique :

DC 12V     320 tr/min   avec réducteur 30

moteur(255,255) alimente le moteur en 12 V (selon la charge de la batterie).

5. Lors de la question 4 nous avons fait tourner notre moteur durant une seconde à 12 V
    si on néglige les régimes transitoires, calculer :

  •  la vitesse du moteur N en tr/s;

  • le nombre d'impulsions Imp ;

  • la période T d'une impulsion ;

  • le décalage ΔT=T/4 entre le signal A1 et A2 ;

  • la vitesse maxi. du robot v en m/s (diamètre des roues = 6,8 cm).

     Cela vous semble-t-il cohérent avec la question 4 ?
     Nous testons la vitesse du robot à vide, elle doit-être légèrement supérieure à sa vitesse nominale.

A cette vitesse, il doit s'écouler au maximum ΔT=142 µs entre 2 appels de  void compteur() pour détecter l'impulsion et son signe.

Pour un programme minimaliste c'est possible. Par contre pour un programme plus complexe nous allons louper des impulsions...

Nous allons remplacer  void compteur()  par des interruptions.

Arduino ne gére que deux interruptions sur d2 et d3.
Aussi nous devons utiliser cette bibliothèque qui permet de créer des interruptions sur toutes les pattes :

#include <PinChangeInt.h>

Nous allons placer dans void setup() :

   attachPinChangeInterrupt(Hall_G_A1, Code_gauche, RISING );
  attachPinChangeInterrupt(Hall_D_A1, Code_droite, RISING );

6. Remplacer void compteur()  par les 2 fonctions suivantes :

    void Code_gauche() // Si G_A2 Cg-- sinon Cg++
   void Code_droite() // Si D_A2 Cd++ sinon Cd-- 

    Tester vos nouvelles fonctions et corriger les problèmes de signes.
   En marche avant les compteurs doivent s'incrémenter.
   En marche arrière les compteurs doivent se décrémenter.
   Faites tourner les moteurs durant une seconde à pleine vitesse.
   Les résultats obtenus sont-ils cohérents ?

7. Est-ce que les deux moteurs tournent à la même vitesse ?
    Proposer une solution pour remédier à ce problème.

Appel 3 : Faites valider par le professeur.

4. Comment faire une régulation de position ?

8. Ecrire la fonction void regulation2() répondant au cahier des charges suivant :

   
    - Calculer grâce à une régulation proportionnelle les puissances droite et gauche à appliquer aux moteurs
    - Appliquer une borne absolue supérieure à vmax ou -vmax
    - Eviter les vibrations permanentes à l'équilibre, par exemple :
           Appliquer une borne absolue inférieure à 20 ou - 20 (puissance mini pour vaincre le couple statique)
           Si la position est proche à 3 impulsions près stopper les moteurs.

Respectez les cahiers des charges suivants pour être compatible avec le VI Labview disponible ici.

      
    Ecrire la fonction void réception() capable de recevoir une chaîne de type : 330;200;5.6;
    et de l'interpréter ainsi :
    - consigne=330
    - vmax=200
    - Kp=5.6
    Pour confirmer la réception envoyer la réponse : Cons.=330 Vmax=200 Kp=5.60

   
    Modifier la fonction affiche, pour afficher 5 variables :
    1. consigne;
    2. Cd;
    3. droite;
    4. Cg;
    5. gauche; 

    
     Afficher les résultats toutes les 20ms pour avoir plus de résultats à afficher lorsque (Cd!=Cd0 || Cg!=Cg0)

      Mettre au point le programme.

9. Evaluer les qualités de votre régulation en remplissant ce tableau récapitulatif :
    avec vmax=255 et un échelon de 1 tour soit 330 impulsions

Consigne ( en imp)

330

330

330

330

Kp

5.6

 

 

 

Bande Proportionnelle
(en imp puis en %)

45 imp
13.6%

 

 

 

Dépassement d1 (en %)

 

20 %

5%

 

Nb de dépassement

 

 

 

0

tr5% en s

 

 

 

 

Erreur statique

 

 

 

 

Capture d’écran
annotée à joindre

1

2

3

4

Précision (de +++ à -)

 

 

 

 

Stabilité (de +++ à -)

 

 

 

 

Rapidité (de +++ à -)

 

 

 

 

    Tr5% : temps de réponse à 5% soit ±16 impulsions.
   Tr1% : temps de réponse à 1% soit ±3 impulsions.

   Bande Proportionnelle :  A partir de quand l'action PWM n'est plus vmax=255 ?
                                              PWM=Kp*écart → 255=Kp*BP→ BP= 255/5.6 = 45 imp
                                              Puis en % de l'échelon : BP(en %) = 45 /330 = 13.6%
                                              Souvent la BP en % de la gamme de mesure remplace Kp dans la programmation des correcteurs industriels.

   Dépassement en % : un dépassement de 20 % d'un échelon de 330 imp
                                        représente 66 imp de dépassement soit un max de 396 imp

    Est-ce que les courbes Cd(t) et Gg(t) sont identiques ?

10. Couplage électronique des moteurs : on souhaite que les positions des moteurs droite et gauche soient quasi-identiques.
      Modifier void regulation2()  dans ce but. Par exemple :
      Si (Cd>Cg) alors il faut ralentir droite : droite=droite-10*(Cd-Cg)
                         sinon il faut ralentir gauche : gauche= gauche-10*(Cg-Cd)

Appel 4 : En vous inspirant de la vidéo de présentation et de votre tableau,
               montrer de manière qualitative au professeur que votre régulation est :
               - précise;
               - rapide;
               - stable même avec une entrée perturbatrice.

5. Etes-vous capable de concevoir une régulation de vitesse ?

11. Conception et Mise en Oeuvre d'une régulation de vitesse à partir du bloc codeur - moteur - réducteur - roue.

  • Calculer et afficher vitD et vitG (en imp/s) toutes les 100ms
    Vérifier à l'aide de l'oscilloscope la validité de votre affichage.

  • A partir du moniteur série on pilote la vitesse N (en imp/s) Kp et Ki

  • Créer un VI Labview qui affiche vitD et vitG en imp/s , en tr/s et en cm/s
    Le VI peut aussi modifier la consigne, Kp et Ki

  • Trouver le Kp permettant une régulation stable, précise et rapide.

  • Quelle est la résolution ΔN (en imp/s et tr/s)  de la vitesse affichée si Δt = 0,1s ?

       Partir du programme régulation de position et faites les modifications nécessaires.

     Comment programmer  ?
     Piste 1 : simple mais peu dynamique (rafraichissement 100 ms)
                   appeler regulation2() tous les 20 cycles, soit 20*5 = 100 ms

     Piste 2 : moins simple mais plus dynamique (rafraichissement 5 ms)
                    créer un tableau en variable globale :
                    stocker dans cette file d'attente First In First Out les 20+1 derniers relevés :
                    [i%21] : pointe sur Cd(t), compteur Cd actuel
                    [(i-20)%21] : pointe sur Cd(t-0,1), compteur Cd 20 cycles en arrière...

  •    L'action proportionnelle seule est-elle précise ?

  •    Ajouter une action Intégrale pour la vitesse droite.
       Puis comparer vitD et vitG

 

12. Réaliser un système instrumenté permettant de déterminer la position, la vitesse et l’accélération d’un objet.

  • Calculer l'accélération en imp.s-2 grâce à fifoCd la file d'attente des 20 dernières mesures.

  • Modifier le programme Arduino et l'interface Labview afin d'afficher  la position, la vitesse et l’accélération du robot.

Pourquoi toutes ces régulations ?

La régulation d'angle de tangage nous a permis de maintenir en équilibre le robot.

Piloter ce robot est un défi que nous pouvons relever grâce à tous nos capteurs.

Comment le faire se déplacer, virer, suivre un parcours ?

Voici quelques pistes de travail pour la bonne utilisation des capteurs (MPU6050 et codeur) du robot  :

-  tangage : permet de maintenir l'équilibre avec une consigne de tangage ct=0.

- position :  pour éviter de virer lors de la phase d'équilibre
                      pourquoi ne pas vérouiller électroniquement les 2 roues ?

- vitesse :    pour que le robot se déplace il suffit de le faire pencher légèrement en avant
                      pourquoi ne pas faire une régulation en cascade : cV (consigne Vitesse) → ct (consigne tangage)  →  θ, V

- lacet :       avec une régulation de l'angle de lacet nous pouvons réguler un changement de cap d'angle θ et
                    calculer le Δ à appliquer : droite=droite-Δ   gauche=gauche+Δ pour virer...

- position : grâce au codeur nous pourrons programmer un parcours automatique :
                    avancer de 1,2m puis virage à droite de 90° puis avancer de 2m....