- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 7 von 7

Thema: Abstandsregelung Regler reagiert zu langsam

  1. #1

    Abstandsregelung Regler reagiert zu langsam

    Anzeige

    Praxistest und DIY Projekte
    Hallo!

    Ich bin in Sachen Regelungstechnik ein blutiger Anfänger und hoffe, dass mir hier vielleicht jemand mit ausreichend Fachwissen behilflich sein kann

    Ich arbeite zurzeit im Rahmen eines Projekts daran die Abstandsregelung eines Roboters mit Mecanum Rädern zu realisieren. Der Roboter ist von der Firma Makeblock und wird über einen Arduino Uno programmiert.

    Ansteuerung der Motoren funktioniert, den Regler habe ich als PID-Regler ebenfalls bereits implementiert. Der Code dazu sieht so aus:

    Code:
      if(currentMicros - previousMicros > TaMicros) {
        previousMicros = currentMicros;
        //Fehler bestimmen
        e = d_soll - d_ist;
        //Integration approximieren; mit Anti-Windup-> wenn Stellgröße zu groß Aufintegrieren stoppen
        if((vy < 1) && (vy > -1)) esum = esum + e;
        //Reglergleichung
        vy = -( Kp*e + Ki*Ta*esum + Kd*(e-ealt)/Ta );
        //Ableitung approximieren
        ealt = e;
        //Stellgröße begrenzen
        if(vy > 1) vy = 1;
        if(vy < -1) vy = -1;
    Die Tastzeit Messungen haben Werte zwischen ca. 17000 und 25000 µs ergeben. Nun wollte ich versuchen, vernünftige Werte für die Regler Parameter zu finden. Dazu wollte ich zunächst empirisch vorgehen. Deshalb habe ich mit einem kleinen Wert für den P Anteil angefangen. Grundsätzlich verhält der Regler sich auch richtig (Roboter versucht Soll-Abstand herzustellen), allerdings fällt eine Sache mMn schwer ins Gewicht. Der Roboter scheint "zeitversetzt" auf den Regelfehler zu reagieren. Ich habe dann mit den Werten rum experementiert, habe es allerdings nicht geschafft bessere Regelergebnisse zu erhalten. Das Problem mit der zeitlichen Verzögerung fällt meiner Vermutung nach zu schwer ins Gewicht. Zum besseren Verständnis des Problems habe ich mal ein kleines Video angehängt (hier ist nur ein P-Anteil von 1,5 vorhanden).



    Kann es sein, dass ich es hier mit einer sehr großen Totzeit der Regelstrecke zu tun habe? Und wenn ja, gibt es eine Möglichkeit diese zu umgehen?

    Vielen Dank im Voraus!

  2. #2
    HaWe
    Gast
    hallo,
    wie errechnest du Ta?
    wie sind deine ganzen Variablen definiert?
    wie sieht die komplette Schleife aus, incl aller delays, und samt Motor-Befehlen?

  3. #3
    Hi, schon mal danke für deine Antwort!
    Ta habe ich mithilfe dieses Codes gemessen (am Ende der Loop platziert):
    Code:
    unsigned long cycleTime;
    unsigned int cycleCount;
      cycleCount++;
      if (cycleCount>=100)
      {
        Serial.print("Cycle Time: ");
        Serial.print((micros()-cycleTime)/cycleCount);
        Serial.println(" microseconds");
        cycleCount=0;
        cycleTime=micros();
    Dabei kamen dann Werte zwischen 17000 und 25000 µs raus, was ich als Taktzeit interpretiert habe. Ich habe dann für Ta einfach mal einen Wert in der Mitte angenommen. Meine Variablen sind wie folgt definiert:
    Code:
    float d_soll = 0.4, d_ist;
    float e, esum = 0, ealt = 0;
    unsigned long TaMicros = 20000; //Abtastzeit in Mikrosekunden
    float Ta = (float)TaMicros/1000000;
    unsigned long currentMicros;
    unsigned long previousMicros = 0;
    float vy = 0;
    float Kp = 1.5;
    float Ki = 0;
    float Kd = 0;
    Die Loop-Schleife sieht dann so aus:
    Code:
      currentMicros = micros();
      d_ist = ultraSensor.distanceCm()/100; //Methode des Herstellers (eigene Library) zum Auslesen des Sensors
      regelung(); //ist in meinem ersten Post enthalten
        motor1.runSpeed(vy,0); //Methoden des Herstellers zum Ansteuern der Motoren
        motor2.runSpeed(vy,0); //Umrechnung in für den Motor zu verarbeitende Drehzahlen findet an anderer Stelle statt
        motor3.runSpeed(vy,0);
        motor4.runSpeed(vy,0);
    Hoffe das ist ausreichend, um dir eine Ahnung zu von dem was ich treibe zu verschaffen

  4. #4
    HaWe
    Gast
    meine ersten Ideen:

    Einheit aller Timestamps immer in identischen Einheiten berechnen (also immer micros oder immer millis)

    Du solltest die Zeit pro Schleifendurchlauf exakt stoppen (machst du glaube ich per cycletime)
    Ta müsste exakt die Dauer des aktuellen Schleifendurchlaufs sein, also Ta=(float)cycletime (kannst du auch direkt einsetzen, ohne zusätzliches Ta)

    Die delays pro Schleife würde ich so wählen, dass ca. 10 millisec = 10000 micros pro Schleife anfallen

    Kp, Ki und Kd können theoretisch durchaus Werte zwischen 0.001 bis 1000000 annehmen, also nicht begrenzen

    Ki allerdings neigt zu übermäßigem Aufsummieren, daher zusätzlich mit einem Dämpfungsfaktor multiplizieren:
    esum = 0.7*( esum + e);

    edit:
    der Dämpfungsfaktor (hier 0,7) mag irgendwo zwischen 0,5 und 0,9 liegen
    Geändert von HaWe (03.03.2018 um 10:27 Uhr)

  5. #5
    Erfahrener Benutzer Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    54
    Beiträge
    542
    Blog-Einträge
    17
    Zitat Zitat von master04 Beitrag anzeigen
    Der Roboter scheint "zeitversetzt" auf den Regelfehler zu reagieren.
    Mir scheint der Roboter nicht zeitlich sondern räumlich versetzt zu starten, als wenn die Antriebe erst bei einer bestimmten Reglerausgabe oder Schwellwert anlaufen. Du kannst vielleicht eine Fahrprobe machen mit Spannungen vom einem Poti vorgegeben, um zu schauen, ob die Antriebe eine Anlaufspannung haben. Wenn du diese Anlaufspannung herausrechnest, könnte das Regelverhalten besser werden.
    Geändert von witkatz (02.03.2018 um 20:32 Uhr)

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.686
    .. Tastzeit Messungen .. 17000 und 25000 µs .. Werte für die Regler Parameter zu finden .. scheint "zeitversetzt" auf den Regelfehler zu reagieren ..
    Bei meinem archie rechne ich auf nem mega1284/20MHz. Dort ist für zwei Regelkreise PID (rechter und linker DC-Motor - also Motor vor dem Getriebe/Antriebsstrang) genug Zeit um mit 100 Hz zu regeln. JEDE Seite separat, also zeitversetzt mit brutto 200 Hz. Regelung im Interrupt, Drehzahl/Drehzeit wird per Interrupt auf Flanken des Encoders gemessen. Geregelt wird nur mit Integers, mittlerweile 16bittig. Mein MiniD0 regelte noch 8bittig - sonst vergleichbare Regelung, aber im selben Zeitraster. Etwa doppelt so schnell wie Du; wie Deine Tastzeit vermuten lässt.

    Was ist bei Dir die Tastzeit ? Die Abtastzeit der Drehzeiten von Motor oder Antriebsstrang oder die Abstände für die Regelung ?
    Wie schnell, in welchem Zeitraster stellst Du die Drehzeiten bereit ?
    . . . . . . Interrupt oder im Hauptprogramm ?
    Wie schnell, in welchem Zeitraster wird die Regelung gefahren ?
    . . . . . . Interrupt oder im Hauptprogramm ?
    Wie genau ist die Drehzeiterfassung ? In Sekunden und Drehwinkel.
    Was wird geregelt? Motordrehzahl oder Raddrehzahl ?
    Kann es sein, dass Du in Deinen Rechnungen alles oder einige Werte FP rechnest (floating point) ? Denn das ist recht zeitintensiv.

    Grundsätzlich hatte ich zu Beginn der Regelung immer ne Sprungantwort aufgenommen, natürlich im "Endausbau" des Fahrzeugs. Daraus hatte ich dann die Regelungskennwerte abgeschätzt - Motorzeitkonstante, Parameter für P, I und D. Einen gewissen Fortschritt brachte es für mich, als ich mir die Skizze der Regelungsschleife hernahm und alle Größen mit MEINEN Namen beschriftet hatte. Sieh mal hier (klick). Das brachte - mir - den Durchblick. Nochn bisschen über meinen Regelungsaufwand steht hier.

    Vielleicht helfen Dir diese Anmerkungen etwas weiter?
    Ciao sagt der JoeamBerg

  7. #7
    HaWe
    Gast
    Zitat Zitat von oberallgeier Beitrag anzeigen
    Bei meinem archie rechne ich auf nem mega1284/20MHz. Dort ist für zwei Regelkreise PID (rechter und linker DC-Motor - also Motor vor dem Getriebe/Antriebsstrang) genug Zeit um mit 100 Hz zu regeln. JEDE Seite separat, also zeitversetzt mit brutto 200 Hz. Regelung im Interrupt, Drehzahl/Drehzeit wird per Interrupt auf Flanken des Encoders gemessen. Geregelt wird nur mit Integers, mittlerweile 16bittig. Mein MiniD0 regelte noch 8bittig - sonst vergleichbare Regelung, aber im selben Zeitraster. Etwa doppelt so schnell wie Du; wie Deine Tastzeit vermuten lässt.

    Was ist bei Dir die Tastzeit ? Die Abtastzeit der Drehzeiten von Motor oder Antriebsstrang oder die Abstände für die Regelung ?
    Wie schnell, in welchem Zeitraster stellst Du die Drehzeiten bereit ?
    . . . . . . Interrupt oder im Hauptprogramm ?
    Wie schnell, in welchem Zeitraster wird die Regelung gefahren ?
    . . . . . . Interrupt oder im Hauptprogramm ?
    Wie genau ist die Drehzeiterfassung ? In Sekunden und Drehwinkel.
    Was wird geregelt? Motordrehzahl oder Raddrehzahl ?
    Kann es sein, dass Du in Deinen Rechnungen alles oder einige Werte FP rechnest (floating point) ? Denn das ist recht zeitintensiv.

    Grundsätzlich hatte ich zu Beginn der Regelung immer ne Sprungantwort aufgenommen, natürlich im "Endausbau" des Fahrzeugs. Daraus hatte ich dann die Regelungskennwerte abgeschätzt - Motorzeitkonstante, Parameter für P, I und D. Einen gewissen Fortschritt brachte es für mich, als ich mir die Skizze der Regelungsschleife hernahm und alle Größen mit MEINEN Namen beschriftet hatte. Sieh mal hier (klick). Das brachte - mir - den Durchblick. Nochn bisschen über meinen Regelungsaufwand steht hier.

    Vielleicht helfen Dir diese Anmerkungen etwas weiter?
    wieso braucht er Encoder?
    Und wieso muss er die Geschwindigkeit oder Drehzahl "messen"?
    Gemessen und geregelt wird doch wohl der Abstand zum anderen Fahrzeug, und zwar je nach Abstand mit verschieden schnellen Motordrehzahlen (über pwm vermutlich) und ggf. mit Richtungsumkehr.
    Ansonsten halte ich den Ansatz schon für richtig, so wie er ist, mit ein paar kleineren Änderungen.
    https://www.roboternetz.de/community...l=1#post642966
    Der Rest ist Tuning und Fein-Tuning von Kp, Ki und Kd.

    edit,
    PS:
    auch der PID-Regler PID_v1 für Arduinos rechnet immer mit float, und das ist auch auf AVRs absolut schnell genug.
    Geändert von HaWe (03.03.2018 um 12:28 Uhr)

Ähnliche Themen

  1. CMPS03 reagiert nicht
    Von Jon im Forum Sensoren / Sensorik
    Antworten: 4
    Letzter Beitrag: 12.08.2009, 15:27
  2. Interrupt reagiert nicht oder nur langsam
    Von Maxxtro im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 09.08.2009, 22:38
  3. PollSwitch reagiert falsch?
    Von weisserAdler im Forum Asuro
    Antworten: 10
    Letzter Beitrag: 22.06.2007, 23:39
  4. IR Abstandsregelung
    Von Wrag im Forum Sensoren / Sensorik
    Antworten: 6
    Letzter Beitrag: 23.08.2005, 22:23
  5. AVR reagiert nicht auf Tastendruck
    Von quad im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 12.06.2005, 18:55

Stichworte

Berechtigungen

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

Solar Speicher und Akkus Tests