PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Regelung fürs Geradeausfahren



theodrin
18.05.2006, 13:41
Hallo!

Ich bin schon eine Weile dabei, daran zu basteln, dass mein Asuro endlich gerade aus fährt. Nach einigen Misserfolgen (vor allem bei der Geschwindigkeitsmessung) bin ich jetzt zumindest so weit, dass ich so ca. die Geschwindigkeit messen kann.
Dann wollt ich was schreiben, dass die beiden Geschwindigkeiten immer gleich geregelt werden. Ich kenn mich leider bei Regelungen nicht sonderlich gut aus, deswegen hab ich mal nur ein Programm geschrieben, was mir die Leistungen von einem Rad erhöht und von anderen erniedrigt(Also wenn das linke schneller ist => links weniger Leistung und rechts mehr Leistung) Hab mir dann die Geschwindigkeiten in LabView ausgeben lassen und halt aufzeichnen lassen. Das Ergebnis ist nicht zufriedenstellend. Ich wollt jetzt fragen ob da wer einen besseren Vorschlag zur Regelung hat. Danke schon mal!

mfg theodrin

Arexx-Henk
18.05.2006, 14:05
Hallo,

Mir ist es wenigsten gelungen die Asuro exact geradeaus fahren zu lassen mit eine exacte geschwindigkeit und exacten abstand..

Aber dass passiert nur dadurch dass beide Rader unabhangig von einander mittels ihren eigene odometer-signal zahlung angesteurt werden.

Theoretisch wurde dass genugen.

Wenn ich versuchte die rader softwaremassig an einander zu knupfen fangte der Asuro an zu Schwenken.

Da muss ich mich mahl noch darin vertiefen.

Ich mochte mal gerne wissen ob deine Asuro mit das Program dass ich geschrieben habe auch wirklich gerade ausfahrt.

(Vielleicht fahrt nur meine Asuro gerade...;-))

https://www.roboternetz.de/phpBB2/viewtopic.php?t=19943&sid=6d7c33c03522a6a452b797e5754fddc2

Gruss

Henk

theodrin
18.05.2006, 14:10
Hallo Henk!

OK, das werd ich ausprobieren. Dann schauen wir mal. Wenns bei dir geht dann sollte es doch auch bei jeden gehen. So hoffe ich doch(auch in meinem Sinne)
Also danke schon mal!

mfg theodrin

theodrin
19.05.2006, 20:39
Hallo!

Ich hab jetzt einmal einen PI-Regler programmiert und einen PID-Regler. Bin mit dem Ergebnis vom PI-Regler eigentlich überrascht worden. Das hat recht gut funktioniert. Ich hab da so eine kleine Teststrecke von 8 Meter Länge und 1 Meter Breite. Da wollte ich halt das mein Asuro durchkommt ohne an die Seitenwände anzustoßen. Mitn PI-Regler hab ichs eigentlich oft geschaft. Also bei 3 Versuchen hab ichs immer einmal geschaft. Da hab ich mich gleich recht gut gefreut. Dumm war nur dass am Anfang immer ein Rad schneller war als das andere. Das hab ich nicht wegbringen können. Aber dann ist er eigentlich ziemlich schön gelaufen. Nicht immer exakt gerade, leicht geschwenkt, aber er hat den Korridor geschafft. Die Versuche wo er es nicht geschafft hat, ist er meistens bei 5-6 Metern angefahren.
Mitn PID-Regler ist es eigentlich schlechter gegangen, aber vielleicht muss ich da noch die Werte der Regelung ändern. Da hat er es nur mehr 1 mal bei 4-5Versuchen geschafft. Sonst ist er auch so bei 5 Metern gescheitert. Selten ist er ganz dumm gefahren.
Ich werd jetzt morgen das Programm vom Henk probieren. Schauen wir mal was sich da tut.
Ach übrigens: Ich hätte gerne wenn mir jemand bei meiner Geschwindigkeitsbestimmung hilft. Ich vertrau der nämlich nicht ganz. Sie funktioniert nur von einem Leistungsbereich von 130-190 richtig. Ich könnts sie euch mal zeigen. Vielleicht habt ihr bessere, oder könnt mir bei meiner helfen, dass sie "immer" geht.

mfg theodrin

theodrin
20.05.2006, 09:10
Hallo Henk!

Dein Geradeausfahrprogramm hat leider nicht funktioniert. Es hat zwar so ausgeschaut als würde er versuchen zu regeln, aber es war immer ein Rad schneller als das andere, aber konstant. Also hat dein Programm bei mir einen konstanten Fehler programmiert. Tut Leid, aber so hab ich meine Teststrecke nicht überwinden können. Da hat meine PI-Regelung noch etwas besser funktioniert. Aber das kann ja daran liegen, dass du vielleicht konstante Werte da reinprogrammiert hast, die nur auf deinen Asuro zutreffen. Vielleicht gehörten die bei mir geändert. Na ich schau mal ob ich mit meinem Regelprogramm weiterkomme.

mfg theodrin

Arexx-Henk
20.05.2006, 13:27
Hallo theodrin,

dass ist ja Schade....

Mmmm....

Dass Program ist geeignet fur Asuro mit Odorader mit 6 Schwarz/Weiss flachen.

Da sich beim fahren die Odowerte durch wechselndes Umgebungslicht andern benutze ich ein festes durch experimentieren gefundene hysteresis von 40 Odowerte. Dass heisst, die hochste und niedrigste Odowerte bei jedem vorbeigehendes Odoflach wird gespeichert. Bewegt sich die momentane gemessene Wert kleiner als aximum-minus-40 oder grosser als minumum-plus-40 dann wird dass wie ein gultiges weiss/schwarz oder schwarz/weiss ubergang interpretiert.

Aber jetzt kommt's:

Weil sich die Odorader durch dass hin und her gleiten auf die Axen naher-an und weiter-weg vom infrarot systeem bewegen andert sich die gemessene Odowert so um die 300 !!!
Da muss ich mein ganzes Prinzip vielleicht uber bord schmeissen.

Meine Asuro fahrt vermutlich ganz gut weil ich die Infrarot Sender und Empfanger umgebogen habe damit die infrarot Strahlung besser ausgerichtet ist und die gemessene Werte weiter aus einander liegen.

Aber daruber bin ich mich noch nicht sicher.

Meine Asuro Odowerte sind: (im Halbschatten):

Linkerrad weiss naher/weiter 50/400
Linkerrad schwarz naher/weiter 750/750

Rechterrad weiss naher/weiter 35/280
Rechterrad schwarz naher/weiter 615/645

Da sieht mann dass gleiten uber die Axe die reflektierung vom weissen Flach erheblich beeinflusst.

Vielleicht sollte die Hysteresis grosser sein.

Kannst Du vielleicht mal deine min/max odowerte schicken? (program auf meinen Homepage) und dann die 4 Werte posten so wie ich die ach gemessen habe?

Wenn dein Program fertig ist mochte ich es auch mal testen.

Gruss

netsroht
20.05.2006, 13:59
Bei mir hat es enorm geholfen die Encoderzeichnungen auf dem Ritzel mit schwarzen bzw. weißen Stiften dick nachzu malen sodaß ein besserer Kontrast entsteht. Damit wr eingeradaus laufen mit der Funktion go() bzw. Kurven mit Turn() kein Problem mehr!
Ein weitere Verbesserung bringt ein kleines Papierhäuschen über den Odometriesensoren (mit Heißkleber vorsichtig festkleben) .

theodrin
20.05.2006, 14:37
Hallo Henk!

War grad fort. Mittagessen und für die Schule lernen. Das muss man auch mal machen. Ich hab mir gerade deine Messung durchgelesen und musste an meine Versuche denken.
Ich hab auch mal so gemessen wie du, zwar nicht so genau, eher einfacher.
Das hat nie funktioniert wenn sich die Helligkeitswerte geändert haben. Ich hab immer den Asuro auf so etwas gestellt, damit die Räder den Boden nicht berühren und dann hab ich getestet. Auf dem Prüfstand hat es immer toll funktioniert, aber wie ich auf dem Boden gefahren bin, ist Blödsinn rausgekommen.
Da hab ich gewusst, dass die geänderten Helligkeitswerte schuld sein müssen. Also hab ich vor jeder Geschwindigkeitsmessung Helligkeitswerte gemessen und so wusste halt mein Asuro wann grad weiß und schwarz ist. Das hätte super funktioniert, nur war dann meine Geschwindigkeitsmessung viel zu langsam. Bevor ich einmal die Geschwindigkeit gemessen habe, ist Asuro schon mindestens 35-40cm falsch gefahren. Wenn ich nur 50cm Platz habe ist das ungenügend.

Dann wollte ich die Geschwindigkeit mit den Flanken messen. Das hat nicht funktioniert.

Jetzt mess ich die Geschwindigkeit ganz anders. Ich nehm in einem Feld 100 Odowerte auf und speichere sie dort. Dann schau ich mir einen Wert an und die darauf folgenden. Z.B: Wert 1 und Wert 10-Wert 15 vergeicht er dann. So in etwa. Dann schaut er ob sich dabei die Werte über einer bestimmten Grenze geändert hat. Die bleibt ja so ungefähr gleich, egal ob hell oder dunkel. Dann schaut er wie viele SchwarzeißÜbergänge stattgefunden haben.

Es ist nicht perfekt, dass wusste ich von Anfang an, aber ich war nach drei falschen(eine Methode hab ich noch probiert) eine Trotz-Methpde, von der ich nicht viel erwartet habe. Aber von Leistung 130-190 funktioniert die Geschwindigkeitserfassung und darüber und darunter seltsamerweise nicht.



#define ANZ 100
#define ABT 2



