- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 64

Thema: fahrzeug mit vier motoren und vier encodern

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von inka
    Registriert seit
    29.10.2006
    Ort
    nahe Dresden
    Alter
    77
    Beiträge
    2.180
    hallo botty,
    Zitat Zitat von botty Beitrag anzeigen
    solltest Du momentan diese Variante
    Code:
    void alle_stepper_vorwaerts()
    {
    
    
      hindernis_vorh();
      if (hindernis == true)
      {
         Serial.print("hindernisabfrage in - alle_stepper_vorwärts -");
         alle_stepper_rueckwaerts();
      }
      // !!! Im Fall das hinderniss == false ist führt das zu einer Rekursion ohne Widerkehr !!!
      else alle_stepper_vorwaerts();
    
    
      
      vorwaerts = true;
      stepper_VL.setRPM(12);
      stepper_HL.setRPM(12);
      stepper_HR.setRPM(12);
      stepper_VR.setRPM(12);
    
    
      stepper_VL.setSPR(4075.7728395);
      stepper_HL.setSPR(4075.7728395);
      stepper_HR.setSPR(4075.7728395);
      stepper_VR.setSPR(4075.7728395);
    
    
      stepper_VL.setDirection(CW);
      stepper_VL.rotate(1);
      stepper_HL.setDirection(CW);
      stepper_HL.rotate(1);
      stepper_HR.setDirection(CW);
      stepper_HR.rotate(1);
      stepper_VR.setDirection(CW);
      stepper_VR.rotate(1);
      //vorwaerts = true;
    }
    
    
    void alle_stepper_rueckwaerts()
    {
      Serial.print("fahre rückwärts nach hindernisabfrage in - alle_stepper_vorwärts -");
      rueckwaerts = true;
      stepper_VL.setRPM(12);
      stepper_HL.setRPM(12);
      stepper_HR.setRPM(12);
      stepper_VR.setRPM(12);
    
    
      stepper_VL.setSPR(4075.7728395);
      stepper_HL.setSPR(4075.7728395);
      stepper_HR.setSPR(4075.7728395);
      stepper_VR.setSPR(4075.7728395);
    
    
      stepper_VL.setDirection(CCW);
      stepper_VL.rotate(1);
      stepper_HL.setDirection(CCW);
      stepper_HL.rotate(1);
      stepper_HR.setDirection(CCW);
      stepper_HR.rotate(1);
      stepper_VR.setDirection(CCW);
      stepper_VR.rotate(1);
      //rueckwaerts = true;
    }
    im Einsatz haben,
    nein habe ich nicht...

    Zitat Zitat von botty Beitrag anzeigen
    Falls Du noch die NewPing lib benutzt gibt es bei "ping()" einen Sonderfall zu berücksichtigen:

    ........Daher muß eine weitere Abfrage da hinein:
    Code:
    void hindernis_vorh(void)
    {
      if (start_ping == false) ping_distanz();
    
    
      if(uS > 0) 
    {
        if (((uS / US_ROUNDTRIP_CM) <= 10))
          hindernis = true;
      } else {
          hindernis = false;
      }
    }
    habe ich berücksichtigt, danke für den tipp...

    - - - Aktualisiert - - -

    hi botty,

    ich habe jetzt eine einigermassen funktionierende version in der ich ein paar sachen die Du hier erwähnst auch schon drin habe:

    - das delay(500) im ping distanz habe ich entfernt, geht auch ohne
    - die schleife do - while bei dem run() der Stepper habe ich eingefügt, meine aber das wäre doppelt gemoppelt hier, oder?

    der roboter:
    - prüft erstmal ob vor ihm ein hindernis ist
    - fährt entsprechend nach vorne, oder zurück
    - nach vorne arbeitet er die (zunächstmal vorgegeben kommandor links, rechts usw) ab
    - nach hindernis wird immer nur im voraus geprüft, ausgewichen nach links (warum auch immer)

    hier der code (habe auch einen ohne "enum, idx" und was sonst noch zu der elegenteren lösung gehört "

    Code:
    #include <CustomStepper.h>
    #include <NewPing.h>
    
    
    #define TRIGGER_PIN  8  // Arduino pin tied to trigger pin on the ultrasonic sensor. //12
    #define ECHO_PIN     7  // Arduino pin tied to echo pin on the ultrasonic sensor. //11
    #define MAX_DISTANCE 400 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
    
    
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
    
    
    uint8_t idx;
    uint16_t distanz;
    uint16_t uS;
    //uint8_t hindernis, start_ping;
    
    
    
    
    enum stepper_e
    { stepper_VL, stepper_HL, stepper_VR, stepper_HR, stepper_MAX };
    
    
    
    
    CustomStepper stepper[stepper_MAX]
    {
      CustomStepper(23, 25, 27, 29),
      CustomStepper(31, 33, 35, 37),
      CustomStepper(47, 49, 51, 53),
      CustomStepper(46, 48, 50, 52)
    };
    
    
    
    
    boolean rotate_li;
    boolean rotate_deg_li;
    boolean rotate_re;
    boolean rotate_deg_re;
    boolean vorwaerts;
    boolean rueckwaerts;
    boolean start_ping;
    boolean hindernis;
    boolean stepper_stop;
    
    
    void setup()
    {
    
    
      rotate_li = false;
      rotate_deg_li = false;
      rotate_re = false;
      rotate_deg_re = false;
      vorwaerts = false;
      rueckwaerts = false;
      start_ping = false;
      hindernis = false;
      stepper_stop = false;
    
    
      Serial.begin(115200);
      Serial.println("setup_ende");
    }
    
    
    void loop()
    {
    
    
      hindernis_vorh();
      /****************************************/
      for (idx = stepper_VL; idx < stepper_MAX; idx++)
      {
        if (stepper[idx].isDone() &&  rueckwaerts == false && hindernis == true)
        {
          Serial.println("start - Stepper rückwärts- if-abfrage_1");
          alle_stepper_rueckwaerts();
    
    
        }
        else if (stepper[idx].isDone() &&  vorwaerts == false && hindernis == false)
        {
          Serial.println("start - Stepper vorwärts- else-abfrage_1");
          alle_stepper_vorwaerts();
    
    
        }
      }
      /*************************************/
    
    
      for (idx = stepper_VL; idx < stepper_MAX; idx++)
      {
        if (stepper[idx].isDone() &&  rueckwaerts == true && rotate_li == false)
        {
          Serial.println("loop - rotiere_links - if-abfrage_2");
          rotieren_links();
        }
      }
    
    
    
    
    
    
      for (idx = stepper_VL; idx < stepper_MAX; idx++)
      {
        if (stepper[idx].isDone() &&  rotate_li == true && vorwaerts == false)
        {
          Serial.println("loop - alle_stepper_vorwärts - if-abfrage_3");
          alle_stepper_vorwaerts();
        }
      }
    
    
    
    
      for (idx = stepper_VL; idx < stepper_MAX; idx++)
      {
        if (stepper[idx].isDone() &&  vorwaerts == true && rotate_re == false)
        {
          Serial.println("loop - rotiere_rechts - if-abfrage_4");
          rotieren_rechts();
        }
    
    
      }
    
    
      for (idx = stepper_VL; idx < stepper_MAX; idx++)
      {
        if (stepper[idx].isDone() &&  rotate_re == true && vorwaerts == true)
        {
          Serial.println("loop - alle_stepper_vorwärts - if-abfrage_5");
          alle_stepper_vorwaerts();
        }
      }
    
    
      /*****************************************/
      do
      {
        for (idx = stepper_VL; idx < stepper_MAX; idx++)
        {
          stepper[idx].run();
        }
      } while ( ! (stepper[idx].isDone()));
    }
    
    
    /***********************************************************/
    
    
    
    
    void ping_distanz(void)
    {
      //delay(500);// Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
      uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
      Serial.print("Ping: ");
      Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)
      Serial.println(" cm");
      start_ping = true;
    }
    
    
    
    
    void hindernis_vorh(void)
    {
      if (start_ping == false) ping_distanz();
      if (uS > 0)
      {
        if (((uS / US_ROUNDTRIP_CM) <= 10))
          hindernis = true;
      } else
      {
        hindernis = false;
      }
    }
    void alle_stepper_stop()
    {
      stepper_stop = true;
      for (idx = stepper_VL; idx < stepper_MAX; idx++)
      {
        stepper[idx].setRPM(0);
        stepper[idx].setSPR(4075.7728395);
        stepper[idx].setDirection(STOP);
      }
    }
    
    
    
    
    void alle_stepper_vorwaerts(void)
    {
      if (start_ping == true) ping_distanz();
      //Serial.print(hindernis);
      if (hindernis == true)
      {
        rueckwaerts = true;
    
    
        Serial.print(hindernis);
        Serial.println("  hindernis - true - alle_stepper_rückwärts - if-abfrage_6");
        hindernis = false;
        //alle_stepper_rueckwaerts();
    
    
        for (idx = stepper_VL; idx < stepper_MAX; idx++)
        {
          stepper[idx].setRPM(12);
          stepper[idx].setSPR(4075.7728395);
          stepper[idx].setDirection(CCW);
          stepper[idx].rotate(1);
        }
    
    
      }
      else
      {
        vorwaerts = true;
    
    
        for (idx = stepper_VL; idx < stepper_MAX; idx++)
        {
          stepper[idx].setRPM(12);
          stepper[idx].setSPR(4075.7728395);
          stepper[idx].setDirection(CW);
          stepper[idx].rotate(1);
        }
      }
    }
    
    
    
    
    
    
    void alle_stepper_rueckwaerts(void)
    {
      rueckwaerts = true;
    
    
      for (idx = stepper_VL; idx < stepper_MAX; idx++)
      {
        stepper[idx].setRPM(12);
        stepper[idx].setSPR(4075.7728395);
        stepper[idx].setDirection(CCW);
        stepper[idx].rotate(1);
      }
    }
    
    
    
    
    void rotieren_links(void)
    {
      rotate_li = true;
    
    
      for (idx = stepper_VL; idx < stepper_VR; idx++)
      {
        stepper[idx].setRPM(12);
        stepper[idx].setSPR(4075.7728395);
        stepper[idx].setDirection(CCW);
        stepper[idx].rotate(1);
      }
    
    
      for (idx = stepper_VR; idx < stepper_MAX; idx++)
      {
        stepper[idx].setRPM(12);
        stepper[idx].setSPR(4075.7728395);
        stepper[idx].setDirection(CW);
        stepper[idx].rotate(1);
      }
    }
    
    
    
    
    void rotieren_rechts(void)
    {
    
    
      rotate_re = true;
    
    
      for (idx = stepper_VL; idx < stepper_VR; idx++)
      {
        stepper[idx].setRPM(12);
        stepper[idx].setSPR(4075.7728395);
        stepper[idx].setDirection(CW);
        stepper[idx].rotate(1);
      }
    
    
      for (idx = stepper_VR; idx < stepper_MAX; idx++)
      {
        stepper[idx].setRPM(12);
        stepper[idx].setSPR(4075.7728395);
        stepper[idx].setDirection(CCW);
        stepper[idx].rotate(1);
      }
    }
    Zitat Zitat von botty Beitrag anzeigen
    Die NewPing-Lib stellt Dir die Funktion "ping()" zur Verfügung, leider blockiert die das System, kommt also nicht in Frage.
    Statt dessen müssen wir "ping_timer()" und "check_timer()" benutzen.
    hier stellt sich mir die frage warum ist es ein problem, wenn - hier sogar beide wesentlichen funktionen - ping() und run() der Stepper blockierend sind? Der roboter fährt, sogar recht zügig, misst zwischendurch und weicht auch hindernissen aus, wo ist das problem? Kannst Du es mir bitte erklären?
    In einem würde ich Dir recht geben: Der roboter fährt nach der messung seine strecke die er vorgegeben bekommen hat noch ab, bleibt also noch der fsetstellung - da vorne ist ein hindernis - nicht sofort stehen. Das kann man aber über die gemessene entfernung lösen, oder?


    Zitat Zitat von botty Beitrag anzeigen
    Ein anderes Beispiel findest Du sonst noch https://bitbucket.org/teckel12/ardui...ping/wiki/Home in der Mitte ist ein Beispiel das den Callback-Mechanismus benutzt aber eine globale Variable verwendet,wovon ich kein Freund bin.
    das muss ich noch lesen...
    gruß inka

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    Grüß Dich inka,

    ich fange mal Hinten an.

    "ping()" würde "run()" blockieren, nicht umgekehrt. die "run()" Funktionen müssen nachdem die Stepper konfiguriert sind immer wieder aufgerufen werden und das so schnell wie möglich, sonst hakt es.

    Sowie Du Dein Programm aufgebaut hast, gibt's zwei kritische Dinge zu beachten:
    Nachdem Du "gepingt" hast, fährst Du los. Wenn jetzt plötzlich etwas vor dem Roboter auftaucht - Eure Katze, Deine Füße oder die Schienbeine Deiner Liebsten - bekommt das das System nicht mit, sondern fährt einfach weiter - schlimmstenfalls "Aua" .
    Das andere Problem hast Du schon richtig erkannt, die gemessene Distanz vom Sensor muss größer sein als der Fahrweg.
    Du legst im Moment bei gerade Fahren immer eine Umdrehung zwischen den "pings" zurück. Dein Grenzwert zum potentiellen Hinderniss sind aktuell 10cm. Das ist zu wenig, denn ich schätze Dein Raddurchmesser wird größer als 10cm/pi sein, oder?
    Rechne mal nach Raddurchmesser * pi - dann muss "hindernis_vorh()" so aussehen:
    Code:
    {
      if (start_ping == false) ping_distanz();
    
    
      if(uS != NO_ECHO) 
    {
        /* richtige Werte einsetzen */
        if (((uS / US_ROUNDTRIP_CM) <= (Raddurchmesser * M_PI))
          hindernis = true;
      } else {
          hindernis = false;
      }
    }
    eine weitere Möglichkeit wäre statt "rotate(1)" "rotateDegrees(180)" oder mit anderen Werten kleinere Schritte zu machen. Das könnte dann zum Stottern führen. Momentan, vermute ich, bewegt die Trägheit den Robbi während des "pings" weiter, so das man das mit bloßem Auge nicht wahr nimmt. Einfach mal kleinere Werte mit "rotateDegrees()" ausprobieren.

    Zum Thema "do{...}while()" und "doppelt gemoppelt":
    Deine "loop()" sah auszugsweise so aus:
    Code:
    void loop() {
    
        if (stepper[idx].isDone() &&  rueckwaerts == false && hindernis == true)
        {
          Serial.println("start - Stepper rückwärts- if-abfrage_1");
          alle_stepper_rueckwaerts();
    
    
        }
        else if (stepper[idx].isDone() &&  vorwaerts == false && hindernis == false)
        {
          Serial.println("start - Stepper vorwärts- else-abfrage_1");
          alle_stepper_vorwaerts();
    
    
        }
    
    // andere if's
    
        for (idx = stepper_VL; idx < stepper_MAX; idx++)
        {
          stepper[idx].run();
        }
     }
    Du testes zwangsweise am Anfang immer ab, ob die Stepper schon das letzte Kommando ausgeführt haben oder nicht.
    Dadurch mischt Du inhaltlich "Sind die Stepper fertig?" mit "Wie wähle ich das nächste Kommando aus?".
    Führst Du jetzt die innere Schleife ein egal ob "while(){}" oder "do{...}while()":
    Code:
    void loop() {
    
        // Kommando Auswahl treffen
        if (rueckwaerts == false && hindernis == true)
        {
          Serial.println("start - Stepper rückwärts- if-abfrage_1");
          alle_stepper_rueckwaerts();
    
    
        }
        else if (vorwaerts == false && hindernis == false)
        {
          Serial.println("start - Stepper vorwärts- else-abfrage_1");
          alle_stepper_vorwaerts();
    
    
        }
    
    // andere if's
    
        // Stepper ausführen lassen
        // Es muessen alle Stepper gleichzeitig getestet werden, sonst ist's falsch!
        while( ! (stepper[stepper_VL].isDone() && stepper[stepper_HL].isDone() 
                    && stepper[stepper_VR].isDone() && stepper[stepper_HR].isDone() ) )
        {
           for (idx = stepper_VL; idx < stepper_MAX; idx++)
          {
            stepper[idx].run();
          }
        }
     }
    dann ist nach der inneren Schleife und vor dem nächsten "loop()" Ablauf absolut sicher, dass die Stepper ihre angewiesene Arbeit getan haben.
    Dadurch reduzieren sich Deine "if()" Ausdrücke, die sich nur noch mit der Auswahl beschäftigen und sind meiner Meinung nach einfacher lesbar.
    Das Konzept der CustomStepper-Lib basiert darauf 1) die Stepper zu konfigurieren was sie tun sollen "rotate()", "setDirection()" etc. und dann 2) sie solange mit "run()" in Schwung zu halten, bis "isDone()" wahr wird. Genau das spiegelt sich in letzterem Aufbau wieder.
    Ich hoffe ich hab's verständlich erklärt?

    Gruß

    Chris

Ähnliche Themen

  1. Vier PWM-Lüfter steuern
    Von Bammer im Forum AVR Hardwarethemen
    Antworten: 22
    Letzter Beitrag: 22.10.2010, 10:21
  2. Vier Servos steuern
    Von Brantiko im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 10
    Letzter Beitrag: 14.04.2008, 23:17
  3. Wie vier Motoren ansteuern???
    Von cinhcet im Forum Bauanleitungen, Schaltungen & Software nach RoboterNetz-Standard
    Antworten: 9
    Letzter Beitrag: 29.06.2006, 12:37
  4. vier L297 und VREF
    Von schmek im Forum Elektronik
    Antworten: 1
    Letzter Beitrag: 01.12.2005, 19:47
  5. Bot mit vier Rädern
    Von themaddin im Forum Mechanik
    Antworten: 17
    Letzter Beitrag: 06.11.2005, 21:39

Berechtigungen

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

12V Akku bauen