Contrôle PID du fader du moteur

15

J'essaie de contrôler un fader motorisé (potentiomètre à glissière linéaire) à l'aide d'un Arduino.
Le contrôle PID donne de bons résultats pour "sauter" à une position cible spécifique, mais le suivi des rampes est un problème, il n'est pas du tout lisse. Le mouvement est très saccadé, peu importe ce que j'essaie.

Voici un tracé de la position de référence, de la position mesurée et de la sortie du moteur lors du suivi d'une rampe: Suivre une rampe

Et voici une vidéo de ce même test.

Sur les systèmes commerciaux, cela semble beaucoup plus fluide, voyez ceci .

Détails :
Le fader du moteur est un Alps RSA0N11M9A0K . Pour le piloter, j'utilise un pont H ST L293D , alimenté par une alimentation régulée 10 V DC ( XL6009 ).
Sur l'Arduino UNO (ATmega328P), j'utilise les broches 9 et 10, avec une fréquence PWM de 31,372 kHz pour le rendre inaudible (Timer1 avec un pré-échelle de 1, TCCR1B = (TCCR1B & 0b11111000) | 0b001).
Le potentiomètre est câblé entre la masse et 5V, avec l'essuie-glace allant à ADC0, comme d'habitude.

Le contrôleur :
J'utilise un simple contrôleur PID avec anti-windup, qui se met à jour à un rythme de 1 kHz (Ts = 1e-3 s):

float update(int16_t input) {
  int16_t error = setpoint - input;
  int16_t newIntegral = integral + error;
  float output = k_p * error 
               + k_i * newIntegral * Ts 
               + k_d * (input - previousInput) / Ts;

  if (output > maxOutput)
    output = maxOutput;
  else if (output < -maxOutput)
    output = -maxOutput;
  else
    integral = newIntegral;

  previousInput = input;
  return output;
}

La sortie du contrôleur est une valeur comprise entre -127 et 127. La sortie PWM est générée comme suit:

const int8_t knee = 48;

uint8_t activation(int8_t val) {
  if (val == 0)
    return 0;
  else {
    return map(val, 0, 127, 2 * knee, 255);
  }
}

void writeMotor(int8_t val) {
  if (val >= 0) {
    analogWrite(forward, activation(val));
    digitalWrite(backward, 0);
  } else {
    analogWrite(backward, activation(-val));
    digitalWrite(forward, 0);
  }
}

J'ai ajouté 48 au signal PWM 7 bits, car c'est là que le moteur commence à se déplacer à 31 kHz, puis je l'ai augmenté à un nombre 8 bits (car c'est ce que la analogWritefonction attend): Vitesse PWM

Ce que j'ai essayé :
j'ai essayé d'ajouter un filtre EMA à l'entrée, au signal de contrôle, à la composante dérivée du contrôleur PID, mais en vain. J'ai également essayé de réduire la résolution de l'entrée analogique, en utilisant l' hystérésis pour l'empêcher de basculer entre deux valeurs à l'arrêt. Cela ne semble rien affecter. Augmenter le pas de temps à 10 ms ne semble pas non plus aider.

J'ai également essayé de faire une identification du système dans MATLAB, et j'ai essayé de le régler dans Simulink (après cela série de vidéos ). J'ai eu un modèle avec un ajustement de 91%, mais je ne savais pas comment gérer les non-linéarités d'entrée et de sortie du modèle MATLAB, comment elles affectent le réglage PID et comment l'implémenter sur l'Arduino.

La dernière chose que j'ai essayée est de créer deux contrôleurs différents: un pour les grands sauts dans la position de référence et un pour les petites erreurs lors du suivi d'une rampe. Cela semble aider un peu, car alors je peux augmenter le coefficient intégral lors du suivi, sans augmenter le dépassement lors du saut.
Cependant, en augmentant le gain intégral (et proportionnel), le moteur fait maintenant toujours quelque chose, même lorsqu'il doit être stationnaire et que la référence ne change pas. (Il ne bouge pas vraiment, mais vous pouvez le sentir vibrer.)
Je n'ai pratiquement pas de gain dérivé, car l'augmentation plus élevée que 1e-4 semble le rendre encore plus saccadé, et je ne remarque pas vraiment de différence entre 0 et 1e-4.

Je suppose qu'il a besoin de plus de puissance pour surmonter le frottement statique, puis le frottement dynamique est moindre, donc il dépasse, donc il entraîne le moteur en arrière, le faisant s'arrêter à nouveau, puis il doit à nouveau surmonter le frottement statique, il tire à nouveau vers l'avant , etc.

Comment les contrôleurs commerciaux surmontent-ils ce problème?

Mes antécédents :
je suis en troisième année de bachelier en génie électrique, j'ai suivi des cours sur la théorie du contrôle, le traitement numérique du signal, le contrôle LQR, etc. J'ai donc des connaissances théoriques, mais j'ai du mal à appliquer toutes ces théories à ce système du monde réel.


Edit :
J'ai testé les mesures du capteur en boucle ouverte, comme recommandé par laptop2d, et je suis assez surpris des résultats: à des fréquences PWM élevées, il y a des pics désagréables dans les lectures. À 490 Hz, il n'y en a pas.
Et ceci est à un rapport cyclique constant, donc je ne peux pas imaginer quel genre de bruit je reçois lorsque le moteur inverse très rapidement la direction.

entrez la description de l'image ici

Je vais donc devoir trouver un moyen de filtrer ce bruit avant de recommencer à travailler sur le contrôleur.

Edit 2 : L'
utilisation d'un filtre exponentiel à moyenne mobile n'était pas suffisant pour filtrer le bruit.

EMA

J'ai essayé avec des poteaux en 0,25, 0,50 et 0,75. Les petits poteaux n'ont pas eu beaucoup d'effet, et les plus grands poteaux ont ajouté trop de latence, j'ai donc dû réduire les gains pour le maintenir stable, ce qui a entraîné une dégradation des performances globales.

J'ai ajouté un condensateur de 0,1 µF à travers le potentiomètre (entre l'essuie-glace et la masse), et cela semble le nettoyer.

Pour l'instant, cela fonctionne assez bien. En attendant, je lis le journal publié par Tim Wescott .
Merci à tous pour votre aide.

