PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Motoren wollen nicht mit niedrigen PWM Werten



nofear87
28.12.2017, 14:07
Hallo,

ich habe 50:1 Metal Gearmotor 37Dx54L von Pololu.

Leider gelingt es mir nicht die Motoren mit PWM < 30 zum drehen zu bewegen. Damit ist sehr langsames fahren so gut wie ausgeschlossen.

Ist das Problem hausgemacht oder mache ich da eventuell einen Fehler?

Als Treiber verwende ich einen Pololu dual vnh5019. An jedem Port sind 2 Motoren angeschlossen (sprich 4WD).

Vielen lieben Dank!

Gruß
Robert

021aet04
28.12.2017, 15:26
Das ist normal. Du musst zuerst eine höhere PWM wählen und kannst dann wieder heruntergehen. Das Problem ist aber das der Motor bei einer größeren Last (z.B. Steigung) stehenbleiben kann. Allerdings ist eine Drehzahlregelung (also mit Drehzahlrückführung) besser, da die PWM je nach Drehzahl angepasst.

MfG Hannes

oberallgeier
28.12.2017, 15:52
.. 50:1 Metal Gearmotor 37Dx54L von Pololu .. nicht die Motoren mit PWM < 30 zum drehen zu bewegen ..
Hallo Robert,

irgendwie sind die Angaben etwas sehr dünn. PWM - 30 von wieviel? Es gibt ja PWM mit fast beliebig hoher Obergrenze, meine Motörchen (nicht nur die pololus) fahren PWM 8 bis 10bittig, manche PWMs fahre ich sogar deutlich höher. Gilt Deine Aussage für Motor mit Last (welche, wieviel, welche Fahrbahn etc) oder einfach nur testweise am Tisch liegend? Welche Spannung? Welcher maximal mögliche Strom?

