PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Geradeaus fahren mit Kollisionserkennung



the~©€¥
18.07.2007, 16:10
Guten Tag!
wie man unschwer erkennen kann bin ich neu hier. wir haben den asuro als projekt gerade in der schule. ich habe zwar ahnung von c programmieren und einen atmega8 kann ich auch programiernen, aber der asuro bereitet mir echt schwierigkeiten. vllt. kann mir hier jmd. helfen.

ich möchte dass der asuro geradeaus fährt und bei kollisionen umdreht. dafür hab ich schon im forum gesucht, doch nix pasendes gefunden.


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


int main(void)
{
unsigned char speed, flagl = TRUE, flagr = FALSE, stop = FALSE;
unsigned int data[2];
int wegl, wegr, diff;
int speedLeft, speedRight;
int taste = 0, taste1 = 0, taste2 = 0;

Init();

MotorDir(FWD,FWD);

do
{
StatusLED(GREEN);

speed = 200;
speedLeft = speedRight = speed;

wegl=0; wegr=0;

do
{
OdometrieData(data);

if ((data[0] < 550) && (flagl == TRUE)) {flagl = FALSE; wegl++;}
if ((data[0] > 650) && (flagl == FALSE)) {flagl = TRUE; wegl++;}
if ((data[1] < 550) && (flagr == TRUE)) {flagr = FALSE; wegr++;}
if ((data[1] > 650) && (flagr == FALSE)) {flagr = TRUE; wegr++;}

diff=wegr-wegl;

if (diff>0) speedRight--;

else if (diff<0) speedLeft--;

else {speedRight=speed; speedLeft=speed;}

if (speedRight<0) {speedRight=0;}

if (speedLeft<0) {speedLeft=0;}

MotorSpeed(speedLeft,speedRight);

taste = PollSwitch();
//taste1 = PollSwitch();
//taste2 = PollSwitch();

if (taste > 0) {stop = TRUE;}
}
while(stop == FALSE);

Hindernis(taste, speedLeft, speedRight);
}
while(1);
}


void Hindernis (int TASTER, int RIGHT, int LEFT);

void Hindernis (int TASTER, int RIGHT, int LEFT)
{
if (TASTER >= 8) {BackLED(ON,OFF);}
else {BackLED(OFF,ON);}

StatusLED(YELLOW);

MotorDir(RWD,RWD);

MSleep(250);

if (TASTER >= 8) {MotorDir(FWD,RWD); MotorSpeed(255,128); MSleep(600);}
else {MotorDir(RWD,FWD); MotorSpeed(255,128); MSleep(600);}

MotorSpeed(0,0);

MSleep(50);

StatusLED(GREEN);

MotorDir(FWD,FWD);

MotorSpeed(LEFT,RIGHT);
}

mein prob ist einfach, dass er nur das macht, wenn eine taste gedrückt ist. und nicht den rest.

hoffe mir kann jmd. helfen.

the~©€¥

Sternthaler
18.07.2007, 19:55
Hallo the~©€¥, (Ist kein schöner Name zum tippen, trotzdem aber auf alle Fälle ein herzliches willkommen hier im Forum)
Dein Problem lößt sich ganz einfach, wenn man weiss wie schnell der 'kleine atmega8" eigendlich tatsächlich ist.

In deiner main()-Loop holst du dir die Odometrie-Werte zum geradeausfahren. Das ist OK.
Nun berechnest du die Differenz der Zählerstände. Das ist auch OK.
Aber du reduziert immer die Geschwindigkeit für den Motor zur Korrektur.
--> Das geht so schnell, dass die Motoren 'sofort' stehen bleiben.
Genau hier musst du dir etwas anderes einfallen lassen.

P.S.: Zu dem Problem gibt es aber Lösungen im Forum ;-)
Versuche es erst einmal selbst, und wenn es dann weiterhin nicht klappt kannst du natürlich weiterfragen.

harry3
11.08.2007, 00:29
Ich hab heute meinen Gerade - Ausfahren - Regler überarbeitet.

Zum Beispiel sollte man die reine Differenz von dem linken und rechten Weg nicht als Reglereingang hernehmen, da es zu einem stetigen Schwingen führt(Asuro 'wackelt' also hin und her anstatt geradeaus zu fahren).

Besser ist da den Weg(es handelt sich um eine Integral - Strecke), immer zu "dämpfen". Also zuerst für die Regelung verwenden, und dann dämpfen:

e=counter_l-counter_r;
counter_l=counter_l*G_I_FAKTOR; //Der I Faktor sollte so etwa den Wert 0.5 haben
counter_r=counter_r*G_I_FAKTOR;

Weiters solltest du zwar dauernd messen, aber nur alle 100ms dann die Regelabweichung usw... berechnen und dann die Motoren ansteuern. So wie du es hast werden die Motoren blitzschnell runtergeregelt und somit steht Asuro.

Da du mit der Odometrie ja den zurückgelegten Weg misst, hast du bereits einen I Anteil(genauer gesagt einen "vergesslichen" I Anteil weil du ja die Werte dämpfst) und es reicht ein einfacher P Regler(also einfach Regelabweichung*Faktor) aus um gute Resultate zu erzielen.

Grüße,
Harri