while(tsys<650)
//Ein mal abtasten ca.200, 2mal ca.500, dreimal ca. 650, usw.
{


ta=Gettime(); //Zeitmessung Anfang
for(i=0; i<ANZ; i++) //Beginn Werte in Feld einzulesen
{
Msleep(2);
OdometrieData(dataodo);
feldlinks[i]=dataodo[0];
feldrechts[i]=dataodo[1];
}
te=Gettime();

t=te-ta;



for(i=0;i<=(ANZ-ABT); i++) //Schwarz-Weiß-Messung
{
ists=uebertraglinks;
uebertraglinks=0;

for(a=0;a<=ABT; a++)
{
abweichung=feldlinks[i]-feldlinks[i+a];
if(abweichung > 100 || abweichung < -100)
{
ists++;
}
if(ists >= (ABT))
{
flankelinks++;
i=i+ABT;
ists=0;
}
}
if(i==(ANZ-ABT))
{
uebertraglinks=ists;
}
ists=0;

}

for(i=0;i<=(ANZ-ABT); i++)
{

istsr=uebertragrechts;
uebertragrechts=0;

for(a=0;a<=ABT; a++)
{
abweichungr=feldrechts[i]-feldrechts[i+a];
if(abweichungr > 100 || abweichungr < -100)
{
istsr++;
}
if(istsr >= (ABT))
{
flankerechts++;
i=i+ABT;
istsr=0;
}
}
if(i==(ANZ-ABT))
{
uebertragrechts=istsr;
}
istsr=0;

}

vl=((flankelinks*60000)/t)/40;
vr=((flankerechts*60000)/t)/40;

flankelinks=0;
flankerechts=0;

tse=Gettime();
tsys=tse-tsa;
}




Vielleicht kannst du ihn verbessern, oder mir sagen, dass er doch Müll ist, aber er funktioniert teilweise wie gesagt.

bis später
mfg theodrin

waste
20.05.2006, 17:43
Hallo!

Probiert mal folgendes Programm:


/************************************************** *****************************
*
* Description: Asuro fährt geradeaus
*
************************************************** ***************************/
#include "asuro.h"
#include <stdlib.h>


int main(void)
{
unsigned char speed, flagl=FALSE, flagr=FALSE;
unsigned int data[2];
int wegl, wegr, diff;
int speedLeft,speedRight;
Init();
MotorDir(FWD,FWD);
StatusLED(GREEN);
speed = 150;
speedLeft = speedRight = speed;
wegl=0; wegr=0;
while(wegl<333){
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--; // fahre geradeaus
else if (diff<0) speedLeft--;
else {speedRight=speed; speedLeft=speed;}
if (speedRight<0) {speedRight=0;}
if (speedLeft<0) {speedLeft=0;}
MotorSpeed(speedLeft,speedRight);
}
MotorDir(BREAK,BREAK);
while(1);
return 0;
}


Damit fährt mein Asuro schön geradeaus.

Gruss Waste

Arexx-Henk
21.05.2006, 16:24
Hallo,

@theodrin
Vielleicht kannst du ihn verbessern, oder mir sagen,
dass er doch Müll ist, aber er funktioniert teilweise wie gesagt.
ich mochte gerne etwas mehr Kommentar dazu lesen...
irgendwo scheint mir dein Program etwas zu kompliziert
Du schreibst: drei Methoden, ich bin jetzt bei 15 oder 16...;-)
Bei jedem Methode lernt sich wieder etwas neues.


@waste
Ich hab dein Program ausprobiert.
Da fahrt die Asuro erstaunlicherweise gerade.
Interessant, wenn mann dass eine Rad mehr oder
weniger blokkiert dreht sich dass andere Rad
gleich langsamer!
Finde dass ein einfaches robustes Program.
Aber wenn der Asuro an das Fenster heran kam
hort er auf gerade zu fahren.
Dein Program arbeitet mit festen vergelichswerte
fur die Odometrie. Da sollte vielleicht noch
etwas variabeles dazu kommen.

@jeden
Ich mochte meinen Prinzip noch mal besser studieren.
Ich mochte gerne wissen warum meine Odometriemessung
z.B. bei theodrin nicht geklappt hat.

Wenn ihr wollt, ladet mal mein neues test Program
dass hier zugefugt ist und schick mir bitte eure
Odometrie daten.

Dass zugefugte Program macht folgendes:

- Asuro startet mit ein durchschnitt geschwindigkeit
- nach 1 Sekunde fahren messt er 250 mal beide odometriewerte
(jeden millisekunde) Die messung daurt 0,25 Sekunde
- Asuro haltet

- startet Hyperterminal
- drucke auf eine beliebige Asuro Taste
- Asuro sendet die gemessene Daten zum Hyperterminal

Schick mir mal bitte die Daten.

Die gemessene Werte sind die 8 hochsten bits vom
10 bit Werte. So Werte von 0 bis 255 werden erscheinen.

Mit Microsoft Excel kann mann dann einfach ein Grafik
daraus machen.

Oder gucke sonst auf meine website. Dort kan
mann dass Program bekommen und meine
Grafiken anschauen.

http://home.planet.nl/~winko001/index.htm

(Logging Odometer values to Hyperterminal)

Ich hab eine Grafik versucht hier zu zu fugen.

Gruss

Henk

theodrin
21.05.2006, 18:01
Hallo!

An Waste:
Hab dein Programm ausprobiert und hab erstmal gestaunt. So toll gerade wie er gefahren ist, ist er bei mir noch nie. Aber ich war auch mal da wo dein Programm steht. Es hat bei Dunkel - bis Halbdunkel sehr gut, ja sogar phänomenal funtkioniert. Dann ist er in eine von Sonne beleuchtete Gegend gekommen und er machte nur noch Müll. Aber in Dunkln - extrem gut.

Ich werd jetzt dein Programm genauer studieren. Henk hat recht, wenn er sagt, dass die Vergeleichstwerte flexibel sein müssen. Sonst hat mal halt auf einmal Probleme. So wie ich bei Sonneneinstrahlung.

theodrin

Vogon
21.05.2006, 23:38
Arexx-Henk,
ich habe mit deinem Programm meinen ASURO getunt. =P~


Left min/max, right min/max values
1. +00066 +00202 +00138 +00212 // Test dunkel
2. +00061 +00199 +00135 +00209 // Test mit Licht
3. +00007 +00140 +00007 +00134 // Test 2 cm unter meiner Schreibtischlampel
4. +00009 +00199 +00011 +00195 // Test " " + Haube auf Lichtschranke
5. +00056 +00201 +00105 +00205 // Test " " + Haube + schwarzen Filzstift auf der Encoderscheibe.

Arexx-Henk
22.05.2006, 08:03
Hallo vogon,

danke fur die datalogs, die Daten wird ich benutzen bei meinem Programme.

Die erste zwei datalogs haben irgendwo ein fehler, vermutlich ein Datenempfang Storung. Die Werte hab ich dann handmassig geandert.

Wass ist mit 11L?

Ich wollte die Daten wie Grafiken zufugen, aber die Datei
ist scheinbar zu gross (400KB).

Du kannst ihn hier downloaden:

http://home.planet.nl/~winko001/vogon/Vogon_datalog_graphics.zip

Gruss

Henk

Arexx-Henk
22.05.2006, 11:21
Hallo waste,

Ich mochte mich gerne etwas mehr vertiefen in die Asuro Fahrtkontrolle.
Dazu habe ich dein Program nochmal angeguckt um aus zu finden warum es sich hier handelt. Ich mochte es hier mal posten denn vielleicht hilft es jemanden.

Einige Bemerkungen:

- so ein schwarzes oder weisses flach am odo Rad nenne ich mal 'Odoflach'

- da wird immmer uber 'speed' gesprochen aber in wirklichkeit ist es eher
ein Mass fur die zugefuhrte Leistung. (Power)


Dein Program:

- zahlt den anzahl an vorbeigehende Odoflache

- zahlt links und rechts unabhangig von einander

- messt einmal pro 240us beide odometers

- fahrt ein rad schneller als die ander wird vom schnelleren rad die
motor Leistung mit 1 verringert

- fahren beide rader gleich schnell, wird die standard
Leistung an beide motoren zugefuhrt


Zusammengefasst:

- ein schnelleres Rad passt sich seine geswindigkeit an an dass
langsameres Rad

- jeden 240us wird die leistung vom eine oder beide
motoren korrigiert

- es regelt sich die gleichumdrehung von beide Rader

- es wird eine feste Leistung zugefuhrt

- die Asuro geschwindigkeit hangt ab vom reibung



Mit dem Oszi gemessen in Freilauf: 14,3ms zwischen zwei
gleichfarbigen odoflache.
Da es 5 gleichfarbigen odoflache fur jedes 1 centimeter
Radversetzung braucht ist die Zeit fur 1cm Radversetzung
gleich wie 5 * 14,3ms = 71,5ms/centimeter = 14cm pro Sekunde

Da flashst mir ein Idee fur den Augen, vielleicht ist so ein
Wie-Gross-Ist-Meine-Asuro-Mechanische-Reibung test zu machen...;-)
(inklusief Batteriespannung Messung)


Gruss

Henk

waste
23.05.2006, 18:18
Hallo Henk,

deine Analyse von meinem Programm ist richtig. Ich habe auch noch eine Variante des Programms, da wird die Variable speed anstatt um eins zu erniedrigen gleich auf 0 gesetzt. Man braucht dann nicht mehr den Grenzwert von 0 zu überprüfen und das Programm ist dadurch kürzer.

Ich habe in meinem Archiv auch noch ein Programm mit Geschwindigkeitsregelung gefunden. Das Programm habe ich mal ins Codefenster kopiert, ohne es nochmal zu prüfen. Es sollte eigentlich funktionieren. Leider hat es wenig Kommentare, aber dafür ist der Lerneffekt beim Analysieren größer. :)

Gruß Waste


/************************************************** *****************************
*
* Description: Geschwindigkeitsregelung
*
************************************************** ***************************/
#include "asuro.h"
#include <stdlib.h>
volatile unsigned char count36kHz;
volatile unsigned long timebase;
unsigned int takte;
int w, x, e, y, kp, ki, esum[2];
unsigned char speedLeft,speedRight;
unsigned long zeit[2];

void ReglerL (void)
{
takte = (timebase*256)+count36kHz - zeit[0];
zeit[0]=(timebase*256)+count36kHz;
x = 27000/takte;
e = w - x;
esum[0] = esum[0] + e;
if (esum[0] < -130) {esum[0] = -130;}
if (esum[0] > 130) {esum[0] = 130;}
y = kp*e + ki*esum[0];
if (y < 0) {y = 0;}
if (y > 255) {y = 255;}
speedLeft = y;
MotorSpeed(speedLeft,speedRight);
}

void ReglerR (void)
{
takte = (timebase*256)+count36kHz - zeit[1];
zeit[1]=(timebase*256)+count36kHz;
x = 27000/takte;
e = w - x;
esum[1] = esum[1] + e;
if (esum[1] < -130) {esum[1] = -130;}
if (esum[1] > 130) {esum[1] = 130;}
y = kp*e + ki*esum[1];
if (y < 0) {y = 0;}
if (y > 255) {y = 255;}
speedRight = y;
MotorSpeed(speedLeft,speedRight);
}

int main(void)
{
unsigned char flagl, flagr, sw;
unsigned int data[2];

Init();
MotorDir(FWD,FWD);
MotorSpeed(150,150);
kp = 18; ki = 2; //ki enthält bereits Multiplikation mal dt=0.01
w = 75;
sw = PollSwitch();
if (sw & 0x01)
{w=5;}
if (sw & 0x02)
{w = 10;}
if (sw & 0x04)
w = 20;
if (sw & 0x08)
w = 40;
if (sw & 0x10)
w = 75;
if (sw & 0x20)
w = 150;
OdometrieData(data);
OdometrieData(data);
if (data[0] > 600) flagl = TRUE; // Flag setzen
else flagl = FALSE;
if (data[1] > 600) flagr = TRUE; // Flag setzen
else flagr = FALSE;
zeit[0]=(timebase*256)+count36kHz;
zeit[1]=(timebase*256)+count36kHz;
while(1){
OdometrieData(data); // messe Odometrie
if ((data[0] < 550) && (flagl == TRUE)) {flagl = FALSE; ReglerL();}
if ((data[0] > 650) && (flagl == FALSE)) {flagl = TRUE; ReglerL();}
if ((data[1] < 550) && (flagr == TRUE)) {flagr = FALSE; ReglerR();}
if ((data[1] > 650) && (flagr == FALSE)) {flagr = TRUE; ReglerR();}
}
return 0;
}

kungfuman
21.06.2006, 17:13
vllt. kann mir da jemand helfen : also...
ich hab mal ne frage zu deinem code waste !

wozu hast du die flags benötigt ??? für mich ist das noch ein rätsel, ansonst versteh ich grob wie das programm funktioniert



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++;}


wäre echt nett wenn mir jemand erklären könnte wozu die dienen...also man braucht sie glaube ich irgendwie bei der bestimmung von den rädern welches schneller ist oder ???? das ist nur geraten...also bitte kan mir es jemand erklären, wäre echt nett von euch

MfG kungfuman

Sternthaler
21.06.2006, 19:01
Hallo kungfuman,
nee, nee, die Flags haben nichts mit dem Geradeausfahren zu tun.
Die werden benötigt, damit die Zähler wegl bzw. wegr NUR dann mit dem ++ hintendran hochgezählt werden, wenn ein Wechsel von Schwarz auf Weiss bzw. von Weiss auf Schwarz erkannt wird.
Wenn also einmal der Wert in data[0] > 650 wurde, und das flagl halt noch false ist, nur dann wird EINMAL wegl hochgezählt. Es wird dann aber eben auch das flagl auf true gesetzt. Nun kann die Schleife so oft sie will die Odometriedaten lesen, der Wert in data[0] ist dann bis zum nächsten Helligkeitswechsel immer noch > 650, aber ein weiteres zählen erfolgt eben erst dann, wenn der Wert wieder unter 550 gesunken ist und das Flag dann umgeschaltet wird.
Somit wird erreicht, dass ein HelligkeitsWECHSEL nur einmal den Zähler erhöht.

Hoffe, das war verständlich.

EDIT: 22.06.06 Oh man oh man, was waren da Rechtschreibfehler drin.

kungfuman
21.06.2006, 21:34
hey ! dankeschön Sternthaler !
echt nett von dir mir das zu erklären !
Ich habs gerafft :D:D:D
ich freu mich , danke nochmal

MfG kungfuman

flobot
03.09.2006, 13:29
Das ist mein erster Eintrag in diesem Forum. Ich habe von euren Darstellungen gelernt, vielen Dank! Nun möchte ich auch einen programmvorschlag beisteuern: Es benutzt im Gegensatz zu dem Programm von waste variable Entscheidungswerte für die Zählung der OdoFeld-Wechsel.

#include "asuro.h"
#include "stdlib.h"


int countChanges(int *d);
int findMd(int *d);

int popSize=500; //Anzahl der Messwerte, die zur Regelung gesammelt werden



int main (void){

int speedL = 200;
int speedR = 200;

int odoIn[2]; //zum Einlesen der Odometriedaten
int dL[popSize], dR[popSize]; //speichern Odometriedaten
int changesDiff=0; //Differenz der OdoFeldWechsel zw. l. & r. Rad

Init();
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(speedL, speedR);


while(1){
int i;

for (i=0; i<popSize; i++){
OdometrieData(odoIn);
dL[i] = odoIn[0];
dR[i] = odoIn[1];}

changesDiff=countChanges(dL)-countChanges(dR);


if (changesDiff>0){
if (speedR<255&&speedL>0){
speedL--;
speedR++;}}

else if (changesDiff<0){
if (speedL<255&&speedR>0){
speedL++;
speedR--;}}

MotorSpeed(speedL, speedR);}

return 0;}





int countChanges(int* d){
int i;
int color; //0=black, 1=white
int changes=0; //Anzahl der OdoFeldWechsel
int md=findMd(d); //Helligkeits-Median

if (d[0]<md) color=0; //erster Messwert war schwarzes Feld
else color=1; //bzw weisses Feld

for(i=0; i<popSize; i++){
if (d[i]<md && color==1){ //Wechsel von weiss nach schwarz
color=0;
changes++;}

else if(d[i]>md && color==0){ //... von s nach w
color=1;
changes++;}}

return changes;}





int findMd(int* d){
int i, j;
int md=0; //Median
int c; //zählt den Rang des Wertes

for (i=0; i<popSize; i++){
c=0;

for(j=0; j<popSize; j++){
if (i!=j && d[i]>d[j]) c++;} //Bestimmung der Helligkeits-Rangordnung

if (c>=popSize/2){ //wenn mind.s die Hälfte aller Werte kleiner sind
if (md==0) md=d[i]; //...dann übernehme den Wert als Median
else md=(d[i]<md)?d[i]:md;}} //...finde den kleinsten Wert der oberen Hälfte

return md;}


Es speichert 500 Odo-Werte und ermittelt den Median, also den Wert, unter dem min. 50% der Werte liegen. Damit fährt er meistens relativ gerade. Ich habe es für speed 90 - 200 getestet. probiert es mal aus und sagt mir was ihr davon haltet,

beste grüsse

florian


PS.: kann mir jemand von euch sagen, in welchem Takt die Odometriedaten eingelesen werden?


edit: hups, hatte RWD statt FWD bei MotorDir.

Sternthaler
06.09.2006, 01:04
Hallo flobot,
erst einmal herzlich willkommen hier im Forum.

Dein Ansatz zur Geradeausfahrt finde ich nicht schlecht. Leider ist nicht immer alles so einfach wie es scheint.
Ich habe mal ein paar Fotos (Film ist zu viel Datenzeugs) angehängt um dir mal das Problem mit meinem Asuro zu zeigen.
Bei mir ist der rechte Motor miserabel (Tschuldigung, einige von euch wissen das schon.), so dass mein Asuro immer mit einer Rechtskurve startet wenn man nichts dagen tut.
Trotzdem ist dein Ansatz auch bei meinem Asuro ungefähr nach 3 Metern funktionsfähig und der Asuro fährt recht ordentlich geradeaus. Klasse Arbeit!

Was ich an deiner Lösung besonders toll finde, ist dass die Reglung ja einen interessanten Ansatz zum lösen des Umgebungslichtproblems hat.
Hierzu ist meines Wissens nach noch kein 'herzhafter' Versuch im Forum aufgetaucht. Ich habe auch gleich eine dicke Taschenlampe zum ärgern vom Asuro rausgekramt und bin echt begeistert wie klein die Abweichungen vom rechten Weg dann sind. Licht aus machen und freudig den geraden Weg sehen war auch nicht schlecht.
Natürlich kommt jetzt nach dem Lob auch gleich das große Fragezeichen in Form von 2 Anmerkungen.
Wenn du auch den Asuro benutzt, hast du als CPU den ATmega8 eingebaut. Das Ding hat gerade mal 1K-Byte RAM.
Du hast in deinem Program aber schon 2 int-Variablen (a 2 Byte) als Array mit jeweils 500 Elementen angelegt. Somit benötigst du eigendlich 2 * 500 * 2 Byte. Ist ein bisschen zu viel. Ich habe bei mir im Programm das ganze über popSize=220 auf 'nur' 880 Byte reduziert. Dann bleibt noch ein Rest für die anderen Variablen und hoffentlich genug für den Stack übrig.
Als 2-tes finde ich deine geschachtelte Schleife in der Funktion findMd sehr 'brutal'. Du loopst mit deinen 500 aus popSize immerhin 250.000 mal da drin rum. Ist es wirklich sinnvoll den Median zu berechnen? Wäre hier ein Mittelwert nicht genauso gut?


Nun noch eine kleine Überschlagsrechnung zu deiner Frage zum Takt der Odometriedaten.
Überschlagen deshalb, da ich nicht zu jedem Maschinenbefehl nachgesehen habe, ob da 1 oder 2 oder auch mal 3 Takte verballert werden.
Ich habe im compilierten Output einfach mal nur die Assemblerbefehle gezählt. Das sind die Angaben mit dem T dahinter.

Deine Loop über OdometrieData
popSize * (29T + 1 * OdometrieData)

Funktion OdometrieData
31T + 2 * ADC

ADC-Wandlung (Hier ist die Zeitangabe recht genau. Maximal plus einen Quarz-Takt)
Quarztakt (1/8Mhz) * 64 (ADC-Vorteiler-In-Init) * 13
(Die 13 gilt ab der 2.ten Wandlung nachdem ADEN eingeschaltet wurde. Für die erste Wandlung muss da ne 25 hin. Vergessen wir das mal ganz schnell wieder, ist ja Haarspalterei)


Ergibt ca.:
ADC-Wandlung = (1 / 8000000) * 64 * 13 = 0,000104 Sekunden
Funktion OdometrieData = 31T + 2 * 0,000104 = 0,000211875 Sekunden
Deine Loop = 500 * (29T + 1 * 0,000211875) = 0,10775 Sekunden

Die Loop in findMd müsste ca. folgende Zeiten haben:
500 * (10 + 2 + 500 * (6 + 17) + 33) = 5772500 Takte = 0,7215625 Sekunden

In Summe verbrennt dein Programm also ca.
2 * findMD + 1 * Loop-Odometrie = 1,55 Sekunden für eine Schleife im Main

