- Akku Tests und Balkonkraftwerk Speicher         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: blockierende funktionen ausschalten

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    36
    Beiträge
    220

    blockierende funktionen ausschalten

    Anzeige

    Praxistest und DIY Projekte
    hallo, gerade ein einfaches programm zum verstehen der blockierenden funktionen geschrieben. der roboter soll beim fahren mit hilfe dem acs und den bumpern hindernissen ausweichen. nur leider tut er das nicht mehr, nachdem einer der bumper gedrückt wird.
    wer kann mir sagen was ich an dem programm verändern muss?
    (dürfte ja an den move bzw. rotate funktionen liegen)



    Code:
     #include "RP6RobotBaseLib.h"     
     void acsStateChanged(void)
     {if(obstacle_left)
    	{writeString_P("Hindernis links\n");
    	moveAtSpeed(100,60);}
    	
    	else if(obstacle_right)
    	{writeString_P("Hindernis rechts\n");
    	moveAtSpeed(60,100);}
    	
    	
    else
    	{moveAtSpeed(80,80);}
    	}
    
    void bumpersStateChanged(void)
    {if(bumper_left)
    	{move(50,BWD,DIST_MM(150),true);
    	rotate(50,RIGHT,90,false);
    	}
    	
    if(bumper_right)
    	{move(50,BWD,DIST_MM(150),true);
    	rotate(50,RIGHT,90,false);
    	}
    }
    
    
    int main(void)
    {initRobotBase();
    ACS_setStateChangedHandler(acsStateChanged);
    powerON();
    setACSPwrMed();
    BUMPERS_setStateChangedHandler(bumpersStateChanged);
    
    while(true)
    {
    task_ACS();
    task_Bumpers();
    task_RP6System();
    
    }
    return 0;
    }
    danke schon mal im voraus

    mfg

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    384
    In ihre main program steht eigentlich nicht was der RP6 machen soll wan da keine Hindernis von ACS/Bumper ist !! Beim Anfang functioniert das einigermasse durch die {moveAtSpeed(80,80);} in der ACSstatechangedhandler. Diese Auftragen laufen weiter wen du das einmal anruft. Einmal der ACS etwas sieht, wird der moveAtSpeed einmal aufgerufen.
    Bei den Bumpertask brauchts du ein {move(50,BWD,DIST_MM(150),true); nach die 150 mm komt dan noch die Rotate mit 90° und dan ist schluss !! Eine neue Move-Auftrag komt nur als der ACS etwas sieht ; dan wird wieder diese ACSstatehandler Function aufgerufen !!
    Besser ist um diese Abfrage in das "Main" teil zu machen, und nicht in diese Handlerfunctionen !!

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    36
    Beiträge
    220
    das muss aber auch anders gehen. wenn du dir zum beispiel das beispielprogramm move5 anschaust, kannst du sehen, dass keine dieser abfragen in den main-teil gemacht wurde.
    es muss also auch anders gehen. die frage ist nur wie?

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Du darfst keine blockierenden Funktionen (nichts länger als ein paar Millisekunden) in den Bumper Event Handler einfügen.
    Das hier: move(50,BWD,DIST_MM(150),true);
    blockiert.
    Bewegungsabläufe (Rückwärtsfahren + Drehen) nach Kollision machst Du am einfachsten komplett OHNE den Event Handler komplett blockierend, oder aber (besser) mit einer Statemachine und Abfrage ob die Bewegung beendet wurde.

    Ohne Event handler - einfach in der Main loop die Bumper Variablen abfragen.
    Aber vorsicht: wenn dann in einem anderen Event Handler auch bewegungsfunktionen aufgerufen werden, müsste das mit einer zusätzlichen Variable gesperrt werden (also "markieren" das da schon jemand die Motoren verwendet).
    Aber das reicht nur für einfache Dinge ... komplexere Sachen macht man dann besser mit Statemachines / Subsumption.

    MfG,
    SlyD

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    36
    Beiträge
    220
    Hallo, ich weiß ich habe damals schon einmal wegen den blockierenden funktionen eine frage gestellt.

    aber jetzt 2 monate später stehe ich wieder vor einem ähnlichen problem.
    mittlerweile habe ich an meinen rp6 einen roboarm mit greifer gebaut.

    vorn am greifer habe ich einen reflexkoppler gebaut, mit welchem der greifer gesteuert wird.

    es funktioniert eigentlich fast alles.

    nur ist es so, dass der rp6 nicht anhält, wenn der reflexkoppler ein teil erkennt.

    ich bin mit ziemlich sicher, dass es an meiner move_At_Speed() funktion liegt.
    nur habe ich keine idee, wie ich dieses problem umgehen kann.

    das fast fertige programm:


    Code:
    #include "RP6RobotBaseLib.h"
    
    uint8_t i;
    uint8_t a;
    uint8_t n;
    uint8_t p;
    uint8_t z;
    
    
    void task_TeilErkannt(void)
    {
    if(PINA & (1<<4))
    	{z=1;
    writeString_P("Teil erkannt\n");}
    else {z=0;
    writeString_P("Kein Teil erkannt\n");}
    
    }
    
    
    
    void task_servo(void)
    {
    
    if(PINA & (1<<4)) // Greifer schließen 
    {
    while(i<52)
    {
    writeString_P("Greifer schließen\n");
    PORTC |=(1<<0);
    mSleep(1);
    PORTC &=~ (1<<0);
    mSleep(19);
    p=0;
    i++;}
    }
    
    
    if(i>50)	// Schwenkarm nach oben
    {
    while(a<52)
    {
    writeString_P("Schwenkarm nach oben\n");
    PORTC |=(1<<1); 
    mSleep(2);
    PORTC &=~ (1<<1);
    mSleep(18);
    i=0;
    a++;}
    }
    
    
    if(a>50) // Greifer öffnen                                      
    {
    while(n<40)
    {
    writeString_P("Greifer öffnen\n");
    PORTC |=(1<<0);
    mSleep(2);
    PORTC &=~ (1<<0);
    mSleep(18);
    setStopwatch1(0);
    a=0;
    n++;}
    
    }
    
    if(n>38) //Schwenkarm wieder nach unten
    {
    while(p<20)
    {
    writeString_P("Schwenkarm wieder nach unten\n");
    PORTC |=(1<<1);
    mSleep(1);
    PORTC &=~ (1<<1);
    mSleep(19);
    n=0;
    p++;}
    }
    
    }
    
    void task_fahren(void)
    {if(z==0)
    	{
    	moveAtSpeed(50,50);}
    	
    	
    else if(z==1)
    	{moveAtSpeed(0,0);}
    
    }
    
    
    int main(void)
    {
    initRobotBase();
    
    DDRC |=(1<<1);		//PORT 1 von Register C als Ausgang für Servo
    DDRC |= (1<<0);	//PORT 0 von Register C als Ausgang für Servo
    DDRA &=~ (1<<4);	//PORT 4 von Register A als Eingang für Reflexkoppler
    
    powerON(); 
    changeDirection(BWD);
    
    
    
    
    
    while(true)
    {task_servo();
    task_TeilErkannt();
    task_fahren();
    task_RP6System();
    }
    return 0;
    }
    hat jemand von euch eine idee?

    danke schon mal im voraus

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    384
    Ich glaube das die While Schleifen die Ursache sein. Sobald der optokoppler etwas sieht, fangen die While Schleifen an von GreiferSteuerung. Da wird nicht anderes mehr gemacht. Nah das alle while Schleifen aggelaufen sind, kommt er in das unterprogram "Task_fahren" und dan wird diese MoveAtSpeed(0,0) activiert, when der Optokopler noch immer etwas sieht.

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    36
    Beiträge
    220
    jetzt hab ich mal das task_TeilErkannt(); aus der while- schleife herausgeholt und ganz normal in die main funktion geschrieben.

    aber der rp6 hält jetzt auch nicht an. es hat sich nichts geändert.

    ich bin mir ja immer noch relativ sicher dass es an dem moveAtSpeed(50,50) liegt. ich glaub das blockiert dann da moveAtSpeed(0,0).

    gruß

  8. #8
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    384
    Setzt du mal auch eine writeString_P(speed50) und writeString_P(speed0) in diese task-fahren. Dann siehst du schon welche MoveAtSpeed ausgefuhrt wird.
    Aber solange den Greifertask lauft, kommt er uberhaupt nicht in das task_fahren.

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    36
    Beiträge
    220
    Jetzt hab ich das Programm einmal nochmal umgeschrieben. Aber ich habe immer noch das gleiche Problem.

    Der RP6 fährt nach wie vor die ganze zeit und bleibt nicht während dem greifen und aufnehmen stehen.

    hier das abgeänderte Programm:

    Code:
    #include "RP6RobotBaseLib.h"
    
    uint8_t i;
    uint8_t a;
    uint8_t n;
    uint8_t p;
    uint8_t z;
    
    
    void task_TeilErkannt(void)
    {
    if(PINA & (1<<4))
    	{z=1;
    writeString_P("Teil erkannt\n");
    mSleep(5000);
    z=0;}
    
    }
    
    
    
    void task_servo(void)
    {
    
    if(PINA & (1<<4)) // Greifer schließen 
    {
    while(i<52)
    {
    writeString_P("Greifer schließen\n");
    PORTC |=(1<<0);
    mSleep(1);
    PORTC &=~ (1<<0);
    mSleep(19);
    p=0;
    i++;}
    }
    
    
    if(i>50)	// Schwenkarm nach oben
    {
    while(a<52)
    {
    writeString_P("Schwenkarm nach oben\n");
    PORTC |=(1<<1); 
    mSleep(2);
    PORTC &=~ (1<<1);
    mSleep(18);
    i=0;
    a++;}
    }
    
    
    if(a>50) // Greifer öffnen                                      
    {
    while(n<40)
    {
    writeString_P("Greifer öffnen\n");
    PORTC |=(1<<0);
    mSleep(2);
    PORTC &=~ (1<<0);
    mSleep(18);
    setStopwatch1(0);
    a=0;
    n++;}
    
    }
    
    if(n>38) //Schwenkarm wieder nach unten
    {
    while(p<20)
    {
    writeString_P("Schwenkarm wieder nach unten\n");
    PORTC |=(1<<1);
    mSleep(1);
    PORTC &=~ (1<<1);
    mSleep(19);
    n=0;
    p++;}
    }
    
    }
    
    void task_fahren(void)
    {if(z==0)
    	{
    	moveAtSpeed(50,50);
    	writeString_P("Fahren\n");}
    else
    	{moveAtSpeed(0,0);
    	writeString_P("Nicht fahren\n");}
    
    }
    
    
    int main(void)
    {
    initRobotBase();
    
    DDRC |=(1<<1);		//PORT 1 von Register C als Ausgang für Servo
    DDRC |= (1<<0);	//PORT 0 von Register C als Ausgang für Servo
    DDRA &=~ (1<<4);	//PORT 4 von Register A als Eingang für Reflexkoppler
    
    powerON(); 
    changeDirection(BWD);
    task_TeilErkannt();
    
    
    
    
    while(true)
    {task_servo();
    
    task_fahren();
    task_RP6System();
    }
    return 0;
    }
    Wer kann mir sagen an was das liegt?

    gruß

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    36
    Beiträge
    220
    kann mir denn niemand sagen an was das liegt?

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad