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
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).
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.
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.
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?
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
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.
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).
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.