PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Odometrie Programm Probleme



Chrise
30.11.2007, 23:39
Hallo!!

Endlich hab ich mal wieder Zeit gefunden um mich mit dem asuro zu beschäftigen.

Ich hab mich mal an die Odometrie gewagt und eigentlich meiner Meinung nach ein nicht so schlechtes Programm geschriebenm welches nur leider nicht funktioniert.



#include "asuro.h"

int main (void)
{
unsigned int data[2];
unsigned int L_alt_l[1]; //Letzte Wert des linken Fototransistors
unsigned int L_alt_r[1]; //Letzte Wert des rechten Fototransistors
float n_l;
float n_r;
int a; //Hilfsvariable
int b; //Hilfsvariable
unsigned char c; //Wert für die Geschwindigkeit des linken Motors
unsigned char d; //Wert für die Geschwindigkeit des rechten Motors
int dh_l;

a = 0;
b = 0;
c = 140; // Wert für linken Motor bestimmen
d = 140; // Wert für rechten Motor bestimmen

Init();

OdometrieData(data);
MotorDir(FWD, FWD);

while(1)
{
MotorSpeed(c, d);
L_alt_l[0] = data[0];
L_alt_r[0] = data[1];
OdometrieData(data);

dh_l = data[0] - L_alt_l[0];

if( dh_l > 200)
{
a++;
n_l=a/8; //Umdrehungen in der Zeit t
}

if( data[1] - L_alt_r[0] > 200 || data[1] - L_alt_r[0] < -200)
{
b++;
n_r=b/8; //Umdrehungen in der Zeit t
}

if( n_l < n_r)
{
d--; //Geschwindigkeit des rechten Motors verkleinern

}

if( n_l > n_r)
{
c--; //Geschwindigkeit des rechten Motors verkleinern
}
}
}

könnt ihr da vielleicht wo nen Fehler entdecken, oder ist das ganze generell falsch was ich da mache? Bitte nicht wunder das ich im unteren Teil für die Berechnung der Differenz zwei verschieden Methoden angewandt habe, will damit nur zeige das es mit keiner der zwei funktioniert.

mfg Chrise

liggi
01.12.2007, 09:06
Dein Fehler ist MotorSpeed(c, d); muss in die while-Schleife, da diese nich verlassen wird. Sonst fallen mir keine Fehler auf.

mfg liggi

Chrise
01.12.2007, 12:09
Ohhh..... stimmt. Das hab ich ja völlig übersehn.
Allerdings funktioniert es noch immer nicht!?!?!?!

Ich habe oben den Programmcode so verändert wie das Programm jetzt aussieht.

liggi
01.12.2007, 15:33
was macht der Asuro überhaupt??? fährter einfach nur rum oder macht er gar nichts.

mfg liggi

asuroer
01.12.2007, 19:59
hi
dein fehler dürfte sein,dass du links(data[0]) nur abfragst, ob das vorher kleiner war. also werden nur die übergänge von s-->w gezählt und nicht andersherum.

außerdem hättest du bei L_alt_l/r(was für umständliche namen xD) nicht [1] hinterschreiben müssen und ich nehme mal an, du möchtest mit der zeile
n_l = a/8
feststellen, wie oft sich das rad gedreht hat, so zählst du aber, wie oft sich das zahnrad davor gedreht hat.
also müsstest du
n_l = a/40
schreibensollte dein programm aber td nicht daran hindern, sich richtig audszuführen, auch wenn du statt n_l und n_r zu vergleichen doch auch einfach a und b vertgleichen könntest.
ich würde dir ausserdem empfehlen, die geschwindigkeit wieder auf 140 zu setzen, wenn links und rechts gleich sind.



MfG


Jan

Chrise
02.12.2007, 12:43
hm.... aber daran kann es doch nicht liegen, dass das programm nicht funktioniert.

Also mein asuro macht neigentlich net viel. Die Räder drehen sich ganz normal und wenn man mit einem finger ein Rad abbremst, dreht sich das andere mit konstanter drehzahl weiter.

achja.... um den Fehler beim linken Übergangszähler wegzubekommen, baruch ja einfach nur
if( dh_l > 200 || dh_l < -200)
schreiben?!?!

mfg
Chrise

asuroer
02.12.2007, 13:32
hi
also ich würde dir mal empfehlen, dieses programm auszuprobieren:


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

void SerWert(unsigned int iWert) {
unsigned char cWert[6] = " ";

itoa(iWert, cWert, 10);
SerWrite(cWert, 5);
SerWrite(", ", 2);
}

/** Hauptprogramm */
int main(void)
{
unsigned int Rmin = 1024;
unsigned int Rmax = 0;
unsigned int Lmin = 1024;
unsigned int Lmax = 0;
/** Geschwindigkeit */
int speed = 90;
/** Odometrie links/rechts */
unsigned int data[2];

Init();
GREEN_LED_ON;

MotorDir(FWD,FWD);
MotorSpeed(speed, speed);

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

// max links
if (data[0] > Lmax)
Lmax += (data[0] - Lmax) / 2;
// min links
if (data[0] < Lmin)
Lmin -= (Lmin - data[0]) / 2;

// max rechts
if (data[1] > Rmax)
Rmax += (data[1] - Rmax) / 2;
// min rechts
if (data[1] < Rmin)
Rmin -= (Rmin - data[1]) / 2;

SerWert(Lmax);
SerWert(Lmin);
SerWert(Rmax);
SerWert(Rmin);
SerWrite("\n\r", 2);

}

return 0;
}



damit sendet der asuro die max und min odo-werte an den pc, denn es könnte sein, dass der s/w unterschied weniger als 200 ist.

Chrise
02.12.2007, 15:04
also ich bekomm, wenn ich mir die Werte zum Computer schicken lasse, immer nur die gleichen:
17, 5, 845, 461

mfg

asuroer
02.12.2007, 15:39
hi
also wenn ich mich recht erinnere sind die ersten beiden werte für inks und die 2. beiden für rechts
d.h., dass dein programm nur rechts funktionieren sollte. links scheint die IR-Led kaputt zu sein.


MfG

Jan

damaltor
02.12.2007, 15:51
bist du sicher dass du darauf geachtet hast dass die beiden teile je nach seite verauscht wurden? auf einer seite ist rosa vorn, auf der anderen seite weiss.

asuroer
02.12.2007, 17:33
hi
also ich denke nicht, das die LED und der Empfänger vertauscht wurden, dann würde der mega8 ja gar nichts mehr messen ausserdem müsste doch dann td der eine motor langsamer werden.

MfG

Jan

Chrise
03.12.2007, 20:27
Aber dann müsste im Programm ja trotzdem noch ein Fehler sein, das es ja eigentlich dann bei einem Rad funktionieren müsste. Und wenn ich das alles richtig verstanden habe, dann müsste ein Rad ja eigantlich ganz schnell langsamer werden da bei einem die Hilfsvariable ja nie großer wird, die andere aber schon.

Eigentlich müssten die Werte wenn ich das Rad mit der Hand abbremse ja änder? - Das tun sie aber nicht.

Mfg Chrise

Sternthaler
03.12.2007, 22:56
Hallo Chrise,
dein Programm rechnet sich meiner Meinung nach den 'Wolf' für nix und wieder nix.

Du nutzt einmal vor der while-Schleife ein MotorDir(), aber deine Rechenergebnisse (Variablen c und d?) werden nirgendwo benutzt um mit MotorSpeed() irgendwo eine Wirkung zu erzielen.
Habe ich da nun etwas total übersehen, oder ist dein geposteter Programmcode nur ein Ausschnitt?

Gruß Sternthaler

Chrise
04.12.2007, 16:41
Ok.... das ein paar Sachen umsonst rechnet seh ich sofort ein (im neuen Programcode hab ich das alles mal weggelassen, wo ich der Ansicht war, dass es eigentlich nichts bringt).

c und d werden aber verwendet. Sie stehen für die Geschwindigkeiten eines Motors (c fur den linken Motor und d für den rechten Motor). Am Ende des Programmes werden die beiden Variablen verkleinert, um eben den Asuro auf einer geraden Bahn zu halten. Es ollte eigentlich noch eine Funktion her, dass wenn beide Räder den gleichen weg zurücklegen, dass die Geschwindigkeit wieder erhöht wird, den sonst würde der Roboter bald einmal stehen.

Und nein..... es ist das ganze Programm.


#include "asuro.h"

int main (void)
{
unsigned int data[2];
unsigned int L_alt_l[1]; //Letzte Wert des linken Fototransistors
unsigned int L_alt_r[1]; //Letzte Wert des rechten Fototransistors
int a; //Anzahl der gezählten Übergenge links von s zu w und w zu s
int b; //Anzahl der gezählten Übergenge rechts von s zu w und w zu s
unsigned char c; //Wert für die Geschwindigkeit des linken Motors
unsigned char d; //Wert für die Geschwindigkeit des rechten Motors
int dh_l;

a = 0;
b = 0;
c = 140; // Wert für linken Motor bestimmen
d = 140; // Wert für rechten Motor bestimmen

Init();

OdometrieData(data);
MotorDir(FWD, FWD);

while(1)
{
MotorSpeed(c, d);
L_alt_l[0] = data[0];
L_alt_r[0] = data[1];
OdometrieData(data);

dh_l = data[0] - L_alt_l[0];

if( dh_l > 200 || dh_l < -200)
{
a++;
}

if( data[1] - L_alt_r[0] > 200 || data[1] - L_alt_r[0] < -200)
{
b++;
}

if( a < b)
{
d--; //Geschwindigkeit des rechten Motors verkleinern

}

if( a > b)
{
c--; //Geschwindigkeit des rechten Motors verkleinern
}
}
}

mfg Chrise

asuroer
04.12.2007, 19:27
hi

also ich hab bei meinem asuro rausgefunden, dass in einem programm nur einmal OdometrieData(data) aufgerufen werden kann. alle weiteren ignoriert er einfach. ich weiß nicht, ob das immer so ist, oder ob ich was falsch mache, aber vllt solltest du das mal versuchen und das erste OdpmetrieData(data) weglassen.

MfG

Jan

Chrise
04.12.2007, 21:52
Ich werds mal probieren, doch ich glaube nicht dass das zweite OdometrieData(data) ignoriert wird, da beim auslesen der Werte, diese sich immer wieder mal ein bisschen geändert haben, aber halt immer nur ca. 10. Das war meiner Ansicht nach nicht erwähnenswert, bereu ich aber eh schon, weil ich euch informationen vorenthalten habe.

Sorry

Mfg

Sternthaler
04.12.2007, 23:25
Hallo Chrise,
mein Fehler. Jetzt habe ich das MotorSpeed() auch im ersten Programm gefunden. Ist meinen wild suchenden Augen irgendwie entfleucht.

Dann nun also zum eigendlichen Inhalt.

L_alt_l[0] = data[0];
L_alt_r[0] = data[1];
OdometrieData(data);
dh_l = data[0] - L_alt_l[0];

Hier in dh_l bestimmst du die Differenz zwischen 2 hintereinander gemachten ODO-Messwerten.

Mit Folgendem untersuchst du diese Differenz auf einen Sprung um mehr als 200 Messeinheiten um a zu beeinflussen:

if( dh_l > 200 || dh_l < -200)
{
a++;
}

Ähnlich machst du das dann auch für die rechte Seite.

Und schon fängt dein Programm wieder von vorne an.
Unterm Strich hast du als größten Zeitfresser nur den Aufruf der Funktion OdometrieData(). Dort werden gerade mal 2 AD-Wandlungen gemacht, die so langsam auch nicht sind.

Nun passiert also folgendes:
- Die Odo-Scheiben drehen sich vor den Sensoren
- Du misst kontinuierlich die Helligkeitsänderungen
- Du untersuchst die Messwerte auf eine Differenz von mehr als 200 Einheiten
- Du berechnest 'Geschwindigkeitsanpassungen' in d und c

Ich glaube, dass dein Asuro startet, und dass sich die Geschwindigkeit überhaupt nicht ändert, so dass er in einem Bogen im Kreis fährt.

Das wird daher kommen, dass die Differenzen zwischen 2 hintereinander gemachten Messungen keinesfalls größer als 200 Einheiten sein werden. (Ausnahmen bestätigen die Regel)

