PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PI(D) - Regler



oratus sum
27.05.2010, 14:07
Hallo.

Vorerst: ich habe mir sowohl den RN-Wissensartikel als auch den Wikipedia Artikel zu diesem Thema mehrfach durchgelesen.

Ich habe einen Roboter mir Ketten (siehe Bilder in Signatur) wo ein Mega2560 drauf sitzt. Jedes zweite Glied der Gleiskette ist weiß eingefärbt und sind daher die "Encoder Scheiben".

Ich habe einige Versuche durchgeführt wo ich die Peaks pro Sekunde in Abhängigkeit zum PWM-Wert erhalten habe.

Jetzt möchte ich gerne einen PI-Regler in meine Software implementieren jedoch habe ich einige Probleme.

Rein intuitiv bevor ich überhaupt wusste, dass es solche Regler gibt habe ich ein P-Regler erstellt. Die Gesammelten Encoder-Werte von einer Sekunde werden mit einer Konstante multipliziert. Danach wird der Fehler mit Soll- und Ist-wert berechnet und das Ergebnis zum PWM-Wert hinzuaddiert (oder subtrahiert)

Jedoch funktioniert das bei mir nicht, der Roboter macht was er will.

Deswegen bin ich dann auf diesen Artikel gestoßen.

Meine Frage ist was diese ganzen Konstanten sind. Also wenn ich den PI-Regler mal hernehme habe ich:

esum = esum + e
y = Kp * e + Ki * Ta * esum

e ist der Fehler, also Soll-Ist

Kp: ist mein Konstanter Faktor um zwischen den Peaks/s zum PWM-Wert umzurechnen

Ki: keine Ahnung

Ta: meine Abtastzeit aber was ist das genau bei mir? Ein Messvorgang? Sprich 1 Sekunde?

esum: Die Summe aller Fehler und das ist etwas was ich logisch nicht verstehe. Esum wird mit der Zeit ja immer größer und größer bis es irgendwann mal unendlich erreicht. Vorausgesetzt der Fehler ist immer positiv.

Es stellt sich auch die Frage wie ich meine Werte erhalte.

Falls wer meine Ergebnise von den versuchen braucht
Die letzte Tabelle enthält die Notwendigen Informationen. Die erste Zeile ist der PWM Wert.

sammler
27.05.2010, 14:46
Also, der PI-Regler ist ein Integrierender (=summierender) Regler mit Proportionialanteil.
D.h. deine erkenntnis mit "esum wird immer größer" ist soweit erstmal richtig. ist auch gut so. denn damit bekommst du den bleibenden Fehler weg.
der haken an der sache ist nur, dass Kp (Verstärkungsfaktor vom P-Anteil) und Ki (Verstärkung des I-Anteils deines Reglers) zusammenpassen müssen. Schau dir dazu mal die Wiki-Artikel zu den Faustformelverfahren (Automatisierungstechnik) an. da werden Methoden zur bestimmung dieser Parameter beschrieben. Allerdings werden da etwas andere Formeln für den PI-Regler zugrunde gelegt, glaube ich...

Im Übrigen kannst du i. A. für Ta die Zykluszeit ansetzen, mit der dein Regler aufgerufen wird.

Hoffe das hilft weiter...

oratus sum
27.05.2010, 14:52
Ich werde mir das (abermals) anschauen.

Die Zykluszeit sit daher eine Sekunde. Also multipliziere ich mit 1 ?

sammler
27.05.2010, 15:01
wusste nicht, dass du den artikel auch schon durch hast ;-)
jo, Ta ist dann bei dir halt 1; kann schon vorkommen.
dummerweise wirst du mit den werten für Kp und Ki experimentieren müssen.
ich würde mal mit Kp=10 oder 15 und Ki=0.1 anfangen und dann langsam mit Ki nach oben gehen. wenn er das überschwingen zu weit treibt, Kp runternehmen, danch wieder an Ki schrauben.

