- LiFePO4 Speicher Test         
Seite 4 von 9 ErsteErste ... 23456 ... LetzteLetzte
Ergebnis 31 bis 40 von 85

Thema: Kurve fahren

  1. #31
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    02.01.2008
    Alter
    33
    Beiträge
    239
    Anzeige

    E-Bike
    hallo ihr beiden

    wie ich sehe seid ihr fleißig am experimentieren, optimieren, programmieren,...

    ich hatte leider in den letzten tagen nicht so viel zeit (z.T. auch wegen dem schönen wetter)

    vl. kann ich mich aber trotzdem wieder einmal dazu überwinden auch etwas herum zu tüftlen

    @sternthaler
    du hattest doch mal nach meinem aktuellen code gefragt: ich glaube es müsst der letzte sein den ich gepostet habe (falls du ihn auch mal probieren willst)


    [edit] am 4.9.08 um 18:46
    kleine frage am rande:
    müssen bei GoTurnArc() oder wie auch immer man sie nennt unbedingt 4 parameter übergeben werden?
    würden nicht 3 genügen?
    - length (wird als radius oder distance verwendet. je nach dem ob degree=0 oder nicht)
    - degree
    - speed

    auswahl des jeweileigen typs:
    -length=0: auf dem stand drehen (entspricht dem früheren Turn())
    -degree=0: gerade strecke fahren (entspricht dem früheren Go())
    -keins der beiden =0: bogen fahren (entspricht Kurve())


    oder wäre es eurer meinung nach besser alle 4 zu verwenden, um die doppelte verwendung von length als radius und distance zu umgehen?

    ich werde auf jeden fall in nächster zeit einmal versuchen meine idee als programm zu verwirklichen. dann kann man noch immer entscheiden was besser ist

    trotzdem bedanke ich mich bei euch schon mal für die (hoffentlich) kommenden rückmeldungen
    [/edit]

    [edit] am 5.9.08 um 10:05
    wie angekündigt habe ich jetzt meine version fertig gestellt
    ich hoffe ihr könnt etwas damit anfangen

    hier einmal mein code:
    um für mich das zusammensetzten leichter zu machen habe ich erstmal viel gleichbedeutende alte und neue variablen nur mit defines ersetzt. später kann man das natürlich im code ersetzten, um das lesen zu erleichtern
    Code:
    #include <asuro.h>
    #include <myasuro.h>
    
    
    //defines zur kurvenfahrt
    #define BREITE     103    //spurbreite in mm
    #define PI         3.141592
    
    //defines, um alte variablennamern weiterverwenden zu können
    #define distance   length
    #define radius     length
    #define winkel     degree
    
    #define enc_count  count_a_soll
    #define tot_count  count_a
    #define l_speed    speed_a
    #define r_speed    speed_i
    
    #define GO   1
    #define TURN 2
    #define ARC  3
    
    void GoTurnArc (
      int length,
      int degree,
      int speed)
    {
    StatusLED(RED);
      unsigned  long  enc_count;
                int   count_a=0,count_i=0;
                int   diff = 0;
                int   speed_a=speed, speed_i=speed;
                int   radius_a, radius_i;
                float quot, teiler;
                long  tik_summe;
    
                int typ; //speichert den typ der gefahrenen strecke
    
      /* stop the motors until the direction is set */
      MotorSpeed (0, 0);
    
      /* Go */
      if (distance != 0 && degree == 0)
      {
        typ=GO;
        /* calculate tics from mm */
        enc_count  = abs (distance) * 10000L;
        enc_count /= MY_GO_ENC_COUNT_VALUE;
    
        if (distance < 0)
          MotorDir (RWD, RWD);
        else
          MotorDir (FWD, FWD);
      }
      /* Turn */
      else if (distance == 0 && degree != 0)
      {
        typ=TURN;
        /*  calculate tics from degree */
        enc_count  = abs (degree) * MY_TURN_ENC_COUNT_VALUE;
        enc_count /= 360L;
    
        if (degree < 0)
          MotorDir (RWD, FWD);
        else
          MotorDir (FWD, RWD);
      }
    /* Arc */
      else if (distance != 0 && degree != 0)
      {
        typ=ARC;
        /*  calculate tics from distance and degree */
        radius_a=radius+BREITE/2;
        radius_i=radius-BREITE/2;
    
        teiler=(float)360/abs(winkel);  //Bruchteil des Kreises
        quot=((float)radius_a)/((float)radius_i);
    
    
        //berechnen der notwendigen tics am außen- und innenrad
        count_a_soll=2*radius_a*(PI*10000L/teiler);
        count_a_soll/=MY_GO_ENC_COUNT_VALUE;
      }
    
    
      /* reset encoder */
      EncoderSet (0, 0);
    
      /* now start the machine */
      if(typ!=ARC)
        MotorSpeed (l_speed, r_speed);
      else
      {
        //mindestgeschwindigkeit=70
        if(speed<70) speed=70;
    
        //anfangsgeschwindigkeiten berechnen
        speed_a=speed;
        speed_i=speed_a/quot;
        //speed_i=speed;
    
        //Motoren starten
        if(winkel>0)
           MotorSpeed(speed_i,speed_a);   //im Gegenuhrzeigersinn
        else
           MotorSpeed(speed_a,speed_i);   //im Uhrzeigersinn
      }
    
      while (tot_count < enc_count)
      {
        if(typ!=ARC)
        {
          tot_count += encoder [LEFT];
          diff = encoder [LEFT] - encoder [RIGHT];
          /* reset encoder */
          EncoderSet (0, 0);
        }
        else
        {
          //einen Tik abwarten
          tik_summe = encoder [LEFT] + encoder [RIGHT];
          while (tik_summe == encoder [LEFT] + encoder [RIGHT]);
    
          //Odometrie einlesen
          if(winkel>0)
          {
              count_a=encoder[RIGHT];
              count_i=encoder[LEFT];
          }
          else
          {
              count_a=encoder[LEFT];
              count_i=encoder[RIGHT];
          }
    
          diff=count_a-(count_i*quot);
          if(winkel > 0) diff*=-1;
        }
    
        if (diff > 0)
        { /* Left faster than right */
          if ((l_speed > speed) || (r_speed > 244))
            l_speed -= 10;
          else
            r_speed += 10;
        }
    
        if (diff < 0)
        { /* Right faster than left */
          if ((r_speed > speed) || (l_speed > 244))
            r_speed -= 10;
          else
            l_speed += 10;
        }
    
    
        if(typ!=ARC) MotorSpeed (l_speed, r_speed);
        else
        {
          if(winkel>0)
              MotorSpeed(speed_i,speed_a);
          else
              MotorSpeed(speed_a,speed_i);
        }
        Msleep (1);
      }
      MotorDir (BREAK, BREAK);
      Msleep (200);
    }
    zur zeit funktionierten leider nur Go und Turn (also entweder distance oder degree =0). Kurve hat bei meinen probefahrten noch nicht funktioniet.
    vl findet ihr einen fehler
    [edit]
    mfg hai1991

    P.S.: wer großbuchstaben oder rechtschreibfehler findet darf sie behalten

  2. #32
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.07.2006
    Ort
    Puchheim
    Alter
    77
    Beiträge
    455
    Hallo Sternthaler,
    Halllo hai1991

    mit den Übergabeparametern hab ich auch so meine Probleme,
    ist ein wenig überbestimmt und man sollte daher einige Kombinationen
    im Programm abfangen.

    Hab dann noch ein wenig getestet, hatte aber immer Probleme mit der Sollvorgabe für die Geschwindigkeit und den unterschiedlichen Motor-Daten (mein rechter Motor ist deutlich langsamer.)
    Hab dann einen zulässigen Korridor für die Geschwindigkeit um die Geschwindigkeitsvorgabe definiert (maxi,mini für innres Rad, maxa, mina für äusseres Rad) und zusätzlich einen Korrekturwert für den rechten Motor definiert für vorwärts + 5 und für rückwärts + 25 (speed_korr)
    .
    Die Werte hab ich vorher für Geschwindigkeit ab 210 ermittelt.

    Hab auch anstelle der encoder[] eine eigene 8-Bit Odometr-Funktion verwandt (vermutlich nicht notwendig), hat den Vorteil, dass ich die
    MY-ODO-Daten nicht ständig ändern un die Bib neue "maken" muss, sondern verwende im Programm die Schwellwerte tlp,tlm,trp,trm .

    Damit kommt das neue Programm ganz gut zurecht, zumindest, wenn die Räder vernünftig drehen ( geölt, keine Haare / Staub an den Achsen, möglichst frische Akku's / Batterien, speed > 170).

    Im Anhang noch der Code


    mausi_mick


    PS: Bin ab heute/morgen im Urlaub
    Angehängte Dateien Angehängte Dateien

  3. #33
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Guten Morgen hai1991 und mausi_mick.

    Hier nur mal kurz auf die schnelle.

    @hai1991
    ARC dürfte nicht funktionieren, da du die beiden Variablen für " while (tot_count < enc_count)" nicht berechnest bzw. bei neuen Tiks neu ermittelst. Hab ich was übersehen?
    Ansonsten finde ich deinen Code gut getrennt durch die 3 Fahrt-Varianten.

    @mausi_mick
    Hey, die Formatierung ist besser . Wie steht in deinem Editor die TAB-weite? Bei 4 bekommt der Code ein fast homogenes aussehen. Ich stelle in meinem Editor immer ein, dass die geschriebenen TAB's in Leerzeichen gewandelt werden. Dann ist der Code grundsätzlich auch für andere identisch.
    Inhaltlich habe ich jetzt noch nicht intensiv geschaut.
    Faulpelz. Die Lib nicht übersetzen zu wollen, wo gibt es denn so was?
    Du kannst die 4 Variablen tlp,tlm,trp,trm komplett sparen. Du kannst sie auch als #define anlegen, da die Inhalte sich nie ändern, und der Wert selber auch nur durch Defines bestimmt werden.
    #define TLP TRIGLEV_L + HYST_L
    Nun aber erst einmal einen schönen Urlaub.

    Gruß Sternthaler
    Lieber Asuro programieren als arbeiten gehen.

  4. #34
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.12.2005
    Beiträge
    535
    Hi, Jungs (SternThaler, mausi_mick und hai1991)

    Ihr kommt ja gut voran! Im Anhang habe ich den Vorschlag, die Motoren zu regeln, um mausi_micks faulem rechten Motor die Flausen auszutreiben . Ich hoffe, mein Vorschlag trägt dazu bei, besser die Kurve zu kratzen.

    Ciao,

    mare_crisium
    Angehängte Dateien Angehängte Dateien

  5. #35
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    02.01.2008
    Alter
    33
    Beiträge
    239
    hallo allerseits

    @sternthaler
    wenn ich deine vermutung richtig verstehe muss ich dich leider entteuschen. ganz oben habe ich die variablen mit defines gleichgesetzt
    Code:
    #define enc_count  count_a_soll
    #define tot_count  count_a
    dadurch musste ich erstmal nicht alles umändern, sondern konnte es so übernehmen wie es ist.
    falls du etwas anderes gemeint hast, bitte ich dich, es etwas genauer zu beschreiben

    @mare_crisium
    ich habe deine datei schnell überflogen und muss sagen, dass es nicht schlecht aussieht. jedoch bin ich mir nicht sicher, ob es für den asuro schon eine fertige funktion für die berechnung der drehzahl gibt. das muss ich erst mit hilfer der suchfunktion heraus finden.
    mfg hai1991

    P.S.: wer großbuchstaben oder rechtschreibfehler findet darf sie behalten

  6. #36
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.07.2006
    Ort
    Puchheim
    Alter
    77
    Beiträge
    455
    hallo ihr Kurver,

    vermutlich liegt mare_crisium gar nicht so daneben, werd mir vielleicht im
    Urlaub Gedanken dazu machen ... wenn der Krimi zu öde ist.


    Gruss
    mausi_mick

  7. #37
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo hai1991
    Oh Mist, da gebe ich mausi_mick den Tipp seine Variablen durch Defines zu ersetzen, und die von dir gemachten Defines habe ich übersehen.
    Ja, dein Hinweis löst genau das was ich übersehen hatte.

    Grüß dich mare_crisium,
    was machst du bei den Asurianern ? Hast du nun auch einen?
    Und wie immer ein guter Vorschlag von dir. (Ist ja ein echter Regler)
    Ähm, in deinem Text schreibst du, dass hier aktuell nicht geregelt würde.
    - while((difl < 10) && (difr < 10))
    - {
    --- OdometrData(dalr);
    --- Auswerten der beiden ODO-Werte aus dalr[2] und ermitteln einer
    --- Geschwindigkeitsänderung
    --- ...
    Das ist doch auch ein Regler? (Vorgabe / Messwerte / Abweichung -> Ergibt neue Stellwerte)
    Und ein schuldbewustes: Ja, Ja, ich sollte eigentlich X, Y und Omega berechnen .

    Und noch mal etwas zu hai1991.
    Deine Suche nach einem Regler für den Asuro wird dich unweigerlich zu wastes linienverfolgendem PID-Regler führen.
    Genau den habe ich schon seit vielen, vielen Äonen zum Kurven-/Geradefahren genutzt.
    Ein paar experimentelle Anpassungen an den Reglerparametern (wie mare_crisium es Dummys wie mir, bei solchen Dingen empfiehlt). Ein weiterer kleiner Umbau darin erlaubt es auch noch, dass man nicht auf das Ende der Fahrt warten muss solange das Hauptprogramm das Ding regelmäßig alle 2ms aufruft.
    Dazu aber nur den Codeausschnitt vom Regler. Schließlich geht es hier um deinen Ansatz.
    Code:
    /*****************************************************************************
       FUNKTION:   MotorPID
       Aufgabe:    Funktion zur Reglung der Motoren.
                   Diese Funktion bzw. die eigentliche 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
             https://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 = 65;
             ki = 5;
             kd = 90;
          }
          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
             https://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
             }
          }
       }
    
       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;
    }
    Diese Funktion muss alle 2ms vom Hauptprogramm aus aufgerufen werden, da waste damals diesen Zeitfaktor in seinen Berechnungen zur Reglerdimensionierung angesetzt hatte.
    Oder innerhalb der Funktion wird ein while() mit Msleep(2) eingebaut.
    Die struct-Variable sens enthält die Messwerte der Sensoren, die per Interrupt immer aktuelle Werte enthalten. Sie 'verbrauchen' innerhalb der Funktion keine Rechenzeit.

    Ein Aufruf erfolgt mit Tik-Angaben bei den Parametern links und rechts. Eine Umrechnung von Strecke bzw. Winkel und Radius und Vorwärts/Rückwärts muss vorher erfolgen.

    Tut mir leid, wenn ich euch das bis jetzt verschwiegen habe. Aber dein Ansatz hai1991 soll ja nicht durch 'Fertigfutter' beeinflusst werden fand ich.

    @mausi_mick
    Dann lass den Krimi doch zu Hause

    Gruß Sternthaler
    Lieber Asuro programieren als arbeiten gehen.

  8. #38
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.12.2005
    Beiträge
    535
    Guten Morgen, alle zusammen,

    gut, wenn der Asuro die Regelfunktion schon eingebaut hat. Auf meine Idee bin ich auch nur deshalb gekommen, weil das Rad an mausi_micks Asuro ohne Sonderbehandlung die Sollgeschwindigkeit nicht erreicht. Er könnte das Problem also beheben, indem er den Regler „schärfer“ einstellt. Ich versuche gerade mich durch den Abschnitt des c-Codes durchzubeissen, um zu verstehen, wie das gehen könnte.

    @SternTahler
    nee, einen Asuro habe ich nicht. An meinem Asuro-ähnlichen Eigenbau bin ich noch am Basteln. Ich will Euch auch kein x für ein y oder Omega vormachen. - Es führen viele Wege nach Roma, ganz besonder für Asuros .

    Ciao,

    mare_crisium

  9. #39
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Auch einen guten Morgen an alle. (Ja meine Zeiten sind etwas ver-rückt)

    Speziell an mare_crisium
    Ich glaube, ich muss mein letztes unverständliches Gebrabbel erst einmal sortieren. Nicht dass wir aneinander vorbei reden.
    - Der Asuro und auch die Lib haben keinen Regler implementiert.
    - Der von waste entwickelte Regler ist 'standalone' zur Linienverfolgung entwickelt worden. (wastes Regler 38970 Ansichten!!!)
    - Das Codeschnipsel oben von mir nutzt die Mathematik von waste. Ich habe ihn nur für meine Belange so umgebaut, dass er auch für beliebige Fahrstrecken als Regler genutzt werden kann.
    Und weil der Begriff Regler hier nun auftauchte, habe ich ihn hier als Muster ins Rennen geworfen.

    Auf alle Fälle sollten mausi_mick und hai1991 sich deinen Pseudo-Code ansehen. Der von dir vorgeschlagene Zweipunkt-Regler ist ja auch ohne Studium, im Gegensatz zu einem ausgewachsenen PID-Regler, auch noch verständlich.

    Somit bleibt erst einmal nur noch eine Navigationsplanung nach Rom zu machen . Ist bestimmt ein gutes Ziel. Und das sollte man immer haben.

    Gruß Sternthaler

    P.S.: @mare_crisium
    Hast du zu deinem Roboter hier im Forum(-Romanum) einen Thread bei den vorgestellten Eigenbauten?
    Lieber Asuro programieren als arbeiten gehen.

  10. #40
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    02.01.2008
    Alter
    33
    Beiträge
    239
    hallo zusammen

    gleich vorweg:
    noch mal ein thx an mare_crisium für die bescheibung eines brauchbaren reglers, aber sollte es nicht auch funktionieren, wenn ich das verhältnis der gefahenen wege bilde und dann dementsprechend die geschwindigkeiten änder? vorausgesetzt man wählt seine mindestgeschwindigkeit dementspechend
    somit brauche ich nicht erst die drehzahl ermittel und auf diese reagieren (das spart vl etwas speicherplatz und zeit, wobei ich nicht weiß wie relevant das in diesem fall ist)

    warum ich aber eigentlich schreibe:
    wie oben schon berichtet hatte ich ein problem mit der integrierung der Arc-funktion in GoTurn.
    durch experimentieren und mehrmaligem durchschauen des codes ist mir aufgefallen, dass ich "nur" ein MotorDir im Arc-Teil vergessen hatte, dadurch war er noch immer auf BREAK.

    hier also der funktionierende code:
    Code:
    #include <asuro.h>
    #include <myasuro.h>
    
    
    //defines zur kurvenfahrt
    #define BREITE     103    //spurbreite in mm
    #define PI         3.141592
    
    //defines, um alte variablennamern weiterverwenden zu können
    #define distance   length
    #define radius     length
    #define winkel     degree
    
    #define enc_count  count_a_soll
    #define tot_count  count_a
    #define l_speed    speed_a
    #define r_speed    speed_i
    
    #define GO   1
    #define TURN 2
    #define ARC  3
    
    void GoTurnArc (
      int length,
      int degree,
      int speed)
    {
    StatusLED(RED);
      unsigned  long  enc_count;
                int   count_a=0,count_i=0;
                int   diff = 0;
                int   speed_a=speed, speed_i=speed;
                int   radius_a, radius_i;
                float quot, teiler;
                long  tik_summe;
    
                int typ; //speichert den typ der gefahrenen strecke
    
      /* stop the motors until the direction is set */
      MotorSpeed (0, 0);
    
      /* Go */
      if (distance != 0 && degree == 0)
      {
        typ=GO;
        /* calculate tics from mm */
        enc_count  = abs (distance) * 10000L;
        enc_count /= MY_GO_ENC_COUNT_VALUE;
    
        if (distance < 0)
          MotorDir (RWD, RWD);
        else
          MotorDir (FWD, FWD);
      }
      /* Turn */
      else if (distance == 0 && degree != 0)
      {
        typ=TURN;
        /*  calculate tics from degree */
        enc_count  = abs (degree) * MY_TURN_ENC_COUNT_VALUE;
        enc_count /= 360L;
    
        if (degree < 0)
          MotorDir (RWD, FWD);
        else
          MotorDir (FWD, RWD);
      }
    /* Arc */
      else if (distance != 0 && degree != 0)
      {
        typ=ARC;
        /*  calculate tics from distance and degree */
        radius_a=radius+BREITE/2;
        radius_i=radius-BREITE/2;
    
        teiler=(float)360/abs(winkel);  //Bruchteil des Kreises
        quot=((float)radius_a)/((float)radius_i);
    
    
        //berechnen der notwendigen tics am außen- und innenrad
        count_a_soll=2*radius_a*(PI*10000L/teiler);
        count_a_soll/=MY_GO_ENC_COUNT_VALUE;
    
        MotorDir(FWD,FWD);
      }
    
    
    
    
      /* now start the machine */
      if(typ!=ARC)
        MotorSpeed (l_speed, r_speed);
      else
      {
        //mindestgeschwindigkeit=70
        if(speed<70) speed=70;
    
        //anfangsgeschwindigkeiten berechnen
        speed_a=speed;
        speed_i=speed_a/quot;
        //speed_i=speed;
    
        //Motoren starten
        if(winkel>0)
           MotorSpeed(speed_i,speed_a);   //im Gegenuhrzeigersinn
        else
           MotorSpeed(speed_a,speed_i);   //im Uhrzeigersinn
      }
    
      /* reset encoder */
      EncoderSet (0,0);
    
      while (tot_count < enc_count)
      {
        if(typ!=ARC)
        {
          tot_count += encoder [LEFT];
          diff = encoder [LEFT] - encoder [RIGHT];
          /* reset encoder */
          EncoderSet (0, 0);
        }
        else
        {
          //einen Tik abwarten
          tik_summe = encoder [LEFT] + encoder [RIGHT];
          while (tik_summe == encoder [LEFT] + encoder [RIGHT]);
    
    
          //Odometrie einlesen
          if(winkel>0)
          {
              count_a=encoder[RIGHT];
              count_i=encoder[LEFT];
          }
          else
          {
              count_a=encoder[LEFT];
              count_i=encoder[RIGHT];
          }
    
          diff=count_a-(count_i*quot);
          if(winkel > 0) diff*=-1;
        }
    
        if (diff > 0)
        { /* Left faster than right */
          if ((l_speed > speed) || (r_speed > 244))
            l_speed -= 10;
          else
            r_speed += 10;
        }
    
        if (diff < 0)
        { /* Right faster than left */
          if ((r_speed > speed) || (l_speed > 244))
            r_speed -= 10;
          else
            l_speed += 10;
        }
    
    
        if(typ!=ARC) MotorSpeed (l_speed, r_speed);
        else
        {
          if(winkel>0)
              MotorSpeed(speed_i,speed_a);
          else
              MotorSpeed(speed_a,speed_i);
        }
        Msleep (1);
      }
      MotorDir (BREAK, BREAK);
      Msleep (200);
    }
    der code ist zwar noch etwas verbesserungsfähig, aber es funktioniert endlich


    was mir beim ausprobieren noch aufgefallen ist:
    die gemessene strecke ist derziet noch recht stark von der beleuchtung abhängig. so fährt er zb im schatten relativ genau seinen vorgegebenen winkel, jedoch bei zimmerbeleuchtung (energiesparlampe) fehlen immer einige grade. da muss ich wohl noch eine abschirmung der odometriesensoren basteln


    wenn noch jemand irgendwelche verbesserungsvorschläge hat bitte bescheidsagen
    mfg hai1991

    P.S.: wer großbuchstaben oder rechtschreibfehler findet darf sie behalten

Seite 4 von 9 ErsteErste ... 23456 ... LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests