Phil23: Bitte KEINE Doppelposts! Danke
Druckbare Version
Phil23: Bitte KEINE Doppelposts! Danke
knapp daneben ist auch vorbei...Zitat:
Zitat von JensK
- es ist ein Reiher! ;)
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!
Hallo Pinsel,
den Source-Code findest du hier unter dem Punkt "downloads".
Er muss aber wahrscheinlich auf die Verhältnisse Deines Asuros angepasst werden, da alles zeitgesteuert abläuft.
Gruß,
robo
Hi robo.fr,
vielen Dank für deine prompte Hilfe. Ich wollte den Code mit der Lib2.71 kompilieren und kriege leider Warnungen:
Code: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...
Ist die Platine für den Sumo-Adapter eigentlich irgendwo käuflich zu erwerben oder nur für Selbst-Ätzer?
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.
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.
Hallo,Zitat:
Zitat von pinsel120866
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.
Bild hier
Code://-------------------------------------------------------------------
//-------------------------------------------------------------------
//
// 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;
}
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.