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!
:
Verschoben durch User
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...
:
Bearbeitet durch User
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...
:
Bearbeitet durch User
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 vorher Marc 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?
Daniel F. schrieb: > Was ist in diesem Fall die Variable "WERT" in deinem beschriebenen > Algorithmus?
1 | if( (motorpos >= (encoderpos - Fehler)) && (motorpos <= (encoderpos + Fehler)) ) encoderpos = motorpos; |
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.