PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anfänger-Verständnis-Projekt (Hilfe & Rat gesucht)



wernerlicious
21.10.2009, 21:30
Guten Abend,
da ich mich mittlerweile mit der Standard Lib zufrieden gegeben habe und versuche alles darauf aufzubauen, bin ich (mal wieder) auf ein Problem gestoßen.

Ich versuche folgendes zu realisieren:
1. Mein Asuro soll auf einem Tisch geradeaus fahren.
2. Beim Losfahren soll er die momentanen Linedata[0] und [1] speichern
(aber nur die momentanen, da jeder Tisch unterschiedlich ist).
3. Kommt er zur Tischkante, macht er Halt,
4. fährt 100mm zurück,
5. dreht sich um 90° rechts um seine eigene Axe herum
6. und fährt dann rückwärts weiter oder so ähnlich

Bereits durchgeführte Umbauten:
Odometrie Sensor mit einer kleinen Karton Konstruktion vom Umgebungslicht abgeschirmt,
und die Zahnräder mit einer Unterlegscheibe (fast) ruckel frei gemacht.
Zuallerletzt die Axen geschmiert .

Erste programmierungstechnische Ideen:

Zu 1.
(ich weiß es gibt mit Sicherheit weit aus bessere Möglichkeiten das Geradeaus fahren zu realisieren, aber ich bin immer noch ein Anfänger und war echt stolz beim entwickeln dieses Programms) :

MotorDir(FWD,FWD);
while(1)
{ OdometrieData(data);
if (data [0] == data [1] )
{MotorSpeed(100,100);}
else if (data [0] > data [1] )
{MotorSpeed(100,120);}
else if (data [0] < data [1] )
{MotorSpeed(120,100);} }

Zu 2. :
Ich habe absolut keine Ahnung, wie ich solch eine Funktion in das Programm einbeziehen könnte.
Als Variable habe ich mir „a“ gedacht.
„Linedata[2] = a“ geht ja wohl nich, da sich die Daten immer ändern.

Zu 3. :
Ich wollte den im Punkt 2. Ermittelten Anfangs Wert nutzen um eine Anweisung zu erstellen die etwa so lauten könnte:

if (data [0], data [1] < a )
MotorDir(BREAK,BREAK);
else
„weiter gerade aus fahren aus Punkt 1"

Zu 4.
(Ich wollte die Wegmessung benutzen, und nich eine beliebige Zeit)
Ich habe mir auf dieser Seite Anregungen geholt:
http://www.cs.hs-rm.de/~linn/vpdv07/asuro3/asuro-website/files/position.html

Ich habe die 12er Musterscheibe drauf, also entspricht wohl folgendes:
U des Reifen = 120mm
120mm / 5 = 24mm
24mm / 12 = 2mm
100mm / 2mm = 50

Sprich, pro Hell-Dunkel-Übergang bewegt sich ein Rad um 2mm und um auf eine zurückgelegte Strecke von 100mm zu kommen bräuchte ich 50 Hell-Dunkelübergänge.
Da beide Musterscheiben (ungefähr) gleich schnell drehen, brauch ich ja nur eine zu kontrollieren theoretisch oder? Wo ich auch schon beim Problem bin.
Um genau das in die Tat umzusetzen habe ich nämlich ungefähr an so etwas gedacht:

„fährt rückwärts“
for ( b=0 ; b < = 50; b++)
{ ????Hell-Dunkel-Übergang???? }

Zu5. (Siehe Anhang)
Asuro hat einen Axenabstand von 105mm, was heißt, dass der Radius 52,5mm beträgt.
Der Umfang beträgt dann:

2*pi* 52,5mm = 329,87mm

Da jedes Rad bei einer 90° Kurve einen Viertel der Umfangsstrecke abfahren muss ergibt sich:

¼ * 329,87mm = 82,47mm

Da pro Hell-Dunkel-Übergang 2mm zurück gelegt werden ergibt sich:

82,47 / 2 = (ungefähr) 41

das heißt wohl, dass beide Räder gleichzeitig 41 Hell-Dunkel-Übergänge zurücklegen müssen.

Also auf der Axe drehen kriege ich hin, ich ändere lediglich aus Punkt 1
“MotorDir(FWD,FWD);” in “MotorDir(FWD,RWD);” um.
Jetzt entsteht aber wieder das gleiche Problem mit der Strecke wie in Punkt 4.

Zu6. :
Jetzt fährt er nur noch rückwärts oder so etwas, ist mir eigentlich egal, leg ich kurzfristig fest.



ZUM KOMPLETTEN PROJEKT:

Was haltet ihr von der Vorgehungsweise?

Ich würde mich wie immer sehr freuen, wenn mir jmd zu helfen versuchen würde.
Ich hoffe durch dieses Projekt versteh ich das ein oder andere etwas besser .

Mit freundlichen Grüßen, Marcel

flieder
21.10.2009, 22:34
Hallo wernerlicious,
die beiden Line Sensoren geben bei gleichen Lichtverhältnissen in der Regel unterschiedliche Werte zurück. Du mußt für die Steuerung die Abweichungen von den Mittelwerten der beiden Sensoren heranziehen.
Gruß Pit

radbruch
21.10.2009, 22:38
Hallo

Für einen "Einsteiger" ist das schon ein recht komplexes Projekt. Ich würde die zwei Grundfunktionen "Liniensensoren erkennen den Abgrund" und "Wegmessung mit Odometrie" trennen und einzeln angehen. Zum Tischkantenproblem habe ich (nach 5 min RN-Suche (https://www.roboternetz.de/phpBB2/search.php)) was einfaches gefunden:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=45586

Übrigens ist genau diese Funktion die häufigste Ursache für ein zu frühes Ableben des asuro:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=23662
http://www.youtube.com/watch?v=As5QJglc9vw

Das sind nur zwei schnelle Beispiele! Vielleicht solltest du doch besser mit der Odometrie beginnen (und die Suche verwenden).

Gruß

mic

flieder
21.10.2009, 22:51
Probier mal dieses kleine Diagnose Programm aus. Das hab ich mir extra zum Testen meiner Line Sensoren gemacht. Anmerkung: Mit den beiden linken Tasten kannst Du die LED unten ein- und auszuschalten. Auf dem Bildschirm bekommst Du die Werte der Line Sensoren angezeigt und beim Drücken von Tasten, auch diese Werte angezeigt.
Dieses kleine Programm war mein erster Gehversuch mit dem Asuro. Ich hoffe, dass ich mit dem Ding noch warm werde.
Vielleicht hilft Dir das weiter
Gruß
Pit


#include "asuro.h"


unsigned int readSwitch (void)
{
unsigned int i;

DDRD |= SWITCHES; // Switches as Output
SWITCH_ON; // Output HIGH for measurement
ADMUX = (1 << REFS0) | SWITCH; // AVCC reference with external capacitor
Sleep(10);

ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF)));// wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
i = ADCL + (ADCH << 8);

SWITCH_OFF;
return i;
}



void sekunden(int anzahl)
{
int i, j;
for(i = 1; i <= anzahl; i++)
{
for(j = 1; j <= 284; j++) {Sleep(255);}
}
}


void sendeZahl(unsigned int wert, unsigned int zahlenSystemAusg, unsigned int stellenAusg)
{
unsigned int restWert, stellenWert, i;
unsigned char zeichenAusg[stellenAusg];

i = 1;
stellenWert = 1;
while ((stellenWert * zahlenSystemAusg <= wert) || (i < stellenAusg)) {stellenWert *= zahlenSystemAusg;i++;}

restWert = wert;
for (i=0; i < stellenAusg; i++)
{
zeichenAusg[i] = (unsigned char) (restWert / stellenWert + 48);
restWert -= ((unsigned int) zeichenAusg[i] - 48) * stellenWert;
stellenWert /= zahlenSystemAusg;
}
SerWrite(zeichenAusg, stellenAusg);
}



unsigned int printTasten(unsigned int ui_taste0)
{
float f_taste;
unsigned int ui_AD_wert0, ui_AD_wert1, ui_taste1, ui_delta;


ui_AD_wert0 = 0;
ui_AD_wert1 = 10;
while (((ui_AD_wert0 + 5) <= ui_AD_wert1) && ((ui_AD_wert0 - 5) >= ui_AD_wert1))
{
ui_AD_wert0 = ui_AD_wert1;
ui_AD_wert1 = readSwitch();
}
f_taste = ((1024.0/(float) ui_AD_wert1 - 1.0) * 63.0);
ui_taste1 = (unsigned int) (f_taste + 0.5);

if (ui_taste0 != ui_taste1)
{
SerWrite("\n\r\n\r", 4);
SerWrite("AD-Wert: ", 9);
sendeZahl(ui_AD_wert1, 10, 4);
SerWrite(" Tastenwert bin: ", 20);
sendeZahl(ui_taste1, 2, 8);
SerWrite(" Tastenwert dez: ", 20);
sendeZahl(ui_taste1, 10, 3);


if (f_taste > (float) ui_taste1)
{
SerWrite(" +0,", 4);
ui_delta = (unsigned int) ((f_taste - (float) ui_taste1) * 100);
sendeZahl (ui_delta, 10, 2);
}
else
{
SerWrite(" -0,", 4);
ui_delta = (unsigned int) (((float) ui_taste1 - f_taste) * 100);
sendeZahl (ui_delta, 10, 2);
}

SerWrite("\n\r", 2);
}
return ui_taste1;
}




int main(void)
{
unsigned int ui_taste, ui_Line[2];
Init();
SerWrite("\n\r\n\r Asuro Line- und Switch-Test\n\r", 34);
StatusLED(OFF);
SerWrite("\n\rStatusLED(OFF)", 16);
ui_taste = 0;
Sleep(25);
while(1)
{
ui_taste = printTasten(ui_taste);
sekunden(1);
if (ui_taste == 32) {FrontLED(ON); SerWrite("\n\rFrontLED(ON)\n\r", 16);}
if (ui_taste == 16 || ui_taste == 8) {FrontLED(OFF); SerWrite("\n\rFrontLED(OFF)\n\r", 17);}
LineData(ui_Line);
SerWrite("\n\rLineData links: ", 23);
sendeZahl(ui_Line[0], 10, 3);
SerWrite(" rechts: ", 18);
sendeZahl(ui_Line[1], 10, 3);
}

return 0;
}


[Code-Tags eingefügt von Radbruch]

flieder
22.10.2009, 19:08
hallo radbruch,
danke für deine Unterstützung mit dem Code Fenster.
Wie wird denn dieses Fenster eingefügt ?
pit

Valen
22.10.2009, 20:27
[co de]Deine code[/ code]

Aber ohne die beiden leerzeichen.

flieder
22.10.2009, 20:56
Valen, danke für den Hinweis

flieder
22.10.2009, 21:24
wernerlicious,
ich möchte mich an deinem Projekt beteiligen, kann allerdings nicht täglich ins Forum kommen.
Ich bin der gleichen Meinung wie radbruch, zunächst nur die Liniensensoren und anschließend die Odometrie anzugehen.
Kannst du schon sagen wie bei deinen Liniensensoren die Werte aussehen?
Ich erhalte z.B. auf einer grauen Unterlage und Kunstlicht links etwa 130 und rechts etwa 95, bei eingeschalteter LED. Bei ausgeschalteter LED erhalte ich Werte zwischen 0 und 8. Eine Tischkante würde ich mit < 40 sicher identifizieren.
Mit dem oben angehängten Programm kannst du neben den Liniensensoren auch überprüfen, wie genau die Tasten erkannt werden.
pit

wernerlicious
23.10.2009, 13:48
Hallo flieder,
das finde ich mal sehr geil, dass sich jemand an diesem Projekt beteiligt.
Also ich schließe mich euch an, ich werde es aufteilen.
Das erste Ziel ist es also, eine Grenze zu finden zwischen Tischkante und Tisch:

Auch ich habe das Programm ausprobiert und bin auf folgende Werte gekommen:
FrontLED(OFF) bei leichtem Tageslicht: weißes Blatt Papier 12 12
Hellbrauner Tisch 8 8
Abgrund 4 4

FrontLED(ON) bei leichtem Tageslicht: weißes Blatt Papier 98 96
Hellbrauner Tisch 73 70
Abgrund 5 6

Bin eigentlich recht glücklich darüber, dass beide Sensoren so nah aneinander liegen.
So nun habe ich aber was entdeckt beim SUCHEN.

http://www.asurowiki.de/pmwiki/pub/html/adc_8c.html

mit diesem ec_bak = autoencode können wir doch bestimmt was anfangen oder?

Wäre natürlich Klasse, wenn wir beim Anschalten des Asuros die aktuellen Linienfolgerdaten speichern könnten (so wie ich es anfangs gedacht hatte).
Dann könnten wir diesem ec_bak einfach einer Variablen zuordnen, meinetwegen a und sagen, wenn data[1] oder data[0] < a ist, dass dann Asuro unseren erwünschten Halt macht.

Somit hätten wir Untergrundunabhängige Werte, und bräuchten nich mit so Werten rum experimentieren, die dann schlussendlich nich überall funktionieren.

@ radbruch:
Danke für deine Hilfe, aber auf deinen aufgelisteten Seiten war ich selbstverständlich schon längst, durch diese bin ich erst auf die idee gekommen das zu verbinden.
Dann kam mir die Idee mit dem Wert speichern, was natürlich genial wäre.


Lg Marcel

flieder
23.10.2009, 18:09
Natürlich soll der Asuro sich automatisch an die Veränderungen der Umgebung anpassen. Dazu möchte ich kontinuierlich Mittelwerte und Abweichungen speichern. Also nicht nur die Werte beim Einschalten. Mir ging es eigentlich zuerst mal nur darum zu verstehen was der Asuro sieht. Wie groß ist der Einfluß vom Streulicht, wie dick muß eine Linie sein um sie zu erkennen, brauche ich einen weißen Untergrund usw. ? Wie stark weichen die Werte der beiden Sensoren von einander ab. Im Prinzip soll das Programm diese Bedingungen abdecken, egal wie die Toleranzen aussehen. Ich finde es deshalb gut, dass sich dein Asuro anders verhält als meiner. Vielleicht gesellen sich ja noch andere Interessenten dazu. Das würde die Sache noch interessanter machen. Ich bin momentan noch dabei, das Verhalten der Sensoren zu testen. Ich schlage vor, die Steuerung zuerst über den Bildschirm zu testen und dann erst an die Odometrie zu gehen. Vielleicht bekommen wir auch noch Tips vom Forum.

wernerlicious
23.10.2009, 18:25
ach so.

Dem stimme ich aber zu.

Ich werde morgen früh auch noch ein paar verschiedene Tests hier durchführen und anschließend posten.

Darf ichd ich mal fragen ob und wenn ja wie du deine Sensoren vorne abgeschirmt hast?

Ich bin nämlich gerade dabei mir etwas dafür zu überlegen.


Lg Marcel

flieder
23.10.2009, 22:58
Hallo,
habe bis jetzt keine Abschirmung vorgesehen. Im Normallfall werde ich vermutlich ohne auskommen. Aber dafür sind noch ein paar Tests vorgesehen. Vor allem will ich noch wissen wie der Unterschied der beiden Sensoren bei starkem Lichteinfall aussieht. Falls eine Abschirming erforderlich wird, dann kann ich später immer noch einen schwarzen Pappring montieren.

vistauser
24.10.2009, 16:21
Hallo flieder,
ich habe die beiden Sensoren mit schwarzem Schrumpfschlauch
abgeschirmt.
Zeigt sich mit deinem prima Testprogramm, daß diese Methode
gut geeignet ist.
Habe nebenbei mit dem Testprogramm auch noch festgestellt, daß
der Widerstand eines Tasters mit einem anderen einen "unerlaubten"
Kontakt hatte.
Schönes Wochenende
vistauser

flieder
24.10.2009, 19:24
So ein Feedback hört man gern.
Mein aktueller Status
Nach meinen Tests war eine sichere Erkennung des Tischrandes bei viel Streulicht und ohne Abschirmung nicht möglich (konnte Werte von 10 bis 1000 ermitteln).
Auf schwarzer Unterlage mit wenig Streulicht erhielt ich dagegen Werte zwischen 0 und 5.
Mit Abschirmung (Fototransistoren und Diode gemeinsam mit einem schwarzen Isolierband umwickelt) ergaben sich relativ stabile Werte auch mit Streulicht. Sichere Tischkantenerkennung mit < 30. Asuros ohne Abschirmung und mit Sicherheitsabfrage auf Null (wie hin und wieder gelesen) leben vermutlich sehr gefährlich.
Für die Liniennavigation, über eine 2 mm breite schwarze Linie erhielt ich als Durchschnittswerte:
links 150 -30 und rechts 132 -18
Möglicherweise reicht mit Abschirmung die einmalige Kontrolle der eingelesenen Werte beim Start aus.
Würde mich freuen, wenn sich noch mehr an dieser Runde beteiligen.
Sind die alten Hasen eigentlich ähnlich vorgegangen?
Gruss Flieder

wernerlicious
28.10.2009, 14:40
Hallo,

also der Schulstress ist seit Montag wieder am Start,
aber finde trotzdem kurz Zeit.

Also ich habe ebenfalls einen ausführlichen Test gemacht am Samstag und musste ebenfalls feststellen, dass die Werte mit Abschirmung eindeutig besser und unbeeinflussbarer sind als ohne.

Habe ebenfalls eine 2mm schwarze Linie probiert und auch eine ungefähr 1mm dicke.
Bei der 1mm musste ich manchmal schon viel Glück haben, im Gegensatz zu der 2mm. Vielleicht sollte ich auch besser mal eine identische Abschirmung vornehmen.

Mich würde es ebenfalls interessieren, wie es bei anderen war.
Würde mich um mehr Beteiligung freuen,
außerdem bin ich zu dem Entschluss gekommen, dass es das Beste ist (MIT ABSCHRIMUNG) die Anfangswerte zu speichern.

Lg Marcel