-         

Ergebnis 1 bis 7 von 7

Thema: links/rechts Antriebverhältnis für Kreisbogenfahrt

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    24.03.2009
    Ort
    Rhein-Necker-Dreieck
    Beiträge
    78

    links/rechts Antriebverhältnis für Kreisbogenfahrt

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Hallo,

    ich bin jetzt schon ein paar Tage aus der Schule und habe erhebliche Schwierigkeiten eine einfache Aufgabe zu lösen:

    Ich habe ein dreirädiges Fahrzeug - vorne eine frei bewegliche Rolle, hinten zwei getrennt voneinander angetriebene Räder mit 42 cm Radstand. Raddurchmesser sind 18cm. Pro Umdrehung werden 120 Impulse des Inkrementaldrehgebers geliefert.
    Durch unterschiedliche Geschwindgkeit zwischen linkem und rechtem Rad kann ich einen Kreisbogen fahren.

    Ich möchte einen - auf die Mitte der Hinterachse bezogenen - Kreisbogen von z.b. 154 Grad mit einem Radius von 2 Metern fahren. Richtung ist unerheblich, da die Richtung ja durch das jeweils schneller drehende Rad vorgegeben wird. Also reduziert sich das ganze auf das Drehzahlverhältnis zwischen links und rechts...

    Frage: In welchem Verhältniss muss der linke Drehgeber gegenüber dem rechten seine Impulse pro Sekunde liefern, damit ich diesen Kreisbogen fahre.

    Ich bin auf der Suche nach einer Formel mit Radius und Winkel als Variablen.

    Vielleicht kann mir ja einer einen Hinweis für die Lösung geben :-)

    Grüße

    Lurchi
    Angehängte Dateien Angehängte Dateien

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    502
    Die Impulse zu berechnen ist eine einfache Sache:
    Du hast einen Radius und Winkel vorgegeben, jetzt musst noch fürs innere und äussere Rad den Weg berechnen. Winkel ist logischweise gleich, Radius-Innen = Radius+Radstand/2, etc.
    Dann hast die Wege für beide Räder, und kannst über den Raddurchmesser die Anzahl der Impulse der Wege ausrechnen.
    Das war der leichte Teil, wenn du über PWM die Motoren regelst hast leider das Problem das zB 70%PWM nicht 70% der Drehzahl sind.
    An einer einfachen Lösung dieses Problems wäre ich auch sehr interessiert

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.410
    Blog-Einträge
    101
    ich versuchs mal auf die Gefahr einer Blamage hin:

    für einen kompletten Kreis muß das äußere Rad einen Weg von (Kreisdurchmesser + Radstand) * PI zurücklegen.

    Dafür muß sich das Rad: Weg / Umfang des Rades drehen.
    ((Kreisdurchmesser + Radstand) * PI) / (Raddurchmesser * PI)
    oder auch (Kreisdurchmesser + Radstand) / Raddurchmesser

    Impulse pro komplettem Kreis = 120 * (Kreisdurchmesser + Radstand) / Raddurchmesser

    Pulse für 154 Grad mit Dreisatz:

    360 Grad => 120 * (Kreisdurchmesser + Radstand) / Raddurchmesser
    1 Grad => (120 * (Kreisdurchmesser + Radstand) / Raddurchmesser) / 360

    Da läßt sich was kürzen:
    1 Grad => ((Kreisdurchmesser + Radstand) / Raddurchmesser) / 3

    154 Grad => 154 * ((Kreisdurchmesser + Radstand) / Raddurchmesser) / 3

    Impulse äußeres Rad für 154 Grad = 154 * (( 4m + 0,42m) / 0,18m ) / 3 = 1260,51...


    Fürs innere Rad analog, nur das man da für den Weg (Kreisdurchmesser - Radstand) * PI hernehmen muß
    Impulse inneres Rad für 154 Grad = 154 * (( 4m - 0,42m) / 0,18m ) / 3 = 1020,96...


    Deine Formeln dürften sein (Kreisdurchmesser = 2 * Kreisradius):
    Impulse äußeres Rad = Winkel in Grad * ((Kreisdurchmesser + Radstand) / Raddurchmesser) / 3
    Impulse inneres Rad = Winkel in Grad * ((Kreisdurchmesser - Radstand) / Raddurchmesser) / 3


    Ohne Gewähr
    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.01.2006
    Beiträge
    4.556
    Ok. damit ist die Anzahl der Impulse für jedes Rad bekannt. Aber beide
    Räder sollen ihre jeweilige Impulsanzahl in der gleichen Zeit abarbeiten!
    Da wird es jetzt haarig....Bin gerade in der Kur angekommen und beinahe
    24 h nicht geschlafen, deshalb versuche ich das heue erst überhaupt nicht.

    Gruß Richard

    Ps.: Habe mir so einen Surfstick zugelegt, klappt prima und die 5 Euronen/24h
    spare ich hier locker an Kippen ein weil quasie überall Rauchverbot herrscht.

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.410
    Blog-Einträge
    101
    Ich wußte doch, daß ich da was nicht richtig verstanden habe

    Gute Erhohlung Richard!

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    24.03.2009
    Ort
    Rhein-Necker-Dreieck
    Beiträge
    78
    Hallo,

    vielen Dank für den Input.
    Wäre es nicht eine plausible Möglichkeit den beiden Motortreibern einfach die gewünschte RPM Zahl vorzugeben - die sollen sich drum kümmern, das die Zahl so genau wie möglich eingehalten wird.
    Das sollte doch auf dem kurzen Weg zwischen PWM Wert und Drehgeber feedback möglich sein. Das ist zwar nicht 100% genau, aber im mittel sollte es doch ziemlich dem entsprechen was man will.

    Dann muss man sich nur noch die Zeit zu überlegen bis die Strecke gefahren ist. (OK - Stichproben alle paar ms könnten sinnvoll sein... )
    -> da die rpm ja bekannt sind...
    Bei angenommenen 1/4 U/sek (15 U/Min) ist das äußere Rad nach 1260,51 / (120 / 4) also nach 42,017 Sekunden fertig.
    Wenn das innere Rad im entsprechend kleinern Verhältniss (also langsamer ist), sollte jetzt der gewünschte kreisbogen gefahren worden sein.

    Grüße

    Lurchi

    @Richard: Auch von mir, gute Erholung.
    Oder habe ich mich jetzt verlaufen...

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo zusammen,

    genau zu dem mathematischen Ergebnis bin ich auch schon vor ein 'paar' Tagen beim Asuro gestoßen.
    Ich hatte das mal in EXCEL gegossen und berücksichtigt auch die Geradeausfahrt. Ist nun im Anhang.

    Der oben angegeben Ausdruck "Raddurchmesser) / 3" ist bei mir in einem RadFaktor gelandet und steht im 2ten blau markierten Feld im EXCEL-Kopf. (Rechts die beiden blauen Felder sind nur der Faktor in Werte unter 255 gerechnet. Bei der Geometrie vom Asuro kommt man so mit einer schnellen Byte-Rechnerei aus.)

    Interessant ist noch das rechts stehende grüne Feld.
    Dort kann man einen Prozentwert eintragen, der Fehler bei der Ermittlung der Drehgeber-Impulse 'schönrechnet'. (Bei meinem Asuro komme ich da mit einem Wert von 97 zum gewünschten Ergebis.)

    Um beide Motoren zu regeln, damit sie die Vorgaben in gleicher Zeit abfahren, hatte ich, auch schon vor ein 'paar' Tagen, den waste-Linienverfolgungsregler so angepasst, das der sich darum kümmert.
    Hier mal der Reglercode:
    Code:
    /*****************************************************************************
       FUNKTION:   MotorPID
       Aufgabe:    Funktion zur Reglung der Motoren.
                   Diese Funktion bzw. die eigendliche Berechnung fuer die
                   Reglung wurde im Forum unter www.roboternetz.de von waste
                   entwickelt.
                   Von Sternthaler ist die Moeglichkeit hinzugefuegt, die
                   Reglerberechnung fuer unterschiedliche Regelaufgaben zu
                   nutzen.
                   Die Parameter steuern, welche Sensoren zur Reglung benutzt
                   werden sollen. Zum einen koennen es die Liniensensoren sein
                   um eine Linienverfolgung zu realisieren, zum anderen kann
                   der Regler zur Ueberwachung der Raddecoder genutzt werden.
       Parameter:  
    *****************************************************************************/
             unsigned char  MotorPID (
             unsigned char  regler,
                      char  speed,
                      int   links,
                      int   rechts)
    {
                      int   LWert = 0, RWert = 0;
                      int   absLinks = 0, absRechts = 0;
                      float faktor;
    static            int   x, x1, x2, x3, x4;
    static            int   xalt, drest, isum;
                      int   kp = 0, kd = 0, ki = 0;
                      int   yp, yd, yi, y, y2;
                      int   LSpeed,	RSpeed;
             unsigned char  LDir,   RDir;
             unsigned char  use_regler = TRUE;
    
       switch (regler)
       {
       case PID_LINIE:
          links = rechts = 1;                 // erzwingt vorwaertsfahrt
          LineData ();                        // Liniensensoren
          LWert = sens.linie [LINKS_DUNKEL] - sens.linie [RECHTS_DUNKEL];
          RWert = sens.linie [LINKS_HELL]   - sens.linie [RECHTS_HELL];
          /* DIESE PARAMETER WURDEN VON waste IM FORUM UNTER
             http://www.roboternetz.de
             ENTWICKELT.
          */
          kp = 5;              // Parameter kd enthält bereits Division durch dt
          ki = 5;
          kd = 70;
          break;
       case PID_ODOMETRIE:
          if (links == 0 || rechts == 0)
             use_regler = FALSE;
          else
          {
             absLinks  = abs (links);
             absRechts = abs (rechts);
             /* Odometrie-Zaehler so justieren, dass fuer eine Kurvenfahrt
                die Tic-Anzahl auf beiden Seiten identisch aussehen.
                Die Seite auf der weniger Tic's zu fahren sind wird auf die
                hoehere Anzahl 'hochgerechnet'.
             */
             if (absLinks < absRechts)
             {
                faktor = (float)absRechts / (float)absLinks;
                LWert = sens.rad_tik [LINKS] * faktor;
                RWert = sens.rad_tik [RECHTS];
             }
             else
             {
                faktor = (float)absLinks / (float)absRechts;
                LWert = sens.rad_tik [LINKS];
                RWert = sens.rad_tik [RECHTS] * faktor;
             }
             kp = g_kp;
             ki = g_ki;
             kd = g_kd;
          }
          break;
       }
    
       LSpeed = (int)(speed - hw.motor_diff / 2);   //Wunschgeschwindigkeit vorgeben
       RSpeed = (int)(speed + hw.motor_diff / 2);   //Hardware beruecksichtigen
    
       if (use_regler == TRUE)
       {
          /* AB HIER IST DIE BERECHNUNG VON waste IM FORUM UNTER
             http://www.roboternetz.de
             ENTWICKELT WORDEN.
          */
          x1 = RWert - LWert;                 // Regelabweichung
    
          x = (x1 + x2 + x3 + x4) / 4;        // Filtert die 4 letzten Werte
          x4 = x3; x3 = x2; x2 = x1;          // Pipe ueber die letzten 4 Werte
    
          isum += x;                          // I-Anteil berechnen
          if (isum >  16000) isum =  16000;   // Begrenzung: Überlauf vermeiden
          if (isum < -16000) isum = -16000;
          yi = isum / 625 * ki;
    
          yd = (x - xalt) * kd;               // D-Anteil berechnen und mit nicht
          yd += drest;                        // berücksichtigtem Rest addieren
          if (yd > 255) drest = yd - 255;     // Eventuellen D-Rest merken
          else if (yd < -255) drest = yd + 255;
          else drest = 0;
    
          yp = x * kp;                        // P-Anteil berechnen
    
          y = yp + yi + yd;                   // Gesamtkorrektur
          y2 = y / 2;                         // Aufteilung auf beide Motoren
          xalt = x;                           // x merken
    
          if (y > 0)                          // Abweichung nach rechts
          {
             LSpeed += y2;                    // links beschleunigen
             if (LSpeed > 255)                // wenn Wertebereich ueberschritten
             {
                y2 += (LSpeed - 255);         // dann Rest rechts berücksichtigen
                LSpeed = 255;                 // und Begrenzen
             }
             RSpeed -= y2;                    // rechts abbremsen
             if (RSpeed < 0)                  // Auch hier Wertebereich
             {
                RSpeed = 0;                   // beruecksichtigen
             }
          }
          if (y < 0)                          // Abweichung nach links
          {
             RSpeed -= y2;                    // rechts beschleunigen
             if (RSpeed > 255)                // wenn Wertebereich ueberschritten
             {
                y2 -= (RSpeed - 255);         // dann Rest links berücksichtigen
                RSpeed = 255;                 // und Begrenzen
             }
             LSpeed += y2;                    // links abbremsen
             if (LSpeed < 0)                  // Auch hier Wertebereich
             {
                LSpeed = 0;                   // beruecksichtigen
             }
          }
       }
    
       /* Und wieder (fast) waste
       */
       if (links >0) LDir = FWD; else if (links <0) LDir = RWD; else LDir = BREAK;
       if (rechts>0) RDir = FWD; else if (rechts<0) RDir = RWD; else RDir = BREAK;
    
       if (LSpeed < 20) LDir = BREAK;         // richtig bremsen
       if (RSpeed < 20) RDir = BREAK; 
       MotorDir   (     LDir,         RDir);
       MotorSpeed (abs (LSpeed), abs (RSpeed));
    
       return 0;
    }
    Folgende Variablen sind zu berücksichtigen:
    - sens.rad_tik [LINKS | RECHTS ] : Aktuelle Zählerstände der Drehgeber
    - g_kp, g_ki, g_kd : Globale PID-Werte. (Bei meinem Asuro 65, 5, 90
    - hw.motor_diff : Kann 0 sein. Berücksichtigt unterschiedliche Motoren

    Die benutzten Defines sollten selbsterklärend sein

    Ach so, wichtig wäre es noch zu erwähnen, dass die Reglerfunktion alle 2 ms aufgerufen werden sollte. Das Timing ist von waste mal so berechnet worden.

    Viel Erfolg mit der Kurvenfahrt.
    Sternthaler

    P.S.: Hier auch noch mal eine Aufrufstelle der Regler-Funktion:
    Code:
             if (v_fahren == TRUE)
             {
                MotorPID (
                   PID_ODOMETRIE,    // Reglerwahl
                   150,              // Mittlere Geschwindigkeitsvorgabe
                   v_weg_l,          // Anzahl Takte linkes  Rad (Odometrie)
                   v_weg_r);         // Anzahl Takte rechtes Rad (Odometrie)
    
                if (sens.rad_tik [LINKS]  >= v_weg_l  &&
                    sens.rad_tik [RECHTS] >= v_weg_r)
                {
                   v_fahren = FALSE;
                   v_weg_l = 0;
                   v_weg_r = 0;
                   MotorSpeed (0,     0);
                   MotorDir   (BREAK, BREAK);
                }
             }
    Angehängte Dateien Angehängte Dateien
    Lieber Asuro programieren als arbeiten gehen.

Berechtigungen

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