Um dir hier nicht alles direkt zu verraten, nur mal ein Hinweis auf einen Thread zu diesem Thema: farratt weist auf einen
Sinusverlauf (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=313274#313274) der Daten hin.
Und dazu dann auch ein Bildchen. Die oberen 10-Bit-Daten gelten für die Funktion OdometrieData().
Es waren ungefähr 30 Messungen in einem Sinuszyklus!

Gruß Sternthaler

Chrise
08.12.2007, 21:18
So.... ich hab jetzt mal die linke Seite der durchgecheckt und bin darauf gestoßen, dass der Fototransistor irgendwie kurzgeschlossen war(Ich weiße jede schuld von mir, da ich ihn nicht zusammen gebaut habe).
Meine neuen Werte betragen: 325, 192, 826, 463

Nun werd ich mal ein Programm schreiben, dass mir die Werte in gemessener Reihenfolge ausgibt und dann den wert beim wechsel von schwarz und weiß und weiß auf schwarz änder und schauen obs funzt

mfg

Edit: Also wenn ich die Daten auslese bekomm ich zwaar für die rechte Seite eine Halbwegs anständige Kurve, jedoch mit ein paar ausnahmen. Bei der linken Seite ist allerdings alles anders. Da sieht das ganze fast mehr nach einem Sägezahn aus, als nach einem Sinus^^.

damaltor
08.12.2007, 23:45
,ach mal ne grafik!

Sternthaler
09.12.2007, 00:49
@damaltor
ja, grafik (und natürlich kleinschreibung) ist cool. Vor allem wenn Platz vorhanden ist ;-)

@Chrise
Kannst du mal deine ermittelten Daten posten. Muss keine Grafik sein.

Gruß Sternthaler

Chrise
09.12.2007, 11:50
Also.... hier mal die Daten:


Rechts Links
176 160
160 161
147 161
130 163
116 165
108 171
106 172
100 164
96 166
97 166
108 167
117 145
123 145
136 146
152 145
169 145
186 146
196 146
199 145
201 145
199 146
198 147
195 148
191 150
179 150
163 152
146 152
131 143
115 144
102 146
98 147
94 148
92 148
93 148
95 148
101 146
115 147
138 146
156 148
173 149
189 148
195 148
193 150
193 151
195 129
193 131
187 132
174 135
156 136
142 133
127 135
109 135
96 135
89 135
91 134
98 135
103 135
112 136
133 136
152 136
171 137
185 137
193 137
195 139
195 140
192 140
188 142
178 143
161 143
150 143
134 143
118 143
105 145
99 144
99 144
101 144
105 144
113 144
127 144
143 144
157 144
174 145
188 147
195 148
200 150
198 150
190 152
186 155
180 158
171 158
156 159
142 159
124 161
110 161
103 144
99 144
94 144
90 143
94 143
103 144
112 144
122 144
143 144
159 144
177 145
190 147
198 148
20 148
201 150
200 151
197 152
195 152
190 155
178 156
160 156
143 156
126 140
110 141
100 140
99 140
97 140
97 140
100 140
102 14
110 140
124 141
143 143
159 126
176 128
192 129
195 131
193 132
193 135
196 136
193 137
187 137
172 137
155 136
143 137
128 136
111 135
101 135
97 135
103 121
106 123
107 124
118 126
135 127
151 128
170 129
184 130
194 130
196 131
196 131
193 131
189 131
176 131
163 130
152 129
138 129
121 129
108 129
100 128
103 128
104 128
108 128
117 130
128 131
147 130
160 131
175 132
188 134
195 134
201 134
200 134
193 135
187 135
183 135
176 135
163 135
150 134
133 132
116 133
105 133
98 133
94 133
8 133
90 133
101 135
111 136
121 136
139 138
156 139
172 140
187 142
194 142
200 142
203 143
200 143
198 144
195 144
191 143
183 14
168 143
152 143
136 143
118 143
105 143
102 145
101 146
101 128
102 130
104 131
110 134
119 134
137 135
156 139
169 140
186 140
195 141
194 140
193 143
196 143
196 143
192 142
182 142
166 142
152 143
137 143
121 143
110 145
102 146
102 147
109 156
114 159
118 160
130 163
148 163
162 167
176 168
187 167
195 166
197 166
197 165
195 166
190 165
178 164
165 164
155 164
143 164


Weil ich es am Anfang nicht glauben konnte, habe ich natürlich gleich noch eine Messung gemacht:



Rechts Links
199 101
192 102
185 102
181 103
176 104
163 104
150 104
129 104
111 104
98 104
97 104
96 104
92 103
92 102
99 101
108 100
121 100
140 100
152 99
169 100
187 100
196 101
201 102
199 103
198 103
195 104
193 104
188 105
175 105
154 104
139 105
123 105
108 104
99 103
95 103
94 102
94 102
94 101
98 100
108 100
124 100
147 101
163 101
184 102
194 103
192 104
192 105
195 105
195 105
191 106
181 106
161 105
148 105
133 105
116 105
103 104
94 103
99 103
106 103
108 103
119 104
135 104
153 105
168 107
183 107
193 108
197 109
196 110
193 110
190 110
180 110
165 110
150 110
131 108
114 108
103 107
99 1
98 108
100 109
105 109
113 109
128 110
147 112
161 112
177 113
190 115
197 117
202 120
198 127
188 135
185 141
180 146
172 151
159 151
145 153
128 154
115 155
110 154
108 151
101 152
92 153
100 152
110 153
120 155
136 156
153 156
166 157
183 159
193 160
200 161
204 163
202 159
200 160
197 160
193 160
186 159
172 159
154 158
137 157
121 158
108 158
102 158
96 159
96 157
97 158
100 159
108 148
120 151
142 155
159 157
173 158
190 159
198 160
195 161
194 160
196 160
196 160
191 159
177 159
15 156
143 156
126 157
112 126
101 128
96 129
100 132
105 134
105 136
116 142
134 144
151 144
169 146
184 147
195 148
197 148
195 14
194 146
190 146
180 145
166 141
153 142
138 139
120 142
108 142
103 144
105 147
104 148
110 149
117 151
130 152
147 153
159 153
174 153
188 155
195 156
201 157
201 156
192 156
186 154
180 153
174 153
160 153
147 153
129 153
117 152
110 153
107 154
100 155
95 156
98 156
107 157
116 158
128 135
146 139
161 140
176 142
190 143
198 143
203 143
201 143
199 141
196 141
194 140
188 140
176 140
156 140
140 140
124 141
111 142
103 119
101 121
99 122
101 124
102 124
105 123
113 124
127 124
149 124
16 124
183 123
195 123
195 122
193 121
195 121
196 120
192 120
182 120
165 121
151 122
137 123
121 124
111 124
101 125
96 124
107 12
112 125
119 126
132 125
151 124
163 123
178 123
191 122
198 103
198 104
196 104
193 104
187 105
174 105
163 107
152 108

Chrise
09.12.2007, 11:54
Sorry für doppel Post, aba bei mir geht das nicht anders oder ich bon zu blöd dafür!

Das zweite Diagramm sieht in etwa gleich aus, nur die rote Linie hat einen anderen Verlauf
mfg

damaltor
09.12.2007, 14:10
der trick ist, oben rechts in der titelzeile deines beitrages auf "edit" zu klicken.

der blaue graph scheint fein zu sein aber der rote scheint noch arbeit zu gebracuhen...

Chrise
09.12.2007, 15:13
Ich habs wohl mit edit gemacht, als ich dann jedoch die Diagramme hinzufügen wollte machte er mir einen neuen Beitrag.

Hat von euch wer mal ein programm mit dem man die Werte der Odo Sensoren auslesen kann. Ich hab zwar schon eins gefunden allerdings nur im .hex format. Dabei bekomm ich aber nur die Werte raus, welche ich gepostet hab. Wenn ich jedoch minimal und maximal mit dem Programm vom Asuroer ausles bekomm ich andere Werte raus. Meine Vermutung ist daher, dass sich die Motoren einfach zu schnell drehen dass an der linken Seite etwas sinnvolles gemessen werden kann - hört sich komisch an, da sich auf der rechten Seite der Motor genau gleich schnell dreht, aber ich weiß langsam nicht mehr was machen.

Was ich eigentlich machen wollte:
Ich wollte den asuro eine Linie(Figur) abfahren lassen, diesen Weg sollte er sich merken und dann wieder geben. Geht jetzt allerdings nicht wenn die Odo kaputt ist.

mfg

damaltor
09.12.2007, 18:13
hmm da gabs schon einige. im prionzip nur ne endlosschleife in der:
- der wert abgefragt wird
- der wert in ascii zeichen umgewandelt wird, mithilfe von itoa()
- der wert an hyperterminal gesendet wird.

für eine exaktere messung sollte man 100 werte messen und dann senden, weil das senden per ir sehr viel zeit verbraucht und deshalb einige werte verloren gehen.