-         

Ergebnis 1 bis 10 von 10

Thema: nette sonntagsaufgabe: fehler im programm...

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    22.04.2008
    Ort
    Frankfurt
    Alter
    35
    Beiträge
    68

    nette sonntagsaufgabe: fehler im programm...

    Anzeige

    Hallo Freunde!

    Seit ca. 2 Wochen bin ich jetzt stolzer Besitzer des RP6 und hatte ja schon seit Anfang an die Idee, meinen Roboter per RS232 zu steuern. Der "Server" läuft jedoch nicht auf dem PC, sondern auf einem modifizierten Fonera Router. Die Verbindung steht, erste Lenkversuche haben auch geklappt. Jetzt haben wir uns eine Gui zusammengebaut, die auch noch verschiedene Informationen (Bumper gedrückt, Obstacles in Sicht, Motorgeschwindigkeit) vom Roboter anfragt und geliefert bekommt. Nur jetzt haben wir angefangen, eben auch mit diesen Daten zu arbeiten und da liegt das Problem, bei zu vielen Anfragen verschluckt sich der RP6 anscheinend und schickt komische Dinge.

    Zum Testen verbinde ich mich mit Telnet auf den Server, der auf der Fonera läuft und sende Commands. Die Fonera leitet diese Befehle an den RP6 über seriell weiter und erhält Antworten, die natürlich zurück zu telnet geschickt werden. commands fangen immer mit einem $ an und schließen mit einem &. alles andere wird vom server verworfen, auch auf dem RP6 schaue ich nicht nach dem absatz als endzeichen, sondern auf das &! Hier ein Beispiel was passiert:

    Code:
    $START& //startet das programm auf dem rp6
    Starting RP6 Program! //rückgabe
    $Q|ALL& //messwerte werden angefragt
    $M|BL:0|BR:0|LDRL:798|LDRR:907|UBAT:830|OL:0|OR:0|ML:0|MR:0& //antwort
    $Q|ALL& //messwerte werden angefragt
    $M|BL:0|BR:0|LDRL:801|LDRR:909|UBAT:830|OL:0|OR:0|ML:0|MR:0& //antwort
    $D|BU& // motorspeed soll um 10 erhöht werden
    $M|BL:0|BR:0|LDRL:802|LDRR:910|UBAT:830|OL:0|OR:0|ML:0|MR:0& // messwerte kommen an, aber motorspeed wird trotzdem erhöht!
    $D|BU& // noch mal motorspeed erhöhen
    $OK& // aknowledge, also speed wurde erhöht
    $Q|ALL& // messwerte anfragen
    $Q|ALL& // keine antwort, noch mal anfragen
    $Q|ALL& // immer noch nix, noch mal anfragen
    $M|BL:0|BR:0|LDRL:811|LDRR:912|UBAT:826|OL:0|OR:0|ML:10|MR:10& // antwort
    $D|STOP& // alles stoppen
    $M|BL:0|BR:0|LDRL:811|LDRR:912|UBAT:826|OL:0|OR:0|ML:10|MR:10& // schon wieder kommen die messwerte an, aber rp6 stoppt trotzdem!
    irgendwie scheint der buffer auf dem rp6 komische sachen zu speichern und zu verschicken. die befehle kommen auf jeden fall an, aber die antwort ist falsch.

    Ich komme einfach nicht mehr weiter. seit 2-3 Tagen Suche in intensiv nach dem Fehler aber ich kann den Code schon nicht mehr sehen. Ich bin mir ziemlich sicher, das der Fehler irgendwo im Programm auf dem RP6 zu suchen ist, da der Server auf der Fonera eigentlich, meiner Meinung nach, alles richtig macht.

    Es wäre toll, wenn ihr mal einen Blick darauf werfen könntet, vielleicht fällt jemanden etwas auf. Den Server habe ich angehängt.

    MfG
    Andieh

    Code:
    #include "RP6RobotBaseLib.h"
    
    
    // returns max value from to integer
    int max(int number1, int number2)
    {
    	if ( number1 > number2) return number1;
    	else return number2;
    }
    
    /*****************************************************************************/
    
    // Main function - The program starts here:
    
    
    
    int main(void)
    
    {
    	int DIR_LEFT = 0; // 0 nothing, 1 FWD, -1 BWD
    	int DIR_RIGHT = 0; // 0 nothing, 1 FWD, -1 BWD
    	int M_SPEED_L = 0;
    	int M_SPEED_R = 0;
    	int SPEED_STEP = 10;
    	
    
    	initRobotBase();
    	 
    
    	powerON();
    	setACSPwrHigh();
    	clearReceptionBuffer();
    	
    	// ---------------------------------------
    
    	// Main loop:
    	
    	uint8_t buffer_pos = 0;
    	int charsToReceive = 50;
    	char receiveBuffer[charsToReceive+1];
    	int send = 0;
    
    	while(true)
    
    	{
    		if(getBufferLength())    // Check if we still have data (means getBufferLength() is not zero)	
    		{
    			receiveBuffer[buffer_pos] = readChar(); // get next character from reception buffer
    			if(receiveBuffer[buffer_pos]=='&') // End of line detected!
    			{
    
    				receiveBuffer[buffer_pos+1]='\0'; // Terminate String with a 0, so other routines can determine where it ends!
    			
    				buffer_pos = -1;
    				clearReceptionBuffer();
    			}
    
    			else if(buffer_pos >= charsToReceive) // IMPORTANT: We can not receive more characters than "charsToReceive"
    			{
    				receiveBuffer[charsToReceive]='\0';	// So if we receive more characters, we just stop reception and terminate the String.
    				writeString_P("$You entered more characters than possible!%\n");
    			}
    
    			buffer_pos++;
    
    			
    
    		}	
    					
    					
    		// try to find something useful information in the 
    		// received string
    		
    		// TODO: check if string starts with $ and ends with &
    		
    		// read all values
    		else if (strncmp("$Q|ALL",receiveBuffer,6) == 0) {
    			int BL = getBumperLeft();
    			int BR = getBumperRight();
    			int OL = isObstacleLeft();
    			int OR = isObstacleRight();
    			char sendValues[85]; 
    			memset(sendValues, '\0', sizeof(sendValues) );
    				
    			sprintf(sendValues,"$M|BL:%d|BR:%d|LDRL:%d|LDRR:%d|UBAT:%d|OL:%d|OR:%d|ML:%d|MR:%d&",BL,BR,adcLSL,adcLSR,adcBat,OL,OR,M_SPEED_L,M_SPEED_R);
    			writeString(sendValues);
    
    			send = 1;
    		}
    				
    		// move forward
    		else if (strncmp("$D|FWD", receiveBuffer,6) == 0) {
    			if ( DIR_LEFT == -1 || DIR_RIGHT == -1 )
    				stop();
    				
    			setMotorDir(FWD,FWD);
    			if ( M_SPEED_L != M_SPEED_R) {
    				M_SPEED_L = max(M_SPEED_L,M_SPEED_R);
    				M_SPEED_R = max(M_SPEED_L,M_SPEED_R);
    			}
    			moveAtSpeed(M_SPEED_L,M_SPEED_R);  
    			DIR_LEFT = 1; DIR_RIGHT = 1;
    			writeString_P("$OK&");
    			send = 1;
    		}
    
    		// move backwards
    		else if (strncmp("$D|BWD", receiveBuffer,6) == 0) {
    			if ( DIR_LEFT == 1 || DIR_RIGHT == 1 )
    				stop();
    				
    			setMotorDir(BWD,BWD);
    			if ( M_SPEED_L != M_SPEED_R) {
    				M_SPEED_L = max(M_SPEED_L,M_SPEED_R);
    				M_SPEED_R = max(M_SPEED_L,M_SPEED_R);
    			}
    			moveAtSpeed(M_SPEED_L,M_SPEED_R);
    			DIR_LEFT = -1; DIR_RIGHT = -1;  
    			writeString_P("$OK&");
    			send = 1;
    		}
    		
    		// turn left
    		else if (strncmp("$D|LEFT", receiveBuffer,7) == 0) {
    			if ( DIR_LEFT == 1 || DIR_RIGHT == -1 )
    				stop();
    			setMotorDir(BWD,FWD);
    			moveAtSpeed(60,60);
    			DIR_LEFT = -1; DIR_RIGHT = 1;  
    			writeString_P("$OK&");
    			send = 1;
    		}
    		
    		// turn right
    		else if (strncmp("$D|RIGHT", receiveBuffer,8) == 0) {
    			if ( DIR_LEFT == -1 || DIR_RIGHT == 1 )
    				stop();
    			setMotorDir(FWD,BWD);
    			moveAtSpeed(60,60);
    			DIR_LEFT = 1; DIR_RIGHT = -1;  
    			writeString_P("$OK&");
    			send = 1;
    		}
    		
    		// stop
    		else if (strncmp("$D|STOP", receiveBuffer,7) == 0) {
    			stop();
    			M_SPEED_L = 0;
    			M_SPEED_R = 0;
    			writeString_P("$OK&");
    			send = 1;
    		}
    		
    		// increase motorspeed
    		else if (strncmp("$D|BU", receiveBuffer, 5) == 0) {
    			if (M_SPEED_L <= (200 - SPEED_STEP) && M_SPEED_R <= (200 - SPEED_STEP)) {
    				M_SPEED_L += SPEED_STEP;
    				M_SPEED_R += SPEED_STEP;
    			}
    			moveAtSpeed(M_SPEED_L,M_SPEED_R);
    			writeString_P("$OK&");
    			send = 1;
    		}
    			
    		// decrease motorspeed
    		else if (strncmp("$D|BD", receiveBuffer, 5) == 0) {
    			if (M_SPEED_L >= SPEED_STEP && M_SPEED_R >= SPEED_STEP) {
    				M_SPEED_L -= SPEED_STEP;
    				M_SPEED_R -= SPEED_STEP;
    			}
    			moveAtSpeed(M_SPEED_L,M_SPEED_R);
    			writeString_P("$OK&");
    			send = 1;
    		}
    		
    		// increase left motorspeed
    		else if (strncmp("$D|LU", receiveBuffer, 5) == 0) {
    			if (M_SPEED_L <= (200 - SPEED_STEP)) M_SPEED_L += SPEED_STEP;
    			moveAtSpeed(M_SPEED_L, M_SPEED_R);
    			writeString_P("$OK&");
    			send = 1;
    		}
    		
    		// increase right motorspeed
    		else if (strncmp("$D|RU", receiveBuffer, 5) == 0) {
    			if (M_SPEED_R <= (200 - SPEED_STEP)) M_SPEED_R += SPEED_STEP;
    			moveAtSpeed(M_SPEED_L, M_SPEED_R);
    			writeString_P("$OK&");
    			send = 1;
    		}
    		
    		// decrease left motorspeed
    		else if (strncmp("$D|LD", receiveBuffer, 5) == 0) {
    			if (M_SPEED_L >= SPEED_STEP) M_SPEED_L -= SPEED_STEP;
    			moveAtSpeed(M_SPEED_L, M_SPEED_R);
    			writeString_P("$OK&");
    			send = 1;
    		}
    		
    		// decrease right motorspeed
    		else if (strncmp("$D|RD", receiveBuffer, 5) == 0) {
    			if (M_SPEED_R >= SPEED_STEP) M_SPEED_R -= SPEED_STEP;
    			moveAtSpeed(M_SPEED_L, M_SPEED_R);
    			writeString_P("$OK&");
    			send = 1;
    		}
    		
    		// set motorspeed to default value
    		else if (strncmp("$D|DEFAULT", receiveBuffer, 10) == 0) {
    			M_SPEED_L = 80;
    			M_SPEED_R = 80;
    			writeString_P("$OK&");			
    			send = 1;
    		}
    		
    		// nothing detected, set send to 0
    		else send = 0;
    		
    		// if something was send, clear receiveBuffer
    		if (send) {
    			memset(receiveBuffer, '\0', charsToReceive);
    			for(uint8_t cnt = 0; cnt < charsToReceive; cnt++)
    
    				receiveBuffer[cnt]=0;
    		}
    		
    	task_RP6System();
    		
    
    	}
    
    	// End of main loop!
    
    	// ---------------------------------------
    
    
    
    	return 0;
    
    }
    Angehängte Dateien Angehängte Dateien

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo,

    vielleicht wird der Empfangsbuffer beim RP6 nicht richtig geleert/gelöscht:
    http://www.roboternetz.de/phpBB2/viewtopic.php?t=43254

    Bei Telegrammen die über ein Netzwerk laufen könnte sich deren Reihenfolge ändern weil sich die Datenpakete gegenseitig überholen können. Erkennen kann man das z.B. über eine fortlaufende Sequenznummer die von beiden Partnern im Wechsel hochgezählt wird. Zum Debuggen könnte der RP6 auch das jeweilige Komando an seine Antwort anhängen.

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    Moin,

    hab mir den Code nur ne halbe Minute lang angesehen - was mir aber zusätzlich zu dem was Radbruch sagt sofort ins Auge gefallen ist ist das hier:

    char sendValues[85];
    memset(sendValues, '\0', sizeof(sendValues) );
    sprintf(sendValues,"$M|BL:%d|BR:%d|LDRL:%d|LDRR:%d |UBAT:%d|OL:%d|OR:%d|ML:%d|MR:%d&",BL,BR,adcLSL,ad cLSR,adcBat,OL,OR,M_SPEED_L,M_SPEED_R);
    writeString(sendValues);

    Könnte durchaus sein, das hier mal ein Pointer ausbüchst und Dir anderswo den Speicher überschreibt. Oder der Stack läuft über - der String da oben ist ja
    schon recht komplex. Auf jeden Fall musst Du das weiter aufsplitten.

    Versuchs am besten mal komplett ohne sprintf und memset.
    Mach es genauso wie im RP6 Selftest Programm mit writeInteger usw.

    MfG,
    SlyD

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    22.04.2008
    Ort
    Frankfurt
    Alter
    35
    Beiträge
    68
    Danke SylD und radbruch für die schnellen Antworten.

    Ich habe den langen String einfach mal rausgenommen und einfach nur einen konstanten String zurückgeschickt, aber auch das ändert nichts. Also glaube ich nicht daran, dass es daran liegt. Ich hatte sogar am Anfang diese Sache so gelöst, dann sind aber voll oft bestimmte Teile gar nicht erst angekommen, das war keine gute Lösung.

    Und zu deinen Tipps radbruch: Ich habe das ganze Prinzip von dem Buffer noch gar nicht so geblickt. Da muss ich mich wohl noch eine weile einlesen.

    Aber danke schon mal, ich werde es weiter probieren!

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    22.04.2008
    Ort
    Frankfurt
    Alter
    35
    Beiträge
    68
    So, wieder etwas weiter probiert.
    Problem ist auf jeden Fall, das der Server auf der Fonera eine Anfrage an den RP6 schickt und sofort auf eine Antwort wartet. So schnell ist der RP6 aber gar nicht, und deshalb geht eine Anfrage quasi ins "leere" und erst beim nächsten Mal wird das richtige Ergebnis übermittelt.

    Habe mit verschiedenen Wartezeiten zwischen Senden und Empfangen gespielt, 10 ms scheinen zu kurz, bei 20 ms klappen zumindest die Aknowledges der Richtungswechsel. Aber das Sammeln aller Messwerte auf dem RP6 scheint wohl noch länger zu dauern. Und allgemein scheint mir diese Möglichkeit als sehr stümperhaft.

    Habt ihr da eine andere Idee, wie man das lösen könnte?

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    16.11.2008
    Ort
    Frankfurt
    Alter
    33
    Beiträge
    21
    Wir haben das Problem übrigens mittlerweile gelöst, es lag wohl daran, dass die übertragungsgeschwindigkeiten vom rp6 zum router ziemlich schwanken..
    Haben es jetzt so gelöst, dass wir eine empfangsschleife auf dem router laufen lassen, die erst abbricht, wenn wir das Endzeichen von unserem Protokoll bekommen. Es fällt auf, dass der RP6 den langen String von oben manchmal komplett auf einmal schickt, jedoch meistens in zwei "Sendungen" aufteilt..
    Naja, mittlerweile funktioniert alles, sogar in ausreichender Geschwindigkeit, um den noch ordentlich steuern zu können.

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    06.12.2008
    Alter
    23
    Beiträge
    24
    Hallo
    Ich habe ein Programm zum Linienfolgen geschrieben und irgendeinen Fehler gemacht,den ich aber nicht finde und ich wollte jetzt kein neues Thema aufmachen, da hab ich mal das hier genommen.


    Hier der Code:
    Code:
    /*****************************************************************************/
    // Includes:
    
    #include "RP6RobotBaseLib.h" 	
    
    /*****************************************************************************/
    //Declarations
    
    uint8_t x = 0;
    
    /*****************************************************************************/
    //functions
    void drive_FWD(void)
    {
    moveAtSpeed(50,50);
    }
    
    void drive_LEFT(void)
    {
    moveAtSpeed(40,60);
    }
    
    void drive_RIGHT(void)
    {
    moveAtSpeed(60,40);
    }
    
    int ADC(void)
    {
    	if((adc0 >= 1000) && (adc1 >= 1000))
    	{
    	x = 1;
    	}
    	if((adc0 < 1000) && (adc1 >= 1000))
    	{
    	x = 2;
    	}
    	if((adc0 >= 1000) && (adc1 < 1000))
    	{
    	x = 3;
    	}
    }
    
    void ADC_Case(void)
    {
    switch(x)
    	{
    	case 1: drive_FWD(); break;
    	case 2: drive_RIGHT(); break;
    	case 3: drive_LEFT(); break;
    	}
    }
    
    /*****************************************************************************/
    // Main:
    
    int main(void)
    {
    	initRobotBase(); 
    	
    	while(true) 
    	{
    	ADC();
    	ADC_Case();
    	task_RP6System();
    	}
    	return 0;
    }

    und die Fehlermeldung:
    Code:
    > "D:\Florian\Roboter\RP6BASE_EXAMPLES\linie_test_02\\make_all.bat" 
    
    D:\Florian\Roboter\RP6BASE_EXAMPLES\linie_test_02>set LANG=C 
    
    D:\Florian\Roboter\RP6BASE_EXAMPLES\linie_test_02>make all 
    
    -------- begin --------
    avr-gcc (GCC) 4.1.1 (WinAVR 20070122)
    Copyright (C) 2006 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.
    
    
    Compiling: RP6Base_Move_04_FSM.c
    avr-gcc -c -mmcu=atmega32 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=RP6Base_Move_04_FSM.lst -I../../RP6Lib -I../../RP6Lib/RP6base -I../../RP6Lib/RP6common -std=gnu99 -MD -MP -MF .dep/RP6Base_Move_04_FSM.o.d RP6Base_Move_04_FSM.c -o RP6Base_Move_04_FSM.o
    RP6Base_Move_04_FSM.c:29: error: expected identifier or '(' before 'volatile'
    RP6Base_Move_04_FSM.c:29: error: expected ')' before '(' token
    RP6Base_Move_04_FSM.c: In function 'main':
    RP6Base_Move_04_FSM.c:64: error: called object '*36u' is not a function
    make: *** [RP6Base_Move_04_FSM.o] Error 1
    
    > Process Exit Code: 2

  8. #8
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    Ich weiss zwar nicht wie der Compiler auf diese Fehlermeldung kommt, aber:
    int ADC(void)

    die Funktion gibt aber nichts zurück (kein return xyz; am Ende).
    Also void davorschreiben anstatt int.

    MfG,
    SlyD

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    48
    Beiträge
    524
    Hallo,

    das ist nicht der passende Code.

    Gruß

    Jens

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    06.12.2008
    Alter
    23
    Beiträge
    24
    Nicht der passende Code?
    naja egal...hab den fehler gefunden

Berechtigungen

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