Forum: Mikrocontroller und Digitale Elektronik long double (80Bit) mit STM32F4 ?


von Pepe (Gast)


Lesenswert?

Hallo.
Ich hab eine Bahnsteuerung mit 100us Regeltakt und hab eine ziemlich 
hohe Encoderauflösung (0,5um). Das Profil wird als S-Kurve berechnet.

Für die Fahrten berechne ich die Werte für die einzelnen Abschnitte ( 
Jerk-Accel-Jerk-etc ) vor, so dass ich während der Fahrt nur noch die 
neue Sollposition "addieren" muss. Funktioniert soweit ganz gut.

Nur bei extrem langsamen Fahrten bekomme ich einen Versatz am Ende der 
Fahrt. So weit ich sehe, kommt der Versatz aus einer minimalen Differenz 
bei jedem Erhöhen der nächsten Sollposition.

Verwende zum berechnen jeweils double Werte (64Bit).
Hatte mir gedacht das ganze mal mit Long double (80Bit) zu probieren. 
Wäre einfacher als die ganze Bahnsteuerung noch mal zu ändern.
Nur leider gibt es anscheinend kein 80Bit Long double für den STM32.

Kennt jemand eine Lösung?

Vielen Dank schon mal.
Pepe

von c-hater (Gast)


Lesenswert?

Pepe schrieb:

> Kennt jemand eine Lösung?

1) Nachdenken, ob der existierende Code wirklich sinnvoll ungesetzt ist.
2) Nachdem die einzig richtige Antwort ("nein") gefunden ist: den
   bestehenden Code algorithmisch verbessern.

Und nein: Datentyp-Bloat ist keine Lösung, sondern nur ein Verschieben 
des Problems in die Zukunft. Nur Schlipsies halten sowas für eine 
Lösung. Die begreifen nämlich nicht: Es könnte u.U. eine sehr nahe 
Zukunft sein...

von Tom (Gast)


Lesenswert?

Pepe schrieb:
> Ich hab eine Bahnsteuerung mit 100us Regeltakt und hab eine ziemlich
> hohe Encoderauflösung (0,5um). Das Profil wird als S-Kurve berechnet.

Erzähl noch mal, was wird bei dir gesteuert und was wird geregelt?

von (prx) A. K. (prx)


Lesenswert?

Pepe schrieb:
> Nur leider gibt es anscheinend kein 80Bit Long double für den STM32.

Das gibts m.W. aktuell ausschliesslich bei x86 und IA64.

von (prx) A. K. (prx)


Lesenswert?

Dass der STM32F4 in Hardware nur mit 32-Bit Fliesskommaformat rechnen 
kann weiss du?

von m.n. (Gast)


Lesenswert?

Pepe schrieb:
> Hatte mir gedacht das ganze mal mit Long double (80Bit) zu probieren.

Geht Deine Meßstrecke hinter den Mond?

Pepe schrieb:
> so dass ich während der Fahrt nur noch die
> neue Sollposition "addieren" muss. Funktioniert soweit ganz gut.

Vermutlich addierst Du dabei auch die Fehler.

von (prx) A. K. (prx)


Lesenswert?

Auch mit dem 64 Bit Format kommt er fast bis zum Mond, ohne an 
Genauigkeit zu verlieren.

Mit 32 Bits aber nur ein paar Meter weit.

: Bearbeitet durch User
von Pepe (Gast)


Lesenswert?

Meine Meßstrecke geht nicht hinter den Mond, wär aber sicher auch mal 
eine Reise wert...

Ich hab das Ganze schon am PC "gegen gerechnet" und ich bekomme dann 
irgendwo eine kleine Abweichung zwischen STM und PC bei irgendeiner 
Nachkommastelle weit hinten. Da ich aber teilweise ziemlich langsam 
fahren muss, hab ich dann leider diesen Fehler in der Endposition.

Hatte eigentlich gehofft das Problem "verschieben zu können", obwohl ich 
kein Schlipsie bin.

von Pepe (Gast)


Lesenswert?

@A.K.
Verwende kein Hardware-Float, nur Software-Double :-)

von (prx) A. K. (prx)


Lesenswert?

Wenn die Apollo Mission freilich alle 0,5µm in 64-Bit Fliesskommaformat 
den Kurs neu berechnet hätte, dann wären die ganz bestimmt nicht auf dem 
Mond gelandet. ;-)

von Pepe (Gast)


Lesenswert?

Ach komm', der Z80 hat doch genügend Leistungsreserven und die Akkus 
waren doch damals auch nicht schlechter als die von heute ;-)

von Bernd K. (prof7bit)


Lesenswert?

Pepe schrieb:
> Verwende zum berechnen jeweils double Werte (64Bit).

Da muss ein grundsätzlicher Fehler in Deinem Algorithmus sein. Die 
Rundungsfehler bei Double sollten sich irgendwo an der sechzehnten 
Nachkommastelle abspielen.

Addierst Du vielleicht irgendwo millionenfach wiederholt irgendein 
winzig kleines Delta zu einem riesengrossen Wert? Wenn ja dann solltest 
Du das vielleicht mal umbauen, eventuell das ganze so umformen daß du 
diese Millionen von wiederholten Additionen ersetzt durch wenige 
Multiplikationen und nur noch Werte addierst die größenordnungsmäßig 
nicht zu weit auseinander liegen.

von Bernd K. (prof7bit)


Lesenswert?

Pepe schrieb:
> so dass ich während der Fahrt nur noch die
> neue Sollposition "addieren" muss

Rechne die Sollposition mit wenigen Multiplikation jedesmal neu aus und 
nicht mit millionen kleinster Additionen.

Oder addiere wenigstens erstmal die winzigen deltas separat (und merk 
Dir ihre Summe daß Du sie wiederverwenden kannst) und addiere diese erst 
ganz zum Schluss zur Absolutposition.

Addiere niemals zwei Zahlen die sich um ein Dutzend Größenordnungen 
unterscheiden (und schon gar nicht mehrmals) und erwarte daß das 
irgendein sinnvolles Ergebnis liefern würde.

: Bearbeitet durch User
von Pepe (Gast)


Lesenswert?

@Bernd K.
Genau das ist mein Problem.

Hatte die Bahnberechnung schon mal so integriert, dass ich die 
SollPosition immer berechne, aber das bedeutet ja, ein Integral in jedem 
Takt des Trajectorygenerators zu berechnen. Da hatte ich dummerweise 
meine Taktvorgabe gesprengt. Also hatte ich mir die Lösung mit dem 
Addieren überlegt.

von Pepe (Gast)


Lesenswert?

Bernd K. schrieb:
> Oder addiere wenigstens erstmal die winzigen deltas separat (und merk
> Dir ihre Summe daß Du sie wiederverwenden kannst) und addiere diese erst
> ganz zum Schluss zur Absolutposition.

Genau das mache ich: Deshalb macht ja die Achse einen Sprung am Ende der 
Fahrt. Dies bringt mich dann natürlich mit dem Einschwingen in der 
Endlage in Probleme.

von Tom (Gast)


Lesenswert?

Pepe schrieb:
> Da ich aber teilweise ziemlich langsam
> fahren muss, hab ich dann leider diesen Fehler in der Endposition.

Bleibt die Frage, wieso sich bei einer Regelung Fehler aufaddieren 
können.
Was regelst du und was steuerst du?

von Pepe (Gast)


Lesenswert?

@Tom:
Bei der Regelung addiert sich aber kein Fehler auf, sondern bei der 
Bahnsteuerung.

Ablauf:
Bahnsteuerung berechnet die Sollpositionen, welche abgefahren werden 
sollen. Die Lageregelung kümmert sich dann darum, dass die Achs doch hin 
fährt.

Also eigentlich wie jede normale Achse.

von Helmut S. (helmuts)


Lesenswert?

Einfach überprüfen ob der nächste Schritt die Zielposition überfährt.
Falls ja, dann "nächste_Position = Endposition".

von Pepe (Gast)


Lesenswert?

Helmut S. schrieb:
> die Zielposition überfährt

Würde mir wenigstens was bringen, wenn ich zu weit fahre. Aber bei zu 
kurz hab ich noch keine Lösung. Aber wenigstens ist dann schon mal das 
"Zurückspringen" weg. Könnte mir vorstellen, dass ein "Weiterspringen" 
weniger Probleme macht, als gegen die Fahrtrichtung...

von Pepe (Gast)


Lesenswert?

Mal eine andere Frage: Kann mir jemand sagen, wie die Sollposition 
"normalerweise" während der Fahrt berechnet wird?

von Jobst M. (jobstens-de)


Lesenswert?

