-         

Ergebnis 1 bis 4 von 4

Thema: Warum eine "Finite State Machine"?

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    25.12.2008
    Beiträge
    27

    Warum eine "Finite State Machine"?

    Anzeige

    Hallo zusammen,

    ich weiß das meine Frage nicht so recht in das RP6-Forum rein passt, aber da sich einige Beispiele des RP6 auf eine Finite State Machine (FSM) beziehen, hoffe ich trotzdem hier nicht ganz falsch zu sein.

    Ich habe mich ein wenig mit dem RP6 beschäftigt und auch ein erstes Programm geschrieben welches den Robo einfach gerade aus fahren lässt. Auf Hindernisse in Fahrtrichtung (per ACS und Bumper) wird reagiert und ausgewichen. Dies habe ich ohne Programmierung einer FSM gelöst. In der Dokumentation wird erwähnt das man für komplexere Verhalten aber eine solche FSM benutzten sollte. Mein Problem ist nun das ich nicht so recht verstehe warum. Was bringt das für Vorteile? Ich habe mich ein wenig über google in das Thema FSM bzw. endliche Automaten versucht einzulesen, aber warum das jetzt so gut sein soll verstehe ich immer noch nicht.

    Vielleicht kann mir ja jemand mal auf die Sprünge helfen. Mein Progi habe ich mal dabei gelegt, vielleicht möchte sich das jemand mal anschauen.

    Besten Dank für eure Hilfe...

    mfg
    ben

    Code:
    /*
    RP6 fährt autonom. Erster Versuch. ACS und Bumper werden nicht per Event Handler angesprochen, 
    sondern direkt in der main loop(). Die Eventhandler haben das eigentliche moven stets unterbrochen.
    Dadurch fuhr der RP6 meist im Kreis. Klappt so jetzt besser...
    
    10.01.2009
    */
    
    #include "RP6RobotBaseLib.h" // Always needs to be included!
    
    // prüft den Akku und löst ein Blinklicht aus, wenn die Spannung < ca. 5,5 V ist
    // und stopp vorübergehend die Fahrt
    void chkAccu (void) {	
    	static uint8_t x=1;  // AccuChk-Zähler	(static bedeutet, das diese Var. den Wert auch ausserhalb der Funktion behält)
    	uint16_t ubat = readADC(ADC_BAT);
    	if (ubat < 550) {
    		if (x >= 4) {
    			writeString_P("!!! Akkuspannung gering = ");
    			writeInteger(ubat, DEC);
    			writeString_P("\n");
    			uint8_t i=1;
    			uint8_t runningLight = 1;
    	
    			while (i < 50) {	
    				setLEDs(runningLight); 		
    				runningLight <<= 1; 	// bit shift nach links 0b000001, 0b000010, etc.
    		
    				if(runningLight > 32)
    					runningLight = 1; 	// starte wieder bei StatusLED1 
    		
    				i++;
    				mSleep(100); // delay 100ms = 0.1s 
    			}
    			setLEDs(0b000000);  // alle LEDs aus
    			x=1;
    		}
    		x++;
    	}
    }
    
    // prüft den Motorstrom; der Motorstrom ist hoch, wenn der Antrieb z.b. aufgrund eines Hindernisses
    // blockiert wird
    void chkMotor(void) {
    	static uint8_t i=1;  // MotorChk-Zähler
    	if (adcMotorCurrentLeft > 100 || adcMotorCurrentRight > 100) {
    		writeString_P("\n");
    		writeString_P("!!! Motorstrom ist zu hoch links: ");
    		writeInteger(adcMotorCurrentLeft, DEC);
    		writeString_P(" rechts: ");
    		writeInteger(adcMotorCurrentRight, DEC);
    		writeString_P("\n");
    		if (i >= 3) { 
    			setLEDs(0b110110); // alle roten LEDs an
    			move(50,BWD,DIST_CM(30),true);
    			rotate(50,LEFT,180,true); 
    			// sind die Motoren immer noch geblockt ?? wenn ja, versuchen wir es mal 90 Grad links herrum...
    			if (adcMotorCurrentLeft > 100 || adcMotorCurrentRight > 100) {
    				rotate(50,LEFT,90,true); 	
    			} 
    			setLEDs(0b000000);  // alle LEDs aus
    			i=0;			
    		}
    		i++;
    	}
    }
    
    
    
    // Hindernissen ausweichen
    void avoid(void) {
    	// ACS-Abfrage
    	if(obstacle_right && obstacle_left) {// left AND right sensor have detected something...
    		writeString_P("ACS -> middle\n");
    		setLEDs(0b100100);
    		move(50,BWD,DIST_CM(30),true);
    		rotate(30,LEFT,30,true);   
    		setLEDs(0b000000);
    	} else if (obstacle_left) {  // Left "sensor" has detected something      
    		writeString_P("ACS -> left\n");    
    		setLEDs(0b010000);
    		rotate(30,RIGHT,30,true);  
    		setLEDs(0b000000);
    	} else if (obstacle_right) {// Right "sensor" has detected something
    		writeString_P("ACS -> right\n");
    		setLEDs(0b000100);
    		rotate(30,LEFT,30,true);   
    		setLEDs(0b000000);
    	}
    
    	// Bumper-Abfrage
    	if(bumper_left || bumper_right) { 
    		writeString_P("Bumper -> left, right or both\n");
    		setLEDs(0b010010);
    		move(50,BWD,DIST_CM(30),true);
    		rotate(30,LEFT,90,true);   
    		setLEDs(0b000000);
    	} 
    }
    
    int main(void)
    {
    	initRobotBase(); // immer als erstes aufrufen, ohne die Funktion geht nix
    	
    	powerON(); // aktiviert alle wichtigen Systeme
    	
    	setLEDs(0b111111);  // alle LEDs einmal an
    	mSleep(1000);       // 1 sek. warten
    	setLEDs(0b000000);  // alle LEDs wieder aus
    
    	// kann man das noch niedriger einstellen? low ist noch zu hoch, der RP6 fährt nicht nah 
    	// genug an Wände heran.
    	setACSPwrLow(); // ACS Power = low
    	
    	chkAccu(); // beim ersten Programmstart einmal ausführen, danach wird die Funktion zeitlich getriggert
    	
    	// Timer starten
    	startStopwatch1();	
    	startStopwatch2();
    
    	// Main loop
    	while(true) 
    	{			
    		task_RP6System();            // ruft motioncontroll, acs, etc. auf
    		
    		// alle 30sek. Akku-Spannung prüfen
    		if(getStopwatch1() > 30000) { 
    			chkAccu();
    			setStopwatch1(0);
    		}
    		
    		// alle 500ms Motor-Spannung prüfen
    		if(getStopwatch2() > 500) {
    			chkMotor();
    			setStopwatch2(0);
    		}
    			
    		// fahr mal los... schön gerade aus und mit 80 Speed pro Kette....
    		changeDirection(FWD);
    		moveAtSpeed(80,80);
    		
    		// Hindernissen ausweichen per IR und Bumper...
    		avoid();
    	}
    	return 0;
    }
    [/code]

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    07.03.2008
    Ort
    Nürnberg
    Alter
    34
    Beiträge
    51
    Hi!

    Automatentheorie ist schon ein wenig her...
    Also ich stand den finite state machines anfangs auch SEHR skeptisch gegenüber.
    Ich war mit denen vorher bei der normalen Programmierung auch nie in Kontakt gekommen.
    Nach der Nutzung von finite state machines bei einem PLD und später beim erlernen von VHDL merkt man eigentlich erst richtig was der ganze Kram soll.
    Bei einer FSM hat man eine idiotensichere und lückenlose Dokumentation und Fehler können sich nur schwer einschleichen und sind meist schnell auffindbar.
    Also vermeintlich sicherer Code bzw. eine sichere Beschreibung eines Verhaltens.
    Ich persönlich finde finite state machines für Architekturbeschreibungen in VHDL genial,
    jedoch nur selten in Sprachen wie C zu gebrauchen!
    Es geht meiner Meinung nach eine Menge (!) Flexibilität verloren,
    erkauft sich dadurch aber Sicherheit und eine leichte Dokumentation.

    Das ist so meine Erfahrung und Meinung mit den FSMs,
    es gibt hier bestimmt einige die da genau anderer Meinung sind ,
    würde mich mal interessieren wie die das sehen.

    Gruß

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    25.03.2006
    Ort
    Darmstadt
    Alter
    26
    Beiträge
    522
    Gude,

    kleinere Programme lassen sich bestimmt einfacher, übersichtlicher und schneller ohne FSM realisieren. Die Vorteile von FSM gegebüber funktionaler Programmierung werden meistens erst bei sehr komplexen Verhaltensweisen deutlich. FSMs ermöglichen einen vergleichsweise einfachen Kontextwechsel bei unerwarteten Ereignissen, weil man eben nur den Zustand zu wecheln braucht. Beim funktionalem Ansatz hingegen könnte es vorkommen, dass quasi aus einer Funktion mitten in eine andere gesprungen werden muss, was natürlich nicht geht und weshalb man teilweise abartige und unübersichtliche Konstrukte bauen muss, um das geschünschte Verhalten zu erziehlen. Ausserdem ist FSM ausfallsicherer, da der Ausfall eines Moduls nicht unbedingt zum Absturz des ganzen Systems führen muss, wie das bei rein funktionalen Lösungen leider meistens der Fall ist. Das beste Beispiel dafür ist das Gehirn, das seine Aufgaben ja nicht sequentiell sondern massiv parallel durchführt.

    Aber wie gesagt, das alles gilt nur für längere und komplizierte Programme, bei kurzen Progs kommt man meistens ohne FSM schneller ans Ziel.

    MfG Mark

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    25.12.2008
    Beiträge
    27
    Ok... das mit der schnelleren Realisierung kann ich bis jetzt nur bestätigen. Ohne FSM konnte die Problemstellungen schneller lösen. Mal schauen ob ich die FSM irgendwann einmal brauchen werde...

    Vielen Dank für eure Meinungen..

    mfg
    ben

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •