- fchao-Sinus-Wechselrichter AliExpress         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 25

Thema: Linienverfolgung Testarena ASURO mit roter LED

  1. #11
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Anzeige

    Praxistest und DIY Projekte
    Zitat Zitat von ehenkes
    Wie finde ich die passenden Zahlen für meinen ASURO?
    Zitat Zitat von damaltor
    wertebestimmung im einfachsten:
    Was habe ich hier nicht mitbekommen?
    @damaltor: Du liefert in deinem Programm die Daten der Liniensensoren über IR an den PC um min- und maxwerte zu finden.
    @ehenkes: Du fragst nach 'passenden Zahlen'.
    So wie ich wastes PID-Regler verstehe, wüsste ich nun aber nicht, welche 'passenden Zahlen' in Verbindung mit den Liniesensorwerten gemeint sein können.
    Im PID von waste werden doch nur die relativen Differenzen zwischen Sensor 'links' und 'rechts' ausgewertet.
    Als Frage zu 'passenden Zahlen' hatte ich die Werte für kp, ki und kd im Auge.
    Die von waste in seinem Thread, sehr ausführlich erklärten/ermittelten Werte hierfür, sind doch angegeben:
    kp = 3; ki = 10; kd = 70; // Regler Parameter kd enthält bereits Division durch dt

    Also jetzt nur für mich: Um welche Werte geht es, ehenkes?
    Lieber Asuro programieren als arbeiten gehen.

  2. #12
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.04.2007
    Ort
    Einhausen
    Alter
    68
    Beiträge
    697
    Es geht um zwei Dinge, die mir Probleme bereiteten:
    a) die Erfassung der Liniendaten
    b) die richtigen Parameter für PID, also Kp, Ki und Kd

    Mit folgendem abgeänderten Programm kam ich bisher gut voran:

    Code:
    #include "asuro.h" 
    #include <stdlib.h> 
    
    #define SPEED    150
    #define SPEEDMAX 230
    #define SPEEDMIN  30
    
    unsigned char speed, j; 
    int speedLeft,speedRight; 
    unsigned int lineData[2]; 
    int x, xalt, kp, kd, ki, yp, yd, yi, drest=0, y, y2, isum=0, ADOffset; 
    
    void FollowLine (void) 
    { 
       unsigned char leftDir = FWD, rightDir = FWD; 
       
       LineData(lineData);
       x = (lineData[LEFT] - lineData[RIGHT]) - ADOffset; // Regelabweichung 
       
       yp = x*kp;                          // P-Anteil 
       
       isum += x; 
       if (isum > 16000)  isum =  16000;   //Begrenzung um Überlauf zu vermeiden 
       if (isum < -16000) isum = -16000; 
       yi = isum / 625 * ki;                 //I-Anteil berechnen 
       
       yd = (x - xalt) * kd;               // D-Anteil  
       yd += drest;                        // nicht berücksichtigten Rest addieren 
       if (yd > 255) 
       {
           drest = yd - 255;    // Rest 
       }
       else if (yd < -255) 
       {
           drest = yd + 255; 
       }
       else 
       {
           drest = 0; 
       }
       
       if (isum > 15000)        BackLED(OFF,ON);   // nur zur Diagnostik 
       else if (isum < -15000) BackLED(ON,OFF); 
       else BackLED(OFF,OFF); 
       
       y = yp + yi + yd;                 // Gesamtkorrektur 
       y2 = y / 2;                         // Aufteilung auf beide Motoren 
       xalt = x;                         // x merken 
       
       speedLeft = speedRight = speed; 
       MotorDir(FWD,FWD); 
       
       if ( y > 0) 
       {                     
          StatusLED(GREEN); 
          speedLeft = speed + y2;         // links beschleunigen 
          if (speedLeft > SPEEDMAX) 
    	  { 
             speedLeft = SPEEDMAX;            // falls Begrenzung 
             y2 = speedLeft - speed;      // dann Rest rechts berücksichtigen 
          } 
          y = y - y2; 
          speedRight = speed - y;         // rechts abbremsen 
          if (speedRight < SPEEDMIN) 
    	  { 
             speedRight = SPEEDMIN; 
          } 
       } 
       
       if ( y < 0) 
       {                     
          StatusLED(RED); 
          speedRight = speed - y2;         // rechts beschleunigen 
          if (speedRight > SPEEDMAX) 
    	  { 
             speedRight = SPEEDMAX;            // falls Begrenzung 
             y2 = speed - speedRight;      // dann Rest links berücksichtigen 
          } 
          y = y - y2; 
          speedLeft = speed + y;            // links abbremsen 
          if (speedLeft < SPEEDMIN) 
    	  { 
             speedLeft = SPEEDMIN; 
          } 
       } 
       leftDir = rightDir = FWD; 
       if (speedLeft  < SPEEDMIN + 5)  leftDir  = BREAK; // richtig bremsen 
       if (speedRight < SPEEDMIN + 5)  rightDir = BREAK; 
       MotorDir(leftDir,rightDir); 
       MotorSpeed(abs(speedLeft),abs(speedRight)); 
    } 
    
    int main(void) 
    { 
       Init();
       FrontLED(ON);
       for (j = 0; j < 255; j++) LineData(lineData);
       LineData(lineData);
       ADOffset = lineData[LEFT] - lineData[RIGHT]; // Helligkeitsunterschied links und rechts     
       
       MotorDir(FWD,FWD); 
       StatusLED(GREEN); 
    
       speed = SPEED; 
       speedLeft = speedRight = speed; 
       
       kp = 10; ki = 4; kd = 70;      // Regler Parameter kd enthält bereits Division durch dt 
       /*   10(!)    4(!)     70(!)   */ /*<=== gute Werte*/   
       
       while(1)
       { 
          FollowLine(); 
       } 
       return 0; 
    }
    Allerdings habe ich es nur bei langsamer Geschwindigkeit geschafft, die gesamte Testarena sauber abzufahren. Das Feintuning ist viel schwieriger, als ich ursprünglich dachte. Eine Ochsentour!

  3. #13
    Neuer Benutzer Öfters hier
    Registriert seit
    09.01.2005
    Ort
    Hochspeyer
    Alter
    57
    Beiträge
    25
    Zitat Zitat von Sternthaler
    Also jetzt nur für mich: Um welche Werte geht es, ehenkes?
    Ich bin zwar nicht ehenkes, aber ich benutze die Werte um die unterschiedlichen Lichtwerte meiner Fototransistoren auszugleichen. Dazu musste natürlich der Code ein klein wenig abändert werden.

  4. #14

  5. #15

  6. #16
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo ehenkes,
    du hast einen wichtigen Teil:

    FrontLED(OFF);
    LineData(lineData); // Messung mit LED OFF
    doff = (lineData[0] - lineData[1]); // zur Kompensation des Umgebungslicht
    FrontLED(ON);
    LineData(lineData); // Messung mit LED ON
    don = (lineData[0] - lineData[1]);
    x = don - doff; // Regelabweichung

    in deinem Sourse eleminiert.
    Damit verlierst du schon mal die Umgebungslicht-Unabhängigkeit. Zwar hast du in deinem main() am Anfang einen ADOffset-Wert ermittelt, aber der ist auch schon bei eingeschalteter Front-LED berechnet worden, und wird auch nicht mehr angepasst.
    Nun hatte waste seine PID-Werte aber für Sensorwerte ermittelt, bei denen das 'x = don - doff; // Regelabweichung' aber eben nach genau diesem Prinzip berechnet wird. (Somit wird x bei waste immer kleiner sein als bei dir, was zur Folge hat, dass die Abweichung vom Sollwert bei dir immer anders 'aussieht')
    Ausserdem hatte waste einen Zeitwert in dem Regler berücksichtigt, der vor allem durch die Sensorabfrage (ADC-Wandler) vorgegeben war. In wastes Lösung aber werden 4 ADC-Messwerte ermittelt, somit ist alleine schon der Zeitfaktor der Schleife komplett anders als nun bei dir.
    Dein Versuch nun, die von waste ermittelten PID-Werte anzupassen
    kp = 3; ki = 10; kd = 70; <-- deine
    kp = 10; ki = 4; kd = 70; <-- waste-Original
    sehen mir nun wirklich danach aus, dass du die Frage nach diesen Werten hier stellen musst. Die Werte sind doch empirisch ermittelt, und nicht berechnet. (Dann wäre ja die Frage überflüßig.)

    Um nun nicht so auszusehen, als ob ich die Berechnungen und Gründe was da nun alles ermittelt und in Betracht gezogen werden muss, aus dem Thread von waste verstanden zu haben, hier mein Geständniss: Das Prinzip ist mir klar, aber nicht der Weg zur Lösung (kp,ki,kd). Somit kann ich nun nicht mehr weiterhelfen.
    Lieber Asuro programieren als arbeiten gehen.

  7. #17
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.04.2007
    Ort
    Einhausen
    Alter
    68
    Beiträge
    697
    kp = 3; ki = 10; kd = 70; <-- deine
    kp = 10; ki = 4; kd = 70; <-- waste-Original
    ist genau umgekehrt.
    FrontLED(OFF);
    LineData(lineData); // Messung mit LED OFF
    doff = (lineData[0] - lineData[1]); // zur Kompensation des Umgebungslicht
    FrontLED(ON);
    LineData(lineData); // Messung mit LED ON
    don = (lineData[0] - lineData[1]);
    x = don - doff; // Regelabweichung
    Das hat bei mir einfach nicht funktioniert, keine Ahnung warum, daher habe ich auf ein funktionierendes Prinzip zurück gegriffen. Vielleicht ein Vorzeichenproblem mit LEFT/RIGHT bzw. 0/1, werde das nochmal probieren. Die Ableitung der Werte von waste habe ich verstanden.

  8. #18
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.04.2007
    Ort
    Einhausen
    Alter
    68
    Beiträge
    697
    Übrigens ist die empirische Methode auch beschrieben und funktioniert auch gut:
    Dimensionierung durch Probieren (Empirisches Einstellen)
    Diese Methode ist geeignet um einfache Systeme zu dimensionieren,
    insbesondere wenn man bereits Erfahrung mit ähnlichen Regelkreisen hat. Man
    fängt mit einer unkritischen Einstellung (Kp klein, Ki = 0, Kd = 0) an und
    erhöht langsam die Verstärkung Kp, bis die Dämpfung schlecht wird. Falls
    eine Schwingneigung auftritt, muss die Verstärkung wieder etwas zurück
    genommen werden. Dann nimmt man allmählich den Integralanteil hinzu, erhöht
    ihn in Schritten und probiert solange herum, bis das Ergebnis einigermaßen
    passt. Bei Bedarf kann noch ein D-Anteil (PID-Struktur) probiert werden.
    Wenn dabei die Regelung stabiler wird, kann noch mal Kp und Ki erhöht
    werden, bis man endgültig zufrieden ist.

  9. #19
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Na dann funktioniert doch alles bei dir.
    Hilf dir selbst, und allen ist geholfen.
    Lieber Asuro programieren als arbeiten gehen.

  10. #20
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.04.2007
    Ort
    Einhausen
    Alter
    68
    Beiträge
    697
    Die Testarena schafft er schon "fast". Nur bei den Steilkurven hängt er sich im Kreis auf. Man müsste ihn auf beiden Rädern zusätzlich abbremsen, wenn die Kurven zu "eng" werden, damit er am Ende nicht einfach weiter dreht und damit aus der Bahn gerät. Ich bin nur noch nicht sicher, an welchem Mess- oder Regelwert man anpacken soll. Was zeigt den Kurvenradius der schwarzen Linie an? Das wäre vielleicht der richtige Wert für eine Geschwindigkeitssteuerung. Gerade Linie - Gas geben, enge Kurve - abbremsen. Ideal wäre vielleicht auch ein Regler, der sich selbst optimiert (neuronale Netze, genetische Algorithmen, so was in der Art).

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad