PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Linienverfolgung Testarena ASURO mit roter LED



ehenkes
20.05.2007, 20:32
Ich wende mich gerade der Linienverfolgung in der Testarena (Danke für das pdf-File im Downloadbereich!) zu. Welches Programm ist für einen normalen ASURO mit normaler roter LED (ohne Abschirmung) für diese Arena das Optimum? Die Programme, die ich bisher über Suchen gefunden habe, funktionieren leider nicht besonders zuverlässig, teilweise überhaupt nicht. Wo liegt der entscheidende Clou außer dem Austausch der normalen LED gegen eine IR-LED und Abschirmung?

Dani-Bruchflieger
21.05.2007, 14:17
Soweit ich weiß, muß man im ersten Schritt ein Programm erstellen, mit dem die Werte der Phototransistoren auf der UART per IR Trasceiver zum PC gesendet werden. Dann wird auf der Testarena ausprobiert, in welchem Datenbereich sicht diese Werte befinden überm weißen Grund bzw. auf der schwarzen Linie (bei mir zB weiß ca125 und Linie ca 85) dann muß in dem Programm der Linienverfolgung der Threshhold dementsprechend angepaßt werden. Gibt da wohl verschiedene Algorithmen....

radbruch
21.05.2007, 15:07
Die Programme in diesem Thread (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=259251#259251) waren noch für einen asuro mit der orginalen FrontLED geschrieben. Maxwerte waren bei ca. 40:

http://popen.pop3.ru/asuro/linie2a.gif (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=259251#259251)

Gruß

mic

damaltor
21.05.2007, 17:04
du musst dir ein programm suchen, und es nahc deinem asuro anpassen. die werte der asuros sind bei niemandem hier gleich.

schreibe dir zuerst ein programm welches die in einer endlosschleife die aktuellen werte deiner fototransistoren in hyperterminal/minicom ausgibt, und dann musst du das programm auf deine werte abändern.

Volley
21.05.2007, 21:30
Ich wende mich gerade der Linienverfolgung in der Testarena (Danke für das pdf-File im Downloadbereich!) zu. ...

ich bin leider wie immer ein wenig blind und finde die Vorlage für die Testarena nicht. Kann mir da mal bitte jemand unter die Arme greifen?

Ich habe meinen ASURO mal den RCJ-Rescue Aufgabe lösen lassen. Dort muss man folgende Aufgaben lösen (Kurzform):
- Linie folgen (Line hat Unterbrechungen bis zu 30cm und bis zu 90°-Ecken in der Linie)
- grüne und silberen Mänchen erkennen
- Hindernisse auf der Linie
- Steigungen bis zu 20° aufwärts und auch abwärts
(Mir ist nicht alles gelungen, aber für ne Demo hat es gerreicht. ;-)
Eventuell könnte man sich dort noch Anregungen für neue Aufgabenstellungen geben. :-)

Gruß Heiko

damaltor
21.05.2007, 21:42
Die Linientestarena findest du hier:

https://www.roboternetz.de/phpBB2/viewtopic.php?t=30004

Volley
21.05.2007, 21:51
Vielen Dank. Das Seiten kommen schon aus meinem Drucker ...

ehenkes
21.05.2007, 22:50
Ich fand dieses Programm mit dem PID-Regler von "Waste" wissenschaftlich ansprechend, aber es funktioniert bei mir nicht. Wie finde ich die passenden Zahlen für meinen ASURO?



