Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie bestimmte Stecke zurücklegen, Encoder ?
Pitchriddick
31.10.2006, 18:13
Hallo, ich habe da einige Probleme bzw. Fragen an euch:
Mit diesem Programm fährt auch mein Asuro wunderbar geradeaus
#include "asuro.h"
int main(void)
{
int diff;
Init();
while(1){
StartSwitch();
Encoder_Init();
while (!switched) {
MotorDir(RWD,RWD);
MotorSpeed(130,130);
diff = encoder[RIGHT]-encoder[LEFT];
MotorSpeed(175+diff,175-diff);
Msleep(100);
}
if(switched){BackLED(OFF,ON);
StatusLED(YELLOW);}
else if(!switched){BackLED(OFF,OFF);
StatusLED(RED);}
}
return 0;
}
1.) Aber ich verstehe überhaupt nicht ,wie es funktioniert (diff= encoder[RIGHT]... ? ; ...175+diff; eigentlich versteh ich garnichts an diesem Programm) ! Könnte mir einer freundlicherweise das Fettgedruckte genau erklären? Hat etwas mit der neuen Asuro Lib zu tun, aber damit komme ich leider auch nicht klar.
2.) Wieso gehen die BackLEDs nicht mehr aus, sobald der/die Taster losgelassen wurden ?
else if(!switched){BackLED(OFF,OFF);
StatusLED(RED);}
3.) Am wichtigsten: Wie bekomme ich den Programm hin, mit dem ich den Asuro sagen kann, wie weit er fahren soll (in cm oder mm ...) ? Das habe ich hier schon einmal gefragt, aber kam mit den gegebenen Antworten nicht weiter.
Achja bevor wieder gesagt wird: "Forumsuche verwenden..."
-> Ich habe schon alle Beiträge gelesen...
Wäre genial wenn ihr meine Fragen beantworten könntet !
damaltor
01.11.2006, 15:17
probier mal else {BACKLED(OFF,OFF)...
also ohne zweites if...
Wie das funktioniert?? eigentlich ganz einfach... ich such mal den thread raus wenn ich mal nen bissl mehr zeit hab...
und was die wegstrecke angeht... da kannst du wirklich nur die suchfunktion benutzen. das problem wurde schon so oft diskutiert, da ist mit sicherheit ne lösung dabei.
Pitchriddick
01.11.2006, 16:24
Hi,
nur mit else geht es auch nicht, aber das ist nicht so wichtig...
und was die wegstrecke angeht... da kannst du wirklich nur die suchfunktion benutzen. das problem wurde schon so oft diskutiert, da ist mit sicherheit ne lösung dabei.
Also ich finde da leider nichts, es wurde vielleicht über das Ausgeben des zurückgelegten Weges gesprochen, jedoch nicht über eine Eingabe des gewünschen Weges in einer bestimmten Einheit :(
#include "asuro.h"
int main(void)
{
int diff;
Init();
// Nur einmal initilisieren vor der Hauptschleife...
Encoder_Init();
while(1){
// Wie soll die LED aus gehen wenn sie nicht
// ausgeschaltet wird?
// switched muss auch restauriert werden auf
// den Urzustand.
BackLED(OFF,OFF);
StatusLED(RED);
switched = 0;
StartSwitch();
while (!switched) {
MotorDir(RWD,RWD);
MotorSpeed(130,130);
// Die variable diff bildet die Differenz aus rechtem und
// linkem Encoder stand ab, d.h. also die (pseudo)
// differenz in der Wegstrecke.
// Durch addition/subtraktion dieser Differenz auf die
// PWM des jeweils anderen Rades wird dieser Fehler
// im Zeitmittel ausgeglichen und dein ASURO fährt
// geradeaus. Natürlich ist dass keine exakte
// Herangehensweise, aber eine gute Näherung.
// Klar?! :)
diff = encoder[RIGHT]-encoder[LEFT];
MotorSpeed(175+diff,175-diff);
Msleep(100);
}
// ...sorry, aber dein else Zweig wird niemals
// ausgeführt...
// Dass If-Konstrukt ist somit überflüssig.
/*if(switched){ */
BackLED(OFF,ON);
StatusLED(YELLOW);
/*} else {
BackLED(OFF,OFF);
StatusLED(RED);}
}*/
Msleep(100); // sonst sieht man die LED nicht...
}
// Nie vergessen, reine Vorsichtsmassnahme..
while(1){}
return 0;
}
O. :)
Pitchriddick
01.11.2006, 19:01
Aha, danke schonmal !
was genau macht denn die encoder Funktion , was ist z.B. hier enthalten encoder[RIGHT] ?
meine dritee Frage kann keiner beantworten ?
hi Pitchriddik
um eine bestimmte strecke zu fahren , musst du entweder die geschwindigkeit, oder die anzahl der "farbwechsel" bei der odometrie kennen. Zweitere ist leichter zu bestimmen
welcher strecke ein farbwechsel entspricht hängt davon ab, was für eine auflösung die schwarzen und weisen felder auf der scheibe ahben. die strecke kann man dann wie folgt berechnen
1Farbwechsel = Durchmesser * pi / Auflösung
Soweit die theoretischen vorüberlegungen. Der rest ist dann eigentlichkein problem mehr. Ich schreib morgen vieleicht noch den passenden code.
mfg EDH
wo ist eigentlich die deklaration/definition der geheimnissvollen encoder funktion
bin ich nur blind oder gibts die gar nicht. (warum das programm dann aber trotzdem funktioniert ist eine andere frage)
andere möglichkeit: ich hab ne zu alte asuro.h
dann schick mir bitte die neure.
gast1234
01.11.2006, 19:54
was genau macht denn die encoder Funktion , was ist z.B. hier enthalten encoder[RIGHT] ?
Wenn du in die Header-Datei asuro.h schaust, siehst Du, dass encoder keine Funktion sondern ein array mit 2 Werten vom Typ integer ist.
in encoder[0] steht der Odometriesensorwert für links und
in encoder[1] der für Rechts.
encoder[0] ist das gleiche wie encoder[LEFT] und
encoder[1] ist das gleiche wie encoder[RIGHT].
In der Headerdatei findest du nämlich auch die Zuweisungen, dass LEFT gleichbedeutend mit 0 und RIGHT mit 1 ist.
Berichtigt mich, wenn ich mich irre,
in der Interuptroutine signal (SIG_ADC) in der Datei asuro.c kann man lesen, dass dort mitgezählt wird, wie oft sich der Hell/Dunkelwechsel vollzieht. Die werte für linke und rechte Odometrie werden dann in besagtem array encoder[] gespeichert.
Um den Abstand in [mm] eingeben zu können, kanst Du deine Sensorik ganz einfach normieren.
1) Nimm ein Maßband von ca. einem Meter länge
2) Schreib ein Proggi das genau n encoderschritte fährt ( siehe Beispiel )
3) Setz Robbi an den Anfang des Massbandes und "Engage..." :)
4) Miss den Abstand(Ln) den er zurückgelegt hat und normiere auf 1mm
z.B. für n = 1000
vex = Ln / n
Ln = 80cm ==> vex = 800mm/1000 = 0.8mm ==> 8 Einheiten für 10mm in diesem Beispiel.
6) Schreibe eine Routine die unter Beruecksichtigung von diesem Faktor die Werte mit der
Einheit [mm] multipliziert.
Das wars...
/* Normierungstest für Einheitsvektor Längenbestimmung
ohne Ausgleich der Gangunterschiede der angeschlossenen
GS-Motoren.
*/
#include "asuro.h"
int main(void)
{
int diff;
Init();
Encoder_Init();
MotorDir(FWD,FWD);
MotorSpeed(170,170);
while( encoder[RIGHT] < 900 ) {}
MotorSpeed(110,110);
while( encoder[RIGHT] < 1000 ) {}
MotorDir(BREAK,BREAK);
while(1){}
return 0;
}
Pitchriddick
02.11.2006, 20:08
Sorry, aber ich bin anscheinend zu dumm dafür. Auch die Go Funktion funktiniert nicht (fährt entweder nur einen Tick oder unendlich).
Pitchriddick
06.11.2006, 14:03
Wie mache ich das nu genau mit den Odometrie Sensoren? Kann mir mir einer helfen?
hast du vor der go funktioin Encoder_Init() aufgerufen.
sonszt geht das ganze nicht, weil dann die go funktion glaubt, der asuro würde stillstehen obwohl er fährt
mfg EDH
Du kannst auch einfach folgende go-Funtkion verwenden. Als Input parameter wird die Distanz in "mm" angegeben. Funktioniert je nach Bodenbeschaffenheit relativ genau.
Gruss,
stochri
/************************************************** *************************
*
* void Go(int distance, int power = 150)
*
* Go distance in mm. Attention: Encoder_Init() has to be called first.
*
* the driven distance depends a little bit from the floor friction
* limitations: maximum distance +-32m
* possible problems: in full sunlight the encoder sensors may be disturbed
*
* input
* distance: postiv->go forward ; negativ-> go backward
* power: sets motorpower
*
* example:
*
* Encoder_Init();
* Msleep(5000);
* Go(200,150); // move 20cm vorward
* Msleep(2000);
* Go(-200,150); // move 20cm backward
* Msleep(2000);
*
*
* last modification:
* Ver. Date Author Comments
* ------- ---------- -------------- ---------------------------------
* sto1 29.07.2005 stochri motorfunction
* And1 31.07.2005 Andun added speed and Odometrie
* sto1 31.10.2006 stochri distance in mm
* ------- ---------- -------------- ---------------------------------
*
************************************************** *************************/
void Go(int distance, int power)
{
uint32_t enc_count;
int tot_count = 0;
int diff = 0;
int l_speed = power, r_speed = power;
// calculation tics/mm
enc_count=abs(distance)*10000L;
enc_count/=19363L;
Encoder_Set(0,0); // reset encoder
MotorSpeed(l_speed,r_speed);
if(distance<0) MotorDir(RWD,RWD);
else MotorDir(FWD,FWD);
while(tot_count<enc_count) {
tot_count += encoder[LEFT];
diff = encoder[LEFT] - encoder[RIGHT];
if (diff > 0) { //Left faster than right
if ((l_speed > power) || (r_speed > 244)) l_speed -= 10;
else r_speed += 10;
}
if (diff < 0) { //Right faster than left
if ((r_speed > power) || (l_speed > 244)) r_speed -= 10;
else l_speed += 10;
}
Encoder_Set(0,0); // reset encoder
MotorSpeed(l_speed,r_speed);
Msleep(1);
}
MotorDir(BREAK,BREAK);
Msleep(200);
}
Pitchriddick
07.11.2006, 21:15
Ja Go Funktion funktioniert nun, ist aber leider fehleranfällig...
bereits hier macht er fehler:
#include "asuro.h"
int main(void)
{
Init();
BackLED(ON,ON);
Encoder_Init();
Go(2000,140,130); Msleep(200);
BackLED(OFF,OFF);
while(1);
return 0;
}
Fährt durch BackLED unendlich lang , hört nicht mehr auf zu leuchten...
Ist das die Rechnungsformel ?
uint32_t enc_count;
int tot_count = 0;
...
enc_count=abs(distance)*10000L;
enc_count/=19363L;
was passiert hier? Kann ich die Übergänge der Odometrie (...wegL++, ...wegR++;...) lesen, dann diese Formel einsetzen?
Wenn der ASURO unendlich lange fährt, könnte das an einer Fehlfunktion Deiner Odometriesensoren liegen. Probiere das Programm mal in einm dunklen Raum aus. Oder besser: probiere ein Programm das Du nicht selbst geschrieben hast und sicher funktioniert aus. Je nach ASURO können die Schaltschwellen für die Sensoren anders liegen.
Die Rechnung oben( ohne abs() ) stellt eine Division durch 1,9363 dar. Die Zahl wird zuerst mit 10000 multiplieziert und dann durch 19363 dividiert damit man keine Fließkommazahlen braucht.
Gruss,
stochri
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.