Forum: Mikrocontroller und Digitale Elektronik PI-Regler mit Festkomma


von Frederic H. (mangan)


Lesenswert?

Hallo,

ich versuche zur Zeit einen PI-Regler mit Festkommazahlen zu 
realisieren. Der normal digitale PI-Rgeler ist mir bekannt. Laut 
rn-wissen 
(http://www.rn-wissen.de/index.php/Regelungstechnik#Dimensionierung_des_Reglers) 
lautet der C-Code wie folgt:

  e = w - x;        //Vergleich
  esum = esum + e;      //Integration I-Anteil
  if (esum < -400) {esum = -400;}          //Begrenzung I-Anteil
  if (esum > 400) {esum = 400;}
  y = Kp*e + Ki*Ta*esum;      //Reglergleichung
  if (y < 0) {y = 0;}      //Begrenzung Stellgröße
  if (y > 255) {y = 255;}
  PWM = y;        //Übergabe Stellgröße

Nur wie bekomme ich diesen nun in festkomma? Wie die allgemeine 
Muliplikation, Addition u.s.w in Festkommazahlen funktioniert ist mir 
klar. Ich arbeite mit Festkommazahlen im Format 1Q15. Also 15 
Nachkommastellen und 1 Bit fürs Vorzeichen. Alle Werte sind immer <1 da 
ich sie zusätlich auf den maximalen Wert normiert habe. Nur scheitert es 
gerade am Verständnis mit den Vestärkungsfaktoren. Damit ich eine 
Verstärkung erziele müssten diese doch größer 1 sein? Muss ich dann 
einfach die Festkommazahlen mal den Verstärkungsfaktor nehmen ohne die 
übliche umrechnung bei Festkomma?

Grüße

von der mechatroniker (Gast)


Lesenswert?

wenn w, x und y dieselbe Skalierungs aufweisen, ist Kp natürlich 
ganzzahlig. Wenn dir das zuwenig Auflösung bietet (weil Kp = 3 zuwenig 
und Kp = 4 zuviel ist), musst du es anders skalieren und nach der 
Berechnung von y den Rechtsshift einbauen.

(Ich hoffe ich habe richtig getippt, worauf du hinaus wolltest).

von Karl H. (kbuchegg)


Lesenswert?

Frederic H. schrieb:

> klar. Ich arbeite mit Festkommazahlen im Format 1Q15. Also 15
> Nachkommastellen und 1 Bit fürs Vorzeichen. Alle Werte sind immer <1 da
> ich sie zusätlich auf den maximalen Wert normiert habe. Nur scheitert es
> gerade am Verständnis mit den Vestärkungsfaktoren. Damit ich eine
> Verstärkung erziele müssten diese doch größer 1 sein? Muss ich dann
> einfach die Festkommazahlen mal den Verstärkungsfaktor nehmen ohne die
> übliche umrechnung bei Festkomma?

Dann musst du ständig mitrechnen, an welcher Position dein Komma ist, je 
nach Verstärkungsfaktor.

Also wird es sinnvoll sein, für die Verstärkungsfaktoren ein anderes 
Fixedpoint Format zu definieren, bei dem du mehr Bits im Vorkommaanteil 
hast und die einzelnen Terme vorher in dieses Fixkommaformat 
umzurechnen.

Wenn man so will, dann kann man ja ein Fixedpoint FOrmat als eine 
Repräsentierung eines Bruchs auffassen.

Die Zahl 23 in einem Fixed Point Format mit 2 dezimalen 
Nachkommastellen, ist ja nichts anderes als

    2300
  --------
     100

(hunderstel deswegen, weil ja 2 dezimalen Nachkommastellen gefordert 
waren und 10^2 nun mal 100 ergibt)

werden 2 Fixedpoint Zahlen addiert, dann geht das entsprechend den 
Bruchregeln klarerweise nur dann, wenn beide denselben Nenner haben


     2300       1000
   --------  + -------
      100        10

      ^           ^
      |           +----- Fixedpoint Format mit 1 Nachkommastelle
      |
      +----- Fixpoint Format mit 2 dezimalen Nachkommastellen

Das geht nur dann, wenn du vorher die beiden Zahlen ins gleiche Fixed 
Point Schema bringst. Deine Erfahrung mit Bruchrechnen sagt dir auch wie 
das geht:

     2300       10000       12300
   --------  + -------  = ---------
      100        100         100



Über die Betrachtung eines Fixedpoint-Formats als 'Bruchrechnung' 
findest du auch den Rest noch raus.

von Simon K. (simon) Benutzerseite


Lesenswert?

der mechatroniker schrieb:
> wenn w, x und y dieselbe Skalierungs aufweisen, ist Kp natürlich
> ganzzahlig. Wenn dir das zuwenig Auflösung bietet (weil Kp = 3 zuwenig
> und Kp = 4 zuviel ist), musst du es anders skalieren und nach der
> Berechnung von y den Rechtsshift einbauen.
>
> (Ich hoffe ich habe richtig getippt, worauf du hinaus wolltest).

Keinen Rechtsshift, sondern eine Division, die korrekt rundet.

Rechtsshift sollte man nur verwenden, wenn man eine binäre Darstellung 
von etwas wirklich schieben möchte.

von Frederic H. (mangan)


Lesenswert?

der mechatroniker schrieb:
> wenn w, x und y dieselbe Skalierungs aufweisen, ist Kp natürlich
> ganzzahlig. Wenn dir das zuwenig Auflösung bietet (weil Kp = 3 zuwenig
> und Kp = 4 zuviel ist), musst du es anders skalieren und nach der
> Berechnung von y den Rechtsshift einbauen.
>
> (Ich hoffe ich habe richtig getippt, worauf du hinaus wolltest).

Danke schonmal für eure Hilfe, hat mir schon sehr geholfen :)

