PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu Odometrie



C-H-T
24.03.2009, 00:31
Hallo werte Community,
habe mir ein Programm geschrieben was Kollision per Taster erkennt, ausweicht usw. und noch auf dunkle Flächen achtet und diese meidet (Tischkante oder Klebeband). Das Funktioniert alles perfekt, auch durch ein kleines Labyrinth kommt mein Asuro durch.
Nun passiert es aber mal das er irgendwo hängen bleibt wo gerade kein Taster ist, daher wollte ich nebenbei noch die Odometrie abfragen ob der Asuro sich bewegt, falls nicht Rückwärtsgang rein und umfahren.
Da gibts jetzt das Problem das er selten erkennt das er sich bewegt.. im großen und ganzen fährt mein Asuro nur rückwärts und lenkt kurz nach links ](*,) hab dann noch ein wenig optimiert und er ist paar Sekunden gerade aus gefahren und dann wieder in seine Rückwärts fahren Schleife gekommen obwohl er da ja nix drinnen zu suchen hat wenn er fährt ^^..

Hat da jemand eine Idee wie ich das parallel laufen lassen kann? weil selbst wenn ich die Fehler beim auslesen oder was auch immer da schief läuft beseitige würde der wahrscheinlich bei Kollision wieder reinkommen da der Asuro nicht schnell genug dagegen kracht Rückwärts fährt und umlenkt ohne das meine Odometrie Abfrage dazwischen kommt und meint Asuro steht .. fährt er also unendlich Rückwärts im Kreis..

Also im Prinzip sollte er wenn normal fahren und sobald er zB 2 Sekunden sich nicht von der Stelle bewegt eine Aktion ausführen.

Hab jetzt vor Frust mein Quellcode gelöscht was die Odometrie gesteuert hatte, aber die Funktionsweiße ist fast die selbe wie die ich auf roboter.net-con.net gefunden hatte..



OdometrieData(data); // 0. links, 1. rechts

// Schwellwert für schwarz/weiss linke Seite
if (data[0] > THRES_L)
Lnow = 1;
else
Lnow = 0;

// Schwellwert für schwarz/weiss rechte Seite
if (data[1] > THRES_R)
Rnow = 1;
else
Rnow = 0;

// wenn sich der linke Wert geändert hat zähler ++
if (Lnow ^ Lold) {
Count1++;
fl_Lch = 1;
}
else {
fl_Lch = 0;
}

// wenn sich der rechte Wert geändert hat zähler ++
if (Rnow ^ Rold) {
Count2++;
fl_Rch = 1;
}
else {
fl_Rch = 0;
}

// hat sich der Asuro bewegt ?
if (fl_Rch || fl_Lch) {
// alte werte merken für nächsten schleifendurchlauf
Lold = Lnow;
Rold = Rnow;

diff = Count2 - Count1;
if (diff > 0)
sr--;
else if (diff < 0)
sl--;
else {
sr = 130;
sl = 130;
}
if (sr < 50) {
sr = 0;
}
if (sl < 50) {
sl = 0;
}
}



Wäre toll wenn mir jemand einen Tipp geben kann, vllt gibt es ja auch andere Methoden um herauszufinden ob Asuro steht oder fährt und ob man das nach bestimmter Zeit abfragen kann.. aber nicht mit Sleep oder so weil in der Zeit reagiert er ja dann nicht.

P.S die Sensoren sind vor Fremdlicht geschützt, Median schwarz: 750 und weiß 230


mfg

Valen
24.03.2009, 15:32
Bitte gib mahl eine korrekte Llink zu dem roboter.net-con.net-Code dem du gefunden hast. Oder meinst du dies:

http://roboter.net-con.net/asuro/source/odotest1.html

Das hat mich aber nicht viel geholfen weil es nur die min und max Beleuchtungswerten misst und uber IR sendet. Deine Code hat ein Geschwindigkeits anpassung drin aber wird nie die Motorspeed wirklich geändert. Dabei redest du von vorwärtz und ruckwärtz Fahrt, aber da is auch kein Motorrichtung anderung commando. Dammit wirds sehr schwierig den fehler zu finden. Fur das klompletes Ubersicht brauchen wir (sönnst nur mich) denn kompleten Code den du vorher hattest. Ist da nichts in deine Müll-mappe?

C-H-T
24.03.2009, 22:19
Den Odo Test hatte ich vorher durchgeführt, meine
http://roboter.net-con.net/asuro/source/ododemo1.html

Hier aber mal der quelltext, fehlt nur die kollisionsabfrage da das ne ewig lange case abfrage ist für die möglichen tast ereignisse und rückwärtsfahren usw.

ps: habs nur schnell wieder zusammen gefriemelt ohne meine eigenen verbesserungen.. aber da eh der selbe fehler auftritt ist das ja egal.. habs jetzt so nochmal getestet und in 90% aller fälle denkt asuro er steht und fährt halt rückwärts.. ganz selten fährt er mal normal gerade aus und reagiert dann auf linienerkennung und taster.





#include "asuro.h"

#define SPEED_L 110
#define SPEED_R 110

unsigned int lineData[2];

/** Odometrie links/rechts */
unsigned int data[2];
/** flag für aktuellen zustand der farbe */
int Lnow = 0;
int Rnow = 0;
int Rold = 0;
int Lold = 0;
// haben sich die werte geändert
unsigned int fl_Lch = 0;
unsigned int fl_Rch = 0;
/** zähler für farbwechsel */
unsigned int Count1 = 0;
unsigned int Count2 = 0;

