PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Linienverfolgung(mal wieder) und PID-Regler



E-lois
28.04.2009, 09:51
Hallo allerseits!

Gleich vorweg: Ich bin ein absoluter Versager im Programmieren!
Ich will es unbedingt verstehen, aber sobald es ein bisschen tiefer geht, kommt bei mir nur noch Bahnhof an. Alle schmeißen dann mit ihren Fachbegriffen um sich, von denen ich 0,1% kenne und folglich trotzdem nicht schlauer werde.

Ich bin gerade dabei ein Programm zu einem Parcours zu schreiben,
mein Linienverfolgungsprogramm ist aber so simpel, dass engere Kurven ein Glücksspiel sind und der Asuro extrem ruckelt beim Linienverfolgen.
Ich habe mir sagen lassen, dass dem mit einem PID-Regler Abhilfe geschaffen werden kann.
Ist vielleicht jemand bereit mir (der Niete) zu helfen?
Damit meine ich erklären und nicht einfach irgend ein Programm zu geben!

Naja hier erst mal mein bisheriges Programm, um einen Einblick zu erhalten:




unsigned int LichtS[2]; //Array für Sensoren
int Differenz ;
Differenz = LichtS[0]-LichtS[1]

void LinieFolgen(void){ //Prozedur zur Linienverfolgung
if(Differenz<-4){ // wenn die Differenz negativ ist, ist es rechts heller, also nach links lenken
MotorDir(FWD, FWD);
MotorSpeed(150, 0);
}
else if(Differenz>4){ //wenn die Differenz positiv ist, ist es links heller, also nach rechts lenken
MotorDir(FWD, FWD);
MotorSpeed(0, 150);
}
else{ //ansonsten geradeaus fahren
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
}
int main(void){

Init(); // zwingend, sonst weiß CPU nicht wo was angesteuert wird

unsigned char Taster1;
unsigned char Taster2;

while(1) { // endlos, weil Bedingung immer "wahr" ist
FrontLED(ON);
Msleep(10);
void LineData(LichtS); //Helligkeitswerte einlesen
FrontLED(OFF);
LinieFolgen();


Taster1 = PollSwitch() ; //Tasterwerte abfragen
Msleep(10) ;
Taster2 = PollSwitch(); //Tasterwerte überprüfen

if(0<Taster1&&0<Taster2){ //wenn Asuro gegen ein Hindernis fährt dann umfahren
EncoderInit();
MotorSpeed(BREAK, BREAK); //Asuro stoppt und fährt ein Stück zurück
Msleep(10);
MotorDir(RWD, RWD);
MotorSpeed(100, 100);
Msleep(100);
Turn(90, 150); //Umfahren
Go(90, 150);
Turn(90, 150);
Go(50, 150);
Turn(35,150);

while(LichtS[0]>70){ //so lange geradeaus fahren bis schwarze Linie kommt ( 70=WertDunkel)
void LineData(LichtS);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
}


}
return 0; // hier her kommt das Programm niemals (darf es auch nicht)
}


Ich hoffe auf Meldungen :)
E-lois

Willa
28.04.2009, 10:21
Also, vielleicht fängst du mal mit was leichtem an:
Im Moment steuert dein Roboter voll nach links bzw. rechts wenn ein bestimmter Schwellwert über bzw. unterschritten wird (...if(Differenz<-4)...).
Versuche doch mal als erstes die Stärke mit der gelenkt wird an den Wert "Differenz" zu koppeln. Das wäre dann schon ein P-Regler:
Pseudocode (sorry, kann kein C):


If differenz < 0 then
Motorspeed = (150, 150+differenz)
end if

==> je größer der Helligkeitsunterschied, desto stärker wird gesteuert. Wie gesagt, das ist der P-Anteil eines PID Reglers. Lies dir mal den Artikel Regelungstechnik durch, vielleicht kommst du nun selber darauf wie du den I ("plus rechnen") und den D ("minus rechnen") Anteil einbauen kannst. Falls nicht können wir dir hier wohl auch weiterhelfen.

E-lois
28.04.2009, 11:01
Ich habe mir den Artikel schon angesehen, bei 7. steig ich aus ^^'

Also die Differenz ist ja die zwischen den Helligkeitswerten der Sensoren links und rechts. Macht das dann viel Sinn wenn ich die Abweichung dieser Werte einfach zu den Geschwindigkeiten addiere/subtrahiere?
Wenn ich das richtig verstanden hab kommt dann diese Proportionalitätsfaktor Kp ins Spiel oder?! (y(t)= Kp * e(t) )
Wenn ja, wie finde ich den heraus?

oberallgeier
28.04.2009, 11:02
Hi, E-lois,

willkommen im Forum.


... Gleich vorweg: Ich bin ein absoluter Versager im Programmieren...Diese Erkenntnis ist, ebenso wie die Feststellung "Controller ist durchgebrannt" und ähnliche Feststellungen, sehr häufig temporär während des Arbeitens auch im Hobbybereich anzutreffen. Da muss man einfach durch.

Es gibt neben dem langen, aber im hinteren Teil recht nützlichen Tutorial zur Reg elungstechnik im RN ein paar lesenswerte, weil informative, Threads zum Regeln des asuro. Damit will ich nicht sagen, dass das alles schnell verständlich ist. Sprungfunktion und Sprungantwort, Zeitkonstante, und ähnliches Zeugs - damit haben sich einige Freaks schon vor Jahren beschäftigt und das auf recht hohem Niveau. Hier zwei interessante Dinge, einmal etwas zur Geschwindigkeit(smessung) (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=98599#98599) und danach dieser sehr interessante Thread zur Regelung des asuro. (https://www.roboternetz.de/phpBB2/viewtopic.php?t=11818)

So - und bitte verstopf jetzt Deinen eigenen Gehörgang, damit Du Deine eigenen Bemerkungen " ... zu kompliziert ... versteh ich nicht ..." wenigstens eine Weile nicht hörst. Es ist kompliziert und manchmal muss man einige Stellen mehrfach lesen - am Besten mit einem Bleistift in der Hand und ein paar Schmierblättern daneben ...

E-lois
28.04.2009, 11:16
Der Bleistift ist schon im Einsatz ;)
Danke für Links, Begrüßung und Aufmunterung! Ich werde mich mal ein bisschen durcharbeiten und hoffen, dass ich Erleuchtung finde.
Aber verlasst euch drauf, dass ich bald wieder Fragen haben werde.
Bis bald E-lois

Willa
28.04.2009, 12:06
Hi!
Also ich hab noch nie einen Asuro oder Linienfolger in den Fingern gehabt. Aber wenn ich mir diese Grafik hier angucke:
https://www.roboternetz.de/phpBB2/files/liniensensor.gif (aus diesem Thread (https://www.roboternetz.de/phpBB2/viewtopic.php?p=106971#106971))
Dann kann ich folgendes

Macht das dann viel Sinn wenn ich die Abweichung dieser Werte einfach zu den Geschwindigkeiten addiere/subtrahiere?
Mit "Ja" beantworten. Denn anscheinend verhalten sich die Helligkeitssensoren linear (also auch proportional) zur Abweichung von der Linie (zumindest bis zu einem Abstand von 7mm).

Wenn ich das richtig verstanden hab kommt dann diese Proportionalitätsfaktor Kp ins Spiel oder?! (y(t)= Kp * e(t) )
e ist "differenz" und kp ist einfach nur ein Verstärkungs bzw. Abschwächungsfaktor. Wenn deine Differenz bspw. 1500 wäre, dann würdest du damit deine Motoren nicht regeln können. Du würdest für kp 0,1 einsetzen und schon kann deine Regelung (theoretisch) funktionieren. Es ist ein bisschen fummelei den richtigen Wert für kp herauszufinden.... Wenns schwingt ist er zu groß. Es gibt aber auch Wissenschaftszweige die sich mit der Dimensionierung der Regelparameter auseinandersetzen... Man kann sich mit der Theorie Jahrzehnte auseinandersetzen und einen 99.99% perfekten Regler errechnen, oder man machts einfach so wie es passt und bekommt nur einen 90% perfekten Regler.

E-lois
28.04.2009, 17:22
Das ist ja mal sehr interessant, vielen Dank!!!

Ich hab mich jetz mal mit einigen Internetseiten und zusätzlich mit dem C++"Büchlein" das ich hier liegen habe beschäftigt.
Zur Geschwindigkeit des Asuros hab ich mir auch Interrupts angesehen. Das Grundprinzip und die Funktion verstehe ich, aber die Umsetzung erfordert wohl doch ein bisschen mehr Informatikwissen.

Die Linienverfolgung von "waste" (erwähnter Link) zu verstehen, scheint mir allerdings ein erreichbares Ziel zu sein.
Ausschnitt:


unsigned char speed;
int speedLeft,speedRight;
unsigned int lineData[2];
int x, xalt, don, doff, kp, kd, ki, yp, yd, yi, drest, y, y2, isum;

void FollowLine (void)
{
unsigned char leftDir = FWD, rightDir = FWD;
FrontLED(OFF);
LineData(lineData); // Messung mit LED OFF
doff = (lineData[0] - lineData[1]); // zur Kompensation des Umgebungslicht
FrontLED(ON);
LineData(lineData); // Messung mit LED ON
don = (lineData[0] - lineData[1]);
x = don - doff; // Regelabweichung
isum += x;
if (isum > 16000) isum =16000; //Begrenzung um Überlauf zu vermeiden
if (isum < -16000) isum =-16000;
yi = isum/625 * ki; //I-Anteil berechnen
yd = (x - xalt)*kd; // D-Anteil berechnen und mit
yd += drest; // nicht berücksichtigtem Rest addieren
if (yd > 255) drest = yd - 255; // merke Rest
else if (yd < -255) drest = yd + 255;
else drest = 0;
if (isum > 15000) BackLED(OFF,ON); // nur zur Diagnostik
else if (isum < -15000) BackLED(ON,OFF);
else BackLED(OFF,OFF);
yp = x*kp; // P-Anteil berechnen
y = yp + yi + yd; // Gesamtkorrektur
y2 = y/2; // Aufteilung auf beide Motoren
xalt = x; // x merken

Kann mir bitte jemand zu erst einmal erklären, was es mit dem isum auf sich hat?
Wenn ich mich jetzt nicht irre bedeutet "isum += x" das selbe wie "isum= isum+x" oder? Jetzt kommt vielleicht eine dumme Frage, aber was ist isum denn dann letztendlich? Da ich mir das nicht erklären kann, ist der Rest auch schwerer nachvollziehbar.

Liebe Grüße E-lois

Willa
28.04.2009, 17:30
isum ist der I-Anteil der Regelung. Im Idealfall ist die Abweichung 0, dann bleibt auch isum 0. Wenn nun eine konstante Abweichung da ist (z.B. +1), dann wird isum bei jedem Programmdurchlauf um 1 größer. Damit versucht der Roboter nun immer stärker die Abweichung auszugleichen. Je länger also die Störung anhält, desto stärker wird gegengesteuert. Zusammen mit dem D und dem P anteil erhält man dadurch eine Regelung die die Störung komplett wegbügelt. Hätte man den I anteil nicht, dann würde der Roboter das nicht schaffen, eine kleine Restabweichung wäre immer noch da.

E-lois
28.04.2009, 17:54
Das hilft mir auf jedenfall schon weiter. Das bedeutet sozusagen erst ist isum= Differenz und beim nächsten durchlauf ist es die alte abweichung plus die neue? und je nach dem wie sich die Differenz verändert, verändert sich auch isum und damit yi. Daraus folgt auch die Änderung der Gesamtkorrektur und schließlich der Geschwindigkeit, richtig?
Tja, bleibt nur das Problem, dass ich die Rechnung zu yi nicht verstehe, also die Werte, die eingesetzt werden.
Vielleicht ist das alles doch eine zu große Hürde im Moment.

Willa
28.04.2009, 18:09
beim nächsten durchlauf ist es die alte abweichung plus die neue?
fast... isum beinhaltet die Summe aller Abweichungen seit dem du den Roboter eingeschaltet hast. Da manche Abweichungen positiv sind und manche negativ kommst du dann ungefähr bei null raus. Es sei denn die Linie wird verlassen. Dann dominiert natürlich entweder die positive oder die negative Regelabweichung.
(ich schreibe hier übrigens absichtlich Dreiviertelwahrheiten, meiner Meinung nach ist das dann alles viel besser verständlich.)

Tja, bleibt nur das Problem, dass ich die Rechnung zu yi nicht verstehe
Naja, danach kommt doch nix kompliziertes mehr...?

if (isum > 16000) isum =16000; //Begrenzung um Überlauf zu vermeiden
if (isum < -16000) isum =-16000;
Das verhindert nur dass isum zu groß wird. Der Wert "16000" ist wahllos ausgesucht, bei meiner Reglung habe ich "1500" gewählt. Wenn du nämlich Pech hast und irgendwas hakt am Roboter, dann wird isum schnell unendlich groß. Und bis das dann mal wieder auf normale Werte zurück kommt dauert es eeeeeeewig.... Oder dein Programm stürzt einfach ab.

yi = isum/625 * ki; //I-Anteil berechnen
Hier wird isum einfach mit einem kleinen Faktor multipliziert. Ob man vorher /625 rechnet oder ob man das gleich mit in ki einrechnet ist völlig egal. In meiner Tricopter Regelung ist ki bspw = 0,02. Vielleicht mag der Autor einfach keine so kleine Zahlen und rechnet deswegen in zwei Schritten :-D. Jedenfalls muss ki ziemlich klein sein im Verhältnis zum P Anteil.

oberallgeier
28.04.2009, 18:10
... Wenn ich mich jetzt nicht irre bedeutet "isum += x" das selbe wie "isum= isum+x" oder? ...Genauso ist es. Ich (bin ja noch immer ziemlich unbedarfter Cäh-Programmierer und) musste auch erst meinen Verdacht im Kernighan-Ritchie bestätigt sehen.

Übrigens sitze und grüble ich (auch) gerade über Regel ungstechnik. Bei meinem Dottie bekam ich das nach etlichen mühevollen Stunden s..gut hin, der läuft schnurgerade (https://www.roboternetz.de/phpBB2/viewtopic.php?p=390196#390196) (wenn er gerade laufen soll), Abweichung rund 1 mm auf 1 m Laufstrecke (das wären also 99,9 % Richtigkeit *gggg*). Blos - trotz Aufwand für Sprungfunktion (https://www.roboternetz.de/phpBB2/viewtopic.php?p=433979#433979) und so kommt mein MiniD0 (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=432909#432909) mit der Regelung nicht so gut in Fahrt (https://www.roboternetz.de/phpBB2/viewtopic.php?p=437582#437582) wie ich will. Klar - ich hatte die Motoren geändert, (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=437282#437282) sprich: ich habe das Getrie be umgebaut auf deutlich schnellere Abtriebsdrehzahl, die Gesamtmasse ist etwas geringer, damit sind wesentliche Daten anders. Und die Feinabstimmung ist manchmal ne Popelei, wenn man nicht schnell zufällig auf die richtigen Werte trifft.

Ach so, ja, waste hatte hier eine Begriffsdefinition (https://www.roboternetz.de/phpBB2/viewtopic.php?p=109170#109170) gegeben, und Sternthaler hatte hier den etwas lang geratenen Thread eher systematisch ausgewertet zu einer Art Inhaltsverzeichnis. (https://www.roboternetz.de/phpBB2/viewtopic.php?p=114472#114472)

E-lois
05.05.2009, 12:45
Hallöchen!
Entschuldigung, dass ich mich die Tage nicht mehr gemeldet hab, war krank.
Also vielen Dank erst mal für die weiteren Links. Ich hab mich jetzt entschlossen nich alle drei Regler einzubauen, dass ist mir im Moment einfach noch zu schwer.

Also es funktioniert jetzt schon besser, hab nur noch ein Problem.
Und zwar ist die Linie bei dem Parcours ein Stück lang unterbrochen. Der Asuro soll dort einfach geradeaus fahren und dann die Linien weiterverfolgen. Das Problem ist, er driftet dann einfach immer ein Stück nach rechts und erreicht dann natürlich die schwarze Linie nicht mehr.Hab die Differenzspanne vergrößert. Hat jemadn eine Idee?
Vielleicht sollte man das Programm so verändern, dass der Asuro merkt, wenn er die schwarze Linie verlässt und das geradeaus Fahren extra programmieren. Sprich, er müsste das ja jetzt eig auch schon können, aber da ich keine andere Idee habe vllt einfach abmessen wie lange er geradeaus fahren soll?

Liebe Grüße