PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme mit einfacher Linenverfolgung!



RuKi000
15.04.2009, 20:09
hallo,

besitze nur die c++ kenntnisse die im asuro handbuch vermittelt werden und wollte jetzt mit meinen ersten kleinen programm anfangen.

der roboter soll einfach einer line folgen und dann bei kollision nur rückwärts fahren!

Das wäre mein Progamm dafür:

#include "asuro.h"

int main(void)
{
unsigned int data[2];
Init ();
FrontLED(ON);
MotorDir(FWD,FWD);
while (PollSwitch()==0)

{

LineData(data);

if (data[0]>data[1])
{MotorSpeed(120,80);}

else

{MotorSpeed(80,120);}

}


MotorDir(RWD,RWD);
MotorSpeed(80,80);

while (1)

return 0;
}

mein problem ist jetzt, dass der Robotr einfach nach einer beliebigen strecke (ist immer unterschiedlich - mal kurz nach einschalten oder erst nach 50 cm strecke) stehenbleibt und dann das rückwärtsprogramm einschaltet!

würde mich freuen, wenn mir jemand helfen kann!

mfg ruki

orusa
15.04.2009, 22:12
Hallo ruki,
die Bedingung "while (PollSwitch()==0)" ist zwar theoretisch richtig, aber praktisch funktioniert die Funktion PollSwitch() beim Asuro leider nicht zuverlässig. Besonders bei laufenden Motoren kann die auch mal einen Wert !=0 liefern, ohne, dass irgend ein Taster gedrückt wurde.
Um die Abfrage zuverlässiger zu machen, solltest du PollSwitch() mehrfach hintereinander abfragen und nur dann darauf reagieren, wenn sich die Werte nicht unterscheiden.
Also z.B.:


int t1=0;
while(1)
{
t1= PollSwitch();
if (PollSwitch()==0 && t1==0)
{
//mach was
} else {
//mach was anderes
}
}

RuKi000
16.04.2009, 18:14
danke für die schnelle antwort!
ich habe jetzt versucht das in mein programm einzubauen aber jetzt fährt der asuro garnicht mehr los... ich denke das der fehler irgendwie mit den if-zuweißungen zusamenhängt...


#include "asuro.h"

int main(void)
{
unsigned int data[2];
int t1=0;
Init ();
FrontLED(ON);
MotorDir(FWD,FWD);
while (1)
t1= PollSwitch();
if (PollSwitch()==0 && t1==0)

{

LineData(data);

if (data[0]>data[1])
{MotorSpeed(120,80);}

else

{MotorSpeed(80,120);}

}


MotorDir(RWD,RWD);
MotorSpeed(80,80);

while (1)

return 0;
}

radbruch
16.04.2009, 18:42
Hallo

Die Überprüfung der Tasten muss umfangreicher sein. Bei eurem Ansatz


int t1=0;
while(1)
{
t1= PollSwitch();
if (PollSwitch()==0 && t1==0)
{
//mach was
} else {
//mach was anderes
}
}
wird eine Ungleichheit als Tastendruck interpretiert. Besser wäre vielleicht so:

#include "asuro.h"

int main(void)
{
unsigned int data[2];
int t1; // braucht nicht mit 0 vorbelegt zu werden
int t2;

Init();
FrontLED(ON);
MotorDir(FWD,FWD);

while (1) // Hauptschleife
{
t1= PollSwitch();
t2= PollSwitch();

if(t1==t2) //nur wenn beide Tastenwerte gleich sind ist t1 gültig!
{
if (t1==0)
{
LineData(data);

if (data[0]>data[1])
{MotorSpeed(120,80);}
else
{MotorSpeed(80,120);}

} // if(t1==0)
else
{
MotorDir(RWD,RWD);
MotorSpeed(80,80);
} // else von if(t1==0)

} // if(t1==t2)

} //while(1)

return 0; // diese Zeile wird nie erreicht
}(nicht getestet weil mein asuro eingemottet ist)

Die Struktur und der Ablauf eines Programms wird deutlicher wenn man mit Einrückungen und Kommentaren arbeitet.

Gruß

mic

RuKi000
16.04.2009, 20:18
hallo,

vielen dank für den programm code! :) der funktioniert einwandfrei!

ich hätte da aber noch eine frage.. und zwar is mir unklar warum der roboter nach einer kollision im "rückwärtsgang" bleibt!

befindet sich durch while(1) sich zuerst die Linienverfolgung in einer endlosschleife und wenn dann der zustand geändert wird (durch die taster) ist der andere programmteil in einer endlosschleife?!

ich möchte nämlich das programm so verändern, dass asuro nach der kollision

-erst ein stück rückwärts fährt (oder gleich dreht)
-drehen
- und dann wieder geradeaus bis zum nächsten hindernis

und das dann in einer endlosschleife!

danke schön

ruki

radbruch
16.04.2009, 21:35
Hallo

Bei jedem while-Schleifendurchgang wird über den Tasterstatus entschieden ob der Linienfolge- oder der Zurückfahrzweig durchlaufen wird. Das er im Rückwärtsgang bleibt hätte ich nicht erwartet, ich dachte, er stößt mehrfach nacheinander gegen das Hinderniss weil beim Rückwärtsfahren die Taster wieder frei werden und sich der Ablauf dann wiederholt. Was passiert wenn du den asuro in der Hand hälst und die Tasten drückst? Vielleicht entstehen im Rückwartsgang mehr Störungen durch die niedrige MotorSpeed()? 80 erscheint mir sehr niedrig. Bringt eine zusätzliche PollSwitch()-Abfrage eine Änderung:

int t1, t2, t3;
...
t1= PollSwitch();
t2= PollSwitch();
t3= PollSwitch();

if(t1==t2 && t1==t3)...

Um beim Zurückfahren weiter als der Tastenhub zu kommen brauchst du eine Zeitverzögerung:


...
int i; // Zählvariable
...
else
{
MotorDir(BREAK,BREAK); // Bremsen und 0,1 Sek. warten bis Stillstand
for(i=0; i<100; i++) Sleep(72); // Sleep(72) dauert 1/1000 Sekunde

MotorDir(RWD,RWD); // Eine Sekunde Zurücksetzen
MotorSpeed(80,80);
for(i=0; i<1000; i++) Sleep(72);

MotorDir(BREAK,BREAK); // Bremsen und 0,1 Sek. warten
for(i=0; i<100; i++) Sleep(72);
} // else von if(t1==0)

...


Häufige Kollisionen sind nicht gesund für den asuro. Wenn er beim Rückwärtsfahren dreht wird er die Linie verlieren?

Gruß

mic

RuKi000
16.04.2009, 22:02
danke deine antwort!!

also ich hab jetzt den MotorSpeed erhöht (auf 200/150) und die pollswitch-abfragen bis auf t4 erweitert.

der roboter verhält sich noch genauso... wenn ein taster 1 wird, fährt er rückwärts. auch wenn der taster wieder 0 ist. ich habe in meinen programm noch zusätzlich die backleds eingeschaltet

else
{
BackLED(ON,ON);
StatusLED(RED);
MotorDir(RWD,RWD);
MotorSpeed(150,150);


diese bleiben auch an!

mit den rest werde ich mich morgen auseinandersetzen.


mfg

orusa
17.04.2009, 18:54
Der Fehler in diesem Programm dürfte wohl darin liegen, dass die Fahrtrichtung nur einmal, vor der while- Schleife auf Vorwärts gesetzt wird:
MotorDir(FWD,FWD);

Sobald man nun einmal einen Taster drückt, wird auf Rückwärtsfahrt umgeschaltet:
MotorDir(RWD,RWD);

Diese Richtung bleibt dann aber für immer, weil sie nie mehr auf Vorwärtsfahrt umgeschaltet wird.

Also müsste man hier noch was einfügen:


.
.
.
if (t1==0)
{
LineData(data);
MotorDir(FWD,FWD); // <==== diese Zeile muss rein
if (data[0]>data[1])
{MotorSpeed(120,80);}
else
{MotorSpeed(80,120);}

} // if
.
.
.


Gruß
Günther

radbruch
17.04.2009, 19:08
Der Fehler in diesem Programm dürfte wohl darin liegen, dass die Fahrtrichtung nur einmal, vor der while- Schleife auf Vorwärts gesetzt wirdKlasse, manchmal sieht man eben die einfachsten Fehler nicht. Danke.

Gruß

mic

orusa
17.04.2009, 20:47
@radbruch:
Mach Dir nichts draus. Passiert mir auch oft, dass ich in meinem eigenen Code ewig lange nach einem Fehler suche, der so offensichtlich ist, dass man ihn eigentlich sofort finden müsste. Manchmal hat man halt einfach Tomaten auf den Augen.

Gruß
Günther