Wenn ich für popSize 220 einsetzet, komme ich auf ungefähr 0,68 Sekunden.

Wenn ich die Zeit mal nehme und ein bisschen weiterrechne kommt da folgendes raus:
Ich weiss von meinem Asuro, dass ich ungefähr eine Differenz von 50 in MotorSpeed brauche um halbwegs gerade zu fahren.
Somit brauche ich also ca. 25 mal die Main-Loop. Das sind dann ca. 17 Sekunden.
Da ich die Startgeschwindigkeit mit 150 angegeben habe sollten danach ungefähr die Werte für links und rechts von 125 und 175 rauskommen.
Wenn ich nun schätze, dass ich bei diesen Werten ca. 20 cm pro Sekunde zurücklege und dann knapp 17 Sekunden brauche, müsste mein Asuro nach ca. 340 cm geradeaus fahren.
Scheint also mit meinen oben geschätzten 3 Metern ganz gut im Rennen zu liegen.

So, ich hoffe hier niemanden allzu stark gelangweilt zu haben.

@flobot: Mach weiter so mit guten Ideen.

jeffrey
06.09.2006, 13:07
hallo,
was haltet ihr davon z.b die letzten 10 werte zu mitteln, um so einen dynamischen mittelwert zu erhalten, so kann dann auch auf lichtänderungen während der fahr reagiert werden. oder dass man den nulldurchgang der ableitung bestimmt, um so die extrema zu bestimmen, für die geschwindigkeitsmessung ist es ja egal, ob ein feld weiß oder schwarz ist, es ist nur wichtig zu wissen, ob man in der mitte des feldes ist.
als regler würde ich mal pd verwenden, das ist gut gegen die schwingungen, kann durch den fehlende i anteil aber zu bleibender eegelabweichung, sprich einem langsamen wegdriften führen.
mfg jeffrey

Sternthaler
06.09.2006, 22:05
Hallo jeffrey,
die Idee sieht erst mal gut aus.
Wenn man sich die Daten aus dem Diagramm von Arexx-Henk hier im Thread aber mal ansieht (und selbst schon solche Daten erzeugt hat), sieht man an dem Diagramm, dass Arexx-Henk bzw. sein Asuro da relativ langsam gefahren ist. --> Ergibt eben viele Messpunkte in einer Periode. Dein Vorschlag nur über 10 Messwerte zu mitteln, verschiebt die 'Mittellinie', also unseren Schwellwert für Hell-Dunkel-Wechsel, bei diesen Daten recht häufig. Bleibt aber tatsächlich immer schön zwischen den Spitzen. Wenn aber der Asuro mal so richtig Gas gibt, dann bekommen wir mal gerade 5 bis 7 Messungen (80 Takte/Radumdrehung Scheibe) pro Periode. Reicht eigendlich um daraus so halbwegs einen brauchbaren Mittelwert zu bilden.
Nun aber das Problem. Der Asuro fährt extrem langsam oder steht sogar bzw. blockiert. Wenn man nun weiter mitteln würde, dann verlagert sich unser Schwellwert im Extremfall nach ganz oben oder unten. Damit können wir aber im weiteren, wenn der Asuro wieder fährt, nichts mehr anfangen da es jetzt wieder etwas dauert bis der Durchschnitt wieder im Mittel liegt. Also zählen wir erst mal keine Helligkeitswechsel und so verlieren wir schon wieder ein paar Takte.
Ich bin mir auch sicher, dass kein Regler dieses Problem lösen wird, solange der Ansatz Daten zu sammeln und 'irgenwie' auszuwerten nichts davon weiss, ob überhaupt sinnvolle Daten kommen.

Hier muessen wir meiner Meinung nach noch ein bisschen weiter grübeln.

jeffrey
06.09.2006, 22:51
hi,
ob das rad dreht oder nicht weiß man ja, weil man das pwmsignal kennt, man kann auch was einbauen, dass sich der wert um mindstens 50 oder sowas ändern muss, damit der neue mittelwert berechnet wird. man kann auch die anzahl der werte zum mitteln von der aktuellen geschwindigkeit abhängig machen, je langsamer, desto mehr werte. aber ich denke, dass sollte auch ohne anpassung kein problem sein(siehe skizze). der mittelwert steigt bei z.b. 10 werten schnell an, sodass die beiden nächsten peaks gut erkannt werden. deswegen auch auf eine feste anzahl der letzten werte begrenzen.
sonst mal die idee mit der ableitung probieren, da sollten solche probleme nicht auftreten.
ein problem könnten periodische lichtänderungen von außen werden.
mfg jeffrey

stochri
07.09.2006, 00:12
Hallo Sternthaler


Nun aber das Problem. Der Asuro fährt extrem langsam oder steht sogar bzw. blockiert. Wenn man nun weiter mitteln würde, dann verlagert sich unser Schwellwert im Extremfall nach ganz oben oder unten.

Folgender Vorschlag:

Maximum und Minimum verwenden.

Es wird eine Mittelwertspeicher für Maximalwerte und ein Mittelwertspeicher für Minimawerte erzeugt.

Ein Messwert wird dem Maximalwertspeicher zugeschlagen, sobald er 25 Digits über dem Minimalwertspeicher liegt.

Nach wenigen Umdrehungen müsste dann die obere und untere Schaltschwelle gefunden sein.

Gruss,
stochri

Torr Samaho 2
07.09.2006, 11:31
Hallo,
um die Störungen durch Fremdlicht wegzubekommen, könnte man doch einmal "dunkel" (LED aus) und einmal "hell" (LED an) messen. Die Differenz ist dann der wahre Wert.
Gruss

jeffrey
07.09.2006, 12:44
hi,

um die Störungen durch Fremdlicht wegzubekommen, könnte man doch einmal "dunkel" (LED aus) und einmal "hell" (LED an) messen. Die Differenz ist dann der wahre Wert.

ich denke nicht, dass das funktioniert, weil man ja nicht weiß, ob zwischen ein und ausschalten ein farbwechsel stattgefunden hat.
mfg jeffrey

Sternthaler
08.09.2006, 02:05
Hallo zusammen. (hier wird es ja richtig aktiv!)


einmal "dunkel" (LED aus) und einmal "hell" (LED an) messen
Eigendlich spielt uns hier die Hardware einen Streich, da die Schaltung auf dem ASURO es 'offiziell' nicht zuläßt die Odometrie-LED's auszuschalten und gleichzeitig eine Messung zu machen.
Ich hatte vor einiger Zeit mit folgenden Macros schon mal versucht die Hardware zu überlisten: (Geht auch)

#define LED_RAD (1 << PD7)
#define PIN_RAD_OUTPUT DDRD |= LED_RAD
#define PIN_RAD_INPUT DDRD &= ~LED_RAD

#define LED_RAD_ON PIN_RAD_OUTPUT; PORTD |= LED_RAD
#define LED_RAD_OFF PIN_RAD_OUTPUT; PORTD &= ~LED_RAD
#define LED_RAD_DARK LED_RAD_OFF; PIN_RAD_INPUT
Hier habe ich DREI Zustände für die LED am RAD: ON, OFF und DARK

Der Trick an der Sache ist, dass ich den Port-Pin als Eingang setze. Somit ist da kein definiertes Signal vorhanden und der Pin 'floatet', soll heissen er passt sich der Spannung von ausserhalb an.


Für die linke Seite der Odometrie sind im Schaltplan nun folgende Bauteile beteiligt:
VCC an R18 an Port C1 (AD-Wandler)
an R18 an T11 (Odo-Sensor) an Masse
an R18 an D15 (Brems-LED) an R19 an Port D7 (FLOATEND also wenig Einfluss)
an R22 an D13/D14 (Odo-LED) an Masse (STROM)
Wir haben also den Odo-Sensor über den R18 mit Spannung versorgt, ohne über Port D7 Strom auf die Odo-LED zu geben und die Odo-LED zum 'hellen' leuchten zu bringt. Es fließt nur noch Strom über R18/D15/R19/R22 und D13/D14 durch unsere Odo-LED. Dieser Strom ist KLEINER als über Port D7 und somit lassen sich 2 Messungen mit unterschiedlich starker Beleuchtung durch die Odo-LED durchführen.

Mit dieser Methode habe ich auch schon einige Messwerte bekommen.
Siehe EXCEL-Anhang (pure Nettodaten mit einer kleine Hilfe zu den einzelnen Diagrammen bzw. Daten)
Leider kann ich aktuell, und zur Zeit der Datenaufnahme, mit den Daten nichts anfangen, da sie nicht so sind, dass ich daraus eine direkte Berechnung des zu benutzenden Schwellwertes hinbekommen.


ich denke nicht, dass das funktioniert, weil man ja nicht weiß, ob zwischen ein und ausschalten ein farbwechsel stattgefunden hat.

Interessanter Einwand, da muss ich mal drüber nachdenken.

Hallo stochri,
auch dein Eintrag ist wie immer eine Überlegung wert.
Ich bin allerdings, aus haarspalterischen Gründen, insgesamt gegen eine Mittelwertbildung egal in welcher Form. (Mal sehen, wann ihr mich doch dazu bringt.) Mein Grund für den Ansatz mit der Hell- / Dunkel-Messung ist, dass ich ohne eine Bewegung versuchen will den Mittelwert zu bekommen. Bewege ich den ASURO ohne den Mittelwert zu kennen, verliere ich (bis jetzt) meistens zwei bis drei Takte der Scheibe. Da jeder Helligkeitswechsel aber 1,5 mm Fahrweg bedeutet sind das schon über 3 mm Positionsverlust.
(Und schon wieder einmal) Rechter Motor ist Schrott. Somit fährt mein ASURO immer NUR links an und damit habe ich einen nicht zu unterschätzenden fehlerhaften Drehwinkel, der dann den Nikolaus bei Tag und Nacht zerstören würde.

EDIT: 08.09.06 09:20 Ich hatte mich bei den LEDs mit der Beschreibung vertan. Odo-LED und Brems-LED vertauscht. Ist nun korrigiert.

jeffrey
08.09.2006, 13:40
hi sternthaler,
deine idde mit dem bestimmen der werte im stand ist ja ganz gut, dann weiß man auch, dass kein farbwechselstattfindet.
meine ideen zielen eher darauf ab lichtwechsel während der fahrt, z.b wenn er vom schatten in die sonne fährt, oder so zu kompensieren, weil dann die am anfang ermittelten werte ja auch nicht mehr stimmen. eine möglichkeit wäre beides zu kombinieren, sprich am anfang led an und aus, um von anfang an einen an die umgebungsbedinungen angepassten startwert hat, und dann während der fahrt auf die mittelwert methode zu wechseln.
mfg jeffrey

Sternthaler
11.09.2006, 23:27
Hallo Leute,
gut dass man Kollegen hat.
Anstatt, wie bei der Linienverfolgung, Hell- und Dunkelwerte von einander abzuziehen, meinte der Kollege, Hell- und Dunkelwerte mal zu dividieren. Die Ergebnisse sahen zwar auch nicht besonders vielversprechend aus, aber folgendes ist dabei rausgekommen:

Sortiert man die Mittelwerte der DUNKELWERTE aufsteigend und trägt das Ergebnis der Division Mittelwert(Hell) / Mittelwert(Dunkel) in einer XY-Ansicht in Excel ein, bekommt man folgende Kurve:

Sternthaler
11.09.2006, 23:37
.. und weiter im Text:

Excel kann auf diese Kurve eine Trendlinie erzeugen. Ich habe eine 'Polynomische' Trendlinie mit 'Reihenfolge' 6 erzeugt. Sie passt am besten auf die Messwerte. Excel liefert dabei die Formel y = 9E-17x^6 - 3E13x^5 + 4E-10x^4 - 2E-07x^3 + 9E-05x^2 - 0,0155x + 1,2523 um diese Trendlinie zu berechnen. Nimmt man nun diese Formel und läßt Excel sie berechnen, kommt aber totaler Schrott dabei heraus, da die Faktoren für die einzelnen Exponenten leider nur mit einer Stelle angegeben werden.
Ausserdem möchte ich bezweifeln, dass wir dem ASURO so eine Formel zum rechnen vorwerfen sollten.

Der nächste Schritt von mir war dann, dass ich einfach eine X-Spalte (Dunkelwerte) von 0 bis 900 in 25'er Abständen angelegt habe und dazu die Y-Werte aus der Excel-Trendlinie 'abgeschrieben' habe. Hierrauf noch eine Trendlinie (auch 'Polynomische' mit 'Reihenfolge' 6) durch Excel legen lassen und die 'abgeschriebenen' Y-Werte so angepasst, dass diese Kurve mit der Trendlinie übereinstimmt.

Diese Tabelle habe ich dann in allen, in den Reitern hinterlegten, Messwerten benutzt um die Schwelle für die Odometriemessung zu berechnen und in die echten Messdaten einzutragen.
In den Reitern 017H01m100 und 018H00m100 sind Messwerte die NICHT zur Ermittlung dieser Tabelle beigetragen haben. Sie zeigen, dass es zumindest da funktioniert.
Weiterhin habe ich mir die Daten dann nochmal angesehen und den Hysteresewert abgeschätzt und auch schon mal in der folgenden Tabelle eingetragen.

Folgende Tabelle ist entstanden: (Zu finden im Anhang im Reiter Formel Spalte I, L und M von Zeile 3 bis 39).


Dunkel Faktor Hysterese
0 1,000 2
25 0,790 2
50 0,600 2
75 0,460 2
100 0,350 2
125 0,270 2
150 0,220 2
175 0,175 2
200 0,150 5
225 0,135 5
250 0,132 5
275 0,130 5
300 0,128 5
325 0,131 10
350 0,135 10
375 0,138 10
400 0,142 10
425 0,145 10
450 0,150 25
475 0,158 25
500 0,168 25
525 0,177 25
550 0,188 25
575 0,205 50
600 0,225 50
625 0,250 50
650 0,275 50
675 0,300 50
700 0,340 50
725 0,390 50
750 0,430 50
775 0,495 50
800 0,560 50
825 0,650 50
850 0,750 50
875 0,870 50
900 1,020 50

Achtung: Für Dunkel = 0 und ab Dunkel = 900 wird der Faktor 1 bzw größer. Eigendlich bedeutet dies, dass der Odo-Messwert MIT unserer LED-Beleuchtung dunkler werden muss als wenn die LED-Beleuchtung aus ist. Was ist hier falsch??? (Ich habe allerdings als maximalen Dunkelmesswert bis jetzt erst 818 bekommen. Wirklich dunkle Dunkelkammer. Und für strahlenden Sonnenschein als Minimum 28. So dass auf dieser Seite möglicherweise kein Problem auftreten wird.)


Noch habe ich kein Programm geschrieben, in welchem diese Daten genutzt werden. Ich bin mir auch ziemlich sicher, dass die Kurve im unteren Bereich (10 bis 150) noch viel zu wenig echte Messwert hat um tatsächlich korrekt zu liegen, da gerade in diesem Bereich die Steigung der Kurve besonders groß ist, so dass hier Fehler auch große Auswirkungen haben. Wahrscheinlich muss die Tabelle in diesem Bereich auch noch mehr Zwischenwerte bekommen. Dafür lassen sich bestimmt Zwischenwerte im Bereich 350 bis 700 eliminieren.
Hier können noch, auf Teufel komm raus, Messkurven gesammelt werden ;-)


Fazit:
- Dunkelmessung machen
- In der Tabelle den besten Eintrag aus Spalte 'Dunkel' suchen
- Faktor und HYSTERESE der Tabelle entnehmen
- Dunkelmessung mit Faktor multiplizieren. Ergebniss ist SCHWELLWERT
- Hellmessung machen
- Mit Schwellwert und Hysterese, mit bekanntem Code, den Tik-Zähler berechnen.

(Wenn das mal gut geht.)

@jeffrey
Stimmt, meine Methode merkt nicht, dass sich das Rad schon weitergedreht hat. Dein Einwand ist immer noch gültig. (Geständnis: Ich habe da immer noch nicht nachgedacht.) Vielleicht ist dein Vorschlag mit dem Startwert aus der Dunkelmessung und den Mittelwerten da hilfreich.

stochri
12.09.2006, 09:43
Hallo Sternthaler,
beim Überfliegen Deiner Excel-Datei radS.xls ist mir aufgefallen, dass bei höheren Umdrehungsgeschwindigkeiten das Signal ziemlich zerhackt wirkt.
Das habe ich auch schon mal bei meinen Messungen beobachtet. Mir scheint die Abtastrate für die Analogwerte zu niedrig um das Signal vollständig zu erfassen.

Deshalb ein Vorschlag, der die Messung wesentlich verbessern könnte:

Abtastrate deutlich erhöhen ( Interruptroutine in Assembler schreiben ? )

Gruss,
stochri

Sternthaler
12.09.2006, 15:15
Hallo stochri,
ich habe mal 3 Diagramme angehängt, damit wir uns über das gleiche Unterhalten.

1. rads-002H6m000-langsam.jpg
2. rads-005H7m100-schnell.jpg
3. OdoHellDunkel-009H9m100-sehr-hell.jpg

In allen Diagrammen habe ich von Exel jetzt mal die * an den Messpunkten zeichnen lassen. Da sieht man, wie schnell/langsam ich messe.

Zerhackt finde ich nur Diagramm 3.
Dort ist allerdings der Extremfall mit tierisch schönem Sonnenschein zu sehen. (Y-Kurve hat sehr kleine Werte) Hier gibt es auch mit meinen neuen Rechnungen weiterhin die meisten Probleme.

Assembler ist ja gut, aber zum einen lese ich die Sensoren erstmal im Interrupt-Betrieb, und zum anderen habe ich ganz bewusst eine Bremse eingebaut, da die LED's nicht schnell genug an und aus gehen. -> Stom an, LED fängt gemütlich mit einer Ladekurve an Licht zu machen. Stom aus, LED dimmt 'langsam' herrunter. Dieses Verhalten habe ich mit dem Oska gemessen und habe in der Timer-Funktion einige defines zum bremsen eingebaut damit die LED's eben genügend Zeit bekommen so richtig an bzw. aus zu sein.
Im Moment sehe ich aber in meinen Kurven noch nicht, dass ich an der Grenze mit der Geschwindigkeit liege, da ich pro Halbwelle immer noch viele Messdaten bekomme.

upaucc
01.12.2006, 10:34
ich habe auch nochmal eine Frage bezüglich waste's ersten codes:



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++;}

werden flagl und flagr nicht einfach nur benutzt damit die zähler gleichzeitig loslegen?
man könnte sie doch auch weglassen, dann werden doch auch jeder übergang von hell-dunkel gezählt oder nicht?

Sternthaler
01.12.2006, 18:10
Hallo upaucc,
blätter doch noch mal eine Seite in diesem Thread zurück. Ich hatte dort schon mal eine Erklärung zu den Flags abgeliefert.
Vielleicht findet waste ja die richtigen Worte um es verständlicher zu erklären, wenn du damit nicht zurande kommst und evl. doch noch mal nachfragen musst.

dorothea
21.01.2007, 16:43
Liebe geradeaus-Regler,

hatte auch so ein ähnliches Programm entworfen und würde gerne dem 3-Meter-Problem dadurch entkommen, dass ich den Offset zwischen dem Vorgabewert vom linken und vom rechten Rad im Permanentspeicher abspeichere.

Gibt es eine Möglichkeit, den Permantentspeicher des Prozessors aus C heraus anzusprechen? Beim Flashen kann ich ja schließlich auch das Programm permanent speichern - also vielleicht geht das auch mit Daten?

Die Idee ist also, den Asuro mal eine Zeit regeln zu lassen und ihn dann dazu zu bringen, dass er sich das, was er beim Regeln gelernt hat, bis zum nächsten Start merkt, damit er dann nicht wieder von vorne anfangen muss, seinen I-Anteil zu lernen.

stochri
21.01.2007, 20:14
Hallo Dorothea,

das Eeprom des ATmega8 kannst Du von C aus ansprechen. Die entsprechenden Routinen sind im AVR-Lib-C Manual ( google ) beschrieben ( eeprom.h muss eingebunden werden ).

Gruss,
stochri

damaltor
21.01.2007, 20:25
genau. den flash-speicher wirst du nicht einfach knacken können. allerdings kannst du auch einfach die richtigen werte experimentell bestimmen und dann ins eeprom schreiben. 512 bytes speicher ist zwar nicht viel, aber für sowas mehr als genug.

oder du verwendest einfach die go() funktion =)

stochri
26.01.2007, 21:19
Hallo Zusammen,

heute habe ich mal mit dem Oszilloskop die beiden Signale der Radencoder nachgemessen. Dabei bin ich zu folgender Erkenntnis gelangt:

1. Die Signale sind zerhackt, wenn sich das Codescheibenzahnrad entlang seiner Achse hin und her verschieben kann. Die Signalampltue ist am besten, wenn sich das Codescheibenzahnrad möglichst nahe an der IR-Diodes befindet. Ich habe das Problem dadurch gelöst, dass ich einen Draht auf die Platine glötet und so gebogen habe, dass er die Zahnräder von außen nach innen drückt.

2. Die Signalamplituden der beiden Fototransitoren sind unterschiedlich, weil sich die Sendedioden an unterschiedlichen Stellen bezüglich der Radachsen befinden. Auf einer Seite sitzt die Sendediode an der Radachse auf der anderes Seite sitzt der Fotodransistor an der Radachse. Wie ich das Signal der schlechten Seite verbessern kann, weiss ich noch nicht. Man könnte aber für beide Seite softwaretechnisch unterschiedliche Schwellen einführen.

So weit erst mal,
stochri

damaltor
26.01.2007, 21:31
eine kleine unterlegscheibe, von aussen auf die achse geklebt, oder ein spannring o.ä. helfen auch gegen die bewegung der räder. auch ein kleiner draht, der zu einem U gebogen wurde, und der auf das ende der achse geklemmt wird, geht.
man kann viel an den werten ändern (zum angleichen) indem man (vorsichtig) die led bzw den transistor ein wenig nach aussen oder innen biegt.

austin2power
30.01.2007, 06:54
Wieso hat eigentlich noch keiner 'ne Fast-Fourier-Transformation für die Frequenzerfassung der Odometriedaten benutzt?

Sollte doch das zuverlässigste und flexibelste sein, da es ermöglicht, den Offset herauszufiltern, und als Endergebnis die Grundfrequenz ausspuckt, demnach wären Umgebungslichtwechsel und Radstillstand kein Problem mehr - theoretisch die sauberste Lösung.

Viele Grüße
Henning

dorothea
30.01.2007, 21:02
Auch wir haben schon einige Versuche mit dem Geradeausfahren gemacht. Zuerst haben wir auch einfach die Flanken (S/W-Übergänge mit Hysterese) gezählt und die Leistungszufuhr zu den Motoren so geregelt, dass die Flankenanzahl links und rechts gleich ist.

Das Problem dabei war, dass im Falle, dass beide Räder sich wunderbar gleichschnell drehen, trotzdem z.B. links die Flanke früher vorbeikommt als rechts (wäre ja ein Zufall, dass immer beide Flanken genau im selben Takt vorbeikommen). So glaubt der Regler, dass das linke Rad sich schneller dreht und dass er links weniger Leistung zuführen muss (obwohl eh beide sich gleich schnell drehen und es sich nur um eine Phasenverschiebung handelt). Asuro macht also eine Kurve nach links. Gleich danach kommt rechts auch die Flanke, somit ist die linke und die rechte Flankenzahl wieder gleich und der Regler inkrementiert wieder die Leistungszufuhr am Linken Rad und Asuro fährt wieder geradeaus.
Das wiederholt sich bei jeder Flanke - in Summe entsteht so ein Links-Drift.

Mein Sohn Jakob (er ist 14) hat die Idee gehabt, nicht die Flankenzahl zu zählen, sondern die Anzahl der Takte zwischen zwei Flanken (ein Maß für den Kehrwert der Geschwindigkeit). So spielt die Phasenverschiebung keine Rolle. Funktioniert bei uns sehr gut

Programm berücksichtigt (noch) nicht unterschiedliche Lichtverhältnisse; gibt am Schluss den Offset aus - den sollte man als Startwert für das nächste Mal eingeben, damit Asuro gleich von beginn an geradeaus fährt.
Damit der inkrementelle I-Regler nicht überschwingt, wird der I-Anteil durch 16 dividiert (also um 4 Bit nach rechts verschoben).

Wir haben damit auf 3m Fahrt 5-10cm seitliche Ablenkung und 0-3mm Längenfehler.

Bitte wundert Euch nicht über die Veriablennamen - ist kindergerecht.






#include "asuro.h"
#define MAXI 3825 //(durch 15= 255)
#define StartwertUmSoVielBrauchtLinksMehrAlsRechts 0 // wird durch 16 dividiert
#define SchwellwertLinksSchwarz 675 //Schwellwert über dem das linke Zahnrad als Schwarz gilt
#define SchwellwertLinksWeiss 625 //Schwellwert unter dem das linke Zahnrad als Weiß gilt
#define SchwellwertRechtsSchwarz 675 //Schwellwert über dem das rechte Zahnrad als Schwarz gilt
#define SchwellwertRechtsWeiss 625 //Schwellwert unter dem das rechte Zahnrad als Weiß gilt
#define AnfangskoordinateX 0 //Anfangskoordinate in x-Richtung in mm, Ziel ist 0
#define AnfangskoordinateY -5000 //Anfangskoordinate in y-Richtung in mm, Ziel ist 0


int KoordinateX=AnfangskoordinateX;
int KoordinateY=AnfangskoordinateY;
int MerkerLinksWarSchonWeiss;
int MerkerRechtsWarSchonWeiss;
int MerkerLinksWarSchonSchwarz;
int MerkerRechtsWarSchonSchwarz;
//int StartdurchgangLinks;
//int StartdurchgangRechts;
int MerkerLinksWarSchonEineGanzePeriode;
int MerkerRechtsWarSchonEineGanzePeriode;
int TakteZaehlerSchwarzLinks; // Zaehlt wie viele Takte zwischen zwei W/S-Übergängen liegen
int TakteZaehlerWeissLinks;
int TakteZaehlerSchwarzRechts;
int TakteZaehlerWeissRechts;
int TaktzahlLinks; // Ergebnis wie viele Takte zwischen zwei W/S-Übergängen Links liegen
int TaktzahlRechts;
int GeschwindigkeitsKorrekturLinks; //Zahl zwischen theoretisch -255 und + 255, die zur Sollgeschwindigkeit dazuaddiert wird, um die unterschiedlichen Motoren auszugleichen
unsigned int UebergangszaehlerLinks; //max. 65535; zaehlt wie viel S/W und W/S-Übergaenge seit dem letzten Rücksetzen links passiert sind
unsigned int UebergangszaehlerRechts; //max. 65535; zaehlt wie viel S/W und W/S-Übergaenge seit dem letzten Rücksetzen rechts passiert sind

int ReglerZurueckSetzen(void)
{
MerkerLinksWarSchonWeiss=FALSE;
MerkerRechtsWarSchonWeiss=FALSE;
MerkerLinksWarSchonSchwarz=FALSE;
MerkerRechtsWarSchonSchwarz=FALSE;
MerkerLinksWarSchonEineGanzePeriode=FALSE;
MerkerRechtsWarSchonEineGanzePeriode=FALSE;
//StartdurchgangLinks=TRUE;
//StartdurchgangLinks=TRUE;
TakteZaehlerSchwarzLinks=0;
TakteZaehlerWeissLinks=0;
TakteZaehlerSchwarzRechts=0;
TakteZaehlerWeissRechts=0;
TaktzahlLinks=0;
TaktzahlRechts=0;

GeschwindigkeitsKorrekturLinks=StartwertUmSoVielBr auchtLinksMehrAlsRechts;
UebergangszaehlerLinks=0;
UebergangszaehlerRechts=0;

return 0;
}

int fahr(int SollGeschwindigkeit, int SollKurve) //SollGeschwindigkeit = Zahl zwischen 0 (stop) und 255 (vorwaerts)
{ //SollKurve = .....muss noch definiert werden.......Derzeit: 0

unsigned int Zahnraddunkelheit[2]; // Zahnraddunkelheit[0]: Odometriedaten links, Zahnraddunkelheit[1]: rechts
int ZahnradstatusLinks=99; //weiß=0, undefiniert=1, schwarz=2, nicht zugewiesen=99
int ZahnradstatusRechts=99; //weiß=0, undefiniert=1, schwarz=2, nicht zugewiesen=99


OdometrieData(Zahnraddunkelheit);
TakteZaehlerSchwarzLinks++;
TakteZaehlerWeissLinks++;
TakteZaehlerSchwarzRechts++;
TakteZaehlerWeissRechts++;

//Abfrage nach Zahnradstatus Links:
if (Zahnraddunkelheit[0] > SchwellwertLinksSchwarz)
ZahnradstatusLinks=2; //links ist schwarz
else if (Zahnraddunkelheit[0] < SchwellwertLinksWeiss)
ZahnradstatusLinks=0; //links ist weiß
else
ZahnradstatusLinks=1; //links ist undefiniert

//Abfrage nach Zahnradstatus Rechts:
if (Zahnraddunkelheit[1] > SchwellwertRechtsSchwarz)
ZahnradstatusRechts=2; //rechts ist schwarz
else if (Zahnraddunkelheit[1] < SchwellwertRechtsWeiss)
ZahnradstatusRechts=0; //rechts ist weiß
else
ZahnradstatusRechts=1; //rechts ist undefiniert

if (ZahnradstatusLinks==0) MerkerLinksWarSchonWeiss=TRUE; //auf wahr setzen
if (ZahnradstatusRechts==0) MerkerRechtsWarSchonWeiss=TRUE; //auf wahr setzen
if (ZahnradstatusLinks==2) MerkerLinksWarSchonSchwarz=TRUE; //auf wahr setzen
if (ZahnradstatusRechts==2) MerkerRechtsWarSchonSchwarz=TRUE; //auf wahr setzen

//Feststellen ob S/W oder W/S-Übergang links oder rechts:
if ((ZahnradstatusLinks==2)&&(MerkerLinksWarSchonWeiss==TRUE))
{TaktzahlLinks=TakteZaehlerSchwarzLinks; TakteZaehlerSchwarzLinks=0;
MerkerLinksWarSchonWeiss=FALSE;
UebergangszaehlerLinks++;
if (MerkerLinksWarSchonEineGanzePeriode<3) MerkerLinksWarSchonEineGanzePeriode++;
}
//Linkes Zahnrad hat neu Schwarz erreicht (W/S-Übergang) => Zaehler++
else if ((ZahnradstatusLinks==0)&&(MerkerLinksWarSchonSchwarz==TRUE))
{TaktzahlLinks=TakteZaehlerWeissLinks; TakteZaehlerWeissLinks=0;
MerkerLinksWarSchonSchwarz=FALSE;
UebergangszaehlerLinks++;}
//Linkes Zahnrad hat neu Weiß erreicht (S/W-Übergang) => Zaehler++
else; //weder S/W noch W/S-Übergang

if ((ZahnradstatusRechts==2)&&(MerkerRechtsWarSchonWeiss==TRUE))
{TaktzahlRechts=TakteZaehlerSchwarzRechts; TakteZaehlerSchwarzRechts=0;
MerkerRechtsWarSchonWeiss=FALSE;
if (MerkerRechtsWarSchonEineGanzePeriode<3) MerkerRechtsWarSchonEineGanzePeriode++;
UebergangszaehlerRechts++;}
//Rechtes Zahnrad hat neu Schwarz erreicht (W/S-Übergang) => Zaehler--
else if ((ZahnradstatusRechts==0)&&(MerkerRechtsWarSchonSchwarz==TRUE))
{TaktzahlRechts=TakteZaehlerWeissRechts; TakteZaehlerWeissRechts=0;
MerkerRechtsWarSchonSchwarz=FALSE;
UebergangszaehlerRechts++;}
//Rechtes Zahnrad hat neu Weiß erreicht (S/W-Übergang) => Zaehler--
else; //weder S/W noch W/S-Übergang

//Geradeausregler (inkrementeller I-Regler):
if ((MerkerLinksWarSchonEineGanzePeriode > 2)&&(MerkerRechtsWarSchonEineGanzePeriode > 2))
{
if ((TaktzahlLinks < TaktzahlRechts)&&(SollGeschwindigkeit+GeschwindigkeitsKorrekturLink s > 0))
{GeschwindigkeitsKorrekturLinks--;StatusLED(GREEN);}
//wenn das linke Rad zu schnell dreht, dann soll es langsamer werden => Korrektur --
else if ((TaktzahlLinks > TaktzahlRechts)&&(SollGeschwindigkeit+GeschwindigkeitsKorrekturLink s < MAXI))
{GeschwindigkeitsKorrekturLinks++;StatusLED(RED);}
//wenn das link Rad sich zu langsam dreht und es nicht eh schon Vollgas gibt, dann soll es schneller werden => Korrektur ++
else;
};

MotorSpeed(SollGeschwindigkeit + (GeschwindigkeitsKorrekturLinks>>4) , SollGeschwindigkeit); //korrigiertes Motorkommando, auf vorgegebene Kurvenkrümmung geregelt
return SollGeschwindigkeit+GeschwindigkeitsKorrekturLinks ;
}

int main(void)
{
// int p,i=0; //Zaehler initialisieren
int s=0;
// unsigned int j,k;
char string[]=" test \n\r"; // Ausgabestring initialisieren
// unsigned int odoleft[MAXI], odoright[MAXI];

Init();
ReglerZurueckSetzen();
MotorDir(FWD,FWD);
// SerWrite(string,20);

StatusLED(GREEN); //
while(UebergangszaehlerRechts<1000)
{
s=fahr(140,0); // Aufruf der Funktion fahre mit 130 Geradeaus (geregelt)
}
MotorDir(BREAK,BREAK);
sprintf(string, "Korr.= %4d\n\r",GeschwindigkeitsKorrekturLinks);
SerWrite(string,13);
sprintf(string, "ZahlL= %4d\n\r",UebergangszaehlerLinks);
SerWrite(string,13);
sprintf(string, "ZahlR= %4d\n\r",UebergangszaehlerRechts);
SerWrite(string,13);

while(1);
return 0;
}

stochri
30.01.2007, 21:15
Hallo Dorothea,

mich würde interssieren, wie Deine Regelung gegenüber der Go-Funktion aus der ASURO-Lib 2.7 https://www.roboternetz.de/phpBB2/viewtopic.php?t=26594&start=0 abschneidet. Wenn Ihr gerade so schön am experimentieren seid, könntet Ihr die vielleicht auch noch ausprobieren.

Gruss,
stochri

Nachtrag:
Uihh, eure Variablennamen sind tatsächlich ganz schön lang O:)

damaltor
31.01.2007, 00:38
Wieso hat eigentlich noch keiner 'ne Fast-Fourier-Transformation für die Frequenzerfassung der Odometriedaten benutzt?

Sollte doch das zuverlässigste und flexibelste sein, da es ermöglicht, den Offset herauszufiltern, und als Endergebnis die Grundfrequenz ausspuckt, demnach wären Umgebungslichtwechsel und Radstillstand kein Problem mehr - theoretisch die sauberste Lösung.

Viele Grüße
Henning

Nicht fragen, machen! Viel Spaß, zeig uns dann mal deine Ergebnisse...

austin2power
31.01.2007, 06:02
Nicht fragen, machen! Viel Spaß, zeig uns dann mal deine Ergebnisse...

Bin schon dabei :-k

Falls Interesse besteht, darauf kann man aufbauen: Auszug aus "Numerical Recipes in C" (http://www.nrbook.com/a/bookcpdf/c12-2.pdf)

reinhaun
Henning

Sternthaler
01.02.2007, 00:21
Hallo dorothea,
die Idee mit dem Kehrwert der Geschwindigkeit finde ich sehr gut. Dickes Lob an deinen 14-er.

Zu der Abweichung von 5-10 cm auf 300 cm mal eine kleine Rechnung:
Folgendes:
Unter der Annahme, dass sich die Räder bei einer perfekter Reglung gleich schnell drehen aber trotzdem einen Differenz zur geraden Linie vorliegt, muss der Asuro somit im Bogen fahren.
Wenn der Asuro also auf einem Kreis fährt, fährt er bei deiner Angabe 300 cm auf dem Umfang und bekommt einen Abstand von 10 cm zur Tangente.
Wenn ich mal wieder Excel bemühe, bekomme ich einen Radius für diesen Kreis von 4505 cm raus.
Somit hätten wir, bei einem Radstand am Asuro mit 10,4 cm einen inneren Radius von 4499,8 cm und einen Außenradius von 4510,2 cm.
Das ist ein Verhältnis von ca. 1,0023
Dieses Verhältnis müssen dann aber auch die Asuro-Räder untereinander haben.
Hat das eine Rad so ca. einen Durchmesser von 3,8 cm, hätte das andere dann etwa 3,8087 cm. Das liegt bestimmt bestens in der Fertigungstoleranz ;-)

Ich bin mir ziemlich sicher, dass unser Asuro niemals eine perfekte Linie abfahren wird. (Was habe ich hier falsch bedacht?)

Trotzdem muss man natürlich alles ausschöpfen um immer besser zu werden. Also weiter mit Kehrwerten und frischen Ideen.

@austin2power
Wenn ich deinen Link anklicke bekommen ich nur folgende Meldung:
'Das für diesen Befehl erforderliche Sicherheitsusatzmodul ist nicht verfügbar'
Ich nutze den Mozilla Firefox in Version 2.0.0.1. Weißt du hier weiter?
P.S.: Ich wäre auch an einer FFT interessiert, die in den Asuro passt. Hier würde ich sogar sehr gerne bei dir abschreiben, da ich mal versucht hatte Barcodes zu lesen die seitlich an einer vom Asuro zu verfolgenden Linie angebracht sind. Bitte um Code \:D/

