Forum: Mikrocontroller und Digitale Elektronik Motordrehzahl mit PID-Regler: Paar Frägelchen


von Karl-alfred R. (karl-alfred_roemer)


Lesenswert?

Hallo zusammen,

ich würde gerne rein aus Spaß, also ohne konkrete Anwendung, an einem 
Gleichstrom-Getriebemotor mit 64-Stufen Encoder die Drehzahl regeln.

Ich habe dazu einen fertigen Algorithmus angepasst und er funktioniert 
auch einigermaßen brauchbar. 
http://forum.arduino.cc/index.php?topic=8652.0 der zweite Codeabschnitt, 
nur mit etwas anderer Verkabelung.

Die Drehzahl wird prima gehalten, sogar ohne bleibender Regelabweichung 
obwohl ich im Code eigentlich keinen I-Anteil sehen kann.

 Hier das maßgebliche Codeschnipsel:

int updatePid(int command, int targetValue, int currentValue)   {
  float pidTerm = 0;
  int error=0;
  static int last_error=0;
  error = abs(targetValue) - abs(currentValue);
  pidTerm = (Kp * error) + (Kd * (error - last_error));
  last_error = error;
  return constrain(command + int(pidTerm), 0, 255);
}

Wie kann es sein, dass diese Funktion ohne bleibende Regelabweichung 
funktioniert?

Eine allgemeine Frage: Muss man bei der Integralberechnung wirklich 
alles berücksichtigen ab dem Moment, wo man den Motor einschaltet, oder 
reicht es aus, wenn man die letzten 10 oder 20 Werte integriert?  Habe 
nämlich auch schon einen anderen Algo gesehen, der sogar nur die vier 
letzte Werte aufsummiert und das als I verkauft.

Eine weitere Frage: Wenn der Motor gestartet wird und nach ein paar 
Zehntel Sekunden der Sollwert überschwungen wird, macht es dann nicht 
sogar Sinn, den PWM-Wert nicht nur auf Null zu setzen, sondern sogar die 
Drehrichtung umzukehren, damit die Bremskraft maximal ist und das 
Zurückschwingen schneller wird? Oder indem man den Motor kurz schließt, 
als Bremse?

Im obigen Algorithmus wird schlimmstenfalls PWM auf Null gesetzt - also 
wird nicht gebremst, sondern nur der Leerlauf eingelegt. Wenn am Motor 
eine große Masse hängen würde, würde das einschwingen nach Überdrehzahl 
unnötig lange dauern. Oder wird das durch das PID-Konzept implizit mit 
berücksichtigt?

Danke für Eure Meinungen und
viele Grüße
Karl

: Bearbeitet durch User
von RP6conrad (Gast)


Lesenswert?

Regelabweichung 0 ist eine Glucksache ohne I-Anteil. Moglich ist Kp sehr 
hoch gesetzt. Was passiert beim belasten von Motor ? Für ein I / D 
anteil muss du auch das Zeitinterval konstant setzen. Ein abbremsen geht 
am besten durch Kurzschluss von beide Polen. Das geht mit die meiste 
H-Brucken, muss du aber richt ansteuern. Standard wird mit PWM die 
Ausgang hochohmig gesetzt, aber wen die PWM auf die dir Anschlusse 
setzt, bleibt die Brucke niederohmig. Eine Anschluss von H-brucke bleibt 
dan immer Low, die andere Seite wird dan mit den PWM frequenz zwischen 
LOW und HIGH geschaltet. Damit haben sie ihre "Kurzschluss". Damit ist 
das Verhaltnis PWM/Drehzahl fast liniair. Al meine Roboter (differential 
drive) werden auf diese Art angesteuert, damit ist eine Schone Regelung 
moglich.

von Pandur S. (jetztnicht)


Lesenswert?

Die letzen N Werte aufsummiert ist aequivalent zu einem Tiefpass. 
Bedeutet fuer Frequenz gegen Null bekommt man keine unendliche 
Verstaerkung.

von Sebastian E. (sbe_15)


Lesenswert?

Der I-Anteil ergibt sich dadurch, dass die Funktion im verlinkten Code 
folgendermaßen aufgerufen wird:
1
PWM_val= updatePid(PWM_val, speed_req, speed_act);

von Olaf (Gast)


Lesenswert?

> Wenn am Motor eine große Masse hängen würde,

...dann haettest du eine andere Regelstrecke und muesstest deine 
Koeffizienten neu berechnen.

Selbstverstaendlich kannst du an deinen Regelalgorythmus alles 
beifummeln was du willst. Es kann sogas sein das er dadurch besser wird. 
Allerdings wird er damit immer weniger PID und damit kannst du nicht 
mehr auf die ueblichen Verfahren zur bestimmung der Koeffizienten 
zurueckgreifen.

Olaf

von Christopher J. (christopher_j23)


Lesenswert?

Sebastian E. schrieb:
> Der I-Anteil ergibt sich dadurch, dass die Funktion im verlinkten Code
> folgendermaßen aufgerufen wird:
> PWM_val= updatePid(PWM_val, speed_req, speed_act);

Ganz genau, und zwar in Kombination mit der letzten Zeile aus 
updatePid(int command, int targetValue, int currentValue)

Karl-alfred R. schrieb:
> return constrain(command + int(pidTerm), 0, 255);

Da wird nämlich entsprechend aufsummiert (integriert). Dadurch wird aus 
dem PD-Regler ein PI-Regler (P zu I und D zu P).


Das zuvor angebrachte Argument von RP6conrad

RP6conrad schrieb:
> Für ein I / D anteil muss du auch das Zeitinterval konstant setzen.

Sollte man natürlich im Auge behalten aber so lange das Abtastintervall 
in etwa konstant bleibt kann man es direkt in Kd verwursten. Ändert man 
jedoch die Abtastrate muss man Kd entsprechend anpassen, sofern man die 
gleiche Regelcharakteristik haben möchte.

: Bearbeitet durch User
von Karl-alfred R. (karl-alfred_roemer)


Lesenswert?

> Ganz genau, und zwar in Kombination mit der letzten Zeile aus
> updatePid(int command, int targetValue, int currentValue)

> Karl-alfred R. schrieb:
>> return constrain(command + int(pidTerm), 0, 255);

> Da wird nämlich entsprechend aufsummiert (integriert). Dadurch wird aus
> dem PD-Regler ein PI-Regler (P zu I und D zu P).

Ahhhhhhhhh Dannnke Christopher und RP6Conrad!!!! Das habe ich glatt 
übersehen. Unter diesen Umständen kann man die Werte für Kp und Kd auch 
nicht nach Ziegler Nicholson optimieren, da Kd ja eigentlich Kp ust und 
Kp eigentlich Ki ist. Das erklärt natürlich alles!


Sapperlot:
> Die letzen N Werte aufsummiert ist aequivalent zu einem Tiefpass.
> Bedeutet fuer Frequenz gegen Null bekommt man keine unendliche
> Verstaerkung.

Verstehe ich nicht. Ich will doch keine unendliche Verstärkung, sondern 
nur eine endliche Rückkopplung, die gerade bei niedrigen Frequenzen, am 
besten gegen Null am stärksten wirkt und bei höheren Frequenzen 
sozusagen taub ist.

Aber das mit den N letzten Werten ist mir immer noch nicht klar. Bei der 
Dimensionierung von Ki nach Ziegler-Nichols muss doch festgelegt werden, 
ob ich von Anfang an integrieren muss, oder ob ich irgendwo die letzten 
10 oder 20 Werte nehme.

@Olaf
> Selbstverstaendlich kannst du an deinen Regelalgorythmus alles
> beifummeln was du willst. Es kann sogas sein das er dadurch besser wird.
> Allerdings wird er damit immer weniger PID und damit kannst du nicht
> mehr auf die ueblichen Verfahren zur bestimmung der Koeffizienten
> zurueckgreifen.

Die Befürchtung hatte ich auch schon. Deshalb auch meine Fragen nach der 
Implementierung.

Die Funktion Constrain bewirkt z.B., dass die PWM-Rückgabewerte zwischen 
0 und 255 liegen. Macht für mich irgendwo Sinn, denn ohne diese 
Begrenzung könnte der Rückgabewert ja theoretisch ins unendliche laufen. 
Nach überschießen des Zielwertes würde es noch ewig dauern, bis wieder 
zurück geregelt wird. Aber inwieweit beeinflusst das die 
Ziegler-Nichols-Parameter?

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.