www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Formel um die Geschwindigkeit der Motoren anzupassen


Autor: Luca Bertoncello (lucabert)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, Leute!

Ich brauche wieder eure Hilfe... Ich bitte euch, etwas Geduld noch mit 
mir zu haben...

So, nachdem ich die Schritten der Encoder richtig auslesen kann (nochmal 
1K Dank!) soll ich die Funktion schreiben, daß die Geschwindigkeit der 
Motoren anhand der Rückgaben anpasst.

Folgendes habe ich geschrieben:
#define MINSPEED      10    // in Schritte pro Sekunde
#define MAXSPEED      80    // in Schritte pro Sekunde
#define MINPWM        40    // Min. PWM-Wert
#define MAXPWM        240   // Max. PWM-Wert
#define CONSTPWM      2.89  // MAXPWM / MOTORMAXSPEED

void doMotorAction()
{
  uint8_t pwm;
  float nSpeed;

  if(getLeftInterval() != 0) // Es sollte nie passieren, daß der Zeitabstand 0 ist, aber sicher ist sicher
  {
    nSpeed = ((float)1000 / (float)getLeftInterval());
    if(nSpeed != (float)getSpeed() && nSpeed != 0)
    {
      pwm = (uint8_t)((float)getLeftPWM() + (((float)getSpeed() - nSpeed) * (float)CONSTPWM));
      if(pwm < MINPWM)
        setLeftPWM(MINPWM);
      if((pwm >= MINPWM) && (pwm <= MAXPWM))
        setLeftPWM(pwm);
      if(pwm > MAXPWM)
        setLeftPWM(MAXPWM);
      turnOnLED(LED2);
    }
    else
      turnOffLED(LED2);
  }
  if(getRightInterval() != 0) // Es sollte nie passieren, daß der Zeitabstand 0 ist, aber sicher ist sicher
  {
    nSpeed = ((float)1000 / (float)getRightInterval());
    if(nSpeed != (float)getSpeed() && nSpeed != 0)
    {
      pwm = (uint8_t)((float)getRightPWM() + (((float)getSpeed() - nSpeed) * (float)CONSTPWM));
      if(pwm < MINPWM)
        setRightPWM(MINPWM);
      if((pwm >= MINPWM) && (pwm <= MAXPWM))
        setRightPWM(pwm);
      if(pwm > MAXPWM)
        setRightPWM(MAXPWM);
      turnOnLED(LED3);
    }
    else
      turnOffLED(LED3);
  }
  if(nStepLeft == 200)
    setDirectionLeft(DIR_STOP);
  if(nStepRight == 200)
    setDirectionRight(DIR_STOP);
}

Nun sollten die Motoren (in meinen Träumen) nach genau eine Umdrehung 
GLEICHZEITIG anhalten.
Sie halten nach eine Umdrehung an, aber leider nicht gleichzeitig, also 
definitiv die Geschwindigkeiten werden NICHT richtig angepasst.
Ich sehe auch, daß LED2 und LED3 ständig an sind, obwohl ich mich 
erwartet hätte, daß die Funktion nicht ständig Korrekturen schickt.

Kann jemand mir sagen, was ich falsches mache?

Besten Dank nochmal und euch eine schöne Woche!
Luca Bertoncello

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was macht getLeftInterval, was getRightInterval. Was macht getSpeed und 
der ganze Rest? Wann und in welchem Zusammenhang wird doMotorAction 
aufgerufen?

Du verwendest hier einiges an Zulieferfunktionen von denen wir nichts 
wissen. Und auch wenn ich deinen Code nicht so ganz verstehe (bei dem 
wenigen, das du zeigst), kommt er mir doch sehr seltsam bzw. aufwändig 
vor. Was ist die Begründung, die Idee hinter deinen Berechnungen?

Als allererstes würde ich mal die ganze Floating Point Rechnerei 
loswerden wollen, damit die Rechnerei schneller geht.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist das eine.

Nach weiterem Codestudium glaube ich herausgelesen zu haben, dass das 
Prinzip so aussieht: Nimm die Encoderdifferenz zum letzten gemessenen 
Zeitpunkt her, rechne das in eine Geschwindigkeit um. Aus der Differenz 
zur Sollgeschwindigkeit errechnet sich eine Korrektur der PWM, so dass 
die Geschwindigkeit konstant gehalten wird.

Das würde ich so gar nicht machen. Und zwar aus dem Grund, weil du auf 
diese Art eine nachhängende linke oder rechte Seite zwar wieder auf 
Sollgeschwindigkeit bringst, du gleichst dadurch aber niemals den 
vrolorengegangenen Weg (wegen der kurzfristig zu niedrigen 
Geschwindigkeit) aus.

Da du den aktuellen Zeitpunkt kennst, kennst du auch den Encoderwert, 
der eigentlich vorliegen müsste. Der aktuelle Enocederwert mag geringer 
sein, als er nach dieser Betrachtung eigentlich sein müsste. UNd dann 
wird die PWM demenstprechend erhöht. Dein Nachregeln darf nicht auf den 
Geschwindigkeiten basieren, sondern auf den links und rechts laut 
Encodern zurückgelegten Wegen. die müssen gleich sein und die PWM 
nachgestellt werden wenn sie es nicht sind. Nicht die Geschwindigkeiten. 
Die sind dafür uninteressant.

Autor: Luca Bertoncello (lucabert)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

Hallo,

also getLeftInterval und getRightInterval geben einfach die 
Zeitabstände, in Millisekunde, zwischen zwei Signale der jeweiligen 
Encoder.
getSpeed gibt mir die Geschwindigkeit zurück, in Schritte pro Sekunde, 
die ich dem Roboter gegeben habe.
Die doMotorAction wird in der Hauptschleife aufgerufen.

> Nach weiterem Codestudium glaube ich herausgelesen zu haben, dass das
> Prinzip so aussieht: Nimm die Encoderdifferenz zum letzten gemessenen
> Zeitpunkt her, rechne das in eine Geschwindigkeit um. Aus der Differenz
> zur Sollgeschwindigkeit errechnet sich eine Korrektur der PWM, so dass
> die Geschwindigkeit konstant gehalten wird.
>
> Das würde ich so gar nicht machen. Und zwar aus dem Grund, weil du auf
> diese Art eine nachhängende linke oder rechte Seite zwar wieder auf
> Sollgeschwindigkeit bringst, du gleichst dadurch aber niemals den
> vrolorengegangenen Weg (wegen der kurzfristig zu niedrigen
> Geschwindigkeit) aus.
>
> Da du den aktuellen Zeitpunkt kennst, kennst du auch den Encoderwert,
> der eigentlich vorliegen müsste. Der aktuelle Enocederwert mag geringer
> sein, als er nach dieser Betrachtung eigentlich sein müsste. UNd dann
> wird die PWM demenstprechend erhöht. Dein Nachregeln darf nicht auf den
> Geschwindigkeiten basieren, sondern auf den links und rechts laut
> Encodern zurückgelegten Wegen. die müssen gleich sein und die PWM
> nachgestellt werden wenn sie es nicht sind. Nicht die Geschwindigkeiten.
> Die sind dafür uninteressant.

OK, aber ich versuche gerade das zu machen: sind die Werte von Encoder 
nicht wie ich erwarte, dann versuche ich die PWM zu ändern.

Das Problem dabei ist nur, daß ich diese PWM nicht richtig berechnen 
kann, bestimmt weil ich die Formel nicht kenne und meine 
Mathe-Kenntnisse etwas begrenzt sind.

Was würdest du mir vorschlagen?

Danke
Luca Bertoncello

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Luca Bertoncello schrieb:
>
> Das Problem dabei ist nur, daß ich diese PWM nicht richtig berechnen
> kann

Ich denke die wirst du auch nicht in dem Sinne berechnen können, das es 
dafür eine allein selig machende Formel gibt. Diese Ding laufen 
normalereise immer darauf hinaus: Wenn zu klein, dann drehe die PWM ein 
wenig auf.

> Was würdest du mir vorschlagen?

Das du mehr Skizzen und Zeichnungen machst und die Vorstellung aufgibst, 
dass es dafür eine (1) Formel gibt, die man benutzt und dann ist alles 
gut.
Willkommen in der Regelungstechnik.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.