Zitat Zitat von pinsel120866
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.


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