oratus sum
27.05.2010, 15:03
Das komische bei mir ist, dass die Ketten macnhmal ganz stehen bleiben dann legt er volle Pulle zu und dann fahren sie wieder viel langsamer als sie sollten, sie stellen sich also nie vernüftig ein.

Dann werde ich wohl rumprobieren...

sammler
27.05.2010, 15:04
ach ja... wie ist das Massenträgheitsmoment deiner Motorachse im Verhältnis zu deiner Kette?
also M(Motor):M(Achse)=?
wenn du das mit nem PI(D) regler vernünftig regeln willst sollte das besser nicht zu extrem sein.
bis 1:20 oder so ists noch (einfach) regelbar...

sammler
27.05.2010, 15:05
doublette durch zu schnelles klickern....

sammler
27.05.2010, 15:06
die beschreibung klingt nach ziemlichem Überschwingen *g*
wie hast du Kp denn gewählt? und wie berechnest du e?

hast du eine möglichkeit ide zykluszeit (deutlich) zu verringern?
1s ist ne ewigkeit, wenn du einen Motor regeln willst.

oratus sum
27.05.2010, 15:11
Nunja, das mit dem Massenträgheitsmoment weiss ich nicht. Mechanisch bin ich weniger als nicht bewandert.

Was ich noch sagen wollte ist, dass mein Motor bei PWM von ca 170 anläuft, hat er das Überwunden kann ich runter bis PWM 140 gehen.

Ich nehme allerdings ein Bereich von 180-230 an. So laut meinem Diagramm habe ich einen Durchschnittlichen Faktor von

3,518304078 Links
3,622007069 Rechts

Daher wäre mein KP-Wert 3,622007069 für Rechts und eben das andere für Links. Meine Rechte Kette dreht sich generell langsamer als die Links (warum auch immer)

E berechne ich indem ich zunächst meine Encoder Ergebnise mit diesem Faktor multipliziere. Dann habe ich ja den IST-Wert in PWM. Diesen IST-Wert ziehe ich dann vom SOLL-Wert ab.

Das ist e.

oratus sum
27.05.2010, 15:14
Erm...

Den Timer kann ich klar ohne Mühe verändern, das ist kein Problem. Was schlägst du vor?

Ich ahbe mal deine Vorgeschlagenen Werte genommen mit Ta = 0.250. Es schwinkt jetzt sehr extrem, die Ketten Fahren auch rückwärts.

sammler
27.05.2010, 15:29
aha.
also, dein bisheriges KP hat im Regler GAR NIX verloren.
das brauchst du ja nur um die Berechnung von e zu machen, bzw. die Kette zu normieren.

e=V_soll-V_ist

da sind wir uns einig.

V_ist bastelst du dir mit den konstanten die du für links und rechts ermittelt hast.
für V_soll nimmst du den PWM-Wert her, von mir aus.

Soweit, so gut.

jetzt jagst du deine Regelabweichung e in den Regler:


Regler(e){
Kp=15;
Ki=0,1;
e_sum = e_sum + e;
y = Kp * e + Ki * Ta * esum;
Return(y);
}
Der Funktion übergibst du in 2 nacheinander folgenden aufrufen einmal e_rechts und einmal e_links;
zurück bekommst du dann entsprechend y_rechts oder y_links.
das wird dann auf V_soll_rechts bzw. V_soll_links aufgeschlagen, und das jeweils ausgegeben, nehme ich an..?

sammler
27.05.2010, 15:33
wenn man das sauber machen will sollte man eigentlich Ta in der funktion ermitteln, wenn ich mir das recht überlege.
immer beim eintritt in die regler-schleife muss einen Zeitstempel nehmen, den alten abziehen und hat so die Zeitdifferenz seit dem letzten Zyklus...

oratus sum
27.05.2010, 15:33
Okay, in Bascom sieht das dann so aus:



l_ist = Left_Distance * 3.518304078
r_ist = Right_Distance * 3.622007069
Left_distance = 0
Right_distance = 0
PIDR = 0
PIDL = 0
Kp = 15
Ki = 0.1
Ta = 1