radbruch
01.02.2007, 09:24
Na, so neu ist die Idee auch nicht, gleiche Probleme ergeben gleiche Lösungen (https://www.roboternetz.de/phpBB2/viewtopic.php?t=26813). Als "Zeitbasis" verwende ich da die Anzahl der Schleifendurchgänge zwischen den Bitwechseln.

austin2power
01.02.2007, 12:45
Wenn ich deinen Link anklicke bekommen ich nur folgende Meldung:
'Das für diesen Befehl erforderliche Sicherheitsusatzmodul ist nicht verfügbar'
Ich nutze den Mozilla Firefox in Version 2.0.0.1. Weißt du hier weiter?


Hi Sternthaler, Windows-Nutzer brauchen 'n Plugin, hier zu beziehen: http://www.nrbook.com/a/bookcpdf.php

Sternthaler
01.02.2007, 21:02
@austin2power
Danke, hat nach einer Firewall-Anpassung für den Acrobat-Reader funktioniert. (Einmaliges Zulassen reichte)

i-wizard
26.02.2007, 17:09
Hi Leute,


beschäftige micht jetzt auch mit dem geradeausfahren meines Asuro.

Hab eure ganzen Beiträge gelesen und mir sind ein paar Fragen entstanden:

1. Hysterese? Was ist das?
2. Was meint ihr mit Flanken.

Hab dann auch mal versucht die Werte die mir die Odometrie liefert zu loggen aber mir ist nicht ganz klar wie ich die Werte interpretieren soll.

Könnt ihr mir helfen?

Hänge das Programm mit dem ich die Werte erfasst habe und die Excel-Tabelle für 500 Werte der Linkensensoren an.

Viele Grüße

Tom

radbruch
26.02.2007, 17:56
SerWrite(messl[i],1);

Das funktioniert nicht. messl[] ist vom Type integer, SerWrite() möchte aber Strings. In der aktuellen asuro.c gibt es für diesen Fall die Funktion PrintInt() die Integerwerte sendet.

Ansonsten sieht das Progi richtig aus. Lediglich die grüne StatusLED zu Beginn ist sinnfrei, da sie bei Init() eh auf grün gesetzt wird.

Hysterese nennt man z.B. den Unterschied zwischen Ein- und Ausschaltpunkt. Flanke ist der Anstieg bzw. der Abfall des Wertes.

Mein (einfacher) Odo-Ansatz geht so:
Ich teile den Wertebereich in drei Teile, unteres Drittel ist low, oberes Drittel high, dazwischen ist nichts.
Bit wird high wenn aktuell low und Wert im oberen Drittel
Bit wird low wenn aktuell high und Wert im unteren Drittel

Das nichts-Drittel dient zur sauberen Trennung verhindert z.B. dass der Odozähler im Stillstand zählt, weil der Wert auf einer Flanke steht.

Das funktioniert übrigens bei Mikrokontrollern ähnlich, unter ca. 1V ist low, über ca. 3,5V ist high, dazwischen passiert nichts.

Gruß

mic

Sternthaler
26.02.2007, 22:30
Hallo i-wizard,
für das Problem mit dem INTERGER-Wert in messl[] kann man folgendes machen:
unsignedcharvariable = (unsigned char) (messl[i] / 4)
Und dann die unsignedcharvariable mit dem SerWrite() senden.

Kurze Erklärung:
Die Messwerte aus OdometrieData() sind nie größer als 1023, da der AD-Wandler nur 10 Bits liefert. Wenn das durch 4 geteilt wird liegen wir bei maximal 255,75.
Dieser Wert ist mit dem (unsigned char)-cast dann wieder maximal bei 255 und passt somit in das SerWrite().
Hiermit bekommst du zwar nicht die volle Auflösung (technische Möglickkeit des AD-Wandlers), aber du hast auf alle Fälle die richtigen Zahlen an den PC gesendet. Nun eben 'nur' mit 8-Bit-Auflösung von 0 bis 255.
Jedenfalls solltest du dann eine Messkurve bekommen, die schon eher an eine Sinus-Funktion erinnert.

Chris90
10.04.2007, 16:26
hey waste
ich hätte mal ne frage zu deinem geradeausfahr prog.
Könnte man das in ne funktion packen um z.B. immer wenn ich gerade ausfahren will dann den "Baustein" einzusetzen???
mfg Christian

waste
10.04.2007, 22:32
Klar geht das. Mach dir aus dem Programm ohne Init() eine Funktion mit einer Übergabevariablen, mit der du die Wegstrecke vorgeben kannst.

Waste

Chris90
11.04.2007, 10:40
guuut
naja wegstrecke ist eher uninteressant da ich ihn so lange gerade aus fahren lassen will bis ein hindernis kommt.
mfg Christian

damaltor
11.04.2007, 16:05
dann muss es halt geändert werden... ode du nimmst immer sehr kleine wegstrecken, prüfst ob er angestoßen ist, wieder n kleines stück, wieder prüfung usw.

alternativ kannst du auch die go() funktion der erweiterten lib nehmen...

Chris90
11.04.2007, 16:22
also mein plan is, dass ich ihn eben geradeaus fahren lass, bis er mit der ir schnitstelle nen hindernis erkennt un dann weicht er aus. das werd ich ganz einfach mit ner if schleife machen bis er was erkennt un dann wird er zur seite ausweichen.
Edit:
mfg
Christian

damaltor
11.04.2007, 16:23
na das klingt doch gut... hast du schon nen anfang? ansonsten poste doch mal dienen programmcode, den du bisher hast, wenn du nicht mehr weiter weisst.

Chris90
11.04.2007, 16:26
nein hab noch kein anfang weil die von elv es noch nich hinkriegen mir endlich mein asuro zu schicken :evil:
hab bis jetz mir nur alles mögliche wissen angelesen un das prog ma auf m papier ausgearbeitet.
mfg
Christian
Edit: @Waste: So ich hab jetzt mein asuro und mal dein programm draufgespielt nur das mein asuro damit rückwerts fährt, wenn ich aber die motordrehrichtung ändere und auf rwd setze fährt er nicht in die andere richtung. Ist das normal?? wenn ja welche werte muss ich denn ändern???
mfg
Christian

damaltor
15.04.2007, 15:20
keine schiebeposts bitte, ich habe deinen entfernt.

was genau meinst du? der asuro fährt in die falsche richtugn oder was? dann such mal ein wenig im forum. das ist ein bekannter fehler.du musst die kabel an den motoren umlöten. ist zwar ärgerlich, aber kein großes problem.

Chris90
15.04.2007, 19:03
@Damaltor
ok werd mich bessern :oops: .
ja er fährt in die falsche richtung ich habe aber im programm die richtung geändert und er fährt immernoch falschrum.
mfg
Christian

damaltor
15.04.2007, 19:26
hmm... eigentich muss der asuro entweder immer passend oder immer falschrum fahren.
kontrolliere bitte ob du gespeichert, das richtige file compiliert hast und auch das richtige hex file kompiliert hast!!

Chris90
15.04.2007, 19:59
hmmm komisch jetzt funktionierts naja morgen erstma die motoren umpolen
mfg
Christian

S
18.04.2007, 16:29
Hi Leute,
bin Neuling, also seid nicht zu streng mit mir, aber mir fällt folgendes auf:
Ihr versucht des Problem Geradeausfahren nur mit Regelung der Odosensoren zu lösen. Bei der Odometrie gibts aber noch andere Probleme. Bei Schienenfahrzeugen is des was anderes, aber so ein Asuro mit den kleinen Rädern tritt event. nicht zu vernachlässigender Schlupf auf.
Wenn die Achsen nicht 100% parallel sind oder die Oberfläche nicht ganz eben ist könnte es doch sein, dass die Bewegung über ein Rad ein klein wenig schiebt. Selbst wenn die Drehzahlen dann immer gleich sind kommt keine lineare Bewegung zustande. Vielleicht hilft es, sich mal um möglichst
parallele Achsen zu kümmern. Ausserdem ist die Pressung der Räder aus
Hertzscher Sicht beim Asuro ein Punkt ( was ich gesehen habe ) was der Bereifung um die Hochachse nicht gerade viel Grip verleiht. Eventuell bringt der "Tischtennisschlägertrick" mit Taft-Spray auch a bisserl was.
Speziell dann, wenn der Asuro bei Geschwindigkeitsänderung dazu neigt in eine Richtung zu driften.

gez. S

damaltor
18.04.2007, 16:59
ich denke, wenn man die achsen passend in die jeweilige gefräste nut einlötet/klebt, sollte das kein problem darstellen.

das bisschen schlupf, was auftritt, kann man glaub ich vernachlässigen: mein asuro fährt ganz gut geradeaus, und dann mache ich mir da keine gedanken drum.

taft hab ich auch schon überlegt, aber dann zieht sich ne klebrige haarspray-spur durch meine bude... und jedes bissl freck und staub bleibt an den reifen kleben. DANN gibts schlupf =)

S
18.04.2007, 19:07
@ damaltor,
was die taft-geschichte betrifft hast Du nach zweimaligem Überlegen sicher recht. Was ich nur meine ist, dass wenn ich instationäre Zustände zulasse ( Beschleunigung, sich ( leicht ) ändernder Untergrund ... ) wirken sich kleine Kraftänderungen stark aus.
Der Tischtennisball ist auch so ein Unruheherd: Wenn der nicht 100% mittig Bodenkontakt hat, bekomm ich einen Moment um die Hochachse und zwar abhängig vom Untergrund -> Haftwert. Das integriert sich kinematisch zweimal hoch.
wenn ich bei einer Modelleisenbahn die Geschwindigkeit erhöhe fährt sie höchstwährscheinlich trotzdem die gleiche Kurve/Strecke ab, wenn ich mit dem Auto auf dem (verlassenenen) Supermarktparkplatz mit dem Auto im Kreis fahre, die Geschwindikeit erhöhe und den Lenkeinschlag gleich lasse wird der Kreisradius sich erhöhen ohne dass die Reifen quietschen oder das ESP den Schleudersitz betätigt. ( ursache merk ich nicht wirklich )
oder wenn ich auf gerader Landstrasse die Augen schließe und die Fahrbahn plötzlich ganz leicht schrägt schau ich nach wenigen Sekunden alt aus obwohl ich nichts ändere.
Wenn man erreicht, dass die Geschwindigkeit über die gesamte Messstrecke immer die gleiche (und gering) ist und der Untergrund sich nicht ändert (Teppich ist schlecht), also für stationäre Bedingungen sorgt, hat man immer die gleichen Fehler, die man sicher durch die Parameter in der Griff bekommt.
Jetzt hab ich mehr gefaselt als ich wollte, mein Fazit ist einfach:
Nur wenn die Bedingungen immer sehr gleich und die mechanischen Fehlerquellen gering sind hab ich mit der relativ einfachen Sensorik Chancen. ( deswegen sind die Trägheitsnavigationssysteme wahrscheinlich so scheissteuer :-)
Fang wie gesagt mit Elektronik erst an und will auch nicht gleich Klugscheißen. Ist nur so, dass man das glaub ich berücksichtigen sollte.

gez. S

damaltor
19.04.2007, 18:32
ja klar, an sich hast du schn recht. allerdings: bis sich eine ernsthafte auswirkung zeigt, müsste der asuro schonmal recht weit geradeausfahren. naja, und bis dahin ist die kleine abweichung glaub ich relativ irrelevant. in meiner wohnung ist überall kantenfreies laminat, und sooo viel lass ich ihn gar nicht fahren. =)

davon abgesehen: ein paar neue sensoren, ein komplexeres regelsystem, dafür ist der kleine prozessor glaube ich nicht ausgelegt...

Philipp2195
03.10.2012, 16:22
Hallo,


Ich selbst beschäftige mich zur zeit mit der überwältigung eines labyrinths. ich habe dazu ein kleines programm geschrieben.
Der Roboter soll also zunächst immer gerade aus fahren bis er auf eine wand trifft. Sobald dies geschehen ist, soll er ein kleines stück rückwarts fahren und sich um 90 ° in die eine richtung drehen. ist dort keine wand soll er seine fahrt fortsetzten. Ansonsten soll er sich um 180° in die andere Richtung drehen und dann weiterfahren.

Das Programm selbst klappt auch soweit. Mein Problem liegt aber eigentlich eher daran, dass der asuro auf den geraden strecken nicht gerade fährt. Da ich aber eher anfänger beim programmieren bin tue ich mich sehr schwer.

Hat von euch jemand vielleicht eine Idee wie man das Programm von mir und das von waste kombinieren kann?


Mein Programm sieht folgendermaßen aus:


#include "asuro.h"

int main(void) {
Init();
int i;
int grad=0;
while(1) {

if(PollSwitch()==0) {
MotorDir(FWD,FWD);
MotorSpeed(130,117);

}

else if(PollSwitch()!=0) {

if (grad==0){

MotorDir(BREAK,BREAK);
MotorDir(RWD,RWD);
MotorSpeed(100,100);
for ( i=0 ; i<=220 ; i++)
{ Sleep (5000); }
MotorDir(RWD,FWD);
MotorSpeed(110,110);

for ( i=0 ; i<=150 ; i++ )
{ Sleep ( 5000 ); }
grad = 1;
}


else if (grad==1) {
MotorDir(BREAK,BREAK);
MotorDir(RWD,RWD);
MotorSpeed(100,100);
for ( i=0 ; i<=220 ; i++)
{ Sleep (5000); }
MotorDir(FWD,RWD);
MotorSpeed(110,110);

for ( i=0 ; i<=340 ; i++ )
{ Sleep ( 5000 ); }
grad = 0;
}

}




}
return 0;
}