Motorfader PID-Regelung


15

Ich versuche, einen motorisierten Fader (lineares Schiebepotentiometer) mit einem Arduino zu steuern.
Die PID-Regelung liefert gute Ergebnisse für das "Springen" zu einer bestimmten Zielposition, aber Tracking-Rampen sind ein Problem, sie sind überhaupt nicht reibungslos. Die Bewegung ist sehr ruckelig, egal was ich versuche.

Hier ist eine grafische Darstellung der Referenzposition, der gemessenen Position und der Motorleistung beim Verfolgen einer Rampe: Verfolgung einer Rampe

Und hier ist ein Video des gleichen Tests.

Auf kommerziellen Systemen scheint es viel flüssiger zu sein, siehe dies .

Details :
Der Motor - Fader eine ist Alpen RSA0N11M9A0K . Für den Antrieb verwende ich eine ST L293D H-Brücke, die von einem geregelten 10-V-Gleichstromnetzteil ( XL6009 ) gespeist wird .
Auf dem Arduino UNO (ATmega328P) verwende ich die Pins 9 und 10 mit einer PWM-Frequenz von 31,372 kHz, um es unhörbar zu machen (Timer1 mit einem Prescaler von 1 TCCR1B = (TCCR1B & 0b11111000) | 0b001).
Das Potentiometer ist zwischen Masse und 5 V verdrahtet, wobei der Wischer wie üblich auf ADC0 geht.

Der Regler :
Ich verwende einen einfachen PID-Regler mit Anti-Windup, der mit einer Rate von 1 kHz aktualisiert wird (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;
}

Der Ausgang des Reglers hat einen Wert von -127 bis 127. Der PWM-Ausgang wird wie folgt generiert:

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);
  }
}

Ich habe dem 7-Bit-PWM-Signal 48 hinzugefügt, weil der Motor dort mit 31 kHz beginnt, sich zu bewegen, und skaliere ihn dann auf eine 8-Bit-Zahl (weil die analogWriteFunktion dies erwartet): PWM-Geschwindigkeit

Was ich versucht habe :
Ich habe versucht, dem Eingang, dem Steuersignal, der Ableitungskomponente des PID-Reglers einen EMA-Filter hinzuzufügen, aber ohne Erfolg. Ich habe auch versucht, die Auflösung des Analogeingangs zu verringern, indem ich die Hysterese verwendet habe , um zu verhindern, dass er im Stillstand zwischen zwei Werten wechselt. Dies scheint nichts zu beeinflussen. Das Erhöhen des Zeitschritts auf 10 ms scheint ebenfalls nicht zu helfen.

Ich habe auch versucht, ein System in MATLAB zu identifizieren und es in Simulink zu optimieren (im Anschluss an diese Videoserie ). Ich habe ein Modell mit einer Anpassung von 91% erhalten, aber ich wusste nicht, wie ich mit den Nichtlinearitäten der Eingabe und Ausgabe des MATLAB-Modells umgehen sollte, wie sie sich auf die PID-Optimierung auswirken und wie sie auf dem Arduino implementiert werden.

Als letztes habe ich versucht, zwei verschiedene Steuerungen herzustellen: eine für große Sprünge in der Referenzposition und eine für kleine Fehler beim Verfolgen einer Rampe. Dies scheint ein bisschen zu helfen, denn dann kann ich den Integralkoeffizienten beim Verfolgen erhöhen, ohne das Überschwingen beim Springen zu erhöhen.
Durch Erhöhen der integralen (und proportionalen) Verstärkung tut der Motor jetzt immer etwas, auch wenn er stationär sein sollte und sich die Referenz nicht ändert. (Es bewegt sich nicht wirklich, aber Sie spüren, wie es vibriert.)
Ich habe praktisch keine abgeleitete Verstärkung, da eine Erhöhung über 1e-4 es noch ruckeliger zu machen scheint und ich keinen Unterschied zwischen 0 und bemerke 1e-4.

Ich vermute, dass es mehr Kraft benötigt, um statische Reibung zu überwinden, dann ist die dynamische Reibung geringer, so dass es überschießt, so dass es den Motor rückwärts antreibt und ihn wieder zum Stillstand bringt, dann muss es statische Reibung wieder überwinden, es schießt wieder vorwärts , etc.

Wie überwinden kommerzielle Controller dieses Problem?