Also Int32 kann 2km in 0,5µm auflösen ... immer.
Wenn es mehr sein soll, dann muß man alle 2km einen übertrag machen.
Also quasi Int64. Dann kommt man auch hinter der Sonne lang ... 29 mal 
...
Oder 8x die ErdumlaufBAHN um die Sonne.
Ich weiß zwar nicht, wie man deren Position auf 0,5µm genau bestimmt, 
Zählfrequenz dürfte dann aber so bei 60GHz liegen.

Um was für eine Bahn geht es eigentlich? Modellbahn? :-)


Gruß

Jobst

von m.n. (Gast)


Lesenswert?

Jobst M. schrieb:
> Also Int32 kann 2km in 0,5µm auflösen ... immer.

Das funktioniert aber nur in einer eindimensionalen Welt. Eine S-Kurve 
braucht schon zwei Dimensionen. Und zum Mond kommt man damit schon 
garnicht.

von Pepe (Gast)


Lesenswert?

m.n. schrieb:
> Eine S-Kurve
> braucht schon zwei Dimensionen

Zwei Dimensionen braucht meine S-Kurve aber nicht. Ich fahr doch immer 
nur in einer Achse ;-)

Jobst M. schrieb:
> Also Int32 kann 2km in 0,5µm auflösen

Stimmt schon. Die Auflösung reicht locker. Nur bringt mir ein ganzer 
Encoderschritt nichts, wenn ich bei langsamen Fahrten 0,001 Enc/Zyklus 
fahren möchte.

von uwe (Gast)


Lesenswert?

> Nur bringt mir ein ganzer Encoderschritt nichts, wenn ich bei langsamen
> Fahrten 0,001 Enc/Zyklus fahren möchte.
Wo ist denn das Problem?!
Dann leg doch fest: 0,001=1 und 1=1000 dann kannst du zwar keine 2km 
mehr fahren sondern nur 2m. Und wenn das nicht reicht nimmst du halt 
64bit.

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Pepe schrieb:
> wenn ich bei langsamen Fahrten 0,001 Enc/Zyklus
hab ich mich nur verrechnet, oder sind das tatsächlich 18mm/h?

von Pepe (Gast)


Lesenswert?

OK. Zum besseren Verständnis:
Ich verwende verschiedene Achsen, die dummerweise extrem 
unterschiedliche "Aufbauten" haben. Ich hab Achsen die mit 0,5um 
Auflösung aufgebaut sind und andere mit 0.75mm. ( Da sind dann 
0.001um/Takt nicht mehr ganz so langsam :-) )
Ist mir klar, dass dies unterschiedliche Voraussetzungen sind, aber die 
hab ich leider.
Im Großen und Ganzen funktioniert die Firmware ja auch so wie sie soll, 
aber eben in den Grenzbereichen gibt's noch leichte Rundungsprobleme.
Wenn's geht würde ich halt gerne alles mit nur einer Firmware abdecken.

von Pepe (Gast)


Lesenswert?

Pepe schrieb:
> 0.001um/Takt

Meinte natürlich 0.001Enc/Takt

von Amateur (Gast)


Lesenswert?

Ich denke, dass der "genutzte" Bereich kalkulierbar ist. Aus diesem 
Grunde würde ich Festkommaarithmetik, zu der es mehrere Bibliotheken 
gibt, empfehlen.

Darüber hinaus sollte man - die Fehler sind kalkulierbar - mal 
überlegen, ob diese, über die theoretische Betrachtung hinaus, überhaupt 
das Ergebnis beeinflussen. Im Normalfall kann man mit einem Fehler von 
0,00001 gut leben.

Ich weiß, dass die Zerleger sagen werden: Der obige Fehler, bezogen auf 
ein Lichtjahr, ist nicht zu tolerieren.

von m.n. (Gast)


Lesenswert?

Amateur schrieb:
> Ich denke, dass der "genutzte" Bereich kalkulierbar ist. Aus diesem
> Grunde würde ich Festkommaarithmetik, zu der es mehrere Bibliotheken
> gibt, empfehlen.

Beim STM32F4 wäre diese Gewürge das Allerletzte!

von (prx) A. K. (prx)


Lesenswert?

Amateur schrieb:
> Ich denke, dass der "genutzte" Bereich kalkulierbar ist. Aus diesem
> Grunde würde ich Festkommaarithmetik, zu der es mehrere Bibliotheken
> gibt, empfehlen.

Wenn man um die Beschränkungen der Mantissenlänge weiss ist 
Fliesskommaarithmetik nicht notwendigerweise teuflischer als 
Festkommaarithmetik. Dafür aber von Haus aus vorhanden und je nach 
Prozessor und gewünschter Rechenbreite erheblich schneller.

von Jay (Gast)


Lesenswert?

Pepe schrieb:
> Im Großen und Ganzen funktioniert die Firmware ja auch so wie sie soll,
> aber eben in den Grenzbereichen gibt's noch leichte Rundungsprobleme.
> Wenn's geht würde ich halt gerne alles mit nur einer Firmware abdecken.

Das mit dem Im Großen und Ganzen ist Ansichtssache. Im Embedded-Bereich 
würde man eher sagen, dein Algorithmus ist in Teilbereichen, vermutlich 
durch Rundungsfehler, instabil. "Instabil" ist ganz weit weg von 
"funktioniert", weil es eine fundamentale Sache ist.

Ins Blaue gedacht, weil ich keine Lust habe, mir die Details anzusehen 
oder dir aus der Nase zu ziehen und mit der Gefahr das ich mich auf die 
Schnelle verrechnet habe:

Feste Minimalschritte wie 0,5 µm schreien nach Integer. Nehmen wir an, 
du würdest mit einem 64-Bit Integer (nicht float) rechnen, und in 0,5 µm 
Schritten, dann würde sich in einem 64 signed int eine Strecke von rund 
4,6^9 km rundungsfrei aufsummieren lassen. Das ist rund 12000 mal die 
Entfernung Erde - Mond, in 0,5 µm Schritten. Man könnte das Gefühl 
bekommen, dass ist mehr als genug für eine Bahnsteuerung.

Man kann sich sogar den Luxus gönnen, ein paar Integer-Stellen als 
Nachkommastellen zu betrachten (fixed point Arithmetik).

Mit 32 signed int käme man auf rund 1 km die sich in 0,5 µm Schritten 
summieren lassen. Vielleicht würde sogar das reichen.

Was noch nicht erwähnt wurde, kann man sich auf die 0,5 µm überhaupt 
verlassen? Wie sieht denn der Schlupf der Räder aus? Könnte es sein, das 
das keine Rundungsfehler in der Rechnung, sondern Fehler in der 
Entfernungsmessung sind?

von Pepe (Gast)


Lesenswert?

Mein Problem liegt darin, dass ich durch das regelmäßige Aufsummieren 
während der Fahrt den berechneten Fehler jedes Mal wieder auf die 
Sollposition drauf addieren. Dadurch kommt die Bahnsteuerung zu einem 
anderem Ergebnis als die Zielposition eigentlich sein sollte. Dann gibt 
es einen kurzen "Sprung" in der Achse was mir das Einschwingen in der 
Zielposition verschlechtert.

PS. Zum Thema Schlupf: wir verwenden lineare Maßstäbe mit direkter 
"mechanischer Kopplung".

von Little B. (lil-b)


Lesenswert?

Pepe schrieb:
> Ich hab Achsen die mit 0,5um
> Auflösung aufgebaut sind und andere mit 0.75mm.

Ich sehe dein Problem im Aufbau.

Du willst eine Achsposition auf 64bit (oder 80bit) genau regeln, die 
aber nur mit 12bit Genauigkeit bestimmt werden kann.

von m.n. (Gast)


Lesenswert?

Pepe schrieb:
> Mein Problem liegt darin, dass ich durch das regelmäßige
> Aufsummieren
> während der Fahrt den berechneten Fehler jedes Mal wieder auf die
> Sollposition drauf addieren. Dadurch kommt die Bahnsteuerung zu einem
> anderem Ergebnis als die Zielposition eigentlich sein sollte.

Kannst Du Zwischenpunkte nicht zusätzlich berechnen und an diesen 
Stellen die jeweilige Zielposition korrigieren? Dann bleiben die Fehler 
während einer Fahrt immer klein.

von Bernd K. (prof7bit)


Lesenswert?

Pepe schrieb:
> Mein Problem liegt darin, dass ich durch das regelmäßige Aufsummieren
> während der Fahrt den berechneten Fehler jedes Mal wieder auf die
> Sollposition drauf addieren. Dadurch kommt die Bahnsteuerung zu einem
> anderem Ergebnis als die Zielposition eigentlich sein sollte.