w, x und y weißen dieselbe Skalierung auf. Wenn ich nur ganze Zahlen als 
Verstärkunksfaktoren Kp und Ki verwende dann kann ich die 
Festkommazahlen einfach ohne Umrechnung mit diesen mutiplizieren. Reicht 
mir diese Auflösung für Ki und Kp nicht, so muss ich eine andere 
Darstellung für die Festkommazahl wählen. Diese Berechnung kann ich dann 
nach der Erklärung von "Karl heinz Buchegger" vornehmen. Richtig?

von Thomas (Gast)


Lesenswert?

Simon K. schrieb:
> Keinen Rechtsshift, sondern eine Division, die korrekt rundet.
>
> Rechtsshift sollte man nur verwenden, wenn man eine binäre Darstellung
> von etwas wirklich schieben möchte.

Naja, wenn man vor dem Shift ein LSB dazuaddiert, dann ist es danach 
richtig gerundet ...

Jeder, der bisserl Ahnung von µCs hat, würde dich auslachen, wenn du mit 
einer richtigen Division kommst, wenn du irgendwas durch 2 teilen 
willst ...

Grüße,
Thomas

von Karl H. (kbuchegg)


Lesenswert?

Thomas schrieb:

> Jeder, der bisserl Ahnung von µCs hat, würde dich auslachen, wenn du mit
> einer richtigen Division kommst, wenn du irgendwas durch 2 teilen
> willst ...

Ganz im Gegenteil.

Jeder der meint er muss cleverer sein als sein Compiler wird ausgelacht. 
Compiler ersetzen seit Jahrzehnten Divisionen durch Shifts >wenn dies 
möglich ist<.

Und genau das ist der springende Punkt:

Wenn dies möglich ist, dann macht dir der Compiler die Ersetzung (der 
macht noch ganz andere Ersetzungen als eine banale 2-er Potenz durch ein 
paar Shift zu ersetzen)

Wenn es aber nicht möglich ist und du den Shift geschrieben hast, dann 
hast du einen Fehler im Programm.


Einen Fehler im Programm zu haben, nur weil man die Compilerbauer für 
doof hält ----   entschuldige wenn ich dich jetzt auslache.

von der mechatroniker (Gast)


Lesenswert?

Allerdings werden Fixkommadarstellungen oft nicht als "um den Faktor 
2**n skaliert" angesehen, sondern unter dem Gesichtspunkt "n Bits sind 
für die Nachkommastellen vorgesehen".

Daher haben Shifts an dieser Stelle -- auch im Hinblick auf vom Menschen 
lesbaren, wartbaren Code -- ihre Daseinsberechtigung (Divisionen 
natürlich je nach Betrachtungsweise auch).

von Karl H. (kbuchegg)


Lesenswert?

der mechatroniker schrieb:

> Daher haben Shifts an dieser Stelle -- auch im Hinblick auf vom Menschen
> lesbaren, wartbaren Code -- ihre Daseinsberechtigung (Divisionen
> natürlich je nach Betrachtungsweise auch).

Unterm Strich:
Wenn eine Division die naheliegende Betrachtungsweise ist, dann benutze 
eine Division.
Wenn Schieben die naheliegende Betrachtungsweise ist, dann nimm 
Schieben.


Aber das Argument:
Ich nehme Schieben weil ich Zeit sparen will
ist ein Nonsense-Argument.


Jeder der schon einmal gezwungen war einen integer auf einen double oder 
float zu ändern, wird dir dein Leben lang 'dankbar' sein, wenn du 
anstelle einer Division einen Optimierungs-Shift geschrieben hast.
Jeder der schon einmal stundenlang gesucht hat, warum er bei negativen 
Zahlen einen 'Off-By-1' Rundungs-Fehler hatte, wird dir über den 
Optimierungs-Shift 'überaus herzlich dankbar' sein.

Nur diejenigen, die einen unsigned int mit einer 2-er Potenz 
multiplizieren / dividieren, werden dir nicht dankbar sein, denn sie 
werden gar nicht merken, dass der Compiler die Multiplikation/Division 
stillschweigend mit Shiften implementiert hat.

von Simon K. (simon) Benutzerseite


Lesenswert?

Thomas schrieb:
> Simon K. schrieb:
>> Keinen Rechtsshift, sondern eine Division, die korrekt rundet.
>>
>> Rechtsshift sollte man nur verwenden, wenn man eine binäre Darstellung
>> von etwas wirklich schieben möchte.
>
> Naja, wenn man vor dem Shift ein LSB dazuaddiert, dann ist es danach
> richtig gerundet ...
Nö, nicht, wenn der Wert negativ ist. Und auch nicht, wenn man mehr als 
ein mal shiftet.
Übrigens ist das Shiften von vorzeichenbehafteten Werten 
implementation-defined (wenn ich mich richtig erinnere).
Mit einer Division ist man IMMER auf der richtigen Seite, wenn man auch 
eine Division braucht.

> Jeder, der bisserl Ahnung von µCs hat, würde dich auslachen, wenn du mit
> einer richtigen Division kommst, wenn du irgendwas durch 2 teilen
> willst ...
So einer wie du, meinst du? ;-) Is klar.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.