PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Odometrie Programmfehler?



Hansi41
05.02.2008, 19:43
Hallo,
ich habe auch ein problem mit der odometrie des ASURO's.
Zwar funktioniert das geradeaus fahr programm einwandfrei, nur wollte ich mal ein programm schreiben, das den asuro nach einem meter abbremsen lässt, also habe ich die ticks pro meter errechnet (bei 8 ticks pro reifenumdrehung). Hier ergab sich der Quotient 67. Nun habe ich folgendes programm geschrieben, allerdings fährt der asuro nur kurz an und stoppt dann.

[programmcode im nächsten post -- damaltor, 07.02.08, 20:00h]

Hoffe ihr könnt mir weiterhelfen!

Hansi41
05.02.2008, 19:45
oh sry habe den falschen button benutzt!!


/*Geradeaus fahren*/

#include "asuro.h"

#define TRIGGERLEVEL 390
#define HYSTERESIS 6
#define LOW 0
#define HIGH 1

int main(void)
{
unsigned int data[2];//Variable für Odometrie
signed int status[2]={0,0};//Variable für Status HIGH or LOW
signed int difference=0;//Zählvariable
unsigned int distance=0;
Init();
MotorDir(FWD,FWD);
while(1) {
//Heligkeitswerte der Lichtschranken auslesen
OdometrieData(data);

//Wechsel LINKER Sensor von niedrig auf hoch
if ((status[0]==LOW) && (data[0]>TRIGGERLEVEL+HYSTERESIS)) {
status[0]==HIGH;
difference++;
distance++;}

//Wechsel LINKER Sensor von hoch auf niedrig
if ((status[0]==HIGH) && (data[0]<TRIGGERLEVEL-HYSTERESIS)) {
status[0]==LOW;
difference++;
distance++;}

//Wechsel RECHTER Sensor von niedrig auf hoch
if ((status[1]==LOW) && (data[1]>TRIGGERLEVEL+HYSTERESIS)) {
status[1]==HIGH;
difference--;}

//Wechsel RECHTER Sensor von hoch auf niedrig
if ((status[1]==HIGH) && (data[1]<TRIGGERLEVEL-HYSTERESIS)) {
status[1]==LOW;
difference--;}

//Sicherheitssperre für Zählvariable
/************************************************** ********/
//Wertebereich größer als 255
if (difference>255) {
difference=255;}
//Wertebereich kleiner als -255
if (difference<-255) {
difference=-255;}
//Zähldifferenz auswerten:
//Motoren passend betreiben
/************************************************** *******/
//links schneller Drehen ==> links um difference verlangsamen
if (difference>0) {
MotorSpeed(150-difference,150);}
//sonst rechts um difference beschleunigen
else {MotorSpeed(150,150+difference);}
if (distance>=67){
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);}
}
return 0;
}

Hansi41
05.02.2008, 19:47
für den jenigen, der es selbstmal ausprobieren möchte, hier istz die .hex datei!!

pinsel120866
05.02.2008, 19:49
Hast du den Wert für den Triggerlevel ermittelt? Ausserdem scheint mir deine Hysterese etwas "eng".

Hansi41
05.02.2008, 20:45
hi,
betreff zu triggerlever und hysteresis:
naja, aber es klappt ja vorher ohne die variable distance, also muss es ja eig auch jeztzt klappen, oer?

Hansi41
05.02.2008, 20:46
hast du es bei dir mal ausprobiert?
funktioniert es bei dir auch nicht?

HAWK-Matze
05.02.2008, 20:53
könnte daran liegen das je nach schwarz weiß kleber 8*5=40 bzw. 12*5=60 sind. du hast ja noch die übersetztung auf die antriebsachse

pinsel120866
05.02.2008, 20:57
Also ich habe folgenden Code (läuft bei mir mit den 12er Scheiben):



#include "asuro.h"

#define TRIGGERLEVEL 830
#define HYSTERESIS 10
#define LOW 0
#define HIGH 1

