- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 9 von 9

Thema: Asuro Labyrinth

  1. #1

    Asuro Labyrinth

    Anzeige

    Powerstation Test
    Hallo,
    ich bin seit kurzem Besitzer eines Asuro und stehe zur Zeit vor dem Problem, dass er allein durch ein Labyrinth finden soll. Dabei gibt es nur rechte Winkel im Labyrinth und auch keine größeren Räume oder solche Späße. Mein Ansatz sah wie folgt aus: Er sollte solange geradeaus fahren bis er an eine Wand stößt, in diesem Fall soll er sich 90° nach rechts drehen und dort überprüfen ob er eine Wand findet. Wenn ja soll er sich 180° nach links drehen und wenn er auch dort eine Wand vorfindet (=Sackgasse) soll er sich noch einmal 90° nach links drehen. Dabei bin ich auf mein erstes Problem gestoßen: Diese Schrittfolge wird auch komplett durchlaufen wenn er nach dem ersten Mal drehen weiterfahren kann, dh. nach dem Rechtsabbiegen würde er sich bei der nächsten Wand 180° drehen und damit zurückfahren. Aus diesem Grund habe ich eine Zählvariable x eingeführt, die die Schleifendurchläufe nach der 90° Drehung nach rechts zählen soll und daraus ermittelt ob gleich nach der Drehung wieder eine Wand kommt oder ob er erst noch ein Stück fährt bevor er wieder anstößt. Und wenn letzteres eintritt, dann soll das Programm wieder von vorn beginnen und nicht bis zum Ende durchlaufen. Ok, um die eventuelle Verwirrung etwas zu beseitigen, hier mein Code:


    Code:
    #include "asuro.h"
    
    int main(void)
    {
    	Init();
    	
    void PrintInt(int wert)
    {  	
      char text[6] ={0};
      itoa(wert,text,10);
      SerWrite(text,strlen(text));	 
      
    }
    	
    
    	char MauerVORN,MauerRECHTS,MauerLINKS;
    	int S1,S2,S3;
    	int x;
    	int i;
    	
    	while(1)
    	{
    	 MauerVORN=0;
    	 MauerRECHTS=0;
    	 MauerLINKS=0;
    	 x=0;
    	 
    	 while (MauerVORN==0)
    	 {
    	     MotorDir(FWD,FWD);
    		 MotorSpeed(150,150);
    		 
    		 S1=PollSwitch();
    		 S2=PollSwitch();
    		 S3=PollSwitch();
    		 
    		 if (S1!=0||S2!=0||S3!=0)
    		     {MauerVORN=1;}
    		 else
    		     {MauerVORN=0;}
    	 }
    	 
    	 MotorDir(RWD,RWD);
    	 MotorSpeed(120,120);
    	 for (i=1;i<80;i++) {Sleep(255);}
    	 MotorDir(FWD,RWD);
    	 for (i=1;i<120;i++) {Sleep(255);}
    	 
    	 while (MauerRECHTS==0)
    	 {
    	     x++;
    		 
    		 MotorDir(FWD,FWD);
    		 MotorSpeed(150,150);
    		 
    		 S1=PollSwitch();
    		 S2=PollSwitch();
    		 S3=PollSwitch();
    		 
    		 if (S1!=0||S2!=0||S3!=0)
    		     {MauerRECHTS=1;}
    		 else
    		     {MauerRECHTS=0;}
    	 }
    	 
    	 PrintInt(x);
    	 
    	 if (x>30/*???*/)
    	 {
    	     MauerLINKS=1;
    	 }
    	 else
    	 {
    		 MotorDir(RWD,RWD);
    	     MotorSpeed(120,120);
    	     for (i=1;i<80;i++) {Sleep(255);}
    	     MotorDir(FWD,RWD);
    	     for (i=1;i<200;i++) {Sleep(255);}
    	 }
    	 
    	 while (MauerLINKS==0)
    	 {
    	     MotorDir(FWD,FWD);
    		 MotorSpeed(150,150);
    		 
    		 S1=PollSwitch();
    		 S2=PollSwitch();
    		 S3=PollSwitch();
    		 
    		 if (S1!=0||S2!=0||S3!=0)
    		     {MauerLINKS=1;}
    		 else
    		     {MauerLINKS=0;}
    	 }
    	 
    	 if (x<30/*???*/)
    	 {
    	     
    		 MotorDir(RWD,RWD);
    	     MotorSpeed(120,120);
    	     for (i=1;i<80;i++) {Sleep(255);}
    	     MotorDir(FWD,RWD);
    	     for (i=1;i<120;i++) {Sleep(255);}
    	 }
    	 
    	}
    	return 0;
    }
    Leider funktioniert es noch nicht ganz wie es soll. Asuro fährt immer nur kurz rückwärts und dreht sich um 90 oder 180°. Ich bin mit meinem Latein echt am Ende.

    Man merkt vielleicht, dass ich noch Anfänger in C++ bin. In der Schule hatte ich nur Delphi. Da ist vieles einfacher.

    Vielen Dank im Voraus für eure Hilfe.

    Gruß KMab

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Dein Glück, dass ich gerade Langeweile hatte... da kam mir dein Problem gerade recht

    Also, ich würde dir 3 Sachen raten:
    1. Quelltext kommentieren.
    Entgegen der landläufigen Meinung, man kommentiere nur für andere, ist es sehr hilfreich sich mit Kommentaren Notizen in den Quelltext zu schreiben. Wozu dient die Quellcodepassage? Erläuterungen etc...
    2. In Funktionen denken
    Programmteile, die wiederholt vorkommen, in Funktionen packen.
    3. Sprechende Variablen
    Variablen- und Funktionsnamen möglichst nach ihrer konkreten Anwendung benennen.

    Das mag erstmal komisch klingen als Antwort auf dein konkretes Problem. Aber durch diese simplen 'Regeln' wird dein Quellcode sehr viel lesbarer und die Probleme werden sehr viel leichter erkennbar.

    Ich hab deinen Code mal umgeschrieben, um am Beispiel zu zeigen, was ich meine:

    Code:
    #include "asuro.h"
    
    // Ausgabe einer Integer-Variablen
    void printInt(int wert) {  	
    	char text[6] = {0};
    	itoa(wert, text, 10);
    	SerWrite(text, strlen(text));	 
    }
    
    // Tastenabfrage mit Entprellung
    // fragt Hindernistaster ab
    unsigned char isHindernis() {
    	return PollSwitch() || PollSwitch() || PollSwitch();
    }
    
    // Richtungen definieren
    enum Richtung {LINKS, RECHTS};
    
    // Drehung um 90 Grad
    void drehen(char richtung) {
    	if (richtung == LINKS) {
    		MotorDir(RWD, FWD);
    	}
    	else {
    		MotorDir(FWD, RWD);
    	}
    	MotorSpeed(120, 120);
    	for (i = 1; i < 120; i++) {Sleep(255);}
    }
    
    // kurzes Stück rückwärts fahren
    void zuruecksetzen() {
    	MotorDir(RWD, RWD);
    	MotorSpeed(120, 120);
    	for (i = 1; i < 80; i++) {Sleep(255);}
    }
    void geradeausfahren() {
    	MotorDir(FWD, FWD);
    	MotorSpeed(150, 150);
    }
    int main(void)
    {
    	Init();
    
    	int gefahreneStrecke;
    	int i;
    
    	// Endlosschleife (loop)
    	while(1)
    	{
    		// Los gehts!
    		geradeausfahren();
    
    		// solange fahren, bis Hindernis detektiert
    		while (!isHindernis() )  { }
    
    		// Aha, ein Hindernis!
    		zuruecksetzen();
    		drehen(RECHTS);
    		geradeausfahren();
    
    		// solange fahren, bis Hindernis detektiert oder Mindestentfernung zurückgelegt
    		gefahreneStrecke = 0;
    		while (!isHindernis() && gefahreneStrecke <= 30)  { gefahreneStrecke++; }
    
    		// Mindestentfernung zurückgelegt?
    		if (gefahreneStrecke > 30)
    		{
    			// loop neu starten 
    			continue;
    		}
    
    		// Aha, rechts ist eine Wand!
    		zuruecksetzen();
    		drehen(LINKS);	// 90° drehen
    		drehen(LINKS);	// 90° drehen -> 180° gedreht
    		geradeausfahren();
    
    		// solange fahren, bis Hindernis detektiert oder Mindestentfernung zurückgelegt
    		gefahreneStrecke = 0;
    		while (!isHindernis() && gefahreneStrecke <= 30)  { gefahreneStrecke++; }
    
    		// Mindestentfernung zurückgelegt?
    		if (gefahreneStrecke > 30)
    		{
    			// loop neu starten 
    			continue;
    		}
    		// Aha, links ist auch eine Wand!
    		// Also Sackgasse gefunden
    		zuruecksetzen();
    
    		// drehen Richtung Ursprung
    		drehen(LINKS);
    
    	}
    	return 0;
    }
    Da ich kein Asuro besitze, kann ich den Code nicht testen, aber ich bin sicher, falls ich Fehler gemacht habe, wirst du sie leicht finden.
    Geändert von Sisor (17.08.2014 um 13:48 Uhr) Grund: isHindernis() korrigiert

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von i_make_it
    Registriert seit
    29.07.2008
    Ort
    Raum DA
    Alter
    56
    Beiträge
    2.814
    1234567890
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken laby-ausg.jpg  
    Geändert von i_make_it (04.02.2015 um 20:39 Uhr)

  4. #4
    Danke erstmal für die hilfreichen Tipps.
    Mit Funktionen habe ich mich bis jetzt gar nicht so intensiv beschäftigt, aber das wird sich in Zukunft ändern. Dadurch wird wirklich vieles übersichtlicher.

    @Sisor:

    Ich habe dein Programm mal auf meinen Asuro geflashed, aber er macht das gleiche wie bei meiner ursprünglichen Variante. Beim Compilen bin ich aber auf folgende Meldung gestoßen:
    test.c:165: warning: the address of 'isHindernis' will always evaluate as 'true'
    test.c:174: warning: the address of 'isHindernis' will always evaluate as 'true'
    test.c:191: warning: the address of 'isHindernis' will always evaluate as 'true'

    Das heißt doch, dass die Anweisungen, die für den Fall dass kein Hindernis da ist, ausgeführt werden sollten, nie ausgeführt werden, oder? Und genau das sieht man auch am Asuro: Er macht nur das, was er machen soll wenn er auf ein Hindernis stößt: rücksetzen und drehen, nie geradeaus fahren. Ich habe mir den Programmcode noch einmal angesehn, aber auch mit deiner übersichtlichen Variante finde ich den Fehler nicht.


    @i_make_it:

    diesen Fall würde ich beim Labyrinthbau einfach umgehen und nur die Umkehrung davon verwenden, d.h. er kommt in deinem Bild vom Ausgang und fährt in eine Richtung und dann kann er entweder eine Sackgasse finden oder eben den richtigen Weg. Das habe ich mit Papier und Stift auch schon ausprobiert. Wenn mein Programm so funktionieren würde wie es soll, dann müsste das funktionieren. Aber Danke trotzdem für deine Überlegungen.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Zitat Zitat von KMab Beitrag anzeigen
    @Sisor:

    Ich habe dein Programm mal auf meinen Asuro geflashed, aber er macht das gleiche wie bei meiner ursprünglichen Variante. Beim Compilen bin ich aber auf folgende Meldung gestoßen:
    test.c:165: warning: the address of 'isHindernis' will always evaluate as 'true'
    test.c:174: warning: the address of 'isHindernis' will always evaluate as 'true'
    test.c:191: warning: the address of 'isHindernis' will always evaluate as 'true'
    Ich habe im Code hinter den Aufrufen von isHindernis die Klammern vergessen. Es muss dort isHindernis() stehen, sonst wird nicht die Funktion aufgerufen, sondern die Adresse der Funktion abgeprüft, und da diese vorher definiert wurde, ist sie immer größer 'null' und damit 'true'.

    Die Funktion fragt übrigens ab, ob IRGENDEIN Taster gedrückt wird.

  6. #6
    Das Hinzufügen der Klammern bewirkt zwar dass die Warnungen verschwinden, aber mein Asuro macht trotzdem nichts anderes als vorher.

    Was genau gibt eigentlich die Funktion an das Hauptprogramm weiter? Wie gesagt im Bereich Funktionen bin ich noch nicht so bewandert.

    unsigned char isHindernis() {
    return PollSwitch() || PollSwitch() || PollSwitch();
    }

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Let me google this for you!
    asurowiki: Tasten
    Pollswitches_testen

  8. #8
    Also gibt isHindernis(), je nach dem welche Taster gedrückt sind, einen Wert an das Hauptprogramm? Also z.B. 8 oder 16 oder so?
    Wenn ja müsste da nicht noch verglichen werden, also wenn PollSwitch()>0 dann ist da ein Hindernis?
    Oder verbirgt sich hinter isHindernis() einfach TRUE oder FALSE?

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    while (!isHindernis() ) { }
    Dies ist gleichzusetzen mit :
    while (isHindernis() == 0) { }
    Also solange kein Taster gedrückt ist, Endlosschleife.
    In C entspricht eine 0 'false', jeder andere Wert ist 'true'.
    Z.B. bedeutet
    if(a) tueEtwas();
    'Wenn a nicht 0 ist tueEtwas'

    Teste mal deine Taster auf Funktion mit dem Programm: Pollswitches_testen

Ähnliche Themen

  1. Asuro Programmierung Brauche Hilfe Labyrinth !!!!!!!!!!!!!!!
    Von marcel_asuro im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 3
    Letzter Beitrag: 07.01.2010, 20:05
  2. Labyrinth
    Von asuro11 im Forum Sensoren / Sensorik
    Antworten: 14
    Letzter Beitrag: 10.05.2009, 13:02
  3. HILFE! Asuro Fährt durch ein "Labyrinth"
    Von Alorom im Forum Open Source Software Projekte
    Antworten: 2
    Letzter Beitrag: 06.04.2009, 15:49
  4. ASURO im Labyrinth, der Film
    Von stochri im Forum Asuro
    Antworten: 1
    Letzter Beitrag: 03.02.2007, 14:13
  5. Antworten: 4
    Letzter Beitrag: 03.05.2005, 19:37

Stichworte

Berechtigungen

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

12V Akku bauen