Ich hab den 30:1 Metal Gearmotor 37Dx52L mm with 64 CPR Encoder (nach eigenen Messungen hat meiner aber 29:1) - dieses pololuding (https://www.pololu.com/product/1443) - MIT Encoder. Zwei davon habe ich in meinen archie eingebaut (https://www.roboternetz.de/community/threads/61379-Kopfsache-und-ein-m1284-etliche-Servos-viel-Alu?p=638683&viewfull=1#post638683), fahrbereit aktuell ca. 6 kg, ca. 90+ cm hoch. Der archie fährt mit ca. 12+ V Akku (ca. max >50A MÖGLich, nie gemessen) am Motortreiber locker an die 7 kmh, vermutlich auch schneller, Anfahrt in der Ebene !im archie! bei ca. 15 PWM/8-bittig. Im Leerlauf, 12,5V, bei Strombegrenzung 4A, keine Last, Motor mit freier Achse, fährt der etwa bei 7..9 PWM/8bittig los.

Wie Hannes schreibt, ein bisschen Dampf brauchen unsere Motörchen schon - so wie jeder Motor ein gewisses Losbrechmoment hat. Ist ja auch kaum ein Problem - ausser wenn man die Motoransteuerung mit Werten von z.B. -255 bis +255 macht, dann braucht man in der Um-die-Null-Lücke ein bisschen if-then Tricks. Aber - kein Problem. Archie z.B. fährt butterweich von mässig vorwärts über langsamer werden - "durch die Null" - bis sanft nach rückwärts . . .

Holomino
29.12.2017, 13:38
Hmm,
ich hab mir dazu einen ZeroBoost in die Regelung eingebaut, weil dieser Minimal-PWM-Wert bei mir:
- abhängig von der Batteriespannung ist (sinkt während des Betriebs)
- abhängig vom Untergrund ist (anderer Wert für Teppich, als für Laminat)
- im Extremfall bis zur Vollaussteuerung gehen muss, insbesondere wenn der Roboter beim Anfahren direkt vor einem überfahrbaren Hindernis (Teppichkante o.ä.) steht.

Der Zeroboost ist bei mir ein Zähler, der im zyklischen Durchlauf der Motorregelung hochzählt, wenn keine Änderungen an den Inkrementalgebern angezeigt werden, der Roboter also steht. Bei einer Änderung der Inkrementalgeberwerte (hurra, die Masse bewegt sich) wird er auf 0 zurückgesetzt.
Multipliziert mit einer Konstante KZB wird der Zeroboost-Zähler auf den vom PID-Regler generierten PWM-Wert aufaddiert.

Eigentlich könnte das auch der I-Anteil des Reglers. Der allerdings neigt bekanntlich zu Überschwingen. Das ist insbesondere dann tödlich, wenn nur eine kurze Strecke zurückgelegt werden soll. Auch kann KZB wesentlich größer als KI gewählt werden, so dass die PWM-Rampe vor dem Anfahren schneller steigt.

Keine Ahnung, ob das so der amtliche Weg ist, mir fiel damals nix Besseres ein.

hbquax
30.12.2017, 11:18
Du musst halt mindestens den Leerlaufstrom bereitstellen, sonst kann sich nichts rühren. Wenn dein Blockierstrom z.B. 10 A ist und dein Leerlaufstrom 1 A, brauchst du mindestens 10%, damit sich der Motor ohne Last überhaupt dreht.

oberallgeier
30.12.2017, 12:03
.. ich hab mir dazu einen ZeroBoost in die Regelung eingebaut, weil dieser Minimal-PWM-Wert bei mir ..Ei, was für ein prächtiger Trick. Den hatte ich ähnlich auch schon bei Testfahrten gemacht (wohl auch bei der etwas hakeligen Regelung am WALL R), aber bei der üblichen Regelung von Drehzahl oder Stellung total unbeachtet gelassen :-/ Schöner Hinweis, danke.


Du musst halt mindestens den Leerlaufstrom bereitstellen ..Das bezweifle ich stark. Immer wieder stelle ich fest, dass ich den Motor - wenn er mal läuft - deutlich geringer bestromen kann bis zum Stillstand. Und das ist natürlich so, sonst hätte die Haftreibung ihr Existenzrecht verloren.

nofear87
31.12.2017, 12:04
Hallo zusammen,


Hallo Robert,

irgendwie sind die Angaben etwas sehr dünn. PWM - 30 von wieviel? Es gibt ja PWM mit fast beliebig hoher Obergrenze, meine Motörchen (nicht nur die pololus) fahren PWM 8 bis 10bittig, manche PWMs fahre ich sogar deutlich höher. Gilt Deine Aussage für Motor mit Last (welche, wieviel, welche Fahrbahn etc) oder einfach nur testweise am Tisch liegend? Welche Spannung? Welcher maximal mögliche Strom?

Ich hab den 30:1 Metal Gearmotor 37Dx52L mm with 64 CPR Encoder (nach eigenen Messungen hat meiner aber 29:1) - dieses pololuding (https://www.pololu.com/product/1443) - MIT Encoder. Zwei davon habe ich in meinen archie eingebaut (https://www.roboternetz.de/community/threads/61379-Kopfsache-und-ein-m1284-etliche-Servos-viel-Alu?p=638683&viewfull=1#post638683), fahrbereit aktuell ca. 6 kg, ca. 90+ cm hoch. Der archie fährt mit ca. 12+ V Akku (ca. max >50A MÖGLich, nie gemessen) am Motortreiber locker an die 7 kmh, vermutlich auch schneller, Anfahrt in der Ebene !im archie! bei ca. 15 PWM/8-bittig. Im Leerlauf, 12,5V, bei Strombegrenzung 4A, keine Last, Motor mit freier Achse, fährt der etwa bei 7..9 PWM/8bittig los.

Wie Hannes schreibt, ein bisschen Dampf brauchen unsere Motörchen schon - so wie jeder Motor ein gewisses Losbrechmoment hat. Ist ja auch kaum ein Problem - ausser wenn man die Motoransteuerung mit Werten von z.B. -255 bis +255 macht, dann braucht man in der Um-die-Null-Lücke ein bisschen if-then Tricks. Aber - kein Problem. Archie z.B. fährt butterweich von mässig vorwärts über langsamer werden - "durch die Null" - bis sanft nach rückwärts . . .

Ich nutze einen Raspi Zero gemeinsam mit Johnny Five (JavaScript). Hier ist PWM meines Wissens nach derzeit auf 8bit beschränkt. Ich arbeite zwischen 0-255. Die Motoren habe ich vorerst an einer Holzkonstruktion befestigt. Es handelt sich ja noch um einen ersten Prototypen. Gefahren wird eben auf Laminatboden. Die Konstruktion samt Akkus, Elektronik und Motoren hat ein Gesamtgewicht von ca. 1,5 KG.

Betrieben werden die Motoren mit einem 3S Lipo Akku. Also ca 12V.


Hmm,
ich hab mir dazu einen ZeroBoost in die Regelung eingebaut, weil dieser Minimal-PWM-Wert bei mir:
- abhängig von der Batteriespannung ist (sinkt während des Betriebs)
- abhängig vom Untergrund ist (anderer Wert für Teppich, als für Laminat)
- im Extremfall bis zur Vollaussteuerung gehen muss, insbesondere wenn der Roboter beim Anfahren direkt vor einem überfahrbaren Hindernis (Teppichkante o.ä.) steht.

Der Zeroboost ist bei mir ein Zähler, der im zyklischen Durchlauf der Motorregelung hochzählt, wenn keine Änderungen an den Inkrementalgebern angezeigt werden, der Roboter also steht. Bei einer Änderung der Inkrementalgeberwerte (hurra, die Masse bewegt sich) wird er auf 0 zurückgesetzt.
Multipliziert mit einer Konstante KZB wird der Zeroboost-Zähler auf den vom PID-Regler generierten PWM-Wert aufaddiert.

Eigentlich könnte das auch der I-Anteil des Reglers. Der allerdings neigt bekanntlich zu Überschwingen. Das ist insbesondere dann tödlich, wenn nur eine kurze Strecke zurückgelegt werden soll. Auch kann KZB wesentlich größer als KI gewählt werden, so dass die PWM-Rampe vor dem Anfahren schneller steigt.

Keine Ahnung, ob das so der amtliche Weg ist, mir fiel damals nix Besseres ein.

Die Idee finde ich super. Lässt sich sicher auch mit JavaScript gut umsetzten. Das einzige Problem was ich derzeit habe ist, das ich die Encoder noch nicht vernünftig auslesen kann. Hier muss ich noch ein wenig testen. Ich habe die Hoffnung das es mit Johnny Five am Ende irgendwie funktionieren muss... Am Ende sind es doch 2 einfach digitale Eingänge pro Encoder?

Gibt es Erfahrungswerte wie lange der höhere Anlaufstrom zur Verfügung gestellt werden muss, bevor ich wieder herunterregeln kann?

oberallgeier
31.12.2017, 12:53
.. das ich die Encoder noch nicht vernünftig auslesen kann .. Am Ende sind es doch 2 einfach digitale Eingänge pro Encoder? ..Genau. Das Arbeiten der Encoder sieht ungefähr so aus - klick (https://www.pololu.com/product/1443/pictures#lightbox-picture0J2643). Meine Dokumentation zur Auswertung sieht so aus - nochnklick (https://dl.dropbox.com/s/7u6q2d8lhn8x4vi/flankenwechsel.jpg?dl=0) - die Farbenliste [White] bis [Red] bezieht sich auf das Kabel für den Motoranschluss!!

Mit Java kann ich ja nu nicht helfen, aber vielleicht bietet Dir (m)ein C-Code-Schnippsel ne Hilfe oder zumindest nen Anhaltspunkt ? Wobei hier für Dich eher nur die IencdrX-Werte für die (Teil)Umdrehungen/Drehwinkel und die tmrEx-Werte für die Drehzahlmessung von Interesse sind.

// ================================================== =========================== =
// === Initialisierung der externen Interrupts bei m1284, doc 8272D-AVR-05/12
// EXT_INT0 auf PORTD2 Pin 16 -- Encoder IencB0 auf PINC 2 Pin 24 und
// EXT_INT1 auf PORTD3 Pin 17 -- Encoder IencB1 auf PINC 3 Pin 25
// ================================================== =========================== =
void XTI_0_1_init( void ) // Initialisiere beide Interrupts auf RISING edge
{ // => EICRA ISC00/~01 + ~10/~11 auf 1 doc S68
EICRA |= (1<<ISC01)|(1<<ISC00); // INT0 triggert auf RISING edge
EICRA |= (1<<ISC11)|(1<<ISC10); // INT1 triggert auf RISING edge
EIMSK |= (1<<INT0) | (1<<INT1); // erlaube INT0 und INT1 in EIMSK
// Initialisierung der Zeiten:
Iencdr0 = Iz_diff0 = Iz_yseci0 = Iz_ysecv0 = 0;
Iencdr1 = Iz_diff1 = Iz_yseci1 = Iz_ysecv1 = 0;
tmrE0 = tmrE1 = 0; // Timer für Drehzahlerfassung
} // Ende von void XTI_0_1_init( void )
// ================================================== =========================== =


// ================================================== =========================== =
// === Nicht unterbrechbare ISR für EXT_INT0 auf mega1284 ================ =
// Der Timer tmrE0 für Laufzeit des EXT_INT0 wird ausgelesen
ISR(INT0_vect) // INT0 triggert auf RISING edge =>
{ // => Wenn Aufruf, dann PORTD2 = high
// ToggleBit (PTLED, LCr); // rtLED toggeln
// - - - - - - - - - - - - - - - -
// Encoderticks Iencdrx nur hochzählen, IencBx rauf- od runterzählen
Iz_diff0 = tmrE0; // Hier die Zeit (in x 50µs-tupsi) seit letztem ISR-Aufruf
tmrE0 = 0; // Resetten ##>> IN der ISR ohne CLI/SEI möglich
Iencdr0 ++; // Incrementiere Encodercounter, zählt NUR aufwärts
if (IsBitSet (PINC, 2)) IencB0++; // Rad treibt vorwärts, math. negativ
else IencB0--; // Rad treibt rückwärts, math. positiv
} // Ende ISR(INT0_vect)
// ================================================== =========================== =


// ================================================== =========================== =
// === Nicht unterbrechbare ISR für EXT_INT1 auf mega1284 ================ =
// Routine setzt einfach einen Zähler hoch.
// Sonst wie ISR für EXT_INT0 für Motor li,re und PWM/Geschw.
ISR(INT1_vect) // hiess mal: ISR(SIG_INTERRUPT1)
{ //
// ToggleBit (PTLED, LCr); // rtLED toggeln
// - - - - - - - - - - - - - - - -
// Encoderticks Iencdrx nur hochzählen, IencBx rauf- od runterzählen
Iz_diff1 = tmrE1; // Hier die Zeit (in x 50µs-tupsi) seit letztem ISR-Aufruf
tmrE1 = 0; // Resetten ##>> IN der ISR ohne CLI/SEI möglich
Iencdr1 ++; // Incrementiere Encodercounter, zählt NUR aufwärts
if (IsBitSet (PINC, 3)) {IencB1--;} // Rad treibt rückwärts (math. positiv)
else {IencB1++;} // Rad treibt vorwärts (math. negativ)
} // Ende ISR(INT1_vect)
// ================================================== =========================== =

nofear87
31.12.2017, 15:56
Vielen Dank für deine Bemühungen. Ich habe folgenden Code finden können und werde damit vorerst mein Glück probieren. Ich melde mich sobald es neues gibt. Ohne funktionierende Encoder fehlt mir ja leider die Abbruchbedingung für den ZeroBoost.

https://gist.github.com/rwaldron/5db750527f257636c5d3b2c492737c99

Holomino
31.12.2017, 15:56
Gibt es Erfahrungswerte wie lange der höhere Anlaufstrom zur Verfügung gestellt werden muss, bevor ich wieder herunterregeln kann?
Bis sich das Fahrzeug in Bewegung gesetzt hat. Genau dann hat es sich von der Haftreibung (Motor, Getriebe, Räder) gelöst und muss nur noch gegen die Roll-/Gleitreibung arbeiten.

In der Praxis: Ich stelle zuerst die PID-Regelparameter KP,KI, KD wie gewohnt auf "langen" Strecken ein. Anschließend optimiere ich KZB anhand der kürzestmöglichen Strecke. "Kürzestmöglich" ist nicht immer "1" (ein Encoderschritt), hängt im wesentlichen vom Haftreibungswert, der Schwungmasse des Fahrzeugs und der Auflösung der Inkrementalgeber ab. Ist die kürzestmögliche Strecke für das System zu kurz gewählt, bekommt man auch mit dem ZeroBoost nur dauerhaftes Schwingen. Hat man diesen Wert allerdings auf das physikalisch Mögliche eingegrenzt, kann man ihn durchaus als Toleranz zum Zielpunkt verwenden.

BTW, ich hab's mir lange nicht erklären können, aber mal zum Nachexperimentieren: Wenn man das Fahrzeug mit erhöhter PWM gerade so zum Rollen bringt, danach die PWM absenkt und anschließend mit dieser "Schleichfahrt-PWM" einfach die Richtung umkehrt, fährt's in der Regel rückwärts ohne erneuten Startboost weiter.
Ich vermute mittlerweile, dass die drei Haftreibungskomponenten "Räder, Getriebe, Motorlager" bei dieser Richtungsumkehr bedingt durch das Getriebespiel zeitlich verzögert kommen. Sie wirken also nur noch nacheinander, nicht mehr in der Summe.

Insofern ist beim Einstellen des Zeroboost die Wirkung eines einzelnen Überschwingers unter erhöhten Lastbedingungen nicht einmal schlimm. Auf ner Schwelle balanciert das Rad so nicht, aber über die Schwelle, danach über den Zielpunkt hinaus und dann wieder zurück geht recht zuverlässig.

nofear87
01.01.2018, 17:37
So, ich habe mich mal an dem ZeroBoost versucht. Nehme ich nur einen Motorkanal (sprich bei mir die linken 2 Motoren) funktioniert alles wunderbar.
Wenn ich den 2ten Kanal ebenfalls zur gleichen Zeit nutze ist unter PWM 30 Schluss. Woran könnte das liegen. Angenommen ich schalte die beiden Kanäle mit etwas Zeitversatz habe ich das Problem das ich dadurch eine Drehung erzeuge.

Anbei noch ein Beispiel (kommentiere ich nach dem Timeout "motor2" aus fahren die Motoren an Kanal 1 auch mit niedrigeren PWM Werten):


if(speed < 30) {
motor1.forward(40);
motor2.forward(40);
setTimeout(() => {
motor1.forward(speed);
motor2.forward(speed);
}, 300)
} else {
motor1.forward(speed);
motor2.forward(speed);
}

oberallgeier
01.01.2018, 18:15
.. Angenommen ich schalte die beiden Kanäle mit etwas Zeitversatz habe ich das Problem das ich dadurch eine Drehung erzeuge ..Das ist eine Annahme? Oder hast Du das schon getestet?

Die Motoren für meine kleine Coladose werden pro Sekunde 100 mal geregelt - bei archie dasselbe. Immer nur ein Motor zur gleichen Zeit, d.h. die Regelroutine läuft für beide Motoren 200 mal pro Sekunde mit gleichmässigen Abständen, 5 ms, von Regelung zu Regelung. Abweichungen der Fahrtrichtung hatte ich damit nicht wirklich festgestellt. Allerdings musste bei Aufnahme der Sprungantwort (fürs MiniD0) auf genaueste Synchronisierung Wert gelegt werden, um Richtungsänderungen beim Anfahren zu vermeiden. Ohne genauere Tests behaupte ich, dass durch die sehr hohe Beschleunigung eines Motors am Bewegungsanfang aus dem Stillstand heraus dieser festgestellte Versatz kam - siehe hier (https://www.roboternetz.de/community/threads/36121-Autonom-in-kleinen-Dosen-R2_D03-Nachfolger-R3D01?p=427784&viewfull=1#post427784).

Holomino
02.01.2018, 08:03
Hast Du vielleicht einen Spannungsabfall in der Versorgung (zu lange Akkuleitung oder zu wenig Stützkondensator am Motorshield)?