-         

Ergebnis 1 bis 9 von 9

Thema: RP6 Von Anfnger fr Anfnger

  1. #1
    Neuer Benutzer fters hier
    Registriert seit
    20.06.2011
    Beitrge
    18

    RP6 Von Anfnger fr Anfnger

    Anzeige

    Hi!
    Seit gestern bin ich ein glcklicher Besitzer eines RP6. Da ich die Akkuladezeit irgendwie berbrcken musste dachte ich mir ein kleines Tutorial zu schreiben. In dem tutorial lernt ihr wie der Robby vorwrts fhrt und bei Berhrung der Tastsensoren (Bumper) anhlt, zurcksetzt und sich um 45 grad dreht. Dann nimmt er die Fahrt vorwrts wieder auf. Wenn man die Anleitung gelesen hat und etwas Verstndnis fr C hat ist das total leicht nachzuvollziehen. Wer sich mit Programmiersprachen gar nicht auskennt sollte vor allem das Handbuch aufmerksam lesen. Viele fragen werden dort sehr gut erlutert. Aber auch mir knnt ihr gerne fragen dazu stellen. Solltet ihr noch fragen dazu haben steht auch meine e-mail adresse mit im tutorial.
    Und jetzt viel Spass und Erfolg
    Angehngte Dateien Angehngte Dateien

  2. #2
    Neuer Benutzer fters hier
    Registriert seit
    20.06.2011
    Beitrge
    18
    So, hab mal versucht das Beispiel 5Move5 mit Deutschen kommentaren auszustatten welche leicht verstndlich vermitteln sollen was da passiert. Ich hoffe habe da keine Denkfehler mit eingebaut... Ist natrlich noch nicht komplett kommentiert, es sollte aber eigentlich mt etwas nachdenken alles beantwortet werden. Daher Anregungen, Fragen usw.
    Hier also der Code mit meinen Kommentaren:
    Code:
    #include "RP6RobotBaseLib.h" 	
    // Leerlauf
    #define IDLE  0
    //Struktur behaviour_command_t wir an die Funktion move() bzw. rotate() bergeben.
    //Alle bentigten werte werden hier abgelegt.
    typedef struct {
    	uint8_t  speed_left; 
    	uint8_t  speed_right;
    	unsigned dir:2;
    	unsigned move:1;
    	unsigned rotate:1;
    	uint16_t move_value;
    	uint8_t  state;
    } behaviour_command_t;
    //wie eine variable(z.B.:uint8_t STOP = 0;) knnen wir nun die Struktur STOP mit diesen werten erstellen.
    //wird dann Stop in der funktion move(STOP) oder rotate(STOP) aufgerufen passiert folgendes :
    //In STOP stehen diese Werte:Stop = speed_left, speed_right, dir, move, rotate, move_value, state;
    //Diese werte werden an die funktion bergeben und beeinflussen so das fahrverhalten (Wie der name vermuten lsst stoppt
    //der Roboter dann ;-)). ber den punktoperator knnen einzelne werte der Struktur abgefragt bzw. gendert werden.
    //z.B. Wert ndern: STOP.dir = BWD; (d.h.: Stop.Fahrtrichtung = vorwrts)
    //oder abfragen und dann ndern: if(Stop.dir == FWD)  	[d.h.: wenn Stop.Fahrtrichtung vorwrts ist] 
    //            					{ Stop.dir = BWD; } 	[      Stop.Fahrtrichtung = Rckwrts] 
    //Das Beispiel macht sogar sinn auch wenn es anfangs verwirrend sein kann weshalb die fahrtrichtung beim stop gendert wird...
    behaviour_command_t STOP = {0, 0, FWD, false, false, 0, IDLE};
    
    //berall wo CRUISE_SPEED_FWD steht wird der wert ( hier im moment 80) eingetragen. So muss man sich nicht jeden wert merken.
    //Einfache aber Sinnvolle namen nehmen (#define CRUISE_SPEED_FWD = #define FAHREN_GESCHWINDIGKEIT_VORWRTS)
    #define CRUISE_SPEED_FWD    80
    
    #define MOVE_FORWARDS 1
    behaviour_command_t cruise = {CRUISE_SPEED_FWD, CRUISE_SPEED_FWD, FWD, 
    								false, false, 0, MOVE_FORWARDS};
    //Da wir kein muster abfahren wollen, sondern nur geradeaus bis wir auf ein hinderniss stossen brauchen wir
    // in dieser funktion keine eintrge. alle wert stehen ja dafr schon in der struktur cruise... 
    void behaviour_cruise(void)
    {
    }
    //Taster : Standartwerte die ber den namen angesprochen werden knnen. siehe #define oben...
    #define ESCAPE_SPEED_BWD    80
    #define ESCAPE_SPEED_ROTATE 60
    
    #define ESCAPE_FRONT		1
    #define ESCAPE_FRONT_WAIT 	2
    #define ESCAPE_LEFT  		3
    #define ESCAPE_LEFT_WAIT	4
    #define ESCAPE_RIGHT	    5
    #define ESCAPE_RIGHT_WAIT 	6
    #define ESCAPE_WAIT_END		7
    behaviour_command_t escape = {0, 0, FWD, false, false, 0, IDLE}; 
    //Bumper Funktion
    void behaviour_escape(void)
    {   //Variable zum zhlen wie oft die taster ausgelst wurden
    	static uint8_t bump_count = 0;
    	//Schalte die Fahreinstellung um, je nachdem welcher Taster getroffen wurde
    	switch(escape.state)
    	{
    	//IDLE ist soviel wie Leer(-lauf) 
    		case IDLE: 
    		break;
    		//Beide Taster ausgelst bzw. Hinderniss mittig
    		case ESCAPE_FRONT:
    		//einzelne werte der struktur escape ndern um auf das tastereignis zu reagieren
    		//zurck fahren und ESCAPE_FRONT_WAIT aufrufen
    			escape.speed_left = ESCAPE_SPEED_BWD;
    			escape.dir = BWD;
    			escape.move = true;
    			//if = wenn... 
    			if(bump_count > 3)
    			// dann...
    				escape.move_value = 220;
    				//else = wenn nicht, dann. Oder auch :sonst...
    			else
    				escape.move_value = 160;
    			escape.state = ESCAPE_FRONT_WAIT;
    			bump_count+=2;
    		break;
    		
    		case ESCAPE_FRONT_WAIT:			
    			if(!escape.move) 
    			{	
    				escape.speed_left = ESCAPE_SPEED_ROTATE;
    				if(bump_count > 3)
    				{
    					escape.move_value = 100;
    					escape.dir = RIGHT;
    					bump_count = 0;
    				}
    				else 
    				{
    					escape.dir = LEFT;
    					escape.move_value = 70;
    				}
    				escape.rotate = true;
    				escape.state = ESCAPE_WAIT_END;
    			}
    		break;
    		//Links ausweichen
    		case ESCAPE_LEFT:
    			escape.speed_left = ESCAPE_SPEED_BWD;
    			escape.dir 	= BWD;
    			escape.move = true;
    			if(bump_count > 3)
    				escape.move_value = 190;
    			else
    				escape.move_value = 150;
    			escape.state = ESCAPE_LEFT_WAIT;
    			bump_count++;
    		break;
    		case ESCAPE_LEFT_WAIT:
    			if(!escape.move)
    			{
    				escape.speed_left = ESCAPE_SPEED_ROTATE;
    				escape.dir = RIGHT;
    				escape.rotate = true;
    				if(bump_count > 3)
    				{
    					escape.move_value = 110;
    					bump_count = 0;
    				}
    				else
    					escape.move_value = 80;
    				escape.state = ESCAPE_WAIT_END;
    			}
    		break;
    		//Rechts ausweichen
    		case ESCAPE_RIGHT:	
    			escape.speed_left = ESCAPE_SPEED_BWD ;
    			escape.dir 	= BWD;
    			escape.move = true;
    			if(bump_count > 3)
    				escape.move_value = 190;
    			else
    				escape.move_value = 150;
    			escape.state = ESCAPE_RIGHT_WAIT;
    			bump_count++;
    		break;
    		case ESCAPE_RIGHT_WAIT:
    			if(!escape.move)
    			{ 
    				escape.speed_left = ESCAPE_SPEED_ROTATE;		
    				escape.dir = LEFT;
    				escape.rotate = true;
    				if(bump_count > 3)
    				{
    					escape.move_value = 110;
    					bump_count = 0;
    				}
    				else
    					escape.move_value = 80;
    				escape.state = ESCAPE_WAIT_END;
    			}
    		break;
    		//Vorgang beenden  
    		case ESCAPE_WAIT_END:
    			if(!(escape.move || escape.rotate))
    				escape.state = IDLE;
    		break;
    	}
    }
    //Bumper Handler
    void bumpersStateChanged(void)
    {	//beide bumper getroffen
    	if(bumper_left && bumper_right)
    	{
    		escape.state = ESCAPE_FRONT;
    	}
    	//linker bumper getroffen
    	else if(bumper_left)
    	{
    		if(escape.state != ESCAPE_FRONT_WAIT) 
    			escape.state = ESCAPE_LEFT;
    	}
    	//rechter bumper getroffen
    	else if(bumper_right)
    	{
    		if(escape.state != ESCAPE_FRONT_WAIT)
    			escape.state = ESCAPE_RIGHT;
    	}
    }
    
    
    #define AVOID_SPEED_L_ARC_LEFT  30
    #define AVOID_SPEED_L_ARC_RIGHT 90
    #define AVOID_SPEED_R_ARC_LEFT  90
    #define AVOID_SPEED_R_ARC_RIGHT 30
    #define AVOID_SPEED_ROTATE 	60
    
    #define AVOID_OBSTACLE_RIGHT 		1
    #define AVOID_OBSTACLE_LEFT 		2
    #define AVOID_OBSTACLE_MIDDLE	    3
    #define AVOID_OBSTACLE_MIDDLE_WAIT 	4
    #define AVOID_END 					5
    behaviour_command_t avoid = {0, 0, FWD, false, false, 0, IDLE};
    //Anti Kollisions System (IR-Sensoren) Funktion
    void behaviour_avoid(void)
    { //letztes hinderniss
    	static uint8_t last_obstacle = LEFT;
    	//variable um hindernisse zu zhlen
    	static uint8_t obstacle_counter = 0;
    	switch(avoid.state)
    	{
    	//Idle prft auf Hindernisse und schaltet zwischen fahrmodis
    		case IDLE: 
    			if(obstacle_right && obstacle_left)
    				avoid.state = AVOID_OBSTACLE_MIDDLE;
    			else if(obstacle_left)
    				avoid.state = AVOID_OBSTACLE_LEFT;
    			else if(obstacle_right)
    				avoid.state = AVOID_OBSTACLE_RIGHT;
    		break;
    		//Hinderniss mittig
    		case AVOID_OBSTACLE_MIDDLE:
    			avoid.dir = last_obstacle;
    			avoid.speed_left = AVOID_SPEED_ROTATE;
    			avoid.speed_right = AVOID_SPEED_ROTATE;
    			if(!(obstacle_left || obstacle_right))
    			{
    				if(obstacle_counter > 3)
    				{
    					obstacle_counter = 0;
    					setStopwatch4(0);
    				}
    				else
    					setStopwatch4(400);
    				startStopwatch4();
    				avoid.state = AVOID_END;
    			}
    		break;
    		//Hinderniss Rechts
    		case AVOID_OBSTACLE_RIGHT:
    			avoid.dir = FWD;
    			avoid.speed_left = AVOID_SPEED_L_ARC_LEFT;
    			avoid.speed_right = AVOID_SPEED_L_ARC_RIGHT;
    			if(obstacle_right && obstacle_left)
    				avoid.state = AVOID_OBSTACLE_MIDDLE;
    			if(!obstacle_right)
    			{
    				setStopwatch4(500);
    				startStopwatch4();
    				avoid.state = AVOID_END;
    			}
    			last_obstacle = RIGHT;
    			obstacle_counter++;
    		break;
    		//Hinderniss Links
    		case AVOID_OBSTACLE_LEFT:
    			avoid.dir = FWD;
    			avoid.speed_left = AVOID_SPEED_R_ARC_LEFT;
    			avoid.speed_right = AVOID_SPEED_R_ARC_RIGHT;
    			if(obstacle_right && obstacle_left)
    				avoid.state = AVOID_OBSTACLE_MIDDLE;
    			if(!obstacle_left)
    			{
    				setStopwatch4(500); 
    				startStopwatch4();
    				avoid.state = AVOID_END;
    			}
    			last_obstacle = LEFT;
    			obstacle_counter++;
    		break;
    		case AVOID_END:
    			if(getStopwatch4() > 1000)
    			{
    				stopStopwatch4();
    				setStopwatch4(0);
    				avoid.state = IDLE;
    			}
    		break;
    	}
    }
    //ACS Handler (schaltet nur LEDs um)
    void acsStateChanged(void)
    {
    	if(obstacle_left && obstacle_right)
    		statusLEDs.byte = 0b100100;
    	else
    		statusLEDs.byte = 0b000000;
    	statusLEDs.LED5 = obstacle_left;
    	statusLEDs.LED4 = (!obstacle_left);
    	statusLEDs.LED2 = obstacle_right;
    	statusLEDs.LED1 = (!obstacle_right);
    	updateStatusLEDs();
    }
    //Funktion erstellt move und rotate befehle mit den bergebenen werten der Struktur behaviour_command_t
    //also Wenn ein ereigniss eintritt(Bumper, Ir- Sensoren usw.)
    void moveCommand(behaviour_command_t * cmd)
    {
    	
    	if(cmd->move_value > 0)
    	{
    	//berprfe ob rotate oder move aufgerufen wurde und erstelle den dementsprechenden Fahrbefehl
    		if(cmd->rotate)
    			rotate(cmd->speed_left, cmd->dir, cmd->move_value, false); 
    		else if(cmd->move)
    			move(cmd->speed_left, cmd->dir, DIST_MM(cmd->move_value), false); 
    		cmd->move_value = 0; 
    	}
    	//weder move noch rotate wurde aufgerufen
    	else if(!(cmd->move || cmd->rotate))
    	{
    		changeDirection(cmd->dir);
    		moveAtSpeed(cmd->speed_left,cmd->speed_right);
    	}
    	//Wenn die bewegung abgeschlossen ist rotate und move auf false setzen um beim nchsten aufruf keine alten werte
    	//zu nutzen. 
    	else if(isMovementComplete())
    	{
    		cmd->rotate = false;
    		cmd->move = false;
    	}
    }
    //Funktion wartet auf Sensorereignisse und ruft die Funktion moveCommand(behaviour_command_t * cmd)
    //auf, und bergibt an die Funktion angepasste Fahrbefehle um Hindernissen auszuweichen
    void behaviourController(void)
    {
    // Die funktionen abfragen und bei nderung in cruise.state, avoid.state oder escape.state darauf reagieren
    	behaviour_cruise();
    	behaviour_avoid();
    	behaviour_escape();
     //wenn escape.state, avoid.state ,oder cruise.state nicht IDLE sind rufe funktion moveCommand()auf und verweise auf die 
    //Struktur in der die werte abgespeichert sind um das Fahrverhalten zu ndern. 
    	if(escape.state != IDLE)
    		moveCommand(&escape);
    	else if(avoid.state != IDLE)
    		moveCommand(&avoid);
    	else if(cruise.state != IDLE)
    		moveCommand(&cruise); 
    	else
    //Wenn alle drei IDLE sind anhalten                     
    		moveCommand(&STOP); 
    }
    
    
    int main(void)
    {
    	initRobotBase(); 
    	setLEDs(0b111111);
    	mSleep(2500);
    	setLEDs(0b100100); 
    //Handler fr Taster und Anti Kollisions System
    	BUMPERS_setStateChangedHandler(bumpersStateChanged);
    	ACS_setStateChangedHandler(acsStateChanged);
    	
    	powerON();
    	setACSPwrMed(); 
    	//Endlosschleife
    	while(true) 
    	{	
    //Diese Funktionen werden stndigaufgerufen. Bei einer nderung in der Funktion (Wenn etwa eine If bedingung erfllt wurde
    //und ein wert sich somit ndert) laufen dann je nachdem was sich ereignet hat verschiedene funktionen. Die bauen sozusagen
    //aufeinander auf(Funktion ruft Funktion auf ruft Funktion auf usw.) Dabei werden Zustnde verglichen und vorgegebene Bewegungs-
    //befehle erstellt. wenn alle werte bestimmt sind fr die Fahrtnderung wird eine Funktion aufgerufen die die Werte in einen 
    //Befehl umwandelt (hier move() oder rotate()). Der wird dann ausgefhrt.Abschlieend wechselt er wieder in den normalen
    //Fahrmodus. Dann wird wieder kontrolliert, ggf. Funktionen aufgerufen usw...	
    		behaviourController();
    		task_RP6System();
    	}
    	return 0;
    }
    Bitte verzeiht mir Tippfehler und Gro-/Kleinschreibung aber stehe gerade etwas neben mir. Naja ist ja auch schon spt

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.05.2009
    Ort
    Berlin
    Beitrge
    450
    Das htte ich mir vor 2 Jahren gewnscht. Die Beispielprogramme mit konkreten Erklrung was jetzt passiert und das dann in Deutsch. Ich find das eine gute Idee. Mach weiter so.
    MfG TrainMen

  4. #4
    Neuer Benutzer fters hier
    Registriert seit
    20.06.2011
    Beitrge
    18
    Danke. Ich wollte erst mal sehen ob da Interesse dran besteht. Werde mich mal die nchsten 2, 3 Wochen mit den Beispielen auseinandersetzen und versuchen sie zu bersetzen. Natrlich bin ich auch nur ein anfnger und deshalb hoffe ich dann bei der Fehlerkorrektur auf euch. Ich will ja auch was lernen.

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beitrge
    1.514
    > hoffe ich dann bei der Fehlerkorrektur auf euch


    OK
    Kleiner Hinweis zu den EventHandler Funktionen:
    Dort besser nichts blockierendes / Pausen verwenden. Das kann in einigen Fllen funktionieren, muss aber nicht.
    Teste einfach mal was passiert wenn Du die Bumper ein paar mal direkt hintereinander drckst wenn Du das so wie bei Dir beschrieben machst mit move(... ,BLOCKING)...
    (msste rekursiv mehrmals hintereinander aufgerufen werden... wenn ich mich recht erinnere - schon lange her)

    Habs nur berflogen aber das war mir sofort aufgefallen.

  6. #6
    Neuer Benutzer fters hier
    Registriert seit
    20.06.2011
    Beitrge
    18
    Jo, danke fr den Tipp. Hatte beim berfliegen von BLOCKING wohl etwas verdreht (um genau zu sein habe ich es komplett andersrum verstanden, hab eben nochmal die Anleitung gelesen. Htte schwren knnen das es so dastand wie ich es in Erinnerung hatte) . Na gut war auch aufgeregt wegen dem neuen RP6. Werde dann mal wenn ich wieder zu Hause bin nachbessern. Poste dann den neuen Code mit Erklrung heute abend oder morgen frh. Achso wollte noch was zu rekursiv sagen (SlyD hat den begriff ja im Post genutzt). Eine Rekursion ist u.a. eine Funktion die sich selbst aufruft. Hab irgendwo in C++ noch nen kleines Programm mit ner Doppelt verketteten Liste. Werde das mal umtippen und dann die tage hier posten. Das sollte recht einfach veranschaulichen wie das mit der rekursion funktioniert.

  7. #7
    Neuer Benutzer fters hier
    Registriert seit
    20.06.2011
    Beitrge
    18
    Da ich gerade anfange Unterlagen fr ein Projekt mit ehemaligen Drogenabhngigen zu erstellen um denen einen Einstieg in Elektronik und Programmierung am beispiel eines Autonomen Roboters zu erlutern (geplant fr nchstes Jahr, falls ich ein Konzept zusammenbekomme), habe ich heute mal Die Umrechnung von dezimal in binr und zurck beschrieben. Natrlich nicht um so stndig Werte umzurechnen, sondern um den Zusammenhang etwas besser zu verdeutlichen. Ich dachte erst das wre in 3, 4 Zeilen zu erklren. Wurde aber von meinen "Beta-Testern" eines besseren belehrt(beide wissen wie man einen PC ein und aus schaltet, aber nicht viel mehr). Am Ende waren es dann viele Zeilen die ich jetzt etwas gekrzt habe. Viel spass beim Lesen
    Angehngte Dateien Angehngte Dateien

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.05.2009
    Ort
    Berlin
    Beitrge
    450
    mach aber nicht den Fehler bei Deinem Projekt, solche Dinge wie diese Hex/Dez Umwandlungen zu frh zu bringen. Die meisten werden sich langweilen, sich wie in der Schule vorkommen oder Dich darauf hinweisen das es Taschenrechner gibt die diese Funktionen haben. Ich wnsch Dir viel Erfolg mit Deinem Konzept.

  9. #9
    Neuer Benutzer fters hier
    Registriert seit
    20.06.2011
    Beitrge
    18
    Danke fr den Hinweis. Genau das hatte ich mir auch schon gedacht. Daher habe ich mir vorgenommen daraus ein klein Heft mit solchen "Schulischen langweiligen Kram" zu machen. So htte jeder ein eigenes kleines Nachschlagewerk und das auch noch umsonst. Da ja gerade bei Sozialen Randgruppen das finanzielle eine groe Rolle spielt knnte man damit schon mal arbeiten, falls man sich eben keine Fachliteratur leisten kann. Und da noch die Finanzierung in der Schwebe ist, (Kirchen und Drogenberatungsstellen schmeien leider nicht mit Geld um sich ) versuche ich den Kurs so gnstig wie mglich zu halten. Naja, mein utopisches Ziel wre es einen wettbewerbsfhigen Roboter von der Gruppe bauen und programmieren zu lassen. Wenn die Gruppe dann auch noch an einem Wettbewerb (Robo Cup, Sumo Roboter oder sowas) teilnehmen knnte wre ich extremst begeistert. Aber das ist noch getrume und weit weg.
    So, muss mal arbeiten.

hnliche Themen

  1. Bot-Anfnger
    Von iBot im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 28
    Letzter Beitrag: 06.04.2009, 23:06
  2. CRP5: meine Erweiterung (vom Anfnger fr Anfnger)
    Von loewenzahn im Forum Robby CCRP5
    Antworten: 11
    Letzter Beitrag: 21.03.2007, 19:37
  3. C fr Anfnger!!!
    Von techboy im Forum C - Programmierung (GCC u.a.)
    Antworten: 11
    Letzter Beitrag: 17.09.2005, 16:44
  4. Anfnger
    Von FRY-Robotik im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 07.08.2005, 21:23
  5. Anfnger: welches modul sollte man als anfnger nehmen???
    Von patti16 im Forum AVR Hardwarethemen
    Antworten: 5
    Letzter Beitrag: 04.01.2005, 09:44

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhnge hochladen: Nein
  • Beitrge bearbeiten: Nein
  •