Hallo,
sollte man bei PID-Regler die Zwischenergebnisse auf Overflow prüfen?
z.B. ist der I-Anteil:
i = iAlt + Regelabweichung;
iAlt = i;
Und da kann die i Variable schnell in Überlauf bzw. Unterlauf kommen.
Wie managet ihr das?
Vielleich hat jemand ein PID-Regler-Code in C zeigen? Wäre echt lieb..
Danke!
Hallo,
wenn die Varieble bei einer Addition überläuft, wird sie nicht mehr
größer sein als ein Grenzwert, sondern eventuell sogar negativ. Man
sollte besser das Overflowflag der ALU der CPU abfragen. Dort wird ein
Overflow festgehalten. Wenn das passiert ist, kann man den Maximalwert
der Variable setzen.
Grüße,
Peter
Hallo Matthias,
in C geht das genauso, wie in Assembler. Normalerweise steht das
Overflow Bit im Satusregister der CPU. Man kann mit C genauso auf alle
Register der CPU zugreifen wie mit Assembler, so auch auf das
Statusregister. Dort muss man dann nur noch prüfen, ob das OF Bit
gesetzt ist. Man nenne mir den Controllertyp und ich zeig dir, wie das
geht.
Es kann sein, dass im Headerfile des Comlipers nicht definiert ist, wo
das Statusregister liegt, das ist aber mit einer kleinen Definition
erledigt. Dann kann man mit C darauf zugreifen.
Beim AVR (Beispiel AtMega16) etwa so:
Sowas macht man nicht!
Es kann funktionieren, muss aber nicht, da der Compiler Codeblöcke
umsortieren kann und somit die Abfrage möglicherweise keinen Sinn mehr
ergibt, da sie an einer falschen Stelle ausgeführt wird.
Hallo,
man muss sich auf jeden Fall nachher den Assemblercode davon ansehen.
Wenn der Compiler das nicht so umsetzt, dass es funktioniert, muss man -
ansonsten rate ich dazu, dass man - sowohl die Addition als auch die
Overflowabfrage in Inlineassembler hinschreibt.
Aber prinzipiell lassen sich die Satusbits auch in C abfragen und in der
Regel wird der Compiler auch die Reihenfolge nicht vertauschen.
Dennoch besteht die Gefahr, dass eine Optimierung dafür sorgt, dass das
nicht mehr geht. Wobei ein guter Compiler auch erkennt, dass die
Statusflags der letzten Operation abgefragt werden und deshalb die
Reihenfolge nicht getauscht werden dürfen. Davon kann man beim gcc aber
nicht ausgehen.
Peter
Eleganter geht es in C, also ohne sich die Mühe machen zu müssen, den
Code nachher zu prüfen, wenn man als i und iAlt 16 bit Werte nimmt und
als Regelabweichung 8 bit Werte. Dann hat man dafür gesorgt, dass
maximal 128 als Regelfehler auftreten kann. So kann man Grenzwerte von i
angeben, ab denen man abschneidet, bei denen sicher noch kein Überlauf
passiert.
i = iAlt + Regelabweichung;
if ((i < 32639) && (i > -32639))
iAlt = i;
else
i = iAlt;
Wenn man aber darauf angewiesen ist, dass i und Regelabweichung vom
gleichen Typ sind, sollte man tatsächlich den Overflow der ALU
auswerten, andernfalls wird die Berechnung, ob ein Überlauf auftreten
wird, recht aufwendig.
Man müsste dazu erst ausrechnen, wieviel Platz noch in i nach oben und
unten ist bis zum Überlauf und dann abfragen, ob die Regelabweichung
größer ist, als dieser Wert. Das ganze mit Fallunterscheidung für
positive und negative Werte.
Auf DSPs hat man dieses Problem im Übrigen meist nicht, denn die meisten
können saturiert addieren, d.h. das Register läuft nicht über, sondern
wird nur auf den Maximalwert gesetzt, wenn man zu viel draufaddiert.
Peter
Eine eigene Frage?
Dieser Thread ist über 18 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.