/************************************************** *****************************
*
* Description: Asuro Linienverfolgung mit PID-Regler
* Version 1: Korrektur auf beide Motoren verteilt
* Autor: Waste 26.8.05
*
************************************************** ***************************/
#include "asuro.h"
#include <stdlib.h>

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
speedLeft = speedRight = speed;
MotorDir(FWD,FWD);
if ( y > 0) { // nach rechts
StatusLED(GREEN);
speedLeft = speed + y2; // links beschleunigen
if (speedLeft > 255) {
speedLeft = 255; // falls Begrenzung
y2 = speedLeft - speed; // dann Rest rechts berücksichtigen
}
y = y - y2;
speedRight = speed - y; // rechts abbremsen
if (speedRight < 0) {
speedRight = 0;
}
}
if ( y < 0) { // nach links
StatusLED(RED);
speedRight = speed - y2; // rechts beschleunigen
if (speedRight > 255) {
speedRight = 255; // falls Begrenzung
y2 = speed - speedRight; // dann Rest links berücksichtigen
}
y = y - y2;
speedLeft = speed + y; // links abbremsen
if (speedLeft < 0) {
speedLeft = 0;
}
}
leftDir = rightDir = FWD;
if (speedLeft < 20) leftDir = BREAK; // richtig bremsen
if (speedRight < 20) rightDir = BREAK;
MotorDir(leftDir,rightDir);
MotorSpeed(abs(speedLeft),abs(speedRight));
}

int main(void)
{
unsigned char sw;
Init();
MotorDir(FWD,FWD);
StatusLED(GREEN);
speed = 150;

kp = 3; ki = 10; kd = 70; // Regler Parameter kd enthält bereits Division durch dt

sw = PollSwitch();

if (sw & 0x01)
{ki=20;}
if (sw & 0x02)
{speed = 200;}
if (sw & 0x04)
speed = 100;
if (sw & 0x08)
kd = 35;
if (sw & 0x10)
kd = 70;
if (sw & 0x20)
kd = 140;

FrontLED(ON);
LineData(lineData);
speedLeft = speedRight = speed;

while(1)
{
FollowLine();
}
return 0;
}


Vielleicht ist dieses Programm inzwischen weiter entwickelt.

Sternthaler
22.05.2007, 00:14
Hallo ehenkes,
bei meinem Asuro kamen als sehr großes Hindernis beim Fahren meine beiden Motoren in's Spiel. Bei mir war der rechte Motor ein 'Schlappi' und benötigte immer ca. 50! Einheiten mehr Saft als der Linke um halbwegs geradeaus zu fahren. Mein Asuro fuhr also immer rechtsrum. (Radius ca. 30 cm) (Habe mitterweile die Motoren getauscht.)
Hast du deinen Asuro schon mal mit gleichen Werten für die Motoren fahren lassen und geschaut, ob auch bei dir die Motoren 'etwas krumm' sind?
In Wastes Programm (ist teuflisch gut!) hatte ich dann einen Korrekturwert eingetragen, der meine Fehler-50 auf beide Motoren noch verteilt hatte.

Weiterer Fehlerursache könnte ein Umbau an deinem Asuro sein. In dem von dir angesprochenen Thread von Waste hat er (mit anderen) unter anderem das Gewicht bzw. Drehmoment vom Asuro natürlich berücksichtigt. Wenn deiner nun 'heftig' anders wiegt, können die Reglerwerte nicht mehr stimmen.

damaltor
22.05.2007, 07:41
wertebestimmung im einfachsten:



#include "asuro.h"

int main(void){
int data[2];
Init();
while(1){
LineData(data);
PrintInt(data[0];
SerWrite(" ",3);
PrintInt(data[1];
SerWrite("\n\r",2);
if(PollSwitch()==32){FrontLED(ON);};
if(PollSwitch()==16){FrontLED(OFF);};
}
}

denke ich sollte so klappen. das programm gibt endlos die werte der fototransistoren aus. wenn du ihn dann ein wenig aufder linie hin- und herschiebst, solltest du deine minimal- und maximalwerte finden. mit zwei tastern (nebeneinander, links oder rechts aussen) kannst du die frontled ein- und ausschalten. hoffe es geht, muss jetzt in die FH

Sternthaler
22.05.2007, 22:28
Wie finde ich die passenden Zahlen für meinen ASURO?
wertebestimmung im einfachsten:Was habe ich hier nicht mitbekommen?
@damaltor: Du liefert in deinem Programm die Daten der Liniensensoren über IR an den PC um min- und maxwerte zu finden.
@ehenkes: Du fragst nach 'passenden Zahlen'.
So wie ich wastes PID-Regler verstehe, wüsste ich nun aber nicht, welche 'passenden Zahlen' in Verbindung mit den Liniesensorwerten gemeint sein können.
Im PID von waste werden doch nur die relativen Differenzen zwischen Sensor 'links' und 'rechts' ausgewertet.
Als Frage zu 'passenden Zahlen' hatte ich die Werte für kp, ki und kd im Auge.
Die von waste in seinem Thread, sehr ausführlich erklärten/ermittelten Werte hierfür, sind doch angegeben:
kp = 3; ki = 10; kd = 70; // Regler Parameter kd enthält bereits Division durch dt

Also jetzt nur für mich: Um welche Werte geht es, ehenkes?

ehenkes
22.05.2007, 23:00
Es geht um zwei Dinge, die mir Probleme bereiteten:
a) die Erfassung der Liniendaten
b) die richtigen Parameter für PID, also Kp, Ki und Kd

Mit folgendem abgeänderten Programm kam ich bisher gut voran:



#include "asuro.h"
#include <stdlib.h>

#define SPEED 150
#define SPEEDMAX 230
#define SPEEDMIN 30

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

void FollowLine (void)
{
unsigned char leftDir = FWD, rightDir = FWD;

LineData(lineData);
x = (lineData[LEFT] - lineData[RIGHT]) - ADOffset; // Regelabweichung

yp = x*kp; // P-Anteil

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
yd += drest; // nicht berücksichtigten Rest addieren
if (yd > 255)
{
drest = yd - 255; // 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);

y = yp + yi + yd; // Gesamtkorrektur
y2 = y / 2; // Aufteilung auf beide Motoren
xalt = x; // x merken

speedLeft = speedRight = speed;
MotorDir(FWD,FWD);

if ( y > 0)
{
StatusLED(GREEN);
speedLeft = speed + y2; // links beschleunigen
if (speedLeft > SPEEDMAX)
{
speedLeft = SPEEDMAX; // falls Begrenzung
y2 = speedLeft - speed; // dann Rest rechts berücksichtigen
}
y = y - y2;
speedRight = speed - y; // rechts abbremsen
if (speedRight < SPEEDMIN)
{
speedRight = SPEEDMIN;
}
}

if ( y < 0)
{
StatusLED(RED);
speedRight = speed - y2; // rechts beschleunigen
if (speedRight > SPEEDMAX)
{
speedRight = SPEEDMAX; // falls Begrenzung
y2 = speed - speedRight; // dann Rest links berücksichtigen
}
y = y - y2;
speedLeft = speed + y; // links abbremsen
if (speedLeft < SPEEDMIN)
{
speedLeft = SPEEDMIN;
}
}
leftDir = rightDir = FWD;
if (speedLeft < SPEEDMIN + 5) leftDir = BREAK; // richtig bremsen
if (speedRight < SPEEDMIN + 5) rightDir = BREAK;
MotorDir(leftDir,rightDir);
MotorSpeed(abs(speedLeft),abs(speedRight));
}

int main(void)
{
Init();
FrontLED(ON);
for (j = 0; j < 255; j++) LineData(lineData);
LineData(lineData);
ADOffset = lineData[LEFT] - lineData[RIGHT]; // Helligkeitsunterschied links und rechts

MotorDir(FWD,FWD);
StatusLED(GREEN);

speed = SPEED;
speedLeft = speedRight = speed;

kp = 10; ki = 4; kd = 70; // Regler Parameter kd enthält bereits Division durch dt
/* 10(!) 4(!) 70(!) */ /*<=== gute Werte*/

while(1)
{
FollowLine();
}
return 0;
}



Allerdings habe ich es nur bei langsamer Geschwindigkeit geschafft, die gesamte Testarena sauber abzufahren. Das Feintuning ist viel schwieriger, als ich ursprünglich dachte. Eine Ochsentour!

Volley
22.05.2007, 23:03
Also jetzt nur für mich: Um welche Werte geht es, ehenkes?
Ich bin zwar nicht ehenkes, aber ich benutze die Werte um die unterschiedlichen Lichtwerte meiner Fototransistoren auszugleichen. Dazu musste natürlich der Code ein klein wenig abändert werden.

ehenkes
22.05.2007, 23:11
Zeig mal vor Deinen Code. ;-)

ehenkes
22.05.2007, 23:28
Interessant ist auch folgender Link:
http://home.arcor.de/Wolfgang.Rossner/roboter/asuro/asuro.html

Sternthaler
23.05.2007, 01:55
Hallo ehenkes,
du hast einen wichtigen Teil:

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

in deinem Sourse eleminiert.
Damit verlierst du schon mal die Umgebungslicht-Unabhängigkeit. Zwar hast du in deinem main() am Anfang einen ADOffset-Wert ermittelt, aber der ist auch schon bei eingeschalteter Front-LED berechnet worden, und wird auch nicht mehr angepasst.
Nun hatte waste seine PID-Werte aber für Sensorwerte ermittelt, bei denen das 'x = don - doff; // Regelabweichung' aber eben nach genau diesem Prinzip berechnet wird. (Somit wird x bei waste immer kleiner sein als bei dir, was zur Folge hat, dass die Abweichung vom Sollwert bei dir immer anders 'aussieht')
Ausserdem hatte waste einen Zeitwert in dem Regler berücksichtigt, der vor allem durch die Sensorabfrage (ADC-Wandler) vorgegeben war. In wastes Lösung aber werden 4 ADC-Messwerte ermittelt, somit ist alleine schon der Zeitfaktor der Schleife komplett anders als nun bei dir.
Dein Versuch nun, die von waste ermittelten PID-Werte anzupassen
kp = 3; ki = 10; kd = 70; <-- deine
kp = 10; ki = 4; kd = 70; <-- waste-Original
sehen mir nun wirklich danach aus, dass du die Frage nach diesen Werten hier stellen musst. Die Werte sind doch empirisch ermittelt, und nicht berechnet. (Dann wäre ja die Frage überflüßig.)

Um nun nicht so auszusehen, als ob ich die Berechnungen und Gründe was da nun alles ermittelt und in Betracht gezogen werden muss, aus dem Thread von waste verstanden zu haben, hier mein Geständniss: Das Prinzip ist mir klar, aber nicht der Weg zur Lösung (kp,ki,kd). Somit kann ich nun nicht mehr weiterhelfen.

ehenkes
23.05.2007, 18:27
kp = 3; ki = 10; kd = 70; <-- deine
kp = 10; ki = 4; kd = 70; <-- waste-Original
ist genau umgekehrt.


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
Das hat bei mir einfach nicht funktioniert, keine Ahnung warum, daher habe ich auf ein funktionierendes Prinzip zurück gegriffen. Vielleicht ein Vorzeichenproblem mit LEFT/RIGHT bzw. 0/1, werde das nochmal probieren. Die Ableitung der Werte von waste habe ich verstanden.

ehenkes
23.05.2007, 18:41
Übrigens ist die empirische Methode auch beschrieben und funktioniert auch gut:


Dimensionierung durch Probieren (Empirisches Einstellen)
Diese Methode ist geeignet um einfache Systeme zu dimensionieren,
insbesondere wenn man bereits Erfahrung mit ähnlichen Regelkreisen hat. Man
fängt mit einer unkritischen Einstellung (Kp klein, Ki = 0, Kd = 0) an und
erhöht langsam die Verstärkung Kp, bis die Dämpfung schlecht wird. Falls
eine Schwingneigung auftritt, muss die Verstärkung wieder etwas zurück
genommen werden. Dann nimmt man allmählich den Integralanteil hinzu, erhöht
ihn in Schritten und probiert solange herum, bis das Ergebnis einigermaßen
passt. Bei Bedarf kann noch ein D-Anteil (PID-Struktur) probiert werden.
Wenn dabei die Regelung stabiler wird, kann noch mal Kp und Ki erhöht
werden, bis man endgültig zufrieden ist.

Sternthaler
23.05.2007, 21:29
Na dann funktioniert doch alles bei dir.
Hilf dir selbst, und allen ist geholfen.

ehenkes
23.05.2007, 21:51
Die Testarena schafft er schon "fast". Nur bei den Steilkurven hängt er sich im Kreis auf. Man müsste ihn auf beiden Rädern zusätzlich abbremsen, wenn die Kurven zu "eng" werden, damit er am Ende nicht einfach weiter dreht und damit aus der Bahn gerät. Ich bin nur noch nicht sicher, an welchem Mess- oder Regelwert man anpacken soll. Was zeigt den Kurvenradius der schwarzen Linie an? Das wäre vielleicht der richtige Wert für eine Geschwindigkeitssteuerung. Gerade Linie - Gas geben, enge Kurve - abbremsen. Ideal wäre vielleicht auch ein Regler, der sich selbst optimiert (neuronale Netze, genetische Algorithmen, so was in der Art).

damaltor
24.05.2007, 10:44
Neuronale Netze auf 7 kb... das ist ein ziel. =)

schafft der kleine die strecke denn wenn du die geschwindigkeit insgesamt etwas zurücknimmst?

ehenkes
27.05.2007, 17:40
Habe bisher keine Einstellung gefunden, die alle Kurven packt. Das Rumprobieren finde ich öde. Hier fehlt irgendwie KI.

damaltor
27.05.2007, 19:38
Na dann... hau rein =)

mein asuro hat den kurs geschafft, vielleicht liegts nur noch an den werten... aber wenn du es schaffst ne ki zu entwickeln dann los =)

HermannSW
27.05.2007, 22:55
Habe bisher keine Einstellung gefunden, die alle Kurven packt. Das Rumprobieren finde ich öde. Hier fehlt irgendwie KI.also es gibt ja zwei Möglichkeiten, das Bestimmen der Werte durch Messungen, ...
das Probierenentoderweder -- KI wird Dir da wohl eher nicht weiterhelfen ...

Ein völlig andersartiges Verfahren zum Linienfolgen (state-machine) kannst Du hier finden:
https://www.roboternetz.de/phpBB2/viewtopic.php?t=29123
Die Infrarot-LED vereinfacht die Sache, ist aber keine Pflicht: Du mußt nur den THRESHOLD (Grenze zwischen "noch auf der Linie" und "nicht mehr auf der Linie") richtig wählen!

Dieser Algorithmus ist trotz seiner Einfachheit für Geschwindigkeiten bis 38cm/s ausreichend, leider schaffen aber auch aufgepeppte Asuro's (der Asuro meines Sohnes schafft full speed 1.8m/s) mit diesem Algorithmus nicht mehr als 38cm/s auf der Linie -- bleiben also nur die oben erwähnten Ansätze aus der Regelungstechnik (PID, ...).

Die Linientestarena schafft mein Asuro übrigens problemlos, trotz der einen engen Kurve rechts unten mit einem Radius von nur 2cm ...

Sternthaler
28.05.2007, 00:07
Habe bisher keine Einstellung gefunden, die alle Kurven packt. Das Rumprobieren finde ich öde. ..
Aber genau das ist doch so reizvoll. siehe unter:
https://www.roboternetz.de/phpBB2/viewtopic.php?p=283080#283080