Mein Hintergrund :
Ich bin in meinem dritten Bachelor-Jahr der Elektrotechnik und habe Kurse in Steuerungstheorie, digitaler Signalverarbeitung, LQR-Steuerung usw. besucht. Daher habe ich einige theoretische Hintergrundinformationen, aber ich habe Probleme, all diese Theorien auf diese anzuwenden dieses reale System.


Edit :
Ich habe die Open-Loop-Sensormessungen getestet, wie von laptop2d empfohlen, und bin ziemlich überrascht von den Ergebnissen: Bei hohen PWM-Frequenzen gibt es unangenehme Spitzen in den Messwerten. Bei 490 Hz gibt es keine.
Und das bei einem konstanten Arbeitszyklus, also kann ich mir nicht vorstellen, welche Geräusche ich bekomme, wenn der Motor die Richtung sehr schnell umkehrt.

Bildbeschreibung hier eingeben

Also muss ich einen Weg finden, dieses Rauschen herauszufiltern, bevor ich wieder an der Steuerung arbeite.

Edit 2 :
Ein exponentielles Filter für den gleitenden Durchschnitt war nicht ausreichend, um das Rauschen herauszufiltern.

EMA

Ich habe es mit Stangen in 0.25, 0.50 und 0.75 versucht. Kleine Pole hatten keinen großen Effekt, und größere Pole erhöhten die Latenz, sodass ich die Verstärkung verringern musste, um sie stabil zu halten, was zu einer schlechteren Gesamtleistung führte.

Ich habe einen 0,1-µF-Kondensator über das Potentiometer (zwischen Wischer und Masse) gelegt, und das scheint es zu bereinigen.

Im Moment funktioniert es gut genug. In der Zwischenzeit lese ich die Zeitung von Tim Wescott durch .
Vielen Dank für Ihre Hilfe.


Kannst du 31KHz pwm mit genau steuern?
Hasan alattar

@Hasanalattar: Nein, die Frequenzen, die ich verwenden kann, befinden sich im zweiten Diagramm (Vorteiler von 1, 8, 64, 256, 1024). 4 kHz und 500 Hz sind hörbar, daher erzeugen sie einen störenden Piepton, den ich vermeiden möchte. Es verbleiben 31 kHz, 120 Hz und 30 Hz. Und die beiden letzteren sind zu langsam, denke ich. Die PWM-Auflösung beträgt 8 Bit, aber ich verwende weniger, da mein Steuersignal nur 7 Bit beträgt und ich nur PWM-Werte über 96 verwende.
tttapa

1
Die von Ihnen verknüpfte H-Brücke befindet sich auf der Vorderseite des Datenblattes: This device is suitable for use in switching applications at frequencies up to 5 kHz. Die elektrischen Eigenschaften auf Seite 3 schlagen jedoch ein absolutes Maximum von 690 kHz vor, wenn Sie alle Verzögerungen addieren. (unterste 4 Zeilen) Persönlich würde ich viel langsamer fahren, aber ich würde denken, dass 31kHz angemessen sein sollte ... ohne den Hinweis auf Seite 1.
AaronD

Dies setzt jedoch ein festes Tastverhältnis voraus. (oder ein "egal" Arbeitszyklus für die absolute Maximalfrequenz, um "nur zu wackeln" - Sie werden bemerken, dass es asymmetrisch ist) Hohe und niedrige Arbeitszyklen können einige sehr enge Impulse erzeugen, also wie breit sind diese im Vergleich zu Ende der Seite 3?
AaronD

1
Ich bin mir nicht sicher, ob es Ihr Problem ist, aber wenn der Zeitstempel variieren kann, sollten Sie meiner Meinung nach Fehler * Ts zum Integral hinzufügen, nicht nur Fehler, und das Integral nicht mit Ts multiplizieren. (Wenn Ts immer eine Konstante ist, spielt es keine Rolle)
user253751

Antworten:


9

Ein Steuersystem ist nur so gut wie sein Sensor. Führen Sie den Sensor-Open-Loop aus und entfernen Sie die Steuereingabe. Erstellen Sie eine eigene Eingabe für den Sensor und schieben Sie ihn langsam (oder suchen Sie einen Weg, um ihn langsam und zuverlässig zu schieben), während Sie Positionsdaten erfassen, um sicherzustellen, dass es sich nicht um den Sensor handelt. Wenn der Sensor verrauscht ist, verbessern Sie die Leistung des Sensors, indem Sie einen neuen Sensor beschaffen oder ihn parallel schalten oder die Ausgabe des Sensors filtern . Möglicherweise benötigen Sie einen Sensor mit höherer Auflösung.

Wenn der Sensor nicht verrauscht ist, müssen Sie einen anderen Regelkreis einrichten. PIDs sind Systeme erster Ordnung und bei der Geschwindigkeitskontrolle nicht besonders gut.


Vielen Dank, es gibt in der Tat viel Rauschen bei höheren PWM-Frequenzen. Ich muss also einen Weg finden, dies zu verbessern. Haben Sie Hinweise dazu?
Tttapa

Verwenden Sie einen Filter, mechanisch oder digital. Wenn Sie das nicht tun können, sind sie möglicherweise gut für die Parallelschaltung von Sensoren. meta.stackexchange.com/questions/126180/…
Voltage Spike

6

Sie haben Recht, dass das Problem auf Reibung oder möglicherweise auf einer Kombination aus Reibung und Spiel beruht. Ihr Diagramm der Durchschnittsgeschwindigkeit über dem Tastverhältnis für verschiedene Impulsbreiten ist charakteristisch für ein System mit Reibung. In diesem Dokument wird erklärt, was Sie sehen, und es enthält eine Sammlung von Lösungen, die seit jeher zur Lösung der Probleme verwendet werden. Sie werden sie in Ihrem technischen Lehrplan nicht gesehen haben, weil sie schwer zu analysieren sind. Im Grunde muss man von Fall zu Fall mit ihnen experimentieren, um sie zum Laufen zu bringen.

Ich weiß nicht, was kommerzielle Controller tun, obwohl ich vermute, dass es eine Vielzahl von Lösungen gibt. Was ich in der Vergangenheit mit solchen Dingen getan habe, ist, wenn das Motorantriebssignal von meinem PID-Regler unter einen Schwellenwert abfällt (wahrscheinlich 60 bis 70 Zählungen in Ihrem Fall), beginne ich, den Motorantrieb mit einer Einschaltdauer an dem Schwellenwert zu pulsieren Zyklus, durch den der durchschnittliche Antrieb dem PID-Ausgang entspricht. Ich benutze im Allgemeinen einen Sigma-Delta-ish-Modulator, weil er in sehr wenigen Zeilen implementiert werden kann, aber Sie können mit allem arbeiten, was für Sie funktioniert.


4

Es scheint, dass das meiste Rauschen vom PWM-Treibersignal herrührt.

Haben Sie versucht, die ADC-Erfassung mit dem PWM-Zyklus zu synchronisieren? Die meisten Mikrocontroller haben eine Möglichkeit, die ADC-Erfassung über den Timer auszulösen, sodass Sie immer am gleichen Punkt des Zyklus triggern können.

Für geringstes Rauschen wäre die optimale Abtastposition direkt vor dem Einschalten des Motors, da dann alle Spikes die längste Zeit zum Einschwingen hatten. Unabhängig von der Position werden durch die Synchronisierung der Erfassung die Spitzen reduziert, da der Versatz zum selben Zeitpunkt des PWM-Zyklus ungefähr gleich bleibt.


3

Also muss ich einen Weg finden, dieses Rauschen herauszufiltern, bevor ich wieder an der Steuerung arbeite.

Sie können das Sensorrauschen (oder jede andere verrauschte Messung / Variable) in einem Code wie folgt filtern (Tiefpassfilterung):

Sgefiltert[k]=αSgefiltert[k-1]+(1-α)Sroh[k]

0<<α1


Ich habe es versucht, aber es reicht nicht aus, um die Peaks loszuwerden, und es fügt zu viel Verzögerung hinzu.
Tttapa

@tttapa Ich verstehe. Welchen Wert für Alpha haben Sie versucht? (0.8,0.9) Es wird einige Abstimmungen erfordern, die Sie vielleicht schon gemacht haben und sich nur gefragt haben.
Big6

Ich habe meinen ursprünglichen Beitrag aktualisiert, um eine Darstellung der EMA-Filter hinzuzufügen, die ich ausprobiert habe. Ich habe auch 0,9 ausprobiert und es war noch schlimmer als die 0,75, die Gewinne müssen wegen der Verzögerung viel niedriger sein. Ich denke, ich werde eine begrenzte EMA verwenden, um das ADC-Rauschen zu bereinigen, aber im Moment ist der Kondensator genug.
Tttapa
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.