int j = 0;
int k = 0;

void Msleep(int dauer) {.....

void drive_back(void) {.....

void drive_back_bit(void) {.....

void drive_left(void) {.....

void drive_right(void) {
Msleep(30);
MotorSpeed(150, 0);
BackLED(ON, OFF);
Msleep(1000);
MotorSpeed(0, 0);
Msleep(10);
}

void kollisions_abfrage(void){
..
..
switch (k) {
case 1:
drive_back_bit();
drive_left(); //K6
break;
case 2:
..
..
default:
MotorSpeed(SPEED_L, SPEED_R);
}
}

void odoabfrage(void){

for (j = 0; j < 30; j++) {
OdometrieData(data); //werte stabilisieren
}
OdometrieData(data); // 0. links, 1. rechts

// Schwellwert für schwarz/weiss linke Seite
if (data[0] > 550)
Lnow = 1;
else
Lnow = 0;

// Schwellwert für schwarz/weiss rechte Seite
if (data[1] > 550)
Rnow = 1;
else
Rnow = 0;

if (Lnow ^ Lold) {
fl_Lch = 1;
}
else {
fl_Lch = 0;
}

if (Rnow ^ Rold) {
fl_Rch = 1;
}
else {
fl_Rch = 0;
}

// hat sich der Asuro bewegt ?
if (fl_Rch || fl_Lch) {
// alte werte merken für nächsten schleifendurchlauf
Lold = Lnow;
Rold = Rnow;
}else{ //Asuro hat sich nicht bewegt
Lold = Lnow;
Rold = Rnow;
drive_back();
drive_left();
}
}

int main(void) {
/*START*/
Init();
MotorDir(FWD, FWD);
StatusLED(YELLOW);
FrontLED(ON);
SerPrint("ASURO Bereit!.. ");
/*WARTEN*/
while (PollSwitch() != 1) {
BackLED(ON, OFF);
Msleep(300);
BackLED(OFF, ON);
Msleep(300);
}
Msleep(1000); //1 sekunde warten
BackLED(OFF, OFF);
StatusLED(GREEN);
SerPrint("Fahre los.. ");
MotorSpeed(SPEED_L, SPEED_R);

while (1) {

//Kollisionsabfrage
kollisions_abfrage();

//Linienabfrage
LineData(lineData);
if (lineData[LEFT] < 20 && lineData[RIGHT] < 20) {
drive_back();
drive_left();
} else if (lineData[RIGHT] < 20) {
drive_left();
} else if (lineData[LEFT] < 20) {
drive_right();
}


//bis hier klappt alles, jetzt die neue odo abfrage falls asuro mal hängen bleibt
//Odometrieabfrage
odoabfrage();


MotorSpeed(SPEED_L, SPEED_R);
BackLED(ON, ON);
}

SerPrint(" Fehler! ");
StatusLED(RED);
BackLED(OFF, OFF);
MotorSpeed(0, 0);

while (1) { }
return 0;
}

Valen
25.03.2009, 00:11
Backleds anschalten und Odometrie messungen können nicht gleichzeitig zusammen gehen. Die brauchen den gleichen Pin wie die Odoleds, aber im niedrige Spannung (0v) Zustand. Den Odoleds leuchten wenn diesen Pin eine hohe Spannung hat (5v). Besser ist diesen Backled function nicht zu nutzen in deine Code. Oder nur auf Odometrie verlassen wenn sie nicht leuchten.

C-H-T
25.03.2009, 16:51
Stimmt, das habe ich jetzt beim zusammen basteln auf die schnelle nur vergessen.. Normalerweise hatte ich die extra immer vorher ausgeschaltet. Aber ich werd sie mal komplett weg lassen, bin kein Elektrotechniker kann mir aber gut vorstellen das da bissel Zeit vergehen muss bis die Odoleds von den Backleds nicht mehr beeinflusst werden wenn sie angeschaltet waren.

Ich werds mal ohne die leds probieren, hoffe es klappt dann.

C-H-T
25.03.2009, 18:36
OMG mein Asuro hat ein eigenes Bewusstsein entwickelt oO spaß bei Seite der macht ohne Mist jetzt das was er soll obwohl ich es garnicht einprogrammiert habe.. das was ich die ganze zeit machen wollte geht auf einmal.. hab mich gefreut.. dann nochmal den Quelltext angeschaut und gesehen das ich die Fahrbefehle garnicht drinne stehen habe sondern ledeglich eine Ausgabe fürs Hyperterminal zwecks debugging...



if (fl_Rch || fl_Lch) {
// alte werte merken für nächsten schleifendurchlauf
Lold = Lnow;
Rold = Rnow;
SerPrint("Bewegt!\n\r");
}else{ //Asuro hat sich nicht bewegt
Lold = Lnow;
Rold = Rnow;
SerPrint("Halt!\n\r");
}


da wo die SerPrint befehle stehen muss dann halt der entsprechende Motor Befehl hin.. aber ist er nicht .. aber der Asuro macht trotzdem halten und rückwärts fahren je nachdem ob sich die odometrie verändert hat.. kann mir das jemand erklären? ist da irgendwie alter code im prozessor das der gerade zufällig das macht? Ich bin echt platt.. komisch ist auch das er mal mehr mal weniger nach hinten fährt.. oder kanns sein das die taster irgendwas abbekommen wenn die motoren laufen aber der asuro sich nicht bewegen kann? weil nur die könnten nach code die reaktionen auslösen die er jetzt macht.. obwohl ich aber halt keine drücke..