int main(void)
{
unsigned int data[2];
signed int status[2]={0,0};
signed int difference=0;
Init();
MotorDir(FWD, FWD);
while(1) {
// Helligkeitswerte der Lichtschranken auslesen
OdometrieData(data);
// Wechsel linker Sensor von niedrig auf hoch?
if ((status[0]==LOW) && (data[0]>TRIGGERLEVEL+HYSTERESIS)) {
status[0]=HIGH;
difference++;
}
// Wechsel linker Sensor von hoch auf niedrig?
if ((status[0]==HIGH) && (data[0]<TRIGGERLEVEL-HYSTERESIS)) {
status[0]=LOW;
difference++;
}
// Wechsel rechter Sensor von niedrig auf hoch?
if ((status[1]==LOW) && (data[1]>TRIGGERLEVEL+HYSTERESIS)) {
status[1]=HIGH;
difference--;
}
// Wechsel rechter Sensor von hoch auf niedrig?
if ((status[1]==HIGH) && (data[1]<TRIGGERLEVEL-HYSTERESIS)) {
status[1]=LOW;
difference--;
}
// zur Sicherheit: verhindern, dass der Differenzz�ler
// den erlaubten Wertebereich verl�st
if (difference<-255) difference=-255;
if (difference>255) difference=255;

// Status-LED noch entsprechend der erkannten Segmente
// aufleuchten lassen, grn fr links, rot fr rechts
StatusLED(status[0]+status[1]*2);

// Z�ldifferenz passend auf die Motoren verteilen
if (difference>0) MotorSpeed(255-difference,255);
else MotorSpeed(255,255+difference);

}
return 0;
}

Hansi41
05.02.2008, 21:41
hallo,
@matze: also du hast schon recht, da ha ich was übersehen. allerdings klappt das auch nicht, wenn ic hden code entsprechend ändere:


/*Geradeaus fahren*/

#include "asuro.h"

#define TRIGGERLEVEL 390
#define HYSTERESIS 6
#define LOW 0
#define HIGH 1

int main(void)
{
unsigned int data[2];//Variable für Odometrie
signed int status[2]={0,0};//Variable für Status HIGH or LOW
signed int difference=0;//Zählvariable
unsigned int distance=0;
Init();
MotorDir(FWD,FWD);
while(1) {
//Heligkeitswerte der Lichtschranken auslesen
OdometrieData(data);

//Wechsel LINKER Sensor von niedrig auf hoch
if ((status[0]==LOW) && (data[0]>TRIGGERLEVEL+HYSTERESIS)) {
status[0]==HIGH;
difference++;
distance++;}

//Wechsel LINKER Sensor von hoch auf niedrig
if ((status[0]==HIGH) && (data[0]<TRIGGERLEVEL-HYSTERESIS)) {
status[0]==LOW;
difference++;
distance++;}

//Wechsel RECHTER Sensor von niedrig auf hoch
if ((status[1]==LOW) && (data[1]>TRIGGERLEVEL+HYSTERESIS)) {
status[1]==HIGH;
difference--;}

//Wechsel RECHTER Sensor von hoch auf niedrig
if ((status[1]==HIGH) && (data[1]<TRIGGERLEVEL-HYSTERESIS)) {
status[1]==LOW;
difference--;}

//Sicherheitssperre für Zählvariable
/************************************************** ********/
//Wertebereich größer als 255
if (difference>255) {
difference=255;}
//Wertebereich kleiner als -255
if (difference<-255) {
difference=-255;}
//Zähldifferenz auswerten:
//Motoren passend betreiben
/************************************************** *******/
//links schneller Drehen ==> links um difference verlangsamen
if (difference>0) {
MotorSpeed(150-difference,150);}
//sonst rechts um difference beschleunigen
else {MotorSpeed(150,150+difference);}
if (distance>=335){
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);}
}
return 0;
}


@pinsel: also mein asuro verfolgt ja so eine linie, allerdings nicht mehr wenn ich vresuche mit der variablen distance die strecke zu definieren zu versuche,

läuft denn test.hex auf euren asuros?

Gerry1973
06.02.2008, 21:09
Ich hab mir folgenden Code gebastelt.
Anders ist, dass der Mittelwert der Sensoren permanent der Umgebung angeglichen wird.

Mit dabei ist noch eine Abfrage der Taster, die den Asuro umkehren/ausweichen lassen. Nachteil dabei ist, dass er nach nem Richtungswechsel erstmal etwas unkontrolliert losrennt, weil er den Zähler während des Richtungswechsels nicht ausreichend hochzählt.

Fehlen tut noch ne Begrenzung der Maximalgescheindigkeit auf 255. Wenn ich ein Rad also nach und nach stärker blockiere, geht der Motor auf null und regelt sich dann wieder neu ein.

Aufgefallen ist mir, dass sich das linke Rad rückwärts langsamer dreht als vorwärts. Kann das mal jemand ausprobieren, obs bei anderen Asuros auch so ist?


#include "asuro.h"


int main(void) {
unsigned int odo_max_l,odo_max_r,odo_min_l,odo_min_r,odo_mitte_ l,odo_mitte_r,data[2];
unsigned char auf_l,auf_r,speed,speed_wert,speed_l,speed_r,zaehl er_l,zaehler_r,schwing,rueckw,dreh_l,dreh_r,taste;
unsigned long dauer1,dauer2;
Init();
MotorDir(FWD,FWD);
auf_r=auf_l=0;
zaehler_r=zaehler_l=rueckw=dreh_l=dreh_r=0;
odo_max_l=odo_max_r=odo_min_l=odo_min_r=300;
speed=120;
speed_l=speed_r=speed;
speed_wert=(speed/20);
MotorSpeed(speed_l,speed_r);

while(1) {

for(schwing=0;schwing<30;schwing++) {
dauer1=Gettime();
odo_max_l--;
odo_max_r--;
odo_min_l++;
odo_min_r++;
OdometrieData(data);
if (data[0]>odo_max_l) {odo_max_l=data[0];}
if (data[1]>odo_max_r) {odo_max_r=data[1];}
if (data[0]<odo_min_l) {odo_min_l=data[0];}
if (data[1]<odo_min_r) {odo_min_r=data[1];}
odo_mitte_l=(odo_max_l+odo_min_l)/2;
odo_mitte_r=(odo_max_r+odo_min_r)/2;
if ((auf_l==0) && (data[0]>(odo_mitte_l+5))) {
auf_l=1;
zaehler_l++;
}
else if ((auf_l==1) && (data[0]<(odo_mitte_l-5))) {
auf_l=0;
}
if ((auf_r==0) && (data[1]>(odo_mitte_r+5))) {
auf_r=1;
zaehler_r++;
}
else if ((auf_r==1) && (data[1]<(odo_mitte_r-5))) {
auf_r=0;
}

dauer2=Gettime();
while ((dauer1+5)>dauer2) {dauer2=Gettime();}
}

if (zaehler_l<speed_wert) {speed_l=speed_l+speed_wert;}
else if (zaehler_l>speed_wert) {speed_l=speed_l-speed_wert;}

if (zaehler_r<speed_wert) {speed_r=speed_r+speed_wert;}
else if (zaehler_r>speed_wert) {speed_r=speed_r-speed_wert;}

zaehler_l=zaehler_r=0;

if (PollSwitch()>0) {
taste=PollSwitch();
if (taste==1) {dreh_l=(800/speed);}
if ((taste==2) || (taste==4)) {dreh_r=(1200/speed);}
if (taste==31) {dreh_r=(800/speed);}
if ((taste==8) || (taste==16)) {dreh_l=(1200/speed);}
}

if (dreh_l>0) {
MotorDir(RWD,BREAK);
dreh_l--;
speed_r=speed_r-speed_wert;
}
else if (dreh_r>0) {
MotorDir(BREAK,RWD);
dreh_r--;
speed_l=speed_l-speed_wert;
}
else {
MotorDir(FWD,FWD);
}

MotorSpeed(speed_l,speed_r);
}
return 0;

Hansi41
07.02.2008, 17:10
hallo,
wisst ihr welche libr. das buch mehr spaß mit asuro band zwei benutzt?
Ich besitze nämlich noch die alte 2.1, kann es daran liegen?

Hansi41
07.02.2008, 17:14
hat denn jemand von euch mal die .hsx datei auf seine masuro ausprobiert?
ich bin mir nämlic hnicht sicher, ob es wirklich am programm liegt....

luckylukas92
08.09.2008, 15:24
Ich habe mir vor einigen tagen einen asuro gekauft, weil ich schon immer gerne mit php programmiere un ne andre sprache testen wollte... ich wollte vorerst mal alle teile testen und glaube meine odometrie sensoren sind kaputt...bei der selftest passiert einfach "nichts"..deswegen habe ich hier im dorum nach nem kleinen programm gesucht bei der die odometie in anspruch genommen wird.... ich habe jetzt das programm von "pinsel120866" drauf und wollte fragen woran es liegen kann, dass der rechte motor nach 2 sekunden aufhör zu drehen und der andre unendlich lang weiter geht?? ...sind wirklich meine teile kaputt?

mfg lukas

pinsel120866
08.09.2008, 16:24
Das liegt daran, dass das Programm 2 Sekunden lang die Odometriewerte misst und danach via IR auf das Hyperterminal ausgibt. Allerdings müssten beide Motoren gleich lang laufen. Möglicherweise hat die linke Odometrie - Seite ein Problem mit der Hardware.

luckylukas92
08.09.2008, 16:29
wenn ich dann ein stück weißes papier vor die rechte seite hebe fängt die linke seite wieder an sich zudrehen......

edit: wennich das programm drauf habe bekommt das hypertermianl keine nachrichten

PS: falls es wirlich nicht kaputt sondern "nur" ein problem/fehler ist...wie kannich diesen fehler den beheben

mfg lukas ....sry wegen meinen doofen fragen

pinsel120866
08.09.2008, 16:34
Es könnte daran liegen dass du die Odometrie - Sender/Empfänger auf der linke Seite verkehrt herum eingelötet hast. Kontrolliere das mal nach Aufbauanleitung.

luckylukas92
08.09.2008, 19:36
ich hab mir den asuro gebraucht in meiner schule gekauft(die arbeiten jetzt mit sonem lego ding) und "nicht" selber zusamen gebaut bis jetzt hab ich gemerkt , das die motoren falschrum eingebaut waren (fehler schon behoben)und das status led war auch nicht richtig drin...aber ich glaub falls du mit odometrie sender/empfänger t11/12 und d13/14 meinst, dass die richtig drin sind...auf jedenfall sieht im manual genauso aus
edit zu meinem letzten post : wennich ein stück papier vor die rechte seite hebe fängt die linke wieder an zu drehen und das liht leuchtet "yellow" die linke seite geht glaube ich richtig , weil wenn ich das rad mit den schwarze/weiß aufklebern drehe wechselt das statusled bei schwarz immer auf rot und geht dann bei weiß wieder aus
mfg... sry für die wirklich dummen posts...ich hab den gekauft , weil ein freund den hat und meinte er wär super einfach zu verstehen...

pinsel120866
09.09.2008, 07:38
OK, ich schlage vor du lädtst dir das Handbuch von www.arexx.com herunter und danach den Selbsttest auf den Asuro. Wenn der Selbsttest nicht fehlerfrei abläuft gib nochmals Bescheid.

Deine Posts sind nicht dumm - wir waren alle irgenmal mal so weit wie du, das wird schon.