Error = l_soll - l_ist

Error_suml = Error_suml + Error

PIDL = Kp * Error
PID_Buffer = Ki * Ta
PID_Buffer = PID_Buffer * Error_suml
PIDL = PIDL + PID_Buffer

Error = r_soll - r_ist

Error_sumr = Error_sumr + Error
PIDR = Kp * Error
PID_Buffer = Ki * Ta
PID_Buffer = PID_Buffer * Error_sumr
PIDR = PIDR + PID_Buffer


Leider muss man in Bascom diese ganzen Rechnungen zerlegen.

sammler
27.05.2010, 15:38
Hmmm.

Kann Bascom keine Funktionen? hab mich noch nie damit befasst...
aber so sieht es gut aus, ja.

und um Ta richtig zu ermitteln würde ich das noch so machen:


T_ist=T1; // oder wie auch immer du den Timer ausliest
Ta=T_alt-T_ist;
T_alt=T_ist;


wobei T_ist und T_alt natürlich statisch sein sollten.

oratus sum
27.05.2010, 15:39
Tja jetzt schwingt er nciht so derbe aber er schwingt noch imemr ziemlich arg. Es ändert sich nicht so schnell, trotzdm fährt die rechte kette ab und zu rückwärts.

Wie meinst du das mit TA? Wie ist eigentlich TA anzugeben? In hz oder Sekunde?

Mein Problem ist, dass wenn ich jetzt die Abtastzeit verändere muss ich mir ncohmal den Faktor ausrechnen. Außerdem weiß ich nciht ob da noch genug Peaks/s sekunde vorhanden sind um damit vernünftig rechnen zu können.

Die Peak/s sind schon so Doppelt weild er Interrupt auf Change ist, daher ein weißer Streifen den Inkrementalinterrupt doppelt aufruft. Das ist aber eigentlich egal.

sammler
27.05.2010, 15:46
hmmm.
der faktor sollte eigentlich nur eine umrechnung von Inkrementen zur Motor-Drehzahl darstellen - zumindest würde ich mir so einen Faktor suchen.

Ta ist wie oben beschrieben die Zykluszeit, nach der der Regler wieder aufgerufen wird.
und um die korrekt zu ermitteln (ich traue dem Quarz nicht), muss man die eben ausmessen. dazu verwendest du einen Timer, der sowieso läuft und ermittelst mit T_ist dessen stand zu beginn der Reglerstrukur.

danach musst du die zeittifferenz seit dem letzten aufruf des Reglers ermitteln: Ta= T_ist-T_alt << da hatte ich oben nen dreher drin, sorry.
danach legst du den gerade ermittelten wert wieder in einer Variablen ab,
die in der nächsten runde wieder verfügbar ist.

mit peaks meinst du die inkremente? wenn die natürlich zu langsam kommen ist das ein problem, da gebe ich dir recht. dann kannst du das mit dieser Regelung leider nicht umsetzen, soweit ich das von hier überblicken kann.

sammler
27.05.2010, 15:57
leider muss ich jetzt los, aber ich guck nachher nochmal nach dir ;-)
dann verrate ich dir auch, wie du das massenträgheitsmoment von der Last ermitteln kannst.
das vom Motor sollte im Datenblatt stehen...

bis denn,
Christian

oratus sum
27.05.2010, 17:10
Ich hab jetzt Ta auf 0.25 gesetzt, also 4 Messungen Pro Sekunde.

Ich hab mal kurz aufgezeichnet was da rauskommt. Es hat sich grundsätzlich nichts geändert

sammler
27.05.2010, 17:22
hmmm.
hast du Ta umgestellt, oder auch die Hardware?
will sagen: wie oft wird die regler-geschichte denn aufgerufen?

oratus sum
27.05.2010, 17:27
die Regler-geschichte wird 4 mal in der Sekunde aufgerufen. Sprich alle 250ms, also müsste ja TA 0.25 sein