tttapa
la source
pouvez-vous contrôler avec précision 31kHz pwm?
Hasan alattar
@Hasanalattar: Non, les fréquences que je peux utiliser sont sur le deuxième graphique (échelle de 1, 8, 64, 256, 1024). 4 kHz et 500 Hz sont audibles, donc ils produisent un bip sonore gênant, que j'aimerais éviter. Cela laisse 31 kHz, 120 Hz et 30 Hz. Et les deux derniers sont trop lents, je pense. La résolution PWM est de 8 bits, mais j'utilise moins, car mon signal de contrôle n'est que de 7 bits, et j'utilise uniquement des valeurs PWM supérieures à 96.
tttapa
1
Le pont en H que vous avez lié a sur la première page de la fiche technique: This device is suitable for use in switching applications at frequencies up to 5 kHz. Mais les caractéristiques électriques à la page 3 suggèrent un maximum absolu de 690 kHz si vous additionnez tous les retards. (4 dernières lignes) Personnellement, j'irais beaucoup plus lentement que cela, mais je pense que 31 kHz devraient être adéquats ... sans la note de la page 1.
AaronD
Cependant, cela suppose un cycle de service fixe. (ou « ne se soucient pas » cycle de service pour la fréquence maximale absolue à « juste agitez » - vous remarquerez qu'il est asymétrique) élevé et de faibles cycles de service peuvent produire des impulsions très étroites, donc la largeur sont celles par rapport à la bas de la page 3?
AaronD
1
Je ne sais pas si c'est votre problème, mais si l'horodatage peut varier, je pense que vous devriez ajouter l'erreur * Ts à l'intégrale, pas seulement l'erreur, et ne pas multiplier l'intégrale par Ts. (Si Ts est toujours une constante, cela n'a pas d'importance)
user253751

Réponses:

9

Un système de contrôle est aussi bon que son capteur, exécutez la boucle ouverte du capteur et supprimez l'entrée de contrôle. Créez votre propre entrée pour le capteur et faites-le glisser lentement (ou trouvez un moyen de le faire glisser de manière fiable et fiable) tout en prenant des données de position pour vous assurer qu'il ne s'agit pas du capteur. Si le capteur est bruyant, améliorez les performances du capteur en obtenant un nouveau capteur ou en le mettant en parallèle, ou en filtrant la sortie du capteur . Vous devrez peut-être un capteur avec une résolution plus élevée.

Si le capteur n'est pas bruyant, vous devrez obtenir une boucle de contrôle différente. Les PID sont des systèmes de premier ordre et pas vraiment efficaces pour le contrôle du débit.

Pic de tension
la source
Merci, il y a en effet beaucoup de bruit avec des fréquences PWM plus élevées, donc je vais devoir trouver un moyen d'améliorer cela. Avez-vous des conseils sur la façon de procéder?
tttapa
Utilisez un filtre, mécanique ou numérique. Si vous ne pouvez pas faire cela, il serait peut-être bon de mettre en parallèle des capteurs. meta.stackexchange.com/questions/126180/…
tension du
6

Vous avez raison de penser que le problème provient de la friction ou peut-être d'une combinaison de friction et de jeu. Votre graphique de la vitesse moyenne en fonction du rapport cyclique pour différentes largeurs d'impulsion est caractéristique d'un système avec friction. Cet article explique ce que vous voyez et contient un recueil de solutions qui ont été utilisées depuis toujours pour résoudre les problèmes. Vous ne les aurez pas vus dans votre cursus d'ingénieur car ils sont difficiles à analyser; vous devez essentiellement jouer avec eux au cas par cas pour les faire fonctionner.

Je ne sais pas ce que font les contrôleurs commerciaux, bien que je soupçonne qu'il existe une variété de solutions. Ce que j'ai fait dans le passé avec des choses comme ça, c'est quand le signal d'entraînement du moteur de mon contrôleur PID tombe en dessous d'un certain seuil (probablement 60 à 70 comptes dans votre cas) Je commence à pulser l'entraînement du moteur au seuil, avec un devoir cycle qui rend le variateur moyen égal à la sortie PID. J'utilise généralement un modulateur sigma-delta-ish pour cela car il peut être implémenté en très peu de lignes, mais vous pouvez aller avec ce qui fonctionne pour vous.

TimWescott
la source
4

Il semble que la plupart du bruit provienne du signal de commande PWM.

Avez-vous essayé de synchroniser la capture ADC avec le cycle PWM? La plupart des microcontrôleurs ont un moyen de déclencher la capture ADC sur la minuterie, vous pouvez donc toujours déclencher au même point du cycle.

Pour un bruit le plus faible, la position d'échantillonnage optimale serait juste avant de mettre le moteur sous tension, car les pointes ont eu le plus de temps pour se stabiliser. Mais quelle que soit la position, la synchronisation de la capture réduira les pics car la quantité de décalage restera approximativement la même au même point du cycle PWM.

jpa
la source
3

Je vais donc devoir trouver un moyen de filtrer ce bruit avant de recommencer à travailler sur le contrôleur.

Vous pouvez filtrer le bruit du capteur (ou toute autre mesure / variable bruyante) dans le code avec quelque chose comme ça (filtrage passe-bas):

Sfiltré[k]=αSfiltré[k-1]+(1-α)Sbrut[k]

0<<α1. Le plus proche de 1, le plus lisse va regarder, mais il ajoute également plus de décalage, commencez par une valeur de 0,9, par exemple et voyez comment il se comporte.

Big6
la source
J'ai essayé, mais ce n'est pas suffisant pour se débarrasser des pics, et cela ajoute trop de décalage.
tttapa
@tttapa je vois. Quelle valeur pour alpha avez-vous essayé? (0.8.0.9) Il va falloir un peu de réglage, ce que vous avez peut-être déjà fait, je me demandais juste.
Big6
J'ai mis à jour mon message d'origine pour ajouter un tracé des filtres EMA que j'ai essayés. J'ai également essayé 0.9, et c'était encore pire que le 0.75, les gains doivent être beaucoup plus bas à cause du retard. Je pense que je vais utiliser un EMA limité pour nettoyer le bruit ADC, mais pour l'instant le condensateur est suffisant.
tttapa