Dann versuch das Integral so zu lösen daß Du nicht Millionen winziger 
Deltas zusammenzählen musst sondern die Sollposition einfach direkt in 
Abhängigkeit von der Zeit ausrechnen kannst.

von M. K. (sylaina)


Lesenswert?

Pepe schrieb:
> Verwende zum berechnen jeweils double Werte (64Bit).
> Hatte mir gedacht das ganze mal mit Long double (80Bit) zu probieren.

64 bit bei 0.5 µm Auflösung reichen dir nicht? Deine Strecke ist also 
~9,2e9 km lang? Also die Sonne ist näher an der Erde. Und jetzt willst 
du noch auf 80 bit gehen? Da wird mit hoher Wahrscheinlichkeit nur dein 
Rundungsfehler, den man bei endlichen Zahlenraum immer hat, immer 
größer. Ich empfehle dir mal ein Buch über numerische Mathematik:

http://www.amazon.de/Numerische-Mathematik-Eine-beispielorientierte-Einführung/dp/3446432337/ref=sr_1_2?ie=UTF8&qid=1444933167&sr=8-2&keywords=numerische+berechnung

von Nosnibor (Gast)


Lesenswert?

Könnte hier der gute alte Bresenham helfen?

Das Problem ist doch (vereinfacht): "Ich muß eine Strecke von x 
Schritten in y Zeiteinheiten zurücklegen. Zu welchen Zeitpunkten ist 
jeweils ein Schritt fällig?"

Wenn man sich die Schritte pro Zeiteinheit (also x/y) ausrechnet, und 
damit dann die Sollposition zu jeder Zeiteinheit akkumuliert, braucht 
man sehr viele Nachkommastellen und wird immer noch nicht 
hundertprozentig genau sein (der Taschenrechner läßt grüßen: 1/3 + 1/3 + 
1/3 = 0,9999...).
Der Bresenham-Algorithmus hält stattdessen Zähler und Nenner getrennt, 
so daß der Rundungsfehler bei der Division x/y nicht auftreten kann.

Gesucht ist jetzt also ein Bresenham-ähnlicher Algorithmus für eine 
S-Kurve anstatt eine Gerade.

von Amateur (Gast)


Lesenswert?

>Beim STM32F4 wäre diese Gewürge das Allerletzte!

Eine interessante Einstellung!

Die eingebaute Fließkommaarithmetik reicht nicht aus also:

Software basierte Berechnung (Ist gut)

Festkommaberechnung durch Software (Ist schlecht) ;)

von Clemens L. (c_l)


Lesenswert?

Pepe schrieb:
> Hatte die Bahnberechnung schon mal so integriert, dass ich die
> SollPosition immer berechne, aber das bedeutet ja, ein Integral in jedem
> Takt des Trajectorygenerators zu berechnen. Da hatte ich dummerweise
> meine Taktvorgabe gesprengt.

Das Problem ist ja, dass die Fehler größer werden, je länger die Strecke 
ist. Warum kannst du nicht die Soll-Position nach jeweils einer kurzen 
Strecke neu berechnen, z.B. ein mal pro Sekunde?

Kann die Steuerung eine regelmäßige Verzögerung verkraften? Oder kannst 
du die Berechnung in mehrere kleine Teile aufspalten?

: Bearbeitet durch User
von Pepe (Gast)


Lesenswert?

Clemens L. schrieb:
> Kann die Steuerung eine regelmäßige Verzögerung verkraften?

Ich würde die Berechnung der Position in der Main{}-Schleife laufen 
lassen. Die Regelung läuft eh im IRQ. Somit sollte die Berechnung der 
"Zwischenpositionen" kein zeitliches Problem darstellen.

Allerdings - wenn ich ehrlich bin - komme ich da zu einem mathematischen 
Problem: Hab dies schon versucht. Das Integral über den 1. Abschnitt der 
S-Kurve ist ja noch ok. (bei Anfangsgeschwindigkeit V0=0)
Der 2. Abschnitt ging auch noch: Gleichmäßige Beschleunigung mit V0<>0.
Aber beim 3. Abschnitt: S-Kurve mit abnehmender Beschleunigung und 
V0<>0. Dafür ist meine Mathematik schon ziemlich eingerostet.
( Vor allem bin ich mir ziemlich sicher, dass ich während des Studiums 
bzw. sogar schon während des Mathe-LKs so was gerechnet hatte... Aber 25 
Jahre lügen nicht ;-) )

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
Noch kein Account? Hier anmelden.