Ich hab den Roboter dann nochmal nen Test durchführen lassen wo er mir alle 250ms 10s lang die Werte der Encoder geliefert hat. Dabei war mein minimum,also PWM 180, 8 Einheiten pro 250ms, also 4 Peaks pro 250ms was wiederum 4 Markierungen pro 250ms sind und das Maximum also 230PWM 20 Einheiten, also 10 Peaks sprich 10 Markierungen pro 250ms

sammler
27.05.2010, 17:32
hmmm.
hast du nur die variable Ta umgestellt, oder auch die Hardware?
will sagen: wie oft wird die regler-geschichte denn tatsächlich aufgerufen?
Ta ist ja nur die (angenommene oder berechnete) Zeit seit dem letzten aufruf.
Solange sich der tatsächliche Aufruf nicht ändert bringt das schrauben an Ta nicht so wirklich viel - darum würde ich es auch berechnen / messen und nicht einfach festlegen.

oratus sum
27.05.2010, 17:36
Ich sag ja berechnet ist es mit 250ms. Alle 250ms wird der Interrupt von meinem Timer aufgerufen, und dort wird dann der Regler berechnet.

Ich nehme an, dass man Ta in Sekunden angibt, stimmt das?

oratus sum
27.05.2010, 17:40
Achja und was ich auch noch nicht ganz verstehe beim P-Glied:

Da habe ich ja diesen Faktor Kp.

Nehmen wir mal folgendes an:

Kp = 15
Soll-wert = 200
Ist-Wert = 190

-> Fehler = 10

p = Kp * e

p = 15*10
p = 150

Motor = soll + p
Motor = 200 + 150
Motor = 350

Was aber nicht möglich ist. Was macht mir dieses Kp - glied? Wieso rechne ich nicht einfach den Fehler hinzu?

sammler
27.05.2010, 18:00
Ta in sekunden, ja.

du erstellst hier einen geschlossenen regelkreis. die neigen dazu eine stellgröße auszuspucken, die das system evtl. nicht behandeln kann. also musst du eben dafür sorgen, dass er bei maximaler stellgröße abriegelt - solltest du schon schaffen ;-)

die rechnung mit
Motor = soll + p ist ja nicht vollständig: da fehlt noch der i-anteil ;-)
Außerdem kann man das ja mit
if motor > motor-max then motor = motormax; einfachstens abfangen. entsprechendes wirst du übrigens auch für motor-min brauchen - obwohl, dann bleibt er stehn oder dreht zurück oder so...

sammler
27.05.2010, 18:02
ach so. vergessen.

Was macht mir dieses Kp - glied? Wieso rechne ich nicht einfach den Fehler hinzu?

das P-Glied ist der "beschleuniger" in deinem Regelkreis. ohne oder mit nur kleinem P-Anteil ist der Regler einfach nur langsam.

oratus sum
27.05.2010, 22:01
Okay...

Folgendes:

Ich habe jetzt verschiedene Sachen ausprobiert und bin zum Schluss gekommen, dass Kp 15 viel zu hoch ist. Wenn ich Ki auf null stelle und Kp auf 0.5 habe ich weder ein Reglereffekt noch eine Schwingung. Bei 0.8 gehts wieder los.

Klar das mit dem Begrenzen ist kein Problem.

Ich habe eine fahrt aufgezeichnet, nicht am Boden sondern beide Ketten sind nicht belastet. Nach einer Zeit habe ich dann dei Rechte Kette mit der Hand blockiert.

Kurz zur Erklärung:
R: ist sind die Inkremente pro 250ms Rechts
R: ist sind die Inkremente pro 250ms Links
Speedr ist der PI-Regler plus dem Soll-Wert, also die geregelte PWM geschwindigekit

l_soll ist der linke soll-wert, der sollte fix 200PWM sein
r_soll ist der rechte soll-wert, der sollte fix 200PWM sein

