Hallo zusammen Folgende Problemstellung: Ich muss einen PID Regler erstellt um eine Positionsregelung eines BLDC Motors zu realisieren. Sollwert ist die aktuelle Encoder Position, IstWert ist ebenfalls wieder eine Encoderposition. Es sind beides Absolutwerte. Der Encoder hat 500I/U, das heisst bei bei beiden Flanken mit AB also 2000Impulse / Umdrehung. Die Ausgangsgrösse des PID Reglers werde ich direkt auf den Speedcontroller geben. Im Prinzip funktioniert die Regelung, nur habe ich das Problem, dass meine Differenz zwischen Soll und Ist-Wert ca. um die 20‘000 ist. Der Speed, auf den ich wirken muss, hat aber einen Wert von ca. 500 (U/min). Ich muss also die 20‘000 auf ca. 500 skalieren, jedoch möchte ich im PID Regler die Anteile für P, I und D als Integer eingeben und nicht als float, die kleiner als 1 sind. (Wegen der Rechenzeit möchte ich nur long Variablen multiplizieren) Wie kann ich diese Problematik lösen? Soll ich den Ausgang vom PID wieder durch einen bestimmten Faktor teilen damit ich nicht über diese 500 komme? Oder gibt es eine bessere Lösung? Oder soll ich die Soll und Istwerte zuerst teilen, darunter leidet aber wieder die Genauigkeit, die oberste Priorität hat. Vielen Dank für Inputs.
Dominik Eugster schrieb: > Die Ausgangsgrösse des PID Reglers werde ich direkt auf den > Speedcontroller geben. Im Prinzip funktioniert die Regelung, nur habe > ich das Problem, dass meine Differenz zwischen Soll und Ist-Wert ca. um > die 20‘000 ist. Dann begrenze die Differenz halt. Über einer bestimmten Größe hat es eh keinen Sinn mehr, die Differenz größer werden zu lassen. Ob die Regelabweichung 15000 oder 20000 ist, ist ja ziemlich egal. Der Regler muss volle Kanne in die Richtung fahren, in der die Differenz kleiner wird. Das einzige was dir passiert: Das Integral summmiert sich zu aberwitzigen Größen auf, die der Regeler nie wieder rechtzeitig abgebaut kriegt um sauber auf die Position einzuregeln. > Der Speed, auf den ich wirken muss, hat aber einen Wert von ca. 500 > (U/min). Ich muss also die 20‘000 auf ca. 500 skalieren, Nö. Musst du nicht. Aus der Regeldifferenz errechnet sich der PID-Controller, was er mit der Speed machen will. > nicht als float, die kleiner als 1 sind. Kann man ja auch skalieren. Stichwort: Fixed Point Integer Arithmetik
Hallo Danke. Aber die Differenz möchte ich nicht begrenzen, da ansonsten die Regelung ja nicht korrekt arbeitet... Aber das mit der Fixed Point Arithmetik sollte passen, danke. Mal zuerst Hirn einschalten wäre keine schlechte Idee... :-)
Dominik Eugster schrieb: > Hallo > > Danke. Aber die Differenz möchte ich nicht begrenzen, da ansonsten die > Regelung ja nicht korrekt arbeitet... Natürlich arbeitet die nach wie vor korrekt. Ganz im Gegenteil. Schau. Du kannst im Auto das Gaspedal nur eine bestimmte Strecke reindrücken. D.h. wenn du 20 fährst und 150 fahren willst, dann spielt es keine Rolle, ob du jetzt als Regelabweichung 130 feststellst oder 65. Denn weiter als voll rein, kannst du das Pedal nicht drücken. Ab einer gewissen Regelabweichung interessiert dich der exakte Wert nicht mehr, denn kompletter daneben als komplett daneben kann dir die Abweichung nicht 'melden'. Erst wenn die Abweichung dann wieder kleiner wird, dann interessiert dich der Zahlenwert wieder. Wenn du um 8km/h zu langsam fährst, dann regelst du das Pedal mit dem Fuss anders an, als bei 3km/h Abweichung. Bei dir dann eben nicht Geschwindigkeiten sondern Positionen. Aber das Prinzip ist dasselbe. Soll dein zu regelndes System von Berlin sich nach München positionieren, dann ist es völlig wurscht, ob du von München noch 678km entfernt bist oder 200km. Denn schneller als 180km/h schafft deine Schüssel nicht. Erst 800Meter vor der Stadtgrenze beginnt dich der exakte Wert zu interessieren. D.h. deine Regelung kann durchaus mit Regelabweichungen von 0 bis 1000 und dem zusätzlichen Wert 'groß' arbeiten (alles über 1000 ist einfach 1000). Der Vorteil davon ist, dass du dadurch weißt, das in deinen nachfolgenden Berechnungen kein Abweichungswert größer als 1000 vorkommen wird und du daher die Berechnungen daraufhin auslegen kannst, dass nichts überläuft. Und im Integralteil kommt dann noch dazu, dass dort eine Begrenzung das Aufintegrieren auf aberwitzige Werte verhindert, die dir dann das Genick brechen, wenn der I-Anteil eigentlich die letzte Regelabweichung ausgleichen sollte, es aber nicht kann, weil der Summenwert gar nicht schnell genug fallen kann. Google mal nach Anti-Windup.
Die Software-Latenzzeit für eine stabile Regelung sollte aber nicht zu lang sein. Hier einige Tips für eine schnelle und stabile Regelung: http://ichaus.biz/wp2_encoderanschluss .
Hallo Klingt logisch ja. AntiWind-Up ist bereits integriert. Das heisst ich Werde nur die Differenz begrenzen, damit ich erst ab ca. Differenz von 60'000 zu arbeiten anfange (3 Umdrehungen). Damit diese Abweichung dann aber auf 500 oder eben 100 skaliert wird, muss ich somit mit fixed point rechnen, denn ansonsten habe ich als Ausgangsgrösse mit P=1000, I= 500 und D=1000 schnell mal sehr hohe Werte... Stimmt doch oder?
Dominik Eugster schrieb: > Hallo > > Klingt logisch ja. AntiWind-Up ist bereits integriert. > Das heisst ich Werde nur die Differenz begrenzen, damit ich erst ab ca. > Differenz von 60'000 zu arbeiten anfange (3 Umdrehungen). Damit diese > Abweichung dann aber auf 500 oder eben 100 skaliert wird, muss ich somit > mit fixed point rechnen, denn ansonsten habe ich als Ausgangsgrösse mit > P=1000, I= 500 und D=1000 schnell mal sehr hohe Werte... Stimmt doch > oder? Klingt logisch. Stell dir die einzelnen Koeffizienten halt einfach als Brüche anstelle von Kommazahlen vor :-)
Ok, werde ich mals so versuchen. Vielen Dank für die schnelle Antwort.
Karl Heinz Buchegger schrieb: > Klingt logisch. > > Stell dir die einzelnen Koeffizienten halt einfach als Brüche anstelle > > von Kommazahlen vor :-) Aber ich muss da die Fixed Point Berechnung einbinden, denn sonst habe ich ein Ausgangswert von 200'000 oder mehr... Gibt es da nicht ein Beispiel dazu, ich habe gesucht aber nicht wirklich was brauchbares gefunden...
Ich rechne meine Regler jeweils in Int32 und skaliere nachher runter. In deinerm Fall 20000 : 500 = > div 40
Kann ich nicht einfach so rechnen: Error = 2000 P = 0.001 (wird aber als 1000 eingegeben) Somit wäre bei einem P Regler 2000*0.001 = 2 Wenn ich jetzt aber 2000*1000= 2*10^6 Das Resultat werde ich danach wieder durch 1000 teilen und somit habe ich schlussendlich auch wieder ein Resultat von 2. Das gleiche kann ich jetzt doch mit den I und D Anteilen machen, oder was mache ich falsch?
Also zur Info: Die Positionierung funktioniert jetzt. Ich habe einen PID mit Soll = Encoder Zielposition und Ist = aktuelle Position vom Encoder. Der Ausgang von diesem PID wird begrenzt auf den maximalen Speed, der eingestellt werden kann. Dieser Wert wiederum wird auf den Rampengenerator für den Speed gegeben. Diese Rampe wird dem PID Speed Regler übergeben und dieser Ausgang steuert direkt die Geschwindigkeit vom Motor (PWM Register für duty cycle). Somit kann jetzt die Beschleunigungs- bzw. Verzögerungsrampe eingestellt werden, der Speed und die Position, die angefahren werden soll. Der Positions-PID regelt bis an den Anschlag vom maximalen Speed der eingestellt wurde. (Achtung Anti Wind-Up von I Anteil nicht vergessen) Vor der Position regelt dieser schlussendlich den Speed auf 0 zurück, und somit bleibt der Motor bei Position X stehen. Natürlich muss die Bremsrampe genug schnell eingestellt sein, damit diese den Vorgaben des PID auch nachkommt. Die ganze Positionierung ist natürlich stark von P, I und D abhängig, aber es ist nicht mal so schwer diese Werte einzustellen. Ich habe da einfach mal ein bisschen geschraubt und schon passt es. Natürlich muss mit der Sprungantwort noch genauer eingestellt werden, aber das sind dann Details. Gruss und Danke für die Hilfe von allen!
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.