PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SUMO ASURO ... eine Beschäftigung für Weihnachten



robo.fr
17.12.2007, 00:15
So, jetzt ist es bald wieder so weit. Die Weihnachtszeit steht vor der Tür und damit auch schon wieder ein paar freie Tage, die ich der Kreativität widmen möchte. :Weihnacht

Vor einiger Zeit habe ich einen Sumo- (http://www.youtube.com/watch?v=UxhKb-zZoWE) Roboterwettkampf beobachtet und dachte mir, dass wäre doch eine schöne Aufgabe für den Asuro.
Beim SUMO-Wettkampf sind 2 Roboter in einer Arena. Jeder der Roboter soll versuchen, den anderen möglichst schnell aus der Arena zu schieben.

Video: hier finde sich das aktuelle Ergebnis dieses Threads (http://www.youtube.com/v/LkEv21QNzsY)

Ich denke, das wäre ein ganz witzige Aufgabe für 2 ASUROs. Für den Anfang kann man das Ganze mit nur einem ASURO probieren. Der zweite Roboter wird durch Joghurtbecher simuliert.

Dazu habe ich mir mal einen kleines Spielbrett gebastelt ( mit normalem DINA4 Druckerpapier und schwarzem Isolierband )

Um die Joghurtbecher zu erkennen, eignet sich der "wastsche" Abstandssensor (https://www.roboternetz.de/phpBB2/viewtopic.php?t=10026).

Wer hat Lust, über die Feiertage zu einem kleinen, entspannten Wettbewerb? :Ostern
Das Ziel könnte sein, die Joghurtbecher möglichst schnell vom Brett zu kriegen.

Falls jeman 2 ASUROs hat, könnte man vielleicht auch das gegnerische Programm hier aus dem Forum posten und dann auf dem eigenen Spielfeld gegeneinander antreten lassen.

damaltor
17.12.2007, 01:21
das klingt gut. nur würden sich vermutlich die abstandssensoren der beiden asuros gegenseitig völlig aus dem konzept bringen... aber da lässt sich sicher ne lödung finden.

Mav3ric
17.12.2007, 17:10
Ich hab meinen Asuro zwar noch nicht, aber vom Grundprinzip her denke ich mir das so:

Asuro fährt einfach gerade aus, bis er an der Begrenzung ist, oder seinen "Gegner" findet.

Wenn er etwas berüht, gibt er Vollgas nach vorne. Sobald der die Linie sieht, fährt er ein Stück rückwärts und eine Kurve. Dann geht das Ganze von vorne los.

robo.fr
18.12.2007, 00:49
Ich hab meinen Asuro zwar noch nicht ...

Wie schade, den bekommst Du aber sicher an Weihnachten, oder? Allerdings wirst Du dann erst mal eine ganze Weile lang mit Lötarbeiten beschäftigt sein.


Asuro fährt einfach gerade aus, bis er an der Begrenzung ist, oder seinen "Gegner" findet.

Hier mal ein kleines Testvideo (http://www.youtube.com/v/zh8upwq_86o)zur Gegnererkennung, bei dem der ASURO nicht gerade ausfährt. Wie man sieht, geht es auch auf kurvigem Wege.

radbruch
18.12.2007, 01:06
Hallo

Eigentlich ja eine nette Idee, aber wenn ich die asuros so zusammenboxen sehe, tuts mir im Herzen weh. Manche wären froh, wenn ihr asuro endlich richtig funktioniert und ihr wollt ihn als Crashcar missbrauchen. Da gefällt mir die Version asuro vs joghurtbecher doch deutlich besser.


Wie schade, den bekommst Du aber sicher an Weihnachten, oder? Allerdings wirst Du dann erst mal eine ganze Weile lang mit Lötarbeiten beschäftigt sein.
Vielleicht dann zu Ostern in der Variante: Eierschubsen.

(Das soll nun aber keine Anmeldung meinerseits zum Wettbewerb sein *anmerkt*)

Gruß

mic

robo.fr
18.12.2007, 10:24
Hallo Radbruch,

das mit dem Zusammencrashen ist natürlich ewas hart für die ASUROs, aber man könnte ja auch einen Schaumstoffschutz um den Roboter bauen.

Auf die Idee mit dem ASURO Sumo bin ich durch eine Veranstaltung mit dem ct-Bot gekommen. Es war wirklich begeisternd, zu sehen wie sich die Roboter bewegt haben. Da dachte ich mir, mit dem ASURO müsste das doch auch möglich sein.

Die Kombination aus Abstandsensor und Liniensensor erweitert die Möglcihkeiten des ASURO ungemein. Das ASURO Projekt erschien mir der einfachste Anwendungsfall dafür zu sein.

Ein Wettbewerb ist immer etwas anstrengend, weil man so viel Zeit dafür braucht. Wer also lieber so ein wenig programmiert, kann ja mit ein paar guten Ideen hier beitragen, vielleicht ergibt sich ja eine interessante Diskussion.

Gruß,
robo

1nDaClu8
18.12.2007, 10:45
@Robo.fr:

Gibts da ein Video über das Sumo ringen der CT Bot´s. Könntest du mir mal den Link schicken, würde mir das gerne mal angugen. Danke

Grüße,

1nDaClu8

robo.fr
18.12.2007, 13:39
Leider habe ich es nur "live" gesehen.

robo.fr
20.12.2007, 10:49
Um zu testen, wie gut man den ASURO mit Hilfe seiner Liniensensoren im Spielfeld halten kann, habe ich ein kleines Testprogramm geschrieben.
Die Auswertung der Liniensensoren reagiert auf die sprungartige Helligkeitsänderung der Liniensensoren. Dazu wird die über einen Tiefpassfilter ermittelte durchschnittliche Helligkeit mit den aktuellen Werten der Sensoren verglichen.


#include "asuro.h"

#define LIMIT 20 // Helligkeitsveraenderung, bei der eine Linie detektiert wird
#define TIEFPASS 50 // grosser Wert=grosse Zeitkonstante
// globale Variablen
uint16_t HellLinks;
uint16_t HellRechts;
/************************************************** ***********************

uint8_t testhell()

testhell ermittelt die durchschnittliche Helligkeit der beiden
Linienphottransistoren mit Hilfe eines Tiefpassfilters.
Unterschreitet die Helligkeit schlagartig den tiefpassgefilterterten
Wert, wird ein Flag gesetzt.

Ausgabe:
testhell=0: keine Linie
Bit0= Linie links erkannt
Bit1= Linie rechts erkannt
Bit0+Bit1 Linie senkrecht


************************************************** ***********************/

uint8_t testhell()
{
uint8_t ergebnis=0;
uint16_t lineData[2];

LineData(lineData);
HellLinks=(HellLinks*TIEFPASS+lineData[0])/(TIEFPASS+1);
HellRechts=(HellRechts*TIEFPASS+lineData[1])/(TIEFPASS+1);
StatusLED(YELLOW);
if((lineData[0]+LIMIT)<(HellLinks)) ergebnis|=1;
if((lineData[1]+LIMIT)<(HellRechts)) ergebnis|=2;
Msleep(10);
return ergebnis;
}

int main(void)
{
int n;

Init();

StatusLED(RED);
FrontLED(ON);

// mittlere Helligkeit im Stand ermitteln
for(n=0;n<300;n++)
{
testhell();
}
StatusLED(YELLOW);

MotorDir(FWD,FWD);
MotorSpeed(150,150);
while(1)
{
n=testhell();

BackLED(n&0x01,n&0x02);
StatusLED(YELLOW);

if(n!=0) // Falls Linie erkannt, dann drehen und zurück
{
StatusLED(GREEN);
MotorDir(RWD,RWD);
MotorSpeed(150,100);
Msleep(600);
MotorDir(RWD,FWD);
MotorSpeed(200,200);
Msleep(600);
MotorDir(FWD,FWD);
MotorSpeed(150,150);
}

Msleep(10);
}

}
/************************************************** *************************
*
* 2007 robo.fr (Nickname) , christoph(at)roboterclub-freiburg.de
*
************************************************** *************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation version 2 of the License, *
* If you extend the program please maintain the list of authors. *
* ( if there is no real name, the nick name has to be mentioned )
* If you want to use this software for commercial purposes and you *
* don't want to make it open source, please contact the authors for *
* licensing. *
************************************************** *************************/


Wie gut das ganze funktioniert sieht man hier (http://www.youtube.com/v/PWmNQyLUl70).

damaltor
20.12.2007, 11:57
und? wie gut klappt es bei dir?

robo.fr
20.12.2007, 12:00
Wie gut das ganze funktioniert sieht man hier (http://www.youtube.com/v/PWmNQyLUl70).

@damaltor: was macht eigentlich die Bilderekennung in OpenCV für Linux. Wolltest Du nicht das Programm nach Linux portieren?

damaltor
20.12.2007, 12:05
jaa.. das wollte ich mal probieren. aber im moment habe ich kaum zeit, auch mein asuro der eine art eval board bekommen soll, liegt schon seit wochen zerlegt im schrank. :( aber deoin programm gefällt mir, die idee mit dem tiefpass ist toll.

robo.fr
20.12.2007, 12:15
Bei mir war die Erfahrung, was Projekte angeht, folgende: Alle Projekte immer auf einen funktiionsfähigen Stand bringen, das kostet zwar etwas Anstrengung, vor allen Dingen gegen Ende. Das Leben eines Entwicklers ist nun einmal hart, und zu einem erfolgreichen Projekt gehören nun mal 2 Dinge: Der Spass an der Idee und die Anstrengung und der Schweiß, etwas zu Ende zu bringen. Belohnt wird das ganze mit der Zahl der Projekte auf die man stolz sein kann.

Aber wieder zurück zum SUMO:
Gerade eben habe ich noch eine erweiterte, schwierigere Variante auf Youtube gefunden (http://www.youtube.com/watch?v=dGWCPavtZec).
In der Mitte des Feldes wird ein Gegenstand aufgestellt, den die Roboter nicht umwerfen sollten. Dadurch wird die Aufgabe erschwert, wel die Roboter nicht mehr einfach so auf alles zufahren dürfen.

radbruch
20.12.2007, 12:26
Hallo

Scheint ja prima zu funktionieren. Wenn wir allerdings alle die selben Programme flashen, dürfte es wohl ein Patt geben. Bitte nicht falsch verstehen, ich bin natürlich für OpenSource und finde es prima, wenn ihr Codes für grundsätzliche Lösungen postet. Aber wir sollten auch Alternativen anbieten.

Könnte man das Spielfeld nicht sechseckig machen? Das wäre sehr viel leichter zu konstruieren und zu kleben. Wer's nimmer weiß: Beim Sechseck sind die Seiten so lang wie der Radius des Umkreises...

http://upload.wikimedia.org/wikipedia/commons/c/cf/HexagonConstructionAni.gif (http://de.wikipedia.org/wiki/Konstruktion_mit_Zirkel_und_Lineal)
(Quelle: wikipedia (http://de.wikipedia.org/wiki/Konstruktion_mit_Zirkel_und_Lineal))

Gruß

mic

robo.fr
21.12.2007, 09:22
Hallo Radbruch,

die ganze Zeit überlege ich schon, ob ein 6-Eck einen Vorteil gegenüber einem 8-Eck hat. Das Bild in meinem ersten Post zeigt das 8-Eck, welches ich für meine Versuche auf zusammengeklebte Din A4-Plätter konstruiert habe. Es war relativ einfach zu erstellen, 4 Seiten sind parallel zur Unterlage und ich habe keinen großen Circel gebraucht.

Eventuell hätte eine kreissymmetrische Spielfläche einen Vorteil, weil dann der Roboter den Mittelpunkt vielleicht besser finden kann.

Gruß,
robo

radbruch
21.12.2007, 09:53
Hallo robo

Nachdem ich mir nun auf zwei A3-Blättern ein sechseckiges Spielfeld zusammengeklebt habe, bin ich mir auch nicht mehr sicher, ob es wirklich bedeutend einfacher als ein Achteck ist. Klassisch konstruiert mit Schnur und Stift ist es zwar schnell, aber beim Kleben der schwarzen Streifen habe ich dann festgestellt, dass man sich dabei auch gut an den Blatträndern orientieren kann und deshalb dürfte ein Achteck auch einfach zu kleben sein.

Vielleicht könnte mein asuro bei meinem Spielfeld die Mitte leichter finden, weil die Winkel der Klebestreifen größer sind und man sie deshalb leichter finden könnte als beim Achteck. Aber ob das für die gestellte Aufgabe (suche den Becher und schiebe ihn raus) einen Vorteil bringt, wage ich zu bezweifeln.

Dein Linienerkennungsprogramm läuft mit meinem asuro auch sehr gut. Da ich aber als FrontLED eine IR-LED aus einer alten Fernbedienung eingebaut habe, musste ich den Wert für Limit auf 200 erhöhen und wegen meiner kürzeren Endübersetzung die Geschwindigkeit etwas anpassen. Blöderweise läuft grad mein linker Motor nicht zurück, ich muss also leider erstmal den Fehler suchen bevor ich mich richtig draufstürzen kann.

Gruß

mic

robo.fr
25.12.2007, 08:12
Hallo radbruch,

wie gehts dem ASURO Motortreiber? Laufen die Motoren schon wieder?


Dein Linienerkennungsprogramm läuft mit meinem asuro auch sehr gut. Da ich aber als FrontLED eine IR-LED aus einer alten Fernbedienung eingebaut habe, musste ich den Wert für Limit auf 200

Den Programmcode habe ich extra auf die Verhältnisse des Standard des Originalasuro angepasst. In einem meiner zwei ASUROs ist eine 24000mcd superhelle rote LED eingebaut. Dort muss der Wert auch auf 200 erhöht werden. Die Grenzlinienerkennung wird dadurch natürlich um noch einiges stabiler.
Vielleicht hat die ultrahelle, roten LED einen Vorteil weil man sehen kann, ob sie eingeschaltet sind und das Infrortliche eventuell den IR-Empfänger für die Abstandmessung stören könnte.


Im Moment beschäftige ich mich ein wenig mit der Zielfindung über den IR-Abstandsmesser. Gar nicht so einfach.

Ich habe eine kleine Funktion geschrieben, mit der grob der Abstand ermittelt werden kann, in dem die Pulsweite durchge"sweept" wird.
Waste hat das schon mal gemacht ( glaube ich ) aber ich konnte es auf die schnelle nicht finden


uint8_t abstand()
{
uint8_t k=FALSE,n;
uint16_t j,z;

for(n=1;n<10;n++)
{
OCR2 = 254-n; //OCR2=0xFE ( sehr nahe )
Msleep(2);
z=0;
for(j=0;j<1000;j++) if (PIND & (1 << PD0))z++;
if (z>900) k=n;
}
if(k==9) k=FALSE; // Falls Abstand größer 10 Abstand=FALSE
return k;
}

radbruch
25.12.2007, 10:23
Hallo robo.fr

Wie du ja weißt habe ich mit der IR-Abstandsmessung auch schon gespielt. Letztlich habe ich dann einen mit Folie beschichteten "Reflektor" gebastelt und ihn unter den Kabelbinder des Motors geklemmt:

https://www.roboternetz.de/phpBB2/album_thumbnail.php?pic_id=1237 (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=252963&sid=210d5698bd427b3e5f9d04eb90af2139#252963)

Und noch ein Video dazu:
http://img.youtube.com/vi/6-5pah_oQUw/1.jpg (http://www.youtube.com/watch?v=6-5pah_oQUw)
http://www.youtube.com/watch?v=6-5pah_oQUw

Ganz wichtig dabei ist ein lichtdichtes Irgendwas (Karton, Folie, aufgeschnittener Schrumpfschlauch...) zwischen den IR-Empfänger und die Platine zu klemmen und es seitlich hoch zwischen Empfänger und IR-LED zu biegen um "Kriechlicht" zu verhindern!

Der "Rüssel" auf der IR-LED besteht aus mehreren Lichtwellenleitern (ca. 1€/Meter) in einem Schrumpfschlauch und dient der Bündelung des Lichtstrahls. Es funktioniert aber auch ohne recht gut, aber nicht so scharfkantig.

Hier noch der Code MIT Kantensuchen (ich hoffe, er funktioniert noch):

/* asuro haelt mittels IR-Messung vorgewaehlten
Abstand zu einem Gegenstand und richtet sich dabei nach einer Kante aus.

14.2.2007 mic
*/

#include "asuro.h" // Version mit dutycycles und TOIE2 in Init() (ab ca. v2.5)

unsigned char i, ir_bits, dist, dir_l, dir_r; // zaehler, bitzaehler, abstand, richtungen
unsigned int bitspeicher, delay; // filter, rythmus

int main(void)
{

Init();

MotorDir(FREE,FREE); // Stillstand vorbelegen
MotorSpeed(150,150); // je mehr desto hektisch
bitspeicher = 1; // 16 Bits Filter für IR-Echos
dist=240; // Sollabstand (zw. 0x90 und ca.250, je groesser desto nah)
delay=Gettime(); // Rythmus fuers Kantensuchen

while (1) {

// vor und zurueck

DDRD |= (1 << DDD1); // IR-LED an
PORTD &= ~(1 << PD1);
OCR2 = dist; // gewuenschter Abstand
bitspeicher = bitspeicher*2+(PIND & (1 << PD0));
ir_bits=0; // bei diesem Abstand soll auf 2 von 8 Nicht-Echos gefahren werden
for (i=0; i<8; i++) if (bitspeicher & (1 << i)) ir_bits++; // letzte 8 Echos
dir_l=dir_r=FREE;
if (ir_bits > 4 ) dir_l = dir_r = FWD; // mehr als zweimal kein Echo = zu weit
if (ir_bits < 2 ) dir_l = dir_r = RWD; // weniger als zwei Nicht-Echos = zu nah
MotorDir(dir_l,dir_r); // Abstand korrigieren
if (Gettime() >= delay) { // mehr als eine Sekunde seit dem letzen Suchen der Kante
// nach links drehen bis kein Echo mehr kommt

if ((dir_l) == (FWD)) { // bei Vorwaertsfahrt
dir_l = FREE; dir_r = FWD;
} else if ((dir_l) == (RWD)) { // bei Rueckwaertsfahrt
dir_l = RWD; dir_r = FREE;
} else { dir_l=FWD; dir_r=RWD; }; // im Stillstand
MotorDir(dir_l,dir_r);
//MotorDir(RWD,FWD);
DDRD |= (1 << DDD1); // IR-LED an
PORTD &= ~(1 << PD1);
OCR2 = 0x90; // maximale Distanz
do {
bitspeicher = bitspeicher*2+(PIND & (1 << PD0)); // Bitspeicher fuellen
ir_bits=0;
for (i=0; i<16; i++) if (bitspeicher & (1 << i)) ir_bits++;
} while (ir_bits < 15); // alle Bits gesetzt bedeutet keine Echo = Kante ueberfahren

// rechts drehen und mit Soll-Distanz nach Echo suchen (sicherheitshalber mehrfach!)

if ((dir_l) == (FREE)) { // abhaengig von verwendeter Methode zurückschwenken
dir_l = FWD; dir_r = FREE;
} else if ((dir_r) == (FREE)) {
dir_l = FREE; dir_r = RWD;
} else { dir_l=RWD; dir_r=FWD; };
MotorDir(dir_l,dir_r);
//MotorDir(FWD,RWD);
DDRD |= (1 << DDD1); // IR-LED an
PORTD &= ~(1 << PD1);
OCR2 = dist; // Messdistanz laden
for (i=0; i<10; i++) { //mehrfach pruefen und gegebenfalls fahren um die Kante sicher zu finden
bitspeicher=1; // alle Bits geloescht bedeutet volles Echo = Kante wiedergefunden
do bitspeicher = bitspeicher*2+(PIND & (1 << PD0)); while (bitspeicher != 0);
//for (bitspeicher=1; bitspeicher != 0; bitspeicher*2+(PIND & (1 << PD0)));
}
if (((dir_l) != (FREE)) && ((dir_r) != (FREE))) MotorDir(FREE,FREE); // anhalten oder durchstarten
//MotorDir(FREE,FREE);
delay=Gettime()+500; // einmal pro Sekunde die Kante suchen
}
} // endloss

while(1); return 0;
}
Der asuro hält den vorgegebenen Abstand zum Blatt und richtet sich nach der linken Blattkante aus. Die IR-Echos werden gefiltert und erst nach einer festgelegten Anzahl von Echos/Nichtechos wird reagiert. Achtung, die verwendete asuro-Lib muss die IR-Erweiterung nach Waste enthalten und den Timer zur IR-Pulserzeugung folgendermaßen Initialisieren:

//-------- seriell interface programmed in boot routine and already running -------
// prepare 36kHz for IR - Communication
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
OCR2 = 0x91; // duty cycle for 36kHz
TIMSK |= (1 << TOIE2); // 36kHz counter for sleep

(aus Init() in asuro.c ab ca. 2.5)

Wenn man OCR2 ändert, kann man nicht mehr per IR mit dem Terminal kommunizieren, weil die 36kHz-Trägerfrequenz nicht mehr stimmt. Zuvor muss man wieder den Defaultwert (OCR2 = 0x91) wieder laden.


wie gehts dem ASURO Motortreiber? Laufen die Motoren schon wieder?
Er ist leider immer noch "krank", ich hatte noch keine Zeit danach zu schauen.

Gruß

mic

robo.fr
25.12.2007, 19:33
Er ist leider immer noch "krank", ich hatte noch keine Zeit danach zu schauen.
Oh, sehr schade, der arme ASURO. [-o< Und das an Weihnachten. :Weihnacht

Mittlerweile habe ich auch neue Versuche unternommen, den ASURO so zu programmieren, dass er einen Joghurtbecher besser finden (http://www.youtube.com/v/McVBXhhvoc8) kann.


Aber ich bin immer noch etwas neidisch auf das Video (http://de.youtube.com/watch?v=DVgYreCle4M) von waste ( ich nehme mal an, dass es von waste ist ). Der ASURO ruckelt da relativ wenig. Daher vermute ich, dass der ASURO eher 2 IR Sensoren verwendet. Aber leider sieht man das auf dem Video so schlecht.

Ich frage nicht einen richtigen Reglerentwurf für das Problem machen könnte. Dazu müsste man aber eine passende Struktur finden :-k

robo.fr
25.12.2007, 22:48
Nach doch etwas mehr Auwand als ursprünglich gedacht, spielen 2 ASUROs in der Sumo-Arena miteinander: O:)

http://www.youtube.com/v/LkEv21QNzsY

Was haltet Ihr davon?

Chief 2
08.01.2008, 18:20
Hallo robo.fr
Ich hab ein Problem mit den einen Programm womit der Asuro im Achteck(Sechseck) bleibt und zwar kent Mein program die funkion "Msleep Nicht"
die Fehlermeldung sieht Folgenermasen aus: C:\ASURO_src\FirstTry/test.C:71:undefined reference to `Msleep'
C:\ASURO_src\FirstTry/test.C:74:undefined reference to `Msleep'
C:\ASURO_src\FirstTry/test.C:79:undefined reference to `Msleep'
Ich wäre dankbar wen einer mir helfen Könnte

Gruß
Chief 2

radbruch
08.01.2008, 18:53
Hallo

Msleep() und andere Funktionen gibt es erst in den neueren Versionen von asuro.c:

http://sourceforge.net/project/showfiles.php?group_id=155217&package_id=172835#

Ab Version 2.7 wird's extrem kompliziert und man entfernt sich zunehmend von der Hardware (auch wenn mich wohl einige schlagen wollen, wenn ich das behaupte). Hier das Chancelog der Version 2.61:

ASURO Library Versions History
==============================

Version 2.6.1
=============

- 20.11.2006 Bugfixes: (Autor: m.a.r.v.i.n)
* PrinInt Funktion: evtl. Fehler beim Flashen mit RS232/IR Transceiver,
wg. Folge von 0-Bytes im erzeugten Hex-File.
Bug tracking von francesco
* SIGNAL (SIG_ADC): static Variable toggle initialisiert
Bugtacking von Rolf_Ebert
Warnings entfernt wg. obsolete Header File bei neueren WinAVR Versionen.

Version 2.6
===========

- 28.09.2005 Doxygen Kommentare. (Autor: m.a.r.v.i.n)

Version 2.5
===========

- 31.07.2005 Turn() Funktion mit speed Parameter. (Autor: Andun)

Version 2.4
===========

- 30.07.2005 Erweiterungen, Go() und Turn() Funktionen. (Autoren: stochri, Andun)

Version 2.3
===========

- 10.06.2005 Anpassungen wg. Umbau der Infrarot Schnittstelle als Kollisionsdetektor (Autor: waste)

count36kHz ersetzt count72kHz. Timer2 geändert.


Version 2.2
===========

- 31.03.2005 Erweiterte Funktionen (Autor: weja - Robotrixer Buxtehude)

Kurzbeschreibung der Funktionen in der neuen asuro.h, asuro.c vom 31.03.05



Leider konnten die neuen Funktionen nicht mehr in einer Extradatei untergebracht
werden, weil mehrere "alte" Funktionen verändert wurden, damit z.B. die Systemzeit
integriert werden konnte. Auch wurde die PollSwitch Funktion vom Ballast der Fließkomma-
berechnung befreit. Nun ist wieder mehr Platz für eigenen Code vorhanden.





Encoder_Init()

Dieser Befehl installiert die Interrupt Funktion für den automatischen Wegzähler.

Encoder_Start()

Startet die automatische Zählung nach

Encoder_Stop()

neu. Diese Stopp Funktion hält den Zähler an

Encoder_Set(int,int)

Setzt die Variablen encoder[0] und encoder[1]. Z.B.: Encoder_Set(0,0) setzt beide
Variablen auf Null.

switches

ist eine Variable, die, wenn Startswitch() gestartet wurde, auf wahr gesetzt wird,
sobald eine Taste gedrückt wurde. gleichzeitig wird die Tastenüberwachung wieder
abgeschaltet. Beispiel:
Start_Switch();
while (!switches){;} //wartet auf Tastendruck
// an dieser Stelle kann mit Pollswitch geprüft werden
// welche Taste gedrückt wurde, wenn nötig.
switches=FALSE; // für eine neuen Aufruf von Startswitch()

Msleep(int)

wartet die angegebene Zeit in ms. Z.B warte 10 Sekunden: Msleep(10000);

Gettime()

Gibt die Zeit, die seit dem letzten Start des Asuro vergangen ist als unsigned long zurück.
Die Angabe erfolgt auch hier in Millisekunden.

PrintInt(int)

Eine kleine Ausgabehilfe für Integerwerte.
Beispiel Zeilenweise Ausgabe der encoder Werte:
PrintInt(encoder[0]);SerWrite(" ",3);PrintInt(encoder[1]);SerWrite("\n\r",2);


31.03.05 Robotrixer Buxtehude

Version 2.1
===========

- 10.11.2003 Original Version von der ASURO CD (Autor: Jan Grewe - DLR)

Ich verwende v2.3

Gruß

mic

liggi
08.01.2008, 18:56
hast du die lib aus dem forum oder welche

mfg liggi

Chief 2
08.01.2008, 19:08
Hallo Radbruch
Wo soll ich den die dateien hintun
Hallo Liggi
Ich habe noch die lib Die bei den WinAVR-20071221 dabei war

radbruch
08.01.2008, 19:53
Die Dateien muss man da hintun wo die alten sind. Sie ersetzen asuro.h und asuro.c

Wenn du nicht weißt, wo die sind, unter Windows kann man auch Dateien suchen: Start->Suchen->Nach Dateien und Ordern

und dann asuro.* eingeben.

Die asuro-Library ist nicht Teil von WinAVR sondern gehört zur Doku des asuros. Deshalb wird sie wohl in dem Ordner sein indem sich auch eure selbstgeschriebenen asuro-Programme befinden. Deshalb werden sie auch mit #include "asuro.h" eingebunden. "" bedeutet im selben Verzeichniss wie das Programm.

Gruß

mic

Chief 2
08.01.2008, 21:01
Wen ich die dateien Asuro.h/c eingebe findet er die nur im first try ordner und wen ich die da ändere dan geht ganix mehr also hab ich wieder die normalen asuro,c/h da hingemac

Gruß
Chief 2

radbruch
08.01.2008, 21:10
Na, wenn du nur die findest, werden es wohl die richtigen sein. Und wenn du die änderst und danach "dann geht garnix mehr" ist, sind sie es bestimmt. Was bedeutet denn "dann geht garnix mehr"?

Um es etwas abzukürzen: Welche Version hast du runtergeladen? Hast du die Dateien entpackt? Hast du beide Dateien (h+c) ersetzt? Welche Fehlermeldungen hast du jetzt?

Gruß

mic

Chief 2
08.01.2008, 21:29
ich habe die version 2.7.1 heruntergeladen und entpakt und dan beide tateien Asuro.c Asuro.h dursch die neuen ersetz und dan war als ich die datai mit der make finkion compiliren wollte standden da nur fehlermeldung
Gruß
Chief 2

Chief 2
08.01.2008, 21:31
Die Funkion "Msleep,MotorDir" und andere wie das das sind doch alle variablen oder?

radbruch
08.01.2008, 22:03
Nein, es sind Funktionen. Hier hast du die Kopie von Msleep():

void Msleep(int dauer)
{
int z;
for(z=0;z<dauer;z++) Sleep(72);
}
(aus asuro.c)

Kopieren und in deinem Programm einfügen, dann kannst du es vermutlich mit den orginalen asuro.c/.h komplilieren.

Ich dachte, du willst den asuro programmieren. Wenn du aber lieber lernen willst, wie man die 2.7er-Lib installiert, kannst du es hier nachlesen:

https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=26594

mic

Chief 2
08.01.2008, 22:13
Ich hab das jetz anstelle des Msleepeingesetz abber dann steht da 4 mal
Test.c:**: error: expected ':', ','or ')' before numerik constant

Chief 2
08.01.2008, 22:49
Und wen Ich Diesen Error anklicken fürt der mich immer in die zeile die den error verusacht und das ist die zeile mit:
void Msleep(int dauer)
Gruß
Chief

radbruch
08.01.2008, 22:56
Da hast du irgendwo noch ein : oder ein , oder eine ) vergessen. Poste doch mal den Bereich mit ein paar Zeilen davor und danach. Oder gleich alles...

Gruß

mic

Chief 2
08.01.2008, 22:59
Ok :

#include "asuro.h"

#define LIMIT 20 // Helligkeitsveraenderung, bei der eine Linie detektiert wird
#define TIEFPASS 50 // grosser Wert=grosse Zeitkonstante
// globale Variablen
uint16_t HellLinks;
uint16_t HellRechts;
/************************************************** ***********************

uint8_t testhell()

testhell ermittelt die durchschnittliche Helligkeit der beiden
Linienphottransistoren mit Hilfe eines Tiefpassfilters.
Unterschreitet die Helligkeit schlagartig den tiefpassgefilterterten
Wert, wird ein Flag gesetzt.

Ausgabe:
testhell=0: keine Linie
Bit0= Linie links erkannt
Bit1= Linie rechts erkannt
Bit0+Bit1 Linie senkrecht


************************************************** ***********************/

uint8_t testhell()
{
uint8_t ergebnis=0;
uint16_t lineData[2];

LineData(lineData);
HellLinks=(HellLinks*TIEFPASS+lineData[0])/(TIEFPASS+1);
HellRechts=(HellRechts*TIEFPASS+lineData[1])/(TIEFPASS+1);
StatusLED(YELLOW);
if((lineData[0]+LIMIT)<(HellLinks)) ergebnis|=1;
if((lineData[1]+LIMIT)<(HellRechts)) ergebnis|=2;
void Msleep(int 10);
{
int z;
for(z=0;z<10;z++) Sleep(72);
}
return ergebnis;
}

int main(void)
{
int n;

Init();

StatusLED(RED);
FrontLED(ON);

// mittlere Helligkeit im Stand ermitteln
for(n=0;n<300;n++)
{
testhell();
}
StatusLED(YELLOW);

MotorDir(FWD,FWD);
MotorSpeed(150,150);
while(1)
{
n=testhell();

BackLED(n&0x01,n&0x02);
StatusLED(YELLOW);

if(n!=0) // Falls Linie erkannt, dann drehen und zurück
{
StatusLED(GREEN);
MotorDir(RWD,RWD);
MotorSpeed(150,100);
void Msleep(int 600);
{
int z;
for(z=0;z<600;z++) Sleep(72);
}
MotorDir(RWD,FWD);
MotorSpeed(200,200);
void Msleep(int 600);
{
int z;
for(z=0;z<600;z++) Sleep(72);
}
MotorDir(FWD,FWD);
MotorSpeed(150,150);
}

void Msleep(int 10)
{
int z;
for(z=0;z<10;z++) Sleep(72);
}
}

}
/************************************************** *************************
*
* 2007 robo.fr (Nickname) , christoph(at)roboterclub-freiburg.de
*
************************************************** *************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation version 2 of the License, *
* If you extend the program please maintain the list of authors. *
* ( if there is no real name, the nick name has to be mentioned )
* If you want to use this software for commercial purposes and you *
* don't want to make it open source, please contact the authors for *
* licensing. *
************************************************** *************************/

radbruch
08.01.2008, 23:11
#include "asuro.h"

#define LIMIT 20 // Helligkeitsveraenderung, bei der eine Linie detektiert wird
#define TIEFPASS 50 // grosser Wert=grosse Zeitkonstante
// globale Variablen
uint16_t HellLinks;
uint16_t HellRechts;
/************************************************** ***********************

uint8_t testhell()

testhell ermittelt die durchschnittliche Helligkeit der beiden
Linienphottransistoren mit Hilfe eines Tiefpassfilters.
Unterschreitet die Helligkeit schlagartig den tiefpassgefilterterten
Wert, wird ein Flag gesetzt.

Ausgabe:
testhell=0: keine Linie
Bit0= Linie links erkannt
Bit1= Linie rechts erkannt
Bit0+Bit1 Linie senkrecht


************************************************** ***********************/
void Msleep(int dauer)
{
int z;
for(z=0;z<dauer;z++) Sleep(72);
}
/************************************************** ***********************/
unsigned char testhell(void)
{
uint8_t ergebnis=0;
uint16_t lineData[2];

LineData(lineData);
HellLinks=(HellLinks*TIEFPASS+lineData[0])/(TIEFPASS+1);
HellRechts=(HellRechts*TIEFPASS+lineData[1])/(TIEFPASS+1);
StatusLED(YELLOW);
if((lineData[0]+LIMIT)<(HellLinks)) ergebnis|=1;
if((lineData[1]+LIMIT)<(HellRechts)) ergebnis|=2;

Msleep(10);
return ergebnis;
}

int main(void)
{
int n;

Init();

StatusLED(RED);
FrontLED(ON);

// mittlere Helligkeit im Stand ermitteln
for(n=0;n<300;n++)
{
testhell();
}
StatusLED(YELLOW);

MotorDir(FWD,FWD);
MotorSpeed(150,150);
while(1)
{
n=testhell();

BackLED(n&0x01,n&0x02);
StatusLED(YELLOW);

if(n!=0) // Falls Linie erkannt, dann drehen und zurück
{
StatusLED(GREEN);
MotorDir(RWD,RWD);
MotorSpeed(150,100);

Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(200,200);

Msleep(600);

MotorDir(FWD,FWD);
MotorSpeed(150,150);
}

Msleep(10);
}
return(0);
}
/************************************************** *************************
*
* 2007 robo.fr (Nickname) , christoph(at)roboterclub-freiburg.de
*
************************************************** *************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation version 2 of the License, *
* If you extend the program please maintain the list of authors. *
* ( if there is no real name, the nick name has to be mentioned )
* If you want to use this software for commercial purposes and you *
* don't want to make it open source, please contact the authors for *
* licensing. *
************************************************** *************************/
Ich hoffe, es funzt jetzt.

mic

Chief 2
08.01.2008, 23:14
Danke es hat endlich funkionirt ich danke dir Für deine Große hilfe

Gruß
Chief 2

robo.fr
09.01.2008, 12:04
Hallo Chief2,

damit das Ganze etwas einfacher wird, habe ich an dieser Stelle ein HEX-File (http://www.roboterclub-freiburg.de/asuro/hardware/chAtmegaAdapter/SumoAdapter.html) abgelegt, damit man die Abstandserkennung sofort ausprobieren kann.

Gruß,
robo

Chief 2
09.01.2008, 23:06
Hallo Robo.fr
Danke Für das Programm Ich werd es sofort ausprobieren

Gruß Chief 2

Chief 2
12.01.2008, 17:06
Hallo alle zusammen
ich hab mir so ein programm machen wollen das der asuro die becher aus dem ring schiebt abber das programm meldet immer den fehler:
"test.c:207:error:expectet Identifiter or '(' before '{' token"
wen ich es kompilieren möchete
Hir ist das ProgrammDie zeile wo angeblich der Fehler liegt ist mit einen/***<<<***/makiert

#include "asuro.h"
#include <stdlib.h>
#define LIMIT 20 // Helligkeitsveraenderung, bei der eine Linie detektiert wird
#define TIEFPASS 50 // grosser Wert=grosse Zeitkonstante
// globale Variablen
uint16_t HellLinks;
uint16_t HellRechts;

void Msleep(int dauer)
{
int z;
for(z=0;z<dauer;z++) Sleep(72);
}

unsigned char testhell(void)
{
uint8_t ergebnis=0;
uint16_t lineData[2];

LineData(lineData);
HellLinks=(HellLinks*TIEFPASS+lineData[0])/(TIEFPASS+1);
HellRechts=(HellRechts*TIEFPASS+lineData[1])/(TIEFPASS+1);
StatusLED(YELLOW);
if((lineData[0]+LIMIT)<(HellLinks)) ergebnis|=1;
if((lineData[1]+LIMIT)<(HellRechts)) ergebnis|=2;

Msleep(10);
return ergebnis;
}

int main(void)
{
int n;

Init();

StatusLED(RED);
FrontLED(ON);

// mittlere Helligkeit im Stand ermitteln
for(n=0;n<300;n++)
{
testhell();
}
StatusLED(YELLOW);

MotorDir(FWD,FWD);
MotorSpeed(150,150);
while(1)
{
n=testhell();

BackLED(n&0x01,n&0x02);
StatusLED(YELLOW);

if(n!=0) // Falls Linie erkannt, dann drehen und zurück
{
StatusLED(GREEN);
MotorDir(RWD,RWD);
MotorSpeed(150,100);

Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(200,200);

Msleep(600);

MotorDir(FWD,FWD);
MotorSpeed(150,150);
}

Msleep(10);
}
return(0);
}

uint8_t objekt_sichtbar(uint8_t distance)
{
uint16_t j,z;

DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW

OCR2 = 254-distance; // wenn OCR2=0xFE dann Objekt sehr nahe
z=0;
for(j=0;j<30;j++); // loop time: 5ms
{
if (PIND & (1 << PD0))z++;
Sleep(6); // 6*Sleep(6)=1ms
}
if (z>=29) return FALSE; // Objekt nicht gefunden
else return TRUE;
}
{
uint8_t k,n; /***<<<***/ /***<<<***/ /***<<<***/

k=255;
for(n=0;n<8;n++)
{
if (!objekt_sichtbar(n)) k=n; // solange kein Objekt, Distanz erhoehen
}
return k;

uint8_t n;

Init();

while(1)
{
n=abstand();
StatusLED(OFF);
BackLED(OFF,OFF);

if(n!=255)
{
if (n<6) MotorDir (FWD,FWD);MotorSpeed(220,220);
if (n<4) MotorDir (FWD,FWD);MotorSpeed(220,220);
if (n<3) MotorDir (FWD,FWD);MotorSpeed(220,220);
if (n<2) MotorDir (FWD,FWD);MotorSpeed(220,220);
Msleep(10);
}
}
}

damaltor
12.01.2008, 17:27
habe deinen doppelpost entfernt. bitte nur einmal klicken und dann warten!!

du schliesst die funktion uint8_t objekt_sichtbar() mit einer schliessenden klammer }. danach öffnest du weider eine klammer { ohne einen funktionsnamen zu definieren.

Chief 2
12.01.2008, 19:32
Hallo Damaltor
Ich hab das gemacht hat abber immer noch nicht funkionirt Vieleicht hab ich es ja falch verstanden Köntest du diesen teil ( nicht alles ) mir mal zeigen wie du das meints
Gruß
Chief 2

damaltor
12.01.2008, 21:42
hier ist das problem:

uint8_t objekt_sichtbar(uint8_t distance)
{
uint16_t j,z;

DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW

OCR2 = 254-distance; // wenn OCR2=0xFE dann Objekt sehr nahe
z=0;
for(j=0;j<30;j++); // loop time: 5ms
{
if (PIND & (1 << PD0))z++;
Sleep(6); // 6*Sleep(6)=1ms
}
if (z>=29) return FALSE; // Objekt nicht gefunden
else return TRUE;
} /* Du beendest hier die funktion objekt_sichtbar(). ab hier darf nichts weiter kommen.*/
{ /*aber hier kommt wieder was, eine öffnende klammer ohne funktionsbezeichnung. wohin gehört der restliche code hier?*/
uint8_t k,n; /***<<<***/ /***<<<***/ /***<<<***/

k=255;
for(n=0;n<8;n++)

Chief 2
12.01.2008, 21:50
Der restliche code ist dafür da wass er machen solll wen ein objekt sichtbar ist

damaltor
12.01.2008, 22:07
das ist klar. aber in welche funktion gehört er? er steht mitten in der datei, ungefähr so:



int main(){
hier steht der ganze main quelltext
}

int objektsichtbar(){
hier steht der objekt sichtbar code
}


{ und hier steht der code der nirgendwo dazugehört
}


er muss aber irgendwo dazu, entweder mit in die main klammern oder in eine eigene funktion.. irgendwohin muss er.

Chief 2
12.01.2008, 22:15
Ich hab jetz das programm geändert dass es jetz irgendwo hinzu gehört abber es gibt dan neue probleme das ganze sieht jetz so aus

#include "asuro.h"
#include <stdlib.h>
#define LIMIT 20 // Helligkeitsveraenderung, bei der eine Linie detektiert wird
#define TIEFPASS 50 // grosser Wert=grosse Zeitkonstante
// globale Variablen
uint16_t HellLinks;
uint16_t HellRechts;

void Msleep(int dauer)
{
int z;
for(z=0;z<dauer;z++) Sleep(72);
}

unsigned char testhell(void)
{
uint8_t ergebnis=0;
uint16_t lineData[2];

LineData(lineData);
HellLinks=(HellLinks*TIEFPASS+lineData[0])/(TIEFPASS+1);
HellRechts=(HellRechts*TIEFPASS+lineData[1])/(TIEFPASS+1);
StatusLED(YELLOW);
if((lineData[0]+LIMIT)<(HellLinks)) ergebnis|=1;
if((lineData[1]+LIMIT)<(HellRechts)) ergebnis|=2;

Msleep(10);
return ergebnis;
}

int main(void)
{
int n;

Init();

StatusLED(RED);
FrontLED(ON);

// mittlere Helligkeit im Stand ermitteln
for(n=0;n<300;n++)
{
testhell();
}
StatusLED(YELLOW);

MotorDir(FWD,FWD);
MotorSpeed(150,150);
while(1)
{
n=testhell();

BackLED(n&0x01,n&0x02);
StatusLED(YELLOW);

if(n!=0) // Falls Linie erkannt, dann drehen und zurück
{
StatusLED(GREEN);
MotorDir(RWD,RWD);
MotorSpeed(150,100);

Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(200,200);

Msleep(600);

MotorDir(FWD,FWD);
MotorSpeed(150,150);
}

Msleep(10);
}
return(0);
}

uint8_t objekt_sichtbar(uint8_t distance)
{
uint16_t j,z;

DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW

OCR2 = 254-distance; // wenn OCR2=0xFE dann Objekt sehr nahe
z=0;
for(j=0;j<30;j++); // loop time: 5ms
{
if (PIND & (1 << PD0))z++;
Sleep(6); // 6*Sleep(6)=1ms
}
if (z>=29) return FALSE; // Objekt nicht gefunden
else return TRUE;
}
uint8_t abstand()
{ /***<<<***/ /***<<<***/ /***<<<***/
uint8_t k,n;

k=255;
for(n=0;n<8;n++)
{
if (!objekt_sichtbar(n)) k=n; // solange kein Objekt, Distanz erhoehen
}
return k;

uint8_t n;

Init();

while(1)
{
n=abstand();
StatusLED(OFF);
BackLED(OFF,OFF);

if(n!=255)
{
if (n<6) MotorDir (FWD,FWD);MotorSpeed(220,220);
if (n<4) MotorDir (FWD,FWD);MotorSpeed(220,220);
if (n<3) MotorDir (FWD,FWD);MotorSpeed(220,220);
if (n<2) MotorDir (FWD,FWD);MotorSpeed(220,220);
Msleep(10);
}
}
}

und die fehlermeldung jetz so:
test.c:106:error:redeclaration of 'n' with no linkage
test.c:97:error:previous declaration of 'n' was here

damaltor
12.01.2008, 23:40
vielleicht solltest du es so ändrn dass es nicht "irgendwo" dazugehört.

bist du sicher das programm selbst entworfen zu haben? dann solltest du auch wissen wo er dazugehört...

Chief 2
12.01.2008, 23:43
ich hab das programm mit den sumo programm und den infrarot test pogramm von robofreak entworfen ich hab die sumo datei genommen und dann mir die IR test programm genommen und geguckt wie es gehen könnte die sumo datei ist komplett drinn die Ir teils

damaltor
13.01.2008, 00:37
dann versuche nich einfach code hinten anzuhängen sondern achte darauf, ihn an passender stelle einzufügen. so einfach klappt es selten.

Chief 2
13.01.2008, 11:51
an welcher stellle könte ich es den einsetzen

damaltor
13.01.2008, 12:48
ich weiss nicht was das endziel ist, und ich weiss nicht woher die codeschnipsel kommen. da kann ch dir nicht helfen.

aber entwirf doch mal so ein programm selbst, das wäre doch ein gutes projekt für die nächsten tage...

Chief 2
13.01.2008, 13:27
Das Ziel war es den asuro im ring zu halten und das er die becher aus dem Ring schiebt wie in diesen Video von robo.fr http://www.youtube.com/v/oscbdxMhX_4

Chief 2
13.01.2008, 14:43
Ich hab jetz ein programm gemacht womit wen er einen becher sieht auf ihn zufährt und dann wegschiebt und wenn er keinen siht dann nur im kreiß fährt abber ich weis jetz nicht wie ich es auch noch unterbringen kann dass er imring bleibt
Hier ist das eine programm

/************************************************** *************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation version 2 of the License, *
* If you extend the program please maintain the list of authors. *
* If you want to use this software for commercial purposes and you *
* don't want to make it open source, please contact the authors for *
* licensing. *
************************************************** *************************/

#include "asuro.h"
#include <stdlib.h>

/************************************************** ***********************

uint8_t objekt_sichtbar(uint8_t abstand)

Ist ein Objekt in der Entfernung kleiner oder gleich
dem Eingangsparameter "abstand" erkennbar?

objekt_sichtbar(7) liefert TRUE zurück, falls überhaupt
ein Object detektierbar.

abstand:
0: 5cm
1: 7cm
2: 13cm
3: 15cm
4: 16cm
5: 17cm
6: 18cm
7: 22cm

( Testobjekt: Joghurtecher, Umgebungsbeleuchtung: Zimmer )

return: TRUE falls Objekt gefunden
FALSE wenn nicht

Zeitbedarf: 5ms

************************************************** ***********************/
uint8_t objekt_sichtbar(uint8_t distance)
{
uint16_t j,z;

DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW

OCR2 = 254-distance; // wenn OCR2=0xFE dann Objekt sehr nahe
z=0;
for(j=0;j<30;j++) // loop time: 5ms
{
if (PIND & (1 << PD0))z++;
Sleep(6); // 6*Sleep(6)=1ms
}
if (z>=29) return FALSE; // Objekt nicht gefunden
else return TRUE;
}
/************************************************** ***********************

uint8_t abstand()

Abstandsermittelung über IR-Sendiode / IR-Empfänger.
0:kleinster Abstand
7:größter Abstand
255: kein Objekt

Zeitbedarf: 5ms*9=45ms

author: robo.fr, christoph ( ät ) roboterclub-freiburg.de
date: 2008

************************************************** ***********************/
uint8_t abstand()
{
uint8_t k,n;

k=255;
for(n=0;n<8;n++)
{
if (!objekt_sichtbar(n)) k=n; // solange kein Objekt, Distanz erhoehen
}
return k;
}
/************************************************** ***********************

Hauptprogramm

************************************************** ***********************/
int main(void)
{
uint8_t n;

Init();

FrontLED(ON);
while(1)
{
n=abstand();
StatusLED(OFF);
BackLED(OFF,OFF);
MotorSpeed(200,200);

if(n!=255)
{
if (n<11) MotorSpeed(0,200);
if (n<10) MotorSpeed(0,200);
if (n<9) MotorSpeed(0,200);
if (n<8) MotorSpeed(0,200);
if (n<7) MotorSpeed(0,200);
if (n<6) MotorSpeed(0,200);
if (n<5) MotorSpeed(0,200);
if (n<4) MotorSpeed(0,200);
if (n<3) MotorSpeed(0,200);
if (n<2) MotorSpeed(200,200);
if (n<1) MotorSpeed(200,200);
Msleep(10);
}
}
}

damaltor
13.01.2008, 15:32
if(n!=255)
{
if (n<11) MotorSpeed(0,200);
if (n<10) MotorSpeed(0,200);
if (n<9) MotorSpeed(0,200);
if (n<8) MotorSpeed(0,200);
if (n<7) MotorSpeed(0,200);
if (n<6) MotorSpeed(0,200);
if (n<5) MotorSpeed(0,200);
if (n<4) MotorSpeed(0,200);
if (n<3) MotorSpeed(0,200);
if (n<2) MotorSpeed(200,200);
if (n<1) MotorSpeed(200,200);
Msleep(10);

das ist doch quatsch... warum fragst du nach dem wert, wenn du egal welcher wert kommt immer die gleiche motorgeschwindigkeit nimmet? da brauchst du doch nur eine if-schleife, welche prüft ob der wert unter 2 liegt...

aber lass doch einfach in der main funktion noch auf die liniensensoren reagieren..

Chief 2
13.01.2008, 16:38
ich habe es jetz so bearbeitet das es kompilirbar ist abber wen ich es auf den asuro flashe macht er nur die Front led an und die statusled auf orange abber bewegt sich kein stück irgendwo muss sich etwas dagegenstellen das er losfährt ich weis abber nicht was

/************************************************** *************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation version 2 of the License, *
* If you extend the program please maintain the list of authors. *
* If you want to use this software for commercial purposes and you *
* don't want to make it open source, please contact the authors for *
* licensing. *
************************************************** *************************/

#include "asuro.h"
#include <stdlib.h>
#define LIMIT 20 // Helligkeitsveraenderung, bei der eine Linie detektiert wird
#define TIEFPASS 50 // grosser Wert=grosse Zeitkonstante
// globale Variablen
uint16_t HellLinks;
uint16_t HellRechts;

/************************************************** ***********************

uint8_t objekt_sichtbar(uint8_t abstand)

Ist ein Objekt in der Entfernung kleiner oder gleich
dem Eingangsparameter "abstand" erkennbar?

objekt_sichtbar(7) liefert TRUE zurück, falls überhaupt
ein Object detektierbar.

abstand:
0: 5cm
1: 7cm
2: 13cm
3: 15cm
4: 16cm
5: 17cm
6: 18cm
7: 22cm

( Testobjekt: Joghurtecher, Umgebungsbeleuchtung: Zimmer )

return: TRUE falls Objekt gefunden
FALSE wenn nicht

Zeitbedarf: 5ms

************************************************** ***********************/
uint8_t objekt_sichtbar(uint8_t distance)
{
uint16_t j,z;

DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW

OCR2 = 254-distance; // wenn OCR2=0xFE dann Objekt sehr nahe
z=0;
for(j=0;j<30;j++) // loop time: 5ms
{
if (PIND & (1 << PD0))z++;
Sleep(6); // 6*Sleep(6)=1ms
}
if (z>=29) return FALSE; // Objekt nicht gefunden
else return TRUE;
}
/************************************************** ***********************

uint8_t abstand()

Abstandsermittelung über IR-Sendiode / IR-Empfänger.
0:kleinster Abstand
7:größter Abstand
255: kein Objekt

Zeitbedarf: 5ms*9=45ms

author: robo.fr, christoph ( ät ) roboterclub-freiburg.de
date: 2008

************************************************** ***********************/
uint8_t abstand()
{
uint8_t k,n;

k=255;
for(n=0;n<8;n++)
{
if (!objekt_sichtbar(n)) k=n; // solange kein Objekt, Distanz erhoehen
}
return k;
}
/************************************************** ***********************/
unsigned char testhell(void)
{
uint8_t ergebnis=0;
uint16_t lineData[2];

LineData(lineData);
HellLinks=(HellLinks*TIEFPASS+lineData[0])/(TIEFPASS+1);
HellRechts=(HellRechts*TIEFPASS+lineData[1])/(TIEFPASS+1);
StatusLED(YELLOW);
if((lineData[0]+LIMIT)<(HellLinks)) ergebnis|=1;
if((lineData[1]+LIMIT)<(HellRechts)) ergebnis|=2;

Msleep(10);
return ergebnis;
}

/************************************************** ***********************

Hauptprogramm

************************************************** ***********************/
int main(void)
{
uint8_t n;

Init();
StatusLED(RED);
FrontLED(ON);

// mittlere Helligkeit im Stand ermitteln
for(n=0;n<300;n++)
{
testhell();
}
StatusLED(YELLOW);

MotorDir(FWD,FWD);
MotorSpeed(150,150);

while(1)
FALSE;
{
n=testhell();

BackLED(n&0x01,n&0x02);
StatusLED(YELLOW);

if(n!=0) // Falls Linie erkannt, dann drehen und zurück
{
StatusLED(GREEN);
MotorDir(RWD,RWD);
MotorSpeed(150,100);

Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(200,200);

Msleep(600);

MotorDir(FWD,FWD);
MotorSpeed(150,150);
}

Msleep(10);

}
TRUE;
{
n=abstand();
StatusLED(OFF);
BackLED(OFF,OFF);
MotorSpeed(200,200);

if(n!=255)
{

if (n<2) MotorSpeed(200,200);
if (n<1) MotorSpeed(200,200);
Msleep(10);
}
}

}

Hilft mir bitte

Gruß
chief 2

M1.R
24.01.2008, 22:14
Hallo,

jetzt hat mein ASURO auch einen IR-Adapter:

http://www.swoenke.de/roboter/asuro/asuro-img/ir-asuro300x330.jpg

@robo:
da ich den kleinsten Abstand ermitteln wollte, habe ich dein Testprogramm folgendermaßen geändert:
if(n!=255)
{
if (n<6) StatusLED(GREEN);
if (n<4) StatusLED(YELLOW);
if (n<3) StatusLED(RED);
//if (n<2) BackLED(ON,ON);
if (n<1) BackLED(ON,ON);
Msleep(10);
}aber anscheinend wird n nie 0, da die BackLEDs nicht leuchten?
Gruss
M.

JensK
25.01.2008, 09:57
wahrscheinlich wird n nie null, da die ir immer irgendwlche strahlen empfängt... versuchs mal im dunkeln. evtl hilft das ja... außerdem sollte keine fernbedingung oder sonstiges mit IR in der nähe sein, da dass alles stören kann...

und was is das da für ein "knubbel" auf der schraube? :D

ich hoffe ich konnte helfen

mfg
jens

pinsel120866
25.01.2008, 10:37
Hi M1.R,

wäre nett, wenn du den Bauplan für den IR Adapter man postest!

(falls es einen gibt :-))

Phil23
25.01.2008, 17:47
Hi Leute,
Ich steh ganz am Anfang der Softwar des Asuros.
Ich schaffe es nicht die test.c Datei in eine test.hex Datei umzuwandeln, vermutlich liegt es daran, dass ich das ,,Schreibgeschützt nicht weg bekomme. Kann mir jm. helfen ?
Der selbst Test des Asuros hat einwandfrei geklappt und jetzt scheitert es an einer blöden Windows Einstellung.
Danke

M1.R
25.01.2008, 18:27
wäre nett, wenn du den Bauplan für den IR Adapter man postest!

https://www.roboternetz.de/phpBB2/viewtopic.php?p=343829#343829

Gruss
M.

JensK
25.01.2008, 22:40
ahhhhhhhhhhhhhhhhh das isn storch :D XDD von vorn schaut es wie eine undefinierbare kugel aus kaugummi aus :D sry sry... das is doch der asuro, der vogegezwitscher auf xoutube gemacht hat oder? :P

damaltor
26.01.2008, 00:47
Phil23: Bitte KEINE Doppelposts! Danke

M1.R
26.01.2008, 22:23
das isn storchknapp daneben ist auch vorbei...
- es ist ein Reiher! ;)

pinsel120866
01.03.2008, 11:56
Hallo,

Ich möchte das Rad nicht neu erfinden und mal höflich fragen ob jemand so nett wäre den fertigen SUMO-Code zu posten.

Danke im voraus!

robo.fr
01.03.2008, 12:56
Hallo Pinsel,

den Source-Code findest du hier (http://www.roboterclub-freiburg.de/asuro/hardware/chAtmegaAdapter/SumoAdapter.html) unter dem Punkt "downloads".
Er muss aber wahrscheinlich auf die Verhältnisse Deines Asuros angepasst werden, da alles zeitgesteuert abläuft.

Gruß,
robo

pinsel120866
01.03.2008, 13:19
Hi robo.fr,

vielen Dank für deine prompte Hilfe. Ich wollte den Code mit der Lib2.71 kompilieren und kriege leider Warnungen:


Build started 1.3.2008 at 13:35:12
-------- begin --------
avr-gcc --version
avr-gcc (GCC) 4.2.2 (WinAVR 20071221)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

avr-gcc -c -mmcu=atmega8 -I. -g -Os -I../../lib/inc -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=test.lst test.c -o test.o
In file included from asuro.h:61,
from test.c:1:
c:/winavr/bin/../avr/include/avr/signal.h:36:2: warning: #warning "This header file is obsolete. Use <avr/interrupt.h>."
test.c:122: warning: function declaration isn't a prototype
test.c:199: warning: function declaration isn't a prototype
test.c:254: warning: function declaration isn't a prototype
test.c:341: warning: function declaration isn't a prototype
test.c:369: warning: function declaration isn't a prototype
test.c:407: warning: function declaration isn't a prototype
test.c: In function 'suchen':
test.c:408: warning: unused variable 'old_n'
test.c:408: warning: unused variable 'n'
test.c: At top level:
test.c:454: warning: function declaration isn't a prototype
test.c: In function 'justieren_schieben':
test.c:465: warning: no return statement in function returning non-void
test.c: In function 'main':
test.c:478: warning: unused variable 't'
test.c:477: warning: unused variable 'k'
test.c: In function 'UeberLinieSchieben':
test.c:343: warning: 't' may be used uninitialized in this function
avr-gcc -c -mmcu=atmega8 -I. -g -Os -I../../lib/inc -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=asuro.lst asuro.c -o asuro.o
In file included from asuro.h:61,
from asuro.c:75:
c:/winavr/bin/../avr/include/avr/signal.h:36:2: warning: #warning "This header file is obsolete. Use <avr/interrupt.h>."
asuro.c: In function 'PrintInt':
asuro.c:360: warning: pointer targets in passing argument 1 of 'SerWrite' differ in signedness
avr-gcc -mmcu=atmega8 -I. -g -Os -I../../lib/inc -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=test.o test.o asuro.o --output test.elf -Wl,-Map=test.map,--cref -L../../lib -lm -lasuro
avr-objcopy -O ihex -R .eeprom test.elf test.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O ihex test.elf test.eep
c:\WinAVR\bin\avr-objcopy.exe: --change-section-lma .eeprom=0x00000000 never used
avr-objdump -h -S test.elf > test.lss
Size after:
test.elf :
section size addr
.text 3206 0
.data 8 8388704
.bss 36 8388712
.stab 888 0
.stabstr 95 0
.debug_aranges 64 0
.debug_pubnames 764 0
.debug_info 2881 0
.debug_abbrev 1097 0
.debug_line 2605 0
.debug_frame 624 0
.debug_str 894 0
.debug_loc 1208 0
Total 14370


Errors: none
-------- end --------
Build succeeded with 16 Warnings...

trapperjohn
01.03.2008, 14:04
Ist die Platine für den Sumo-Adapter eigentlich irgendwo käuflich zu erwerben oder nur für Selbst-Ätzer?

damaltor
01.03.2008, 14:47
die warnings sind ja ganz schön viele...

aber los:

alles was mit "isnt a prototype" endet, sind funktionen welche du ÜBER der mainfunktion einfügen solltest. der einfachste trick ist, die entsprechende funktion zu suchen und sie dann so hoch wie möglich im quelltext einzufügen.

"unused variable" ist irrelevant, stört nicht weiter. kann sein dass es sich nach dem verschieben von allein löst.

test.c: In function 'justieren_schieben':
test.c:465: warning: no return statement in function returning non-void
hier ist eine funktion, welche einen wert zurückgeben sollte, aber es fehlt die return-zeile am ende.

pinsel120866
01.03.2008, 15:10
Danke Dalmator!

Der Code ist ja ganz schön heftig...

Die Linienerkennung läuft mit meiner IR-LED ganz gut, nur der Gegener wird nicht erkannt. (Das Testprogramm von robo.fr funktioniert einwandfrei) Wo muss ich hier Feintunen?

@trapperjohn: Ich habe den Bausatz im Ebay ersteigert.

M1.R
01.03.2008, 15:15
Ich möchte das Rad nicht neu erfinden und mal höflich fragen ob jemand so nett wäre den fertigen SUMO-Code zu posten.
Hallo,
hier noch ein, zwar chaotisches, aber erfolgreiches Joghurt-Sumo - Programm.

Vielen Dank an robo.fr für die Abstands- und Zufallsfunktionen!

Die defines am Anfang müssen passend zum ASURO (Front-LED) und zur Arena-Größe angepasst werden.

Gruss
M.


http://www.swoenke.de/roboter/asuro/asuro-img/joghurt-sumo.jpg



//-------------------------------------------------------------------
//-------------------------------------------------------------------
//
// joghurt-sumo-wettkampf
// M1.R
// joghurt_sumov02
//
//-------------------------------------------------------------------
//-------------------------------------------------------------------

#include "asuro.h"
#define HALF 2


//-------------------------------------------------------------------
//variable
uint16_t hell_links, hell_rechts, i, zuf;
uint8_t linie, objekt_weit, objekt_nah, rechts, speed1, speed2, richtung, abbrechen;




//-------------------------------------------------------------------
// defines anpassen !!!!!!!!!!!!!!!!!!!!!!!!!!

//schwellenwert linie mit heller led
//weiss:links 600-650, rechts 500-550
//schwarz: links 25-30, rechts 32

#define achtung_linie 200 //200


//abstand für ir-messung
#define nah 1 //1
#define weit 14 //max 16

#define geradeaus 200 ////*6ms dauer geradeausfahrt 200 entspricht ca. 80cm
#define leichtekurve 200 ////*6ms dauer geradeausfahrt 200 entspricht ca. 80cm

#define schwenkdauer 60
#define verlierdauer 500

#define rauszeit 4000
#define rueckwaertszeit 500

#define liniendauer1 500
#define liniendauer2 500
#define liniendauer3 500

#define wendedauer 100



//-------------------------------------------------------------------
//projekt-funktionen
//-------------------------------------------------------------------

void BackLEDleft(uint8_t status);
void BackLEDright(uint8_t status);
void akku_kontrolle (void);
uint8_t zufallbat(void);
uint8_t objekt_sichtbar(uint8_t abstand);


//-------------------------------------------------------------------
//-------------------------------------------------------------------
//akku kontrolle
//berechnung: wert=spannung/0.0055
//1090 entsprechen ca. 6 volt
//909 entsprechen ca. 5 volt
//810 entsprechen ca. 4,455 Volt
//wenn kleiner als 4,455 volt rot blinken motoren aus
//wenn kleine als 5 volt 3 sec gelb blinken
//wenn >= 5 volt led grün 3 sec

void akku_kontrolle (void)
{
uint16_t wert;
uint8_t i;
StatusLED(OFF);
Msleep(1000);
wert = Battery();
if (wert < 810)
{

for(i = 1; i <= 10; ++i)
{
StatusLED(RED);
Msleep(100);
StatusLED(OFF);
Msleep(50);
}
}
if (wert < 909)
{
for(i = 1; i <= 10; ++i)
{
StatusLED(YELLOW);
Msleep(100);
StatusLED(OFF);
Msleep(50);
}
}
else
{
for(i = 1; i <= 10; ++i)
{
StatusLED(GREEN);
Msleep(100);
StatusLED(OFF);
Msleep(50);
}
}
}
//-------------------------------------------------------------------

//------------------------------------------------------------------
//backled funktionen um die leds unabhängig voneinander
//hell leuchten oder glimmen zu lassen
//------------------------------------------------------------------
// rechte led
void BackLEDright(uint8_t status) // aus - hell - glimm
{
PORTD &= ~(1 << PD7); //odoleds aus
if (status == OFF)
{ //rechte backled aus
DDRC |= (1 << PC0); //rechts auf out
PORTC &= ~(1 << PC0); //rechte aus
}
if (status == ON)
{
//rechte backled hell
DDRC |= (1 << PC0); //rechts auf out
PORTC |= (1 << PC0); //rechte an
}
if (status == HALF)
{ //rechte backled glimmt
DDRC &= ~(1 << PC0); //rechts auf in
}
}

//------------------------------------------------------------------
// linke led
void BackLEDleft(uint8_t status) // aus - hell - glimm
{
PORTD &= ~(1 << PD7); //odoleds aus
if (status == OFF)
{ //rechte backled aus
DDRC |= (1 << PC1); //links auf out
PORTC &= ~(1 << PC1); //linke aus
}
if (status == ON)
{
//rechte backled hell
DDRC |= (1 << PC1); //links auf out
PORTC |= (1 << PC1); //linke an
}
if (status == HALF)
{ //rechte backled glimmt
DDRC &= ~(1 << PC1); //links auf in
}
}


/************************************************** ***********************

uint8_t objekt_sichtbar(uint8_t abstand)

Ist ein Objekt in der Entfernung kleiner oder gleich
dem Eingangsparameter "abstand" erkennbar?

objekt_sichtbar(7) liefert TRUE zurück, falls überhaupt
ein Object detektierbar.

abstand:
0: 5cm
1: 7cm
2: 13cm
3: 15cm
4: 16cm
5: 17cm
6: 18cm
7: 22cm

( Testobjekt: Joghurtecher, Umgebungsbeleuchtung: Zimmer )

return: TRUE falls Objekt gefunden
FALSE wenn nicht
------------------------------------
geändert (m1.r):
schaltet nach dem messen die led aus
und wartet noch 1ms wegen
der AGC(automatic gain control,
automatische Verstärkungsregelung) des empfängers
------------------------------------

Zeitbedarf: 6ms

author: robo.fr, christoph ( ät ) roboterclub-freiburg.de
date: 2008

************************************************** ***********************/
uint8_t objekt_sichtbar(uint8_t distance)
{
uint16_t j,z;

DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW => ir-led an

OCR2 = 254-distance; // wenn OCR2=0xFE dann Objekt sehr nahe
z=0;
for(j=0;j<30;j++) // loop time: 5ms
{
if (PIND & (1 << PD0))z++;
Sleep(6); // 6*Sleep(6)=1ms
}
PORTD |= (1 << PD1); // PD1 auf High led auschalten
Msleep(1); // kurz warten
if (z>=29) return FALSE; // Objekt nicht gefunden
else return TRUE;
}


//-------------------------------------------------------------------
// liniensuche
// 1 wenn getroffen, 0 wenn nicht
uint8_t linie_getroffen(uint16_t schwellenwert)
{
FrontLED(ON);
uint16_t data[2];
LineData(data);
hell_links = data[0];
hell_rechts = data[1];
if ((hell_links >= achtung_linie) && (hell_rechts >= achtung_linie))
return FALSE; // keine linie
else return TRUE;
}




//-------------------------------------------------------------------
// linie getroffen
void linie_ueberfahren (void)
{
i = 0;

StatusLED(OFF);
BackLEDleft(OFF);
BackLEDright(OFF);



//ein kleines stückchen vorwärts
MotorDir(FWD,FWD);
MotorSpeed(255,255);
Msleep(30);

//wenn die linie noch nicht überfahren ist, noch weiter vorwärts
while((linie_getroffen(achtung_linie) == 1) && (i<= liniendauer1))
{
MotorDir(FWD,FWD);
MotorSpeed(255,255);
Msleep(1);
i++;
}
i = 0;
//jenseits der linie vollbremsung!
MotorDir(BREAK,BREAK);
StatusLED(RED);
Msleep(100);
StatusLED(OFF);


//rückwärts bis linie getroffen
while((linie_getroffen(achtung_linie) == 0) && (i<= liniendauer2))
{
MotorDir(RWD,RWD);
MotorSpeed(255,255);
Msleep(1);
i++;

}

//wenns rechts heller ist, ist die linie rechts
if(hell_rechts>=hell_links)
{
rechts = 1;
BackLEDleft(OFF);
BackLEDright(HALF);
}

if(hell_links>hell_rechts)
{
rechts = 0;
BackLEDleft(HALF);
BackLEDright(OFF);
}

i = 0;
//rückwärts bis keine linie mehr
//mit kurve
while((linie_getroffen(achtung_linie) == 1) && (i<= liniendauer3))
{




if (rechts == 1) //wenn die linie rechts ist
{
MotorDir(RWD,RWD);
MotorSpeed(80,255);
}

else if (rechts == 0) //wenn die linie links ist
{
MotorDir(RWD,RWD);
MotorSpeed(255,80);
}

Msleep(1);
i++;
}
//noch ein stückchen rückwärts
MotorDir(RWD,RWD);
MotorSpeed(255,255);
Msleep(20);

//vollbremsung
MotorDir(BREAK,BREAK);
Msleep(100);

//und jetzt wenden
i=0;
while ((linie_getroffen(achtung_linie)==0) && (i<wendedauer)) //i<?? => 180 grad wendung
{
if(rechts == 1)
{
MotorDir(RWD,FWD); //rechts dunkler also ist die linie rechts dreh nach links
}
else if(rechts == 0)
{
MotorDir(FWD,RWD);
}

MotorSpeed(255,255);
Msleep(1);
i++;
}

// anschliessend ein stück geradeaus, um wieder in die mitte zu kommen
// !!!! z einstellen!!!
i = 0;
while ((linie_getroffen(achtung_linie)==0) && (objekt_sichtbar(weit)==0) && (i<geradeaus))
{
MotorDir(FWD,FWD);
MotorSpeed(255,255);
BackLEDleft(OFF);
BackLEDright(OFF);
StatusLED(GREEN);
i++;
Msleep(1);
}



}


//------------------------------------------------------------------
// zufallbat()
// Pseudozufallsfunktion von robo.fr
// erweitert mit Batterie-Abfrage M1.R
// uint8_t zufallbat()
// Liefert eine 8Bit Zufallszahl zurück,
// int Batterie (void) in der Datei adc.c
// liefert 10-Bit-Wert der Batteriespannung (Bereich 0..1023)

//------------------------------------------------------------------

uint8_t zufallbat(void)
{
static uint16_t startwert=0x0AA;

uint16_t temp;
uint8_t n;

for(n=1;n<8;n++)
{
temp = startwert;
startwert=startwert << 1;

temp ^= startwert;
if ( ( temp & 0x4000 ) == 0x4000 )
{
startwert |= 1;
}
}
startwert^= Batterie(); // macht den Pseudozufall wirklich zufällig

return (startwert);
}

//------------------------------------------------------------------





//-------------------------------------------------------------------
// linie getroffen
void linie_wenden (void)
{
StatusLED(RED);
MotorDir(RWD,RWD);
MotorSpeed(255,255);
Msleep(200);


//rechts dunkler also ist die linie rechts dreh nach links
if(hell_rechts <= hell_links)
{
i=0;
while ((linie_getroffen(achtung_linie)==0) && (i<wendedauer)) //i<?? => 180 grad wendung
{
MotorDir(RWD,FWD);
BackLEDleft(OFF);
BackLEDright(HALF);
MotorSpeed(255,255);
Msleep(1);
i++;
}
// anschliessend ein stückchen leichte kurve, um wieder in die mitte zu kommen
i = 0;
while ((linie_getroffen(achtung_linie)==0) && (objekt_sichtbar(weit)==0) && (i<leichtekurve))
{
StatusLED(OFF);
MotorDir(FWD,FWD);
MotorSpeed(200,255);
Msleep(1);
i++;
}

}
//links dunkler also ist die linie links dreh nach rechts
if (hell_links < hell_rechts)
{
i=0;
while ((linie_getroffen(achtung_linie)==0) && (i<wendedauer)) //i<?? => 180 grad wendung
{
MotorDir(FWD,RWD);
BackLEDleft(HALF);
BackLEDright(OFF);
MotorSpeed(255,255);
Msleep(1);
i++;
}
// anschliessend ein stückchen leichte kurve, um wieder in die mitte zu kommen
i = 0;
while ((linie_getroffen(achtung_linie)==0) && (objekt_sichtbar(weit)==0) && (i<leichtekurve))
{
StatusLED(OFF);
MotorDir(FWD,FWD);
MotorSpeed(255,200);
Msleep(1);
i++;
}
}



}


//-------------------------------------------------------------------


//-------------------------------------------------------------------
// linie getroffen beim rückwärtsfahren
void linie_vorwaerts (void)
{
StatusLED(RED);
while (linie_getroffen(achtung_linie)==1)
{
MotorDir(FWD,FWD);
MotorSpeed(255,255);
}
}


//-------------------------------------------------------------------

//-------------------------------------------------------------------
// linie getroffen beim rückwärtsfahren
void rueckwaerts (void)
{
StatusLED(RED);
i = 0;
while ((abbrechen == 0) && (i<= rueckwaertszeit))
{
linie = linie_getroffen(achtung_linie);
if (linie == 1)
{
abbrechen = 1;
linie_vorwaerts();
}
MotorDir(RWD,RWD);
MotorSpeed(255,255);
Msleep(1);
i++;
}
}


//-------------------------------------------------------------------



//-------------------------------------------------------------------
//-------------------------------------------------------------------
//hauptprogramm
int main(void)
{
Init();

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!
//-------------------------------------------------------------------
//ab hier test

StatusLED(OFF);

Msleep(1000);

//akku_kontrolle();

//while(1);


//bis hier test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!

//-------------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------

// letzte vorbereitungen

objekt_weit = objekt_sichtbar(weit);
linie = linie_getroffen(achtung_linie);


// hauptschleife

while(1)
{

objekt_weit = objekt_sichtbar(weit);
linie = linie_getroffen(achtung_linie);


//-------------------------------------------------------------------
//wenn linie getroffen...
if (linie == 1)
{
linie_wenden();

}


//-------------------------------------------------------------------
//wenn objekt gesehen, verfolgen!!
else if (objekt_weit == 1)
{
StatusLED(YELLOW);
BackLEDleft(OFF);
BackLEDright(OFF);
MotorDir(FWD,FWD);
richtung = 0;
abbrechen = 0;

linie = linie_getroffen(achtung_linie);
if (linie == 1)
{
abbrechen = 1;
linie_wenden();
}

while(abbrechen == 0)
{
while ((objekt_sichtbar(weit) == 1) && (abbrechen == 0) && (objekt_sichtbar(nah) == 0))
{

linie = linie_getroffen(achtung_linie);
if (linie == 1)
{
abbrechen = 1;
linie_wenden();
}


//fahr nach links
if ((objekt_sichtbar(weit) == 1) && (richtung == 0) && (abbrechen == 0))
{
i=0;
while ((abbrechen == 0) && (i<= schwenkdauer))
{
linie = linie_getroffen(achtung_linie);
if (linie == 1)
{
abbrechen = 1;
linie_wenden();
}
StatusLED(YELLOW);
BackLEDleft(HALF);
BackLEDright(OFF);
MotorSpeed(150,255);
richtung=1;
i++;
Msleep(1);
}
i=0;
}


//fahr nach rechts
if ((objekt_sichtbar(weit) == 1) && (richtung == 1) && (abbrechen == 0))
{
i=0;
while ((abbrechen == 0) && (i<=schwenkdauer))
{
linie = linie_getroffen(achtung_linie);
if (linie == 1)
{
abbrechen = 1;
linie_wenden();
}
StatusLED(YELLOW);
BackLEDleft(OFF);
BackLEDright(HALF);
MotorSpeed(255,150);
richtung=0;
i++;
Msleep(1);
}
i=0;
}
}


//wenn kein objekt mehr zu sehen ist
if ((objekt_sichtbar(weit) == 0) && (abbrechen == 0))
{
//wenn letzte richtung nach rechts war
//dann ist das objekt links verloren gegangen
//linke backled an
//nach links fahren bis objekt wieder da ist

BackLEDleft(OFF);
BackLEDright(OFF);


if (richtung == 0)
{
i = 0;

while ((objekt_sichtbar(weit) == 0) && (abbrechen == 0) && (i<=verlierdauer))
{
linie = linie_getroffen(achtung_linie);
if (linie == 1)
{
abbrechen = 1;
linie_wenden();
}
StatusLED(RED);
BackLEDleft(HALF);
BackLEDright(OFF);
MotorSpeed(150,255);
richtung=0; //danach mit links anfangen
Msleep(1);
i++;
}
abbrechen = 1;
}

//wenn letzte richtung nach links war
//dann ist das objekt rechts verloren gegangen
//rechte backled an
//nach rechts fahren bis objekt wieder da ist
//oder nach einer gewissen zeit nicht wieder aufgetaucht ist
else if (richtung == 1) //letzte richtung war nach links
{

i = 0;
while ((objekt_sichtbar(weit) == 0) && (abbrechen == 0) && (i<=verlierdauer))
{
linie = linie_getroffen(achtung_linie);
if (linie == 1)
{
abbrechen = 1;
linie_wenden();
}
StatusLED(RED);
BackLEDleft(OFF);
BackLEDright(HALF);
MotorSpeed(255,150);
richtung=1; //danach mit rechts anfangen
Msleep(1);
i++;
}
abbrechen = 1;
StatusLED(OFF);
BackLEDleft(OFF);
BackLEDright(OFF);
}
}
//wenn objekt ganz nah, dann raus damit
if (objekt_sichtbar(nah) == 1)
{
StatusLED(RED);
BackLEDleft(ON);
BackLEDright(ON);
while ((abbrechen == 0) && (i<= rauszeit))
{
linie = linie_getroffen(achtung_linie);
if (linie == 1)
{
linie_ueberfahren();
abbrechen = 1;
}
MotorDir(FWD,FWD);
MotorSpeed(255,255); //schnell vorwärts!
Msleep(1);
i++;
if (i > rauszeit)
{
rueckwaerts();
abbrechen = 1;
}
}
}
}
}

//-------------------------------------------------------------------

//ansonsten rumfahren und objekt suchen
else
{
StatusLED(GREEN);
BackLEDleft(OFF);
BackLEDright(OFF);
MotorDir(FWD,FWD);

zuf = zufallbat();
zuf = zuf/128;
if (zuf == 0)
{
speed1 = 255;
zuf = zufallbat();
zuf = zuf/2;
speed2 = 100 + zuf;
BackLEDleft(HALF);
BackLEDright(OFF);
}

if (zuf == 1)
{
speed1 = 255;
zuf = zufallbat();
zuf = zuf/2;
speed2 = 100 + zuf;
BackLEDleft(OFF);
BackLEDright(HALF);
}

i=0;
abbrechen = 0;
while ((abbrechen == 0)&&(objekt_sichtbar(weit)==0) && (i<500))
{
linie = linie_getroffen(achtung_linie);
if (linie == 1)
{
linie_wenden();
abbrechen = 1;
}
MotorSpeed(speed1,speed2);
i++;
}

i=0;
abbrechen = 0;
while ((abbrechen == 0)&&(objekt_sichtbar(weit)==0) && (i<500))
{

linie = linie_getroffen(achtung_linie);
if (linie == 1)
{
linie_wenden();
abbrechen = 1;
}
MotorSpeed(speed2,speed1);
i++;
}





}

}





while (1);
return 0;
}

pinsel120866
01.03.2008, 16:34
Danke M1.R,

auch bei deinem Programm "sieht" mein ASURO den Jogurtbecher nicht, die schwarze Linie aber schon. Meine Arena ist ein Achteck mit einem Durchmesser von ca. 60cm.

M1.R
01.03.2008, 16:58
Danke M1.R,

auch bei deinem Programm "sieht" mein ASURO den Jogurtbecher nicht, aber schwarze Linie aber schon. Meine Arena ist ein Achteck mit einem Durchmesser von ca. 60cm.
Versuch mal hier etwas zu ändern.:

//abstand für ir-messung
#define nah 1 //1
#define weit 14 //max 16

Wenn der ASURO einen "weit" entfernten Joghurtbecher sieht, leuchtet die StatusLED gelb, bei einem "nahen" rot. Wenn er nichts sieht grün.

Mein Programm ist für einen Durchmesser von 1.5 m angepasst.

Gruss
M.

pinsel120866
01.03.2008, 17:47
OK, mit "#define weit 4" sieht er jetzt den Becher. Er sucht aber den Becher nicht, sondern fährt nur chaotisch mit Vollgas im Kreis herum.

M1.R
01.03.2008, 18:18
OK, mit "#define weit 4" sieht er jetzt den Becher. Er sucht aber den Becher nicht, sondern fährt nur chaotisch mit Vollgas im Kreis herum.Das ist schon richtig so, wenn er beim chaotisch rumfahren zufällig einen Becher sieht, fängt er an, ihn zu "verfolgen" (StatusLED gelb) und schiebt ihn anschließend über die Linie (StatusLED rot).
Aber wie schon gesagt, mein Programm ist für eine Riesenarena.

hier kannst du für deine kleine Arena mal rumprobieren:
#define geradeaus
#define leichtekurve
und
bei:
//ansonsten rumfahren und objekt suchen
speed1 und speed2 ändern

Oder du machst deine Arena größer ;)

Gruss
M.

pinsel120866
01.03.2008, 18:56
Super Programm, M1.R und nochmals Danke!

Ich hab's jetzt für meine kleine 60cm Arena angepasst. Der ASURO sucht gemächlich ein Objekt und wenn er eines gefunden hat, schiebt er es mit Vollgas aus dem "Ring".

pinsel120866
01.03.2008, 19:33
Auch das Programm von robo.fr kann ich jetzt Warnungsfrei kompilieren.

Noch eine Frage:

Bei Zimmerbeleuchtung funktioniert das Programm einwandfrei, bei Tageslicht nicht. Wo kann ich die Empfindlichkeit der IR Sensoren anpassen dass das Objekt auch bei Tageslicht gut erkannt wird?

robo.fr
01.03.2008, 19:35
Na dann besten Dank an M. Das Programm von M war tatsächlich das erfolgreichste im ASURO-Sumo Wettkampf.
Gute Leistung, weiter so O:)

robo

pinsel120866
01.03.2008, 19:47
@robo.fr: Ich meine mit meiner Frage dein Programm, das Programm von M1.R läuft bei Tages- und Kunstlicht.

So ein Roboterclub ist schon eine tolle Sache, schade dass es in meiner Umgebung keinen gibt.

M1.R
01.03.2008, 21:53
Super Programm, M1.R und nochmals Danke!

Ich hab's jetzt für meine kleine 60cm Arena angepasst. Der ASURO sucht gemächlich ein Objekt und wenn er eines gefunden hat, schiebt er es mit Vollgas aus dem "Ring".freut mich, dass es jetzt klappt! :)


Gute Leistung, weiter soDanke!!! :)

robo.fr
02.03.2008, 08:30
@robo.fr: Ich meine mit meiner Frage dein Programm, das Programm von M1.R läuft bei Tages- und Kunstlicht.

Falls das Problem eine Linienüberschreitung bei Tageslicht ist, musst du das Limit ( der Unterschied, bei dem ein Hell/Dunkel Übergang der Linie erkannt wird, anpassen )

/#define LIMIT 15 // FrontLED Helligkeitsgrenzwert fuer Standard-Asuro
( verschiedene Werte ausprobieren )

Was natürlich den ASURO besonders verbessert, ist eine superhelle LED einzubauen.


So ein Roboterclub ist schon eine tolle Sache, schade dass es in meiner Umgebung keinen

Vielleicht kannst Du ja selbst einen gründen. Du müsstest erst einmal herauskriegen, ob es in Deiner Umgebung Leute gibt, die sich dafür interessieren. Dann trefft Ihr euch einfach alle 2-4 Wochen z.B. in einer gemütlichen Kneipe und unterhaltet euch über Roboter. Mit der Zeit hat dann vielleicht der ein oder andere Lust, mehr Roboter zu basteln.

Gruß,
robo

pinsel120866
02.03.2008, 11:45
OK robo.fr, danke. Wie kann ich bei deinem Programm die Empfindlichkeit der IR - Sensoren anpassen? Ich vermute dass mein ASURO bei Tageslicht die Weisse Wand wegschieben will :-)

robo.fr
02.03.2008, 14:07
Das musst Du in der Funktionen "abstand" o.ä. machen. Vielleicht kannst Du auch einfach die Abstandsfunktionion von M. in das Programm übernehmen. Irgendwo gibt es hier auch einen Thread, wo das ganz genau diskutiert wurde.