l_ist ist der gemessene linke Inkrementalwert umgerechnet in den PWM wert
r_ist ist der gemessene rechte Inkrementalwert umgerechnet in den PWM wert

PIDR und PIDL ist der erechneter PI-Wert, PID weil es mich nciht an diese schreckliche Zahl erinnert :-D

Die Werte mit Links sind nur zum vergleich da, sie wurden nicht beeinflusst.

Ich möchte noch ncihts zu den Werten sagen zuerst den Experten anhören.

Eine Frage ist nich aufgetaucht.
Wann übergebe ich den Wert des PID-Reglers?

Es sieht ungefähr bei mir gerade so aus:

Do
KL = 200 + PID
KR = 200 + PID

Drive(KL,KR)
Loop

Dann im interrupt alle 250ms:

PIDL = PI-Regler
PIDR = PI-Regler

passt das so?

sammler
27.05.2010, 22:36
na, klingt doch gut.
Wenn die (über)schwingung bei Kp=0.8 anfängt hast du doch den wert, mit dem du anhand der regeln von chien hrones und reswick bzw. den andern beiden deinen regler berechnen kannst ;-)

RP6conrad
28.05.2010, 20:26
Ich glaube das ihre Problem eigentlich anfangt beim messen !! Die Verteilung von Weisse Glieder zu Schwarze ist ca 1/4. Du hast ein interrupt bei jeden Wechsel. Das bedeutet das bei gans stabiles fahren die pulsen absolut keine feste Periode haben. Bei jeden Weisse glied haben sie eine Periode von 1, bie das naechste Schwarze gliedern eher 4 !! Da kan keinen Regler sie helfen, ihre Messung selbst gibt da Riesenschwankungen an von die Ketten geschwindigkeit, obwohl das nicht so is.
Forschlag : du messt nur noch die positive Flanke, und nicht das Anzahl Flanke/Zeit aber die Zeit zwischen zwei positive Flanken. Leiter bekommst du dan einen neueProblem bie gans langsam fahren : Ihre Regelkreis erwartet eine neue Messwerte, aber die gibts nicht wegen noch keine neue positive Flanke passiert.
Nur wen die Messung stimmt, kansst du ihre Regler parameter optimieren.

oratus sum
28.05.2010, 21:24
Die Bilder in meinem Avatar sind nciht aktuelle.

Jedes 2-te Kettenglied ist nun weiß, so habe ich ein verhältnis von 1:1 also die Hälfte weiß die hälfte schwarz, ganz genau.

Du hast oben gesagt, dass Kd die Geschwindigkeit ändert. Aber ein Kd von unter 1 also z.b. 0.8 entspricht ja eienr Division also wird es quasi verlangsamt, oder?

_werwurm_
30.05.2010, 14:30
Hallo!

Ich stimme RP6conrad zu und glaube auch, daß es ein Meßproblem ist. Auch wenn jetzt jedes 2. Kettenglied weiß ist - vielleicht erzeugt die Messung zuviele Flanken? Kannst Du prüfen, ob bei einem vollständigen Umlauf der Kette auch die richtige Anzahl Impulse gezält werden?

Wenn nämlich "Geister-Impulse" auftauchen (also mehrere Flankenwechsel wo nur einer auftreten sollte) dann kann ich mir gut vorstellen, daß der Regler versucht zu bremsen und die Kette stehen bleibt oder gar rückwärts läuft.


Do
KL = 200 + PID
KR = 200 + PID

Drive(KL,KR)
Loop

Dann im interrupt alle 250ms:

PIDL = PI-Regler
PIDR = PI-Regler


Ich muß zugeben, daß ich jetzt nicht wirklich weiß wovon ich rede - aber ich glaube, der Reglerwert sollte nur im festen Zeitintervall aufaddiert werden. Laut dem Code wird bei Dir ja ständig die Antriebsgeschwindigkeit geändert (?). Kann noch mal jemand mit Ahnung diesen wichtigen Teil verifizieren?

MfG
Martin