Hallo liebe Experten,
ich sitze hier vor einem Modulo Problem und komme nicht weiter:
Ich habe einen Schrittmotor mit einem Encoder, der in diesem immer eine
ganze Umdrehung fährt, was genau 38000 Einheiten entspricht. Nun mache
ich nach jedem Schittmotorbefehl eine Überprüfung der Position, ob
motorposition und Encoderposition übereinstimmen bzw. innerhalb einenr
gewissen Toleranz liegen.
Da es sich um eine Dreheinheit handelt, Ist die Position 38000 genau
gleich der Position 0, 38001 gleich 1 etc...
Wenn ich nun mehrere Umdrehungen fahre, kommen höhere Positionen von
Enocder und Motorcontroller zurück (z.B. bei 3 Umdrehungen 114000 etc).
Ich will die Positionen immer in den Bereich 0-31999 Mappen.
Da erste was mit einfällt ist Modulo aber da gibt es folgendes Problem:
Durch Ungenauigkeiten kann es sein, dass die Encoderposition z.B. nach
einer Umdrehung nur bei 31997 liegt, die Motoposition aber genau bei
32000. Wenn ich nun Modulo mache, kommt beim Motor 0 raus und beim
Encoder bleibt die 31997. Das bedeutet für den Algorithmus, der die
beiden Werte auf Abstand vergleicht, dass der Abstand zu hoch ist.
Ich bin echt schon verzweifelt, kann mir hier jemand weiterhelfen??
DANKE!
Daniel F. schrieb:> Durch Ungenauigkeiten kann es sein, dass die Encoderposition z.B. nach> einer Umdrehung nur bei 31997 liegt,
Wie das?
Wenn der Encoder etwas Anderes zeigt als Schritte angesteuert werden,
dann verliert der Stepper Schritte (Schlupf). Dann müssen
Korrekturschritte nachgeschickt werden.
Daniel F. schrieb:> Wenn ich nun mehrere Umdrehungen fahre, kommen höhere Positionen von> Enocder und Motorcontroller zurück (z.B. bei 3 Umdrehungen 114000 etc).> Ich will die Positionen immer in den Bereich 0-31999 Mappen.
Wenn man bereit wäre, eine Abweichung vom Soll (also Vielfachen von
38000) zu akzeptieren, dann muss das Ergebnis natürlich signed sein,
denn es wären ja sowohl positive als auch negative Abweichungen denkbar.
Also muss man nach dem Modulo noch mit der Hälfte der Encoderschritte
vergleichen. Ist das Modulo kleiner als die Halfte der Encoderschritte,
dann handelt es sich um eine positive Abweichung->der Fehlerwert
entspricht direkt dem gefundenen Modulo-Wert.
Ist er hingegen größer als die Hälfte der Encoderschritte, dann ist die
Abweichung negativ und man erhält sie, indem man das Modulo-Ergebnis von
der Zahl der Encoderschritte/Umdrehung abzieht.
Ziehe die beiden Werte zuerst voneinander ab (als signed Variablen) und
dann Modulo.
Eigentlich sollte das Modulo aber gar nicht nötig sein, denn so weit
sollten die beiden Werte ja nicht auseinanderliegen...
oder caste die zahl in ein float 31997.0 dann teilen durch 100 = 319.997
und dann aufrunden 320 dann mal 100 = 32000 und wieder in int casten und
dann modulo
runden schrieb:> oder caste die zahl in ein float 31997.0
Ich will's nicht fassen.
Es geht um diskrete Schrittzahlen. Dafür ist float nun wirklich
denkbar ungünstig. Die Idee kann nur von einem Softwerker kommen, der
für Zahlensysteme nicht eine Spur von Verständnis hat.
Mathematiker schrieb:> Ich will's nicht fassen.
Jo. Und ausserdem, was soll das runden bringen?
Der Fehler entsteht ja durch das Modulo, das auf 2 Werte angewandt wird,
die dann voneinander abgezogen werden.
Dadurch entsteht eine falsche Differenz.
Der Weg ist wie gesagt, erst abziehen, und dann modulo (wenn überhaupt
nötig).
Daniel F. schrieb:> Ich will die Positionen immer in den Bereich 0-31999 Mappen.
Warum?
> Durch Ungenauigkeiten kann es sein, dass die Encoderposition> z.B. nach einer Umdrehung nur bei 31997 liegt, die Motoposition> aber genau bei 32000. Wenn ich nun Modulo mache, kommt beim> Motor 0 raus und beim Encoder bleibt die 31997.
Eben. Wuerdest Du direkt 31997 und 32000 vergleichen, haettest
Du das Problem gar nicht.
Merke: Den Hauptwert erst ganz am Schluss bilden; Rechnungen
wenn moeglich alle vorher erledigen.
Hi
So wie ich Das verstehe, 'schwanken' die Encoder-Schritte um +/-1
Das wäre kein Problem, da dieser Abstand wohl 'im grünen Bereich' ist.
Das Problem wird erst Eins, wenn die Soll-Position 'normiert' wird, also
von 38000 auf 0 gesetzt wird, wodurch die Differenz auf 37999 anwächst,
was wohl einen Schlepp-Fehler anzeigen wird (+Abbruch).
Kann der Motor auch anders herum verfahren, oder wird Dieser IMMER nur
in eine Richtung angesteuert, da so an eine Verriegelung angefahren
wird?
Wenn KEINE andere Drehrichtung benötigt wird, könntest Du auch 'einfach'
erst 'Normieren', wenn beide Werte über dem Maximal-Wert liegen.
So hast Du immer die Abweichung und von 38000 bis zur nächsten 2er
Potenz sind's noch >28000, sollte zur Schleppfehlererkennung reichen,
ohne, daß Dir einer der Zähler überläuft.
MfG
@ Daniel
Es scheint mir richtig, nicht die Symptome zu beheben, sondern die
Ursache.
Für Schrittverluste bzw. überschüssige Schritte gibt es, allgemein
gesprochen, die Ursache, dass bewegte Masse und Schrittfrequenz nicht
zueinander passen.
Wenn das Problem gelöst ist, gibt es auch nicht mehr die Notwendigkeit,
durch willkürliches Gleichsetzen, etwaige Unterschiede zwischen
Projektion und Messung, zu beseitigen. Das Ergebnis der Modulo-Operation
ist ja nur deswegen unbefriedigend, weil überhaupt Schritt-Differenzen
vorkommen. Es liegt also nicht am Modulo.
Nun schreibst Du in Deinem Eröffnungspost von Schrittverlusten. Im
allgemeinen ist dann die Last zu groß bzw. die Schrittfrequenz. Um das
wenigstens grob bestätigen zu können, hast Du die Möglichkeit die
Schrittfrequenz bzw. die Rate, mit der sie erhöht wird, zu verringern.
Mit einem binären Verfahren kannst Du (im allgemeinen) eine minimale
Schrittfrequenz bzw. minimale Änderungsrate finden, bei der es keine
Verluste mehr gibt. Vermutlich wird die zu gering sein, aber es geht
hier nur darum, ob es überhaupt geht. Falls es selbst bei extrem
geringen Frequenzen bzw. Raten nicht geht, liegt vermutlich ein
SW-Problem oder ein mechanisches Problem vor.
Falls Du eine gezielte Bewertung möchtest, wäre es zweckmäßig, wenn Du
uns mal folgende Angaben machst:
1. Motor, Typ, Link auf Datenblatt
2. Angaben zur Last und des dynamischen Verhaltens (falls anwendbar). Am
besten eine Zeichnung mit Massenangaben.
3. Quellcode des Codes der die Schrittfolge erzeugt (bitte auf das
wesentliche reduzieren; das Ergebnis sollte compilierbar sein).
4. Schaltung
Daniel F. schrieb:> ganze Umdrehung fährt, was genau 38000 Einheiten entspricht. Nun mache> Da es sich um eine Dreheinheit handelt, Ist die Position 38000 genau> gleich der Position 0, 38001 gleich 1 etc...
ACHTUNG: GLEICH GEHEN 6000 SCHRITTE VERLOREN!
> Wenn ich nun mehrere Umdrehungen fahre, kommen höhere Positionen von> Enocder und Motorcontroller zurück (z.B. bei 3 Umdrehungen 114000 etc).> Ich will die Positionen immer in den Bereich 0-31999 Mappen.> einer Umdrehung nur bei 31997 liegt, die Motoposition aber genau bei> 32000. Wenn ich nun Modulo mache, kommt beim Motor 0 raus und beim> Encoder bleibt die 31997. Das bedeutet für den Algorithmus, der die> Ich bin echt schon verzweifelt, kann mir hier jemand weiterhelfen??
Bitte, ab solchem Zahlensalat verzweifele auch ich ganz von alleine,
ohne weiter Hilfe...
Daniel F. schrieb:> Wenn ich nun Modulo mache, kommt beim Motor 0 raus und beim> Encoder bleibt die 31997.
Lass es einfach mit Modulo. Rechne einfach mit der Differenz. Das
entlastet dich und deinen Prozessor. Wenn die Differenz größer als 16000
oder kleiner als -16000 wird, korrigiere einfach mit 32000.
c-hater schrieb:> Wenn man bereit wäre, eine Abweichung vom Soll (also Vielfachen von> 38000) zu akzeptieren, dann muss das Ergebnis natürlich signed sein,> denn es wären ja sowohl positive als auch negative Abweichungen denkbar.
Ja, die Abweichungen sind akzeptierbar und summieren sich über die Zeit
auch nicht, das wurde intensiv getestet, die Abweichungen liegen auch
innerhalb der Toleranz. Es handelt sich um eine Dreheinheit, d.h. es
wird in beide Richtungen gefahren, je nachdem in welche Richtung die
Zielposition näher ist.
c-hater schrieb:> Also muss man nach dem Modulo noch mit der Hälfte der Encoderschritte> vergleichen. Ist das Modulo kleiner als die Halfte der Encoderschritte,> dann handelt es sich um eine positive Abweichung->der Fehlerwert> entspricht direkt dem gefundenen Modulo-Wert.>> Ist er hingegen größer als die Hälfte der Encoderschritte, dann ist die> Abweichung negativ und man erhält sie, indem man das Modulo-Ergebnis von> der Zahl der Encoderschritte/Umdrehung abzieht.
Das Problem ist, dass die Dreheinheit, wenn sie gerade keine genaue
Position anfahren muss, in einem sogenannten Idle Mode immer ganzzahlige
Umdrehungen fährt (z.B. 3 Umdrehungen alle 30 Sekunden). D.h. der
Motortreiber zählt die Schritte mit, die dann natürlich weit über 32000
liegen (Sorry, der erste Post mit den 38000 war tatsächlich falsch, es
handelt sich bei einer Umdrehung genau um 32000 Einheiten). Annahme:
Motor steht bei Position null nach referentfahrt und macht dann 3 ganze
Umdrehungen: nach Ausführung steht Motor bei 96000, der Encoder irgendwo
in der Nähe, Beispiel 95998. Nun gibt es natürlich nur die Positionen
0-31999, was auch logisch ist, denn im normalen betrieb (nicht Idle)
wird auch immer nur eine von 80 Positionen am Kreis angefahren, es ist
sonst nie eine ganze Umdrehung notwendig. Deswegen will ich nach so eine
IDLE Umdrehung die Position wieder in den Bereich 0-31999 Mappen, damit
bei eine normalen Positionierung (außerhalb Idle mode, wo die
Zielposition zwischen 0 und 31999 liegt) nicht die ganezn Umdrehungen
wieder zurück gefahren werden müssen. Man stelle sich nur vor, wenn die
Anzahl der Idle Umdrehungen nicht 3, sondern 10 oder noch höher wird...
Patrick J. schrieb:> So wie ich Das verstehe, 'schwanken' die Encoder-Schritte um +/-1> Das wäre kein Problem, da dieser Abstand wohl 'im grünen Bereich' ist.> Das Problem wird erst Eins, wenn die Soll-Position 'normiert' wird, also> von 38000 auf 0 gesetzt wird, wodurch die Differenz auf 37999 anwächst,> was wohl einen Schlepp-Fehler anzeigen wird (+Abbruch).
Richtig!
Patrick J. schrieb:> Kann der Motor auch anders herum verfahren, oder wird Dieser IMMER nur> in eine Richtung angesteuert, da so an eine Verriegelung angefahren> wird?
Ja genau, es wird in beide Richtungen gefahren, siehe Beschreibung oben.
Motorenfütterer schrieb:> ACHTUNG: GLEICH GEHEN 6000 SCHRITTE VERLOREN!
Sorry, wie bereits erwähnt, war dies falsch, es handelt sich um 32000
Einheiten bei einer ganzen Umdrehung.
DANKE!
Daniel F. schrieb:> Durch Ungenauigkeiten kann es sein, dass die Encoderposition z.B. nach> einer Umdrehung nur bei 31997 liegt, die Motoposition aber genau bei> 32000.
LOL.
Wenn du dich aufs zählen der Schritte verlässt und dein Encoder so
ungenau ist, wozu brauchst du es dann überhaupt ?
Entweder stimmen die Schritte, dann brauchst du normallerweise keinen
Encoder, oder die Schritte stimmen nicht, dann musst du dich aber auf
den Encoder verlassen können.
Schritte (die nach deinen Angaben genau sind) mit einem Encoder zu
kontrollieren (der nach deinen Angaben ungenau ist) - ist ein
bisschen schizophren, oder ?
> Wenn ich nun Modulo mache, kommt beim Motor 0 raus und beim> Encoder bleibt die 31997. Das bedeutet für den Algorithmus, der die> beiden Werte auf Abstand vergleicht, dass der Abstand zu hoch ist.
So etwas nennt man Tolleranz. Entweder bleibt diese in Grenzen, dann
wird der Fehler auf erlaubten Wert geprüft, oder nicht - dann wird
der Encoder weggeschmissen, so einfach ist das.
Und das kann mit einem Vergleich auf:
1
(WERT-MaxFehler)&&(WERT+MaxFehler)
ganz einfach festgestellt werden.
Falls true, EncoderWert = SollPosition und weiter geht es mit Modulo...
Marc V. schrieb:> So etwas nennt man Tolleranz. Entweder bleibt diese in Grenzen, dann> wird der Fehler auf erlaubten Wert geprüft, oder nicht - dann wird> der Encoder weggeschmissen, so einfach ist das.> Und das kann mit einem Vergleich auf: (WERT - MaxFehler) && (WERT +> MaxFehler)> ganz einfach festgestellt werden.> Falls true, EncoderWert = SollPosition und weiter geht es mit Modulo...
Ich glaube du verstehst mein Problem nicht ganz... es ist nicht die
Überprüfung das Problem, sondern dass nach dem Move die werte nicht mehr
zwischen 0-31999 liegen. natürlich könnte ich die Überprüfung vorher
machen, das ändert aber nichts daran, dass die werte danach nicht im
definierten Bereich liegen.
Danke,lG
Das ist ein klassisches Problem. Tritt auch bei jedem Ringpuffer auf, da
ja dort auch bei einem Überlauf vorne wieder angefangen wird.
Reinschreiben und Auslesen, kein Problem. Aber wieviel ist drin oder
frei?
Das gleiche gilt auch für Timer mit Überlauf. Im Umfeld einer dieser
beiden Anwendungen würde ich mal nach Lösungen suchen.
MfG Klaus
Daniel F. schrieb:> Ich glaube du verstehst mein Problem nicht ganz... es ist nicht die> Überprüfung das Problem, sondern dass nach dem Move die werte nicht mehr> zwischen 0-31999 liegen. natürlich könnte ich die Überprüfung vorherMarc V. schrieb:
1
(WERT-MaxFehler)&&(WERT+MaxFehler)
Falls true,
EncoderWert = SollPosition
und weiter geht es mit
EncoderWert % WomitAuchImmer
...
Ok, angenommen, die beiden Positionen sind nach einem Idle Move bei:
motorpos: 96000
encoderpos: 96003
Nehmen wir weiters an, dass die maxuimale Abweichung bei +/- 10 liegt,
d.h. Abweichungen innerhalb dieser Toleranz werden akzeptiert.
Was ist in diesem Fall die Variable "WERT" in deinem beschriebenen
Algorithmus?
Wenn ich einen Encoder habe, dann ist der doch bindend. D.h. ich
berechne die nächste Schrittzahl des Motors ausgehend von der
Encoderposition.
Ansonsten kann ich mir den Encoder doch gleich schenken.
Peter D. schrieb:> Ansonsten kann ich mir den Encoder doch gleich schenken.
LOL.
Ja.
Marc V. schrieb:> So etwas nennt man Tolleranz. Entweder bleibt diese in Grenzen, dann> wird der Fehler auf erlaubten Wert geprüft, oder nicht - dann wird> der Encoder weggeschmissen, so einfach ist das.
Daniel F. schrieb:> Das Problem ist, dass die Dreheinheit, wenn sie gerade keine genaue> Position anfahren muss, in einem sogenannten Idle Mode immer ganzzahlige> Umdrehungen fährt (z.B. 3 Umdrehungen alle 30 Sekunden).
Erstmal: Warum tut sie das? Welcher grenzdebile Vollidiot hat ihr das
befohlen? Das ergibt doch überhaupt keinen Sinn...
Und selbst wenn irgendwo ein verborgener Sinn dahinterstecken sollte:
Das ändert rein garnix. Es gilt immer noch der von mir beschriebene
Algorithmus als bestmögliche Näherung. Funktioniert definitiv so lange,
wie der Fehler jederzeit kleiner bleibt als die Hälfte des
Encoder-Zählumfangs.
Was natürlich jedem Nicht-Vollidioten unmittelbar klar sein sollte. Der
wäre allerdings auch selber auf den Algorithmus gekommen. Ist ja
schließlich nicht gerade höhere Mathematik...
Daniel F. schrieb:> Ok, angenommen, die beiden Positionen sind nach einem> Idle Move bei:> motorpos: 96000> encoderpos: 96003
Okay.
> Nehmen wir weiters an, dass die maxuimale Abweichung> bei +/- 10 liegt, d.h. Abweichungen innerhalb dieser> Toleranz werden akzeptiert.
Okay. Also berechnest Du "diff:=motorpos-encoderpos",
da kommt also diff=-3 heraus.
Jetzt reduzierst Du encoderpos auf den Hauptwert, da kommt
3 heraus.
Wo ist das Problem?
Wenn es mit zwei Absolutpositionen PARTOUT nicht klappen
will, dann versuche es doch mal mit einer Position und einer
Differenz...
Klaus schrieb:> Das gleiche gilt auch für Timer mit Überlauf. Im Umfeld> einer dieser beiden Anwendungen würde ich mal nach Lösungen> suchen.
Sehr guter Tipp.
Das mentale Problem ist, dass man Ueberlauf i.d.R. im
Zusammenhang mit vorzeichenlosen Zahlen hat, Differenzen
aber positiv und negativ sein koennen.
Die Diskussion ueber Timer hat (bei mir) die Erkenntniss
reaktiviert, dass alles perfekt funktioniert, wenn man
1. alle Absolutwerte vorzeichenbehaftet speichert und
2. sicherstellt, dass die DIFFERENZ keinen Ueberlauf
(weder positiv noch negativ) erleidet.