PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Linienfindung. Problem :(



Marit
18.12.2006, 13:11
Hi,
ich hab ein Programm geschrieben welches eine Linie finden und einfangen soll, aber der Roboter fährt nur grade aus, anstatt sich zu drehen und dann stehen zu bleiben auf der Linie. Erst soll ein Phototransistor ausgelesen werden, wenn er über einer schwarzen linie ist, und ab dann die zeit, bis der nächste über einer schwarzen ist per gettime() befehl. Dann soll später der Winkel ausgerechnet werden den der Roboter sich drehen soll per Turn() befehl.
Zur winkelberechnung hab ich erst den Tangens berechnet und den später umgewandelt per atan() befehl, welcher aus der math.h kommt (M_PIl kommt auch daher und ist die Zahl Pi). Für den Tangens hab ich hab ich aber Geschwindigkeit und Zeit benötigt um die Strecke auszurechnen die der Asuro fährt bis der zweite Phototransistor auf der schwarzen Linie ist. Zeit wurde schon vorher ausgerechnet und die Geschwindigkeit ist nur sehr ungefähr ausgerechnet.
Die Geschwindigkeit wird ja in den Werten von 0-255 angegeben. Ein Freund hat mal eine ungefähre Rechnung aufgestellt über Durchschnittswerte etc. und is zum Ergebnis Geschwindigkeit/818 gekommen. Dann hat man aus den 0-255 Werten einen Geschwindigkeitswert in m/s.
Jetzt kann man theoretisch über die Strecke a (Abstand zwischen Phototransistor 1 und 2) durch Strecke b (ausgerechnet über Geschwindigkeit mal Zeit) den Tangens ausrechnen: tan=a/(v*time)
Irgendwie fährt mein Roboter aber nur grade aus. Kann mir jemand helfen?
Hoffe das war jetz gut genug erklärt. Schaut einfach ma in den Code oder fragt nochma falls es Probleme geben sollte ;) .


#include "asuro.h"
#include "math.h" //dient der späteren Tangensumrechnung

int main(void)
{
double const a=1.5; // Abstand der beiden Phototransistoren: 1,5cm
double time;
double tan;
double time1;
double time2;
double v;
int arc;
int x;
double arc2;
unsigned int data[2];
unsigned char tmp[2] = {OFF,OFF};
Init();
while(1)
{
MotorDir(FWD,FWD);
MotorSpeed(120,120); // Geschwindigkeitsberechnung. 120/818 ist ein
v = 120/818; //ungefairer! Geschwindigkeitswert in meter pro sekunde.
LineData(data);
if (data[0] > 400) { //Überprüfung welcher Phototransistor an ist.
tmp[0] = ON;
time1 = Gettime(); } //Erste Zeit
if (data[1] > 400) {
tmp[1] = ON;
time1 = Gettime(); }
while(tmp[0]==ON)
{
if (data[1] > 400) //Überprüfung bis zweite Phototransistor an ist.
tmp[1] = ON;
if(tmp[1]==ON)
{
time2 = Gettime(); //Zweite Zeit
time = (time2 - time1)/1000; //Zeitabstand in sekunden
tan=a/(v*time); //Tangensberechnung über a(1.5)/b(v*time)
arc2 = atan(tan) * 180 / M_PIl; //Tangensumrechnung in Winkel
arc = (int)arc2; //double Wert wird in int Wert geändert
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
Turn (arc, v); //Drehung
tmp[1] = OFF; //Reset der Phototransistoren auf 0
tmp[0] = OFF;
}
}
while(tmp[1]==ON)
{
time1 = Gettime();
if (data[0] > 400)
tmp[0] = ON;
else{}
if(tmp[0]==ON)
{
time2 = Gettime();
time = (time2 - time1)/1000;
tmp[1]==OFF;
tan=a/(v*time);
arc2 = atan(tan) * 180 / M_PIl;
arc = (int)arc2;
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
Turn (arc, v);
tmp[1] = OFF;
tmp[0] = OFF;
}
}
}

return 0;
}

damaltor
18.12.2006, 21:07
vielleicht solltest du erstmal mit was einfacherem anfangen wir der linienverfolgung... ausserdem: wenn er mit der schnauze auf der linie steht, und sich dann dreht, dann ist die schnauze wieder weg von der linie. er muss also erst noch ein gutes stück vor fahren.

m.a.r.v.i.n
18.12.2006, 21:24
Hi,

du überprüfst in den beiden while Schleifen while (tmp[x] == ON)
weiter die Daten der Liniensensoren auf Änderung. Diese können sich aber nicht ändern, wenn du nicht auch innerhalb der while Schleifen die Fotosensoren abfragst, mit der Funktion LineData(data).

Gruß m.ar.v.i.n

damaltor
18.12.2006, 21:30
jo genau das habe ich auch gerade gesehn. versuch mal, LineData(data) mit in der schleife laufen zu lassen.

wenn der zweitee fototransistor dann "dunkel" findet, muss der asuro genau eine asurolänge vorwärts fahren, und sich dann mit beiden rädern recht gleichmäßig drehen.

leider geht das dann nur, wenn die linie gerade ist, weil der "gefundene" punkt dann unter dem asuro-hintern liegt und die schnauze nict unbedingt mehr auf der linie liegt, wenn diese krumm ist.

Marit
19.12.2006, 16:35
Linienverfolgung ist es ja nicht. er soll ja am Ende grade auf der Strecke stehen damit man Linienverfolgung ausführen kann (das Programm is auch bissl einfacher :) ).


Danke für den Tip mit LineData werde es gleich ausprobieren. Ich frage ja nur die alten Werte nach nicht neue :D . Hab ich garnicht gemerkt. Dann dürfte es eigentlich wirklich klappen.

damaltor
19.12.2006, 21:01
oder du lässt ihn einfach losfahren und lässt dann das linienFOLGER programm laufen. mit ein bissl glück findet er die linie und "rastet darauf ein" und fährt ihr nach.

Marit
20.12.2006, 13:47
Die Wahrscheinlichkeit dass der Asuro die Linie findet ist mir aber zu gering. und wenn er in einem ~90° Winkel auf die Linie zukommt wird er sicherlich nicht auf der Linie weiterfahren.
Habe nun mal LineData mit eingebaut. Auch dass sich die StatusLED farbe ändert. Aber noch nichteinmal die Farbe ändert sich.


#include "asuro.h"
#include "math.h"

int main(void)
{
double const a=1.5;
double time;
double tan;
double time1;
double time2;
double v;
int arc;
int x;
double arc2;
unsigned int data[2];
unsigned char tmp[2] = {OFF,OFF};
Init();
while(1)
{
MotorDir(FWD,FWD);
MotorSpeed(120,120);
v = 120/818;
LineData(data);
if (data[0] > 400) {
tmp[0] = ON;
time1 = Gettime();
StatusLED(RED);
}
else{}
if (data[1] > 400) {
tmp[1] = ON;
time1 = Gettime();
StatusLED(RED);
}
else{}

while(tmp[0]==ON)
{
LineData(data);
if (data[1] > 400)
tmp[1] = ON;
else{}
if(tmp[1]==ON)
{ StatusLED(YELLOW);
time2 = Gettime();
time = (time2 - time1)/1000;
tan=a/(v*time);
arc2 = atan(tan) * 180 / M_PIl;
arc = (int)arc2;
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
Turn (arc, v);
tmp[1] = OFF;
tmp[0] = OFF;
}
else{}
}
while(tmp[1]==ON)
{
LineData(data);
if (data[0] > 400)
tmp[0] = ON;
else{}
if(tmp[0]==ON)
{ StatusLED(YELLOW);
time2 = Gettime();
time = (time2 - time1)/1000;
tmp[1]==OFF;
tan=a/(v*time);
arc2 = atan(tan) * 180 / M_PIl;
arc = (int)arc2;
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
Turn (arc, v);
tmp[1] = OFF;
tmp[0] = OFF;
}
else{}
}
}

return 0;
}

Downad
20.12.2006, 16:25
hast du dir die werte von linedata mal ausgeben lassen?

kommen die überhaupt über 400?

damaltor
20.12.2006, 18:13
also 400 ist eigentlich ein recht mittlerer wert... allerdings ist der wert für ganz HELL 1023, der wert für ganz DUNKEL ist 0 (idealerweise). aber wenn ich das recht sehe, dann vergleichst du in deinem programm doch ob der wert über 400 ist, also ob es heller als 400 ist. sollte das evtl mal umgekehrt sein?

versuch mal, dir die linedata werte ausgeben zu lassen, dann hast du ungefähr ein verhältnis dazu welcher vergleichswert der richtige sein könnte

Marit
22.12.2006, 12:47
sehr gute beobachtung :D Hab das ausm selftest und ich hab gedacht der schaut dabei nach obs schwarz ist, wäre aufjedenfall eine gute erklärung, da der roboter bisher ja noch garnichts gemacht hat. werds nachher mal ausprobieren.

Marit
23.12.2006, 15:02
Ne die müssen doch umgedreht sein, wenn ich nämlich die phototransistoren gegens licht halte dann wird die StatusLED rot. Auf einem weißen blatt wurde sie sofort gelb. Hm...ich weiß net mehr weiter :(

damaltor
23.12.2006, 16:49
weisses blatt papier und licht sollten eigentlich den gleichen effekt haben. was passiert bei schwarzem papier bzw. abgedunkeltem raum?

das prinzip ist das folgende: je mehr licht auf die fototransistoren fällt (bzw vom weissen papier reflektiert wird) desto mehr strom kann durchfliessen. je mehr strom durchfliesst, desto höher ist der messwert, den der ADC des prozessors zurückgibt. und je höher der messwert, desto höher ist die zahl, die die funktion LineData() zurückgibt bzw in der variable speichert.

Marit
24.12.2006, 14:52
jap ich weiß. aber das is iwi komisch, das weiße blatt is eigentlich noch hell genug gewesen als ich das gemacht hab, also von den lampen her, ina luft hat er noch die rote lampe angezeigt, obwohl sie eigentlich sofort auf gelb hätte schalten sollen, war iwi verwirrend ^^.

damaltor
24.12.2006, 19:56
auch in der luft bekommen die fototransistoren licht ab. dunkel sie mal komplett ab, und schau was dann passiert. oder leuchte sie extrem an (schreibtischlampe) und schau was dann passiert.

Paritybit
28.12.2006, 00:00
versuch es mal mit dem Quelltext, diesen habe ich geschrieben.
Der Asuro reagiert auf das Licht, macht sich also in einem etwas dunklem Raum und einer Taschenlampe.

einfach mal ausprobieren. :-)

Achja, mein Asuro hat ein kleines Problem FWD ist bei dem RWD und umgekehrt....


#include "asuro.h"

int main(void)
{
unsigned int data[2];
unsigned char tastea;
unsigned char tasteb;
Init();
int i;
StatusLED(GREEN);
FrontLED(OFF);
MotorDir(RWD,RWD);
while(1)
{
tastea = PollSwitch();
Sleep(216);
tasteb = PollSwitch();
if (tastea == tasteb)
{
if (tasteb > 0)
{
MotorDir(FWD,FWD);
MotorSpeed(100,100);
StatusLED(RED);
for(i=0;i<=650;i++)
{
Sleep(216);
}
}
else
{
MotorDir(RWD,RWD);
LineData(data);
StatusLED(GREEN);
if(data[1] > data[0])
{
MotorSpeed(200,100);
BackLED(ON,OFF);
}
else
{
BackLED(OFF,ON);
MotorSpeed(100,200);
}
}
}

}
return 0;
}

damaltor
28.12.2006, 10:51
dieses problem haben fast alle neuen asuros. das solltest du umlöten, denn sonst laufen deine programme nicht auf fremden asuros und umgekehrt.

das scheint leider ein konstruktionsfehler von arexx zu sein.