PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ASURO Kollision



Hamlet83
22.05.2010, 13:29
Hallo zusammen,

ich sitze gerade an meinem Asuro und möchte ihm beibringen, dass wenn er auf ein Hinderniss trifft diesem ausweicht.

Kurze Programmbeschreibung.
Wird der Asuro eingeschalten, fährt er gerade aus.
Werden Taster betätigt, soll er zuerst zurück fahren und dann in die jeweilige richtung rückwärts einbiegen und dann vorwärts fahren, bis irgendein anderer Taster gedrückt wird.

Z.B.==> Wurde ein rechten Taster betätigt, dann zuerst rückwärtsfahrt und dann rückwärts nach rechts wegbiegen.Anschließend vorwärts fahren,
bis erneut irgendein Taster betätigt.

Bin auch schon gut davor, habe aber immer noch zwei Probleme.
Folgendes tritt auf:

1.Schalte ich ihn ein fährt er sofort rückwärts und fährt dann erst vorwärts
bzw. es ist dann erst die Kollisionsabfrage möglich.

2.Wenn er fährt und es wird einTaster betätigt, dann macht er genau das was er laut Programmcode auch machen soll. ABER manchmal fährt er dann 2x rückwärts bzw. dreht sich 2x.

Woran liegt das?????


Wäre toll, wenn Ihr mir helfen könntet.



Danke schonmal im vorraus Hamlet83.


Hier mal mein Programmcode.


int main (void)
{

unsigned char t1, t2;
int i;

Init();

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

if((t1 == 0) && (t2 == 0)) /* keine Taste */
{
MotorFwd(); /* vorwärts fahren */
FrontLED(ON);
BackLED(OFF,OFF);
}
else

if (t1 && (t1 == t2)) /*irgendeine Taste gedrückt*/
{
MotorStop();

if (t1 & 0x07) /* Tasten links gedrückt? */
{
MotorRwd(); /* Rückwärtsfahren */
BackLED(ON,ON);
StatusLED(RED);

for (i=0;i<400;i++) // for - Schleife 400 mal
{Sleep(255);} //durchlaufen, ~ 3 ms Sleep- //Funktion
MotorRwdL(); /* Rückwärtskurve links fahren */
BackLED(ON,OFF);
StatusLED(RED);

for (i=0;i<100;i++) // for - Schleife 100 mal
{Sleep(255);} //durchlaufen, ~ 3 ms Sleep-
//Funktion
}

if (t2 & 0x38) /* Tasten rechts gedrückt? */
{
MotorRwd(); /* Rückwärtsfahren */
BackLED(ON,ON);
StatusLED(RED);

for (i=0;i<400;i++) // for - Schleife 400 mal
{Sleep(255);} //durchlaufen, ~ 3 ms Sleep-
//Funktion
MotorRwdR(); /* Rückwärtskurve rechts fahren */
BackLED(OFF,ON);
StatusLED(RED);

for (i=0;i<100;i++) // for - Schleife 100 mal
{Sleep(255);} //durchlaufen, ~ 3 ms Sleep-
//Funktion
}
}
}
return 0;
}

Skroete
22.05.2010, 19:13
Hallo Hamlet,

das Programm wurde wirklich fehlerfrei übersetzt???
Es sind die Kleinigkeiten, die uns stolpern lassen. O:)


Hier der Code mit 2 Anmerkungen.



int main (void)
{

unsigned char t1, t2;
int i;

Init();

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

if((t1 == 0) && (t2 == 0)) /* keine Taste */
{
MotorFwd(); /* vorwärts fahren */
FrontLED(ON);
BackLED(OFF,OFF);
}
else
//Heisser Tip : Fehlt hier nicht was
if (t1 && (t1 == t2)) /*irgendeine Taste gedrückt*/
{
MotorStop();

if (t1 & 0x07) /* Tasten links gedrückt? */
{
MotorRwd(); /* Rückwärtsfahren */
BackLED(ON,ON);
StatusLED(RED);

for (i=0;i<400;i++) // for - Schleife 400 mal
{Sleep(255);} //durchlaufen, ~ 3 ms Sleep- //Funktion
MotorRwdL(); /* Rückwärtskurve links fahren */
BackLED(ON,OFF);
StatusLED(RED);

for (i=0;i<100;i++) // for - Schleife 100 mal
{Sleep(255);} //durchlaufen, ~ 3 ms Sleep-
//Funktion
}

if (t2 & 0x38) /* Tasten rechts gedrückt? */
{
MotorRwd(); /* Rückwärtsfahren */
BackLED(ON,ON);
StatusLED(RED);

for (i=0;i<400;i++) // for - Schleife 400 mal
{Sleep(255);} //durchlaufen, ~ 3 ms Sleep-
//Funktion
MotorRwdR(); /* Rückwärtskurve rechts fahren */
BackLED(OFF,ON);
StatusLED(RED);

for (i=0;i<100;i++) // for - Schleife 100 mal
{Sleep(255);} //durchlaufen, ~ 3 ms Sleep-
//Funktion
}
}
//Heisser Tip : Fehlt hier nicht was
}
return 0;
}


Wenn die Unterprogramme MotorFwd,MotorRwd... in Ordnung sind solltest du es damit zum Laufen bringen

lg
Skroete

Hamlet83
22.05.2010, 20:25
Guten abend Skroete,

erstmal danke für Deine Antwort und Deinen Hinweisen.
Ja das Programm wurde komplett fehlerfrei übersetzt (auch ohne Warnungen).
Fals Du bei den von Dir angegebenen Stellen meinst, dass dort Klammern fehlen,muss ich Dich leider enttäuschen.Dies ist nicht der Fall.
Die Probleme treten trotzdem auf.

In den Unterfunktionen steht lediglich die Drehrichtung der Motoren und deren Geschwindigkeit.
z.B.

void MotorRwdL (void)
{
MotorDir(RWD,FWD);
MotorSpeed(150,200);
}

Meiner Meinung nach hängt das Programm teilweise in der dritten und vierten if Anweisung. Komischerweise, jedesmal wen ich meinen Asuro anschalte, fährt er als erstes rückwärts.


Ich bin total am verzweifeln.


Liebe Grüße Hamlet83.

Thund3r
23.05.2010, 01:57
Hallo

Ein viel besprochenes Problem ist dass die Taster beim Asuro nicht besonders zuverlässig sind. Aufgrund mehrerer Faktoren wird manchmal ein Wert ungleich 0 zurückgegeben obwohl nichts gedrückt wurde.

Um dies vorzubeugen gibt es mehrere Möglichkeiten wie mehrfache Abfragen:


...
int T,T1,T2;
T=PollSwitch();
T1=PollSwitch();
T2=PollSwitch();
if (T==0||T1==0||T2==0) { ... }
...

oder indem du einfach auf einen Taster verzichtest und sagst


...
if (Taster<2) { ... }
...

oder etwas ausgefallener:


...
while(1) {
StatusLED(GREEN);
MotorDir(FWD,FWD);
MotorSpeed(150,150);
while((PollSwitch()==0) || (PollSwitch()==0) || (PollSwitch()==0));

...

}
...


Gruß Thund3r

Hamlet83
23.05.2010, 10:17
Hallo Thund3r,

danke für deine Antwort.
Habe eine Deiner Möglichkeiten in das Programm eingebaut und es funktioniert einwandfrei.
Danke dafür. =D>


Habe nun aber noch eine andere Frage.
Wenn ich zwei Programme zusammen fügen möchte, wie kann ich das denn am besten realisieren.

Wäre hier eine do while Schleife von Vorteil, oder auch wieder eine if else Abfrage, oder etwas ganz anderes??
Habe es mal mit einer do while Schleife versucht.
Bekomme es aber irgendwie nicht so ganz hin.
Der Asuro macht dann irgendwas, bloß nicht das was er soll.

Danke schonmal im vorraus für die Antworten.


Hamlet83.

Thund3r
23.05.2010, 11:00
Hallo

Das kommt ganz auf die Programme an.
Sollen die Programme zeitgleiche ablaufen, das eine in das andere übergehen oder das 2te erst nach beenden des 1ten aufgerufen werden?

Ein Quellcode würde die Sache auch vereinfachen ;)

Gruß Thund3r

Hamlet83
23.05.2010, 11:40
Hallo Thund3r,

ich habe ein Kollisions und Linienprogramm seperat erstellt.
Diese beiden möchte ich nun zusammen bringen.

Hier der Quellcode.


unsigned int data[2];
unsigned char t, t1, t2;
int i;

int main (void)
{
Init();
do
{
MotorFwd();
FrontLED(ON);
BackLED(OFF,OFF);
StatusLED(GREEN);

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

LineData(data);

if (t1 == 0 && t2 == 0)
{
if ((data [0] > 50) || (data [1] > 50 ))
{
if ((data [0] < 32) && (data [1] > 32 ))
{
MotorDir(RWD,FWD);
MotorSpeed(0,160);
BackLED(OFF,ON);
StatusLED(RED);
}
if ((data [1] < 32) && (data [0] > 32 ))
{
MotorDir(FWD,RWD);
MotorSpeed(160,0);
BackLED(ON,OFF);
StatusLED(RED);
}
if ((data [1] < 32) && (data [0] < 32 ))
{
MotorFwd();
BackLED(ON,ON);
StatusLED(GREEN);
}
}
else
MotorFwd();
BackLED(ON,ON);
StatusLED(GREEN);
}
else
while(1)
{
t = PollSwitch();
t1 = PollSwitch();
t2 = PollSwitch();
if(t==0 || t1==0 || t2==0)
{
MotorFwd(); FrontLED(ON);
BackLED(OFF,OFF);
}
else
{
if (t && t1 && (t == t1) && (t1 == t2) && (t == t2))
{
MotorStop();
if (t1 & 0x07)
{
MotorRwd();
BackLED(ON,ON);
StatusLED(RED);
for (i=0;i<400;i++){Sleep(255);}
MotorRwdL();
BackLED(ON,OFF);
StatusLED(RED);
for (i=0;i<100;i++){Sleep(255);}
}
if (t2 & 0x38)
{
MotorRwd();
BackLED(ON,ON);
StatusLED(RED);
for (i=0;i<400;i++)
{Sleep(255);}
MotorRwdR();
BackLED(OFF,ON);
StatusLED(RED);
for (i=0;i<100;i++)
{Sleep(255);}
}
}
}
break;
}
}
}
while ((data [0] > 50) && (data [1] > 50 ));
for (i=0;i<100;i++){Sleep(255);}
return 0;
}


Gruß Hamlet83

Hamlet83
23.05.2010, 13:13
Hallo Thund3r,

ich vergaß Dir mitzuteilen, wie die Programme ablaufen sollen.
Wenn der ASURO eine Linie gefunden hat, soll er diese abfahren.
Wenn er auf ein Hinderniss trifft, soll er diesem ausweichen.

Die Programme mussten eigentlich parallel (Zeitgleich) abrufbar sein, weil der Asuro ja nicht weiß was zuerst kommt.


Ich hoffe Du kannst mir da weiter helfen.


Hamlet83.

Thund3r
24.05.2010, 01:11
Hallo

Auf Anhieb fallen mir hier einige Sachen auf die sehr problematisch sind:
Du benutzt eine do Schleife in der eine while(1) benutzt wird in der wiederum eine while(1) benutzt wird.
while(1) ist eine Endlosschleife heißt das drumherum kannst du dir sparen da die while(1) nie beendet wird.
Unabhängig von dem und einigen anderen Sachen verstehe ich nicht ganz wie dein Programm ablaufen soll.
Soll er die Linie suchen und während er die Linie sucht Hindernissen ausweichen oder soll er erst wenn er die Linie gefunden hat Hindernissen die sich auf der Linie befinden ausweichen?

Gruß Thund3r

Hamlet83
24.05.2010, 09:28
Hallo Thund3r,

die 2 while(1) Schleifen habe ich zu einer gemacht und die do while Schleife habe ich entfernt. Dachte ich müsste diese in jedem Programmteil (Linie und Kollision) einfügen.
Danke für die Hinweise, funktioniert auch nun schon recht gut, bis auf ein paar kleine Macken.

Folgende kleine Macke hat er noch:
Die Linie erkennt er jetzt nur noch, wenn er in einem besonders spitzen Winkel drüber fährt.
Fährt er z.B. 90 Grad über die Linie, fährt er einfach weiter.

Funktion Programm:

Soll er die Linie suchen und während er die Linie sucht Hindernissen ausweichen oder soll er erst wenn er die Linie gefunden hat Hindernissen die sich auf der Linie befinden ausweichen?


Er soll während er die Linie sucht Hindernissen ausweichen, es wäre aber auch schön, wenn er gleichzeitig noch Hindernissen auf der Strecke ausweichen würde. Letzteres muss aber nicht unbedingt sein.


Danke für Deine Hilfe

Hamlet83

Hamlet83
24.05.2010, 15:01
Hallo Leute,

sitze nun schon seit einigen Stunden an dem Programm, bekomme es aber absolut nicht auf die Kette, dass der Asuro der Linie folgt.
Was mach ich nur falsch?? :roll:


Brauche dringendst Hilfe.

Hamlet83



Ach so der veränderte Quellcode.

int main (void)
{
Init();
while (1)
{
t = PollSwitch();
t1 = PollSwitch();
t2 = PollSwitch();
LineData(data);
MotorFwd();
FrontLED(ON);
BackLED(OFF,OFF);
StatusLED(GREEN);
if (t==0 || t1==0 || t2==0)
{
if ((data [0] > 50) || (data [1] > 50 ))
{
if ((data [0] < 32) && (data [1] > 32 ))
{
MotorDir(RWD,FWD);
MotorSpeed(0,160);
BackLED(OFF,ON);
StatusLED(RED);
}
if ((data [1] < 32) && (data [0] > 32 ))
{
MotorDir(FWD,RWD);
MotorSpeed(160,0);
BackLED(ON,OFF);
StatusLED(RED);
}
if ((data [1] < 32) && (data [0] < 32 ))
{
MotorFwd();
BackLED(ON,ON);
StatusLED(GREEN);
}
}
else
MotorFwd();
BackLED(ON,ON);
StatusLED(GREEN);
}
else
{
if (t && t1 && (t == t1) && (t1 == t2) && (t == t2))
{
MotorStop();
if (t1 & 0x07)
{
MotorRwd();
BackLED(ON,ON);
StatusLED(RED);
for (i=0;i<400;i++)
{Sleep(255);}
MotorRwdL();
BackLED(ON,OFF);
StatusLED(RED
for (i=0;i<100;i++)
{Sleep(255);}
}
if (t2 & 0x38)
{
MotorRwd();
BackLED(ON,ON);
StatusLED(RED);
for (i=0;i<400;i++)
{Sleep(255);}
MotorRwdR();
BackLED(OFF,ON);
StatusLED(RED);
for (i=0;i<100;i++)
{Sleep(255);}
}
}
}
}
return 0;
}


Hamlet 83

Valen
24.05.2010, 19:25
Was fehlt? Der linie entlang gehen oder ausweichen?

Hamlet83
24.05.2010, 22:38
Hallo Valen,

es fehlt die Linienerkennung.
Er erkennt diese nur, wenn er in einem besonders spitzen Winkel drüber fährt, oder ich ihn direkt drauf setze.
Fährt er z.B. 90 Grad über die Linie, fährt er einfach weiter, aber die Back LEDs leuchten kurz beim drüber fahren auf. Er steuert also nicht nach links bzw. nach rechts, um der Linie zu folgen.

Das Linienprogramm hat seperat tadellos funktioniert.
Der fehler tritt nur bei dem Quellcode auf, wo beide Programme enthalten sind.


Danke für die Unterstützung

Hamlet83

Thund3r
25.05.2010, 00:25
Hallo

Vielleicht liegt es daran dass es keine Option gibt wenn data[1] UND data[1] einen Wert über 32 liefern. Es gibt nur die Möglichkeit wenn

if ((data [1] < 32) && (data [0] < 32 ))

oder


if ((data [1] < 32) && (data [0] > 32 ))

erfolgt.

Trifft der Asuro aber zB orthogonal auf die Linie sind beide data über 50 also leuchtet die BackLED kurz aber auch beide größer als 32 also trifft keine "if" ein und der Linienteil wird übersprungen.

Gruß Thund3r

Hamlet83
25.05.2010, 07:22
Hallo Thund3r,

werde Deinen Vorschlag mal einbauen.
Das ist sehr gut möglich, dass es daran liegt.




Hamlet83

Hamlet83
25.05.2010, 16:12
Hallo,

an der Abfrage data[1] UND data[0] liegt es nicht, habe mehrere Varianten
ausprobiert. Habe auch die if ((data[0]>50)&&(data[1]>50)) und die zugehörige else Anweisung entfernt, da sie in dem komplett Programm keine großen Auswirkungen hat
(habe ich getestet). Diese wird aber in dem einzelnen Linienprogramm benötigt.

Was mich aber eigentlich so ratlos macht ist, dass das einzelne Linienprogramm so wie es in dem eingebundenen Quelltext steht, tadellos funktioniert.

Habe ich die beiden Programme eventuell falsch zusammen gefügt??


HILFE!!! [-o<


Hamlet83

SirWesley
12.12.2010, 21:19
Hallo Hamlet83,
hast du eine Lösung für Dein Problem gefunden, oder hast du aufgegeben?

grüsse
Michael