Sie müssen zwei Probleme behandeln:
- arithmetischer Überlauf
- Integrator Windup
Der arithmetische Überlauf recht einfach ist - wann immer Sie integer Mathe tun, stellen Sie sicher , dass Sie größere Breitenzwischenwerte verwenden: zum Beispiel, wenn a
und b
sind 16-Bit, und Sie addieren / subtrahieren, verwenden Sie eine 32-Bit - Zwischen und begrenzen Sie ihn auf den Bereich eines 16-Bit-Werts (0 bis 65535 für vorzeichenlose Werte, -32768 bis 32767 für vorzeichenbehaftete Werte), bevor Sie ihn auf 16 Bit zurücksetzen. Wenn Sie absolut sicher sind , dass Sie niemals überlaufen können, weil Sie absolut sicher sind , welche Bereiche die Eingabevariablen haben, können Sie diesen Schritt überspringen, aber Vorsicht.
Das Problem mit dem Integrator-Windup ist subtiler. Wenn Sie über einen längeren Zeitraum einen großen Fehler haben, so dass Sie die Sättigungsgrenze Ihres Controller-Ausgangs erreichen, der Fehler jedoch immer noch ungleich Null ist, sammelt der Integrator weiterhin Fehler an und wird möglicherweise viel größer, als er erreichen sollte Gleichgewichtszustand. Sobald der Controller nicht mehr gesättigt ist, muss der Integrator wieder heruntergefahren werden, was zu unnötiger Verzögerung und möglicherweise zu Instabilität der Controller-Reaktion führt.
Noch ein Hinweis:
Ich würde dringend empfehlen (ja, ich weiß, dass diese Frage 18 Monate alt ist, also sind Sie wahrscheinlich mit Ihrer Aufgabe fertig, aber zum Wohle der Leser tun wir so, als wäre dies nicht der Fall), den Integralbegriff anders zu berechnen: Anstelle von Ki * (integrierter Fehler), Integral von (Ki * -Fehler) berechnen.
Dafür gibt es mehrere Gründe. Sie können sie in einem Blogbeitrag lesen, den ich über die korrekte Implementierung von PI-Controllern geschrieben habe .
<stdint.h>
füruint8_t
unduint16_t
anstelle vonunsigned int
undunsigned char
.