float Variable Berechnungsfehler

OP #2592561
Lesenswert?

Hallo,

Ich bin derzeit mit dem Bau einer CNC Fräse beschäftigt (zumindest 
versuche ich es). Jetzt stehe Ich derzeit vor dem Problem das ich mit 
Float Werten rechnen will. Dazu habe ich einen Versuchsaufbau 
zusammengestellt.

PC verbunden über RS232 mit einem Atmega8, der Atmega8 rechnet zu der 
Zahl 0.0 insgesamt 10000x hintereinander immer 0.075 zu einer Float 
Variable hinzu, dies müsste die Zahl 750.0 ergeben. Danach gebe ich die 
Zahl über RS232 an den PC weiter zur Anzeige.

Mein Problem an der Sache ist das bei mir am Computer 750,073059... 
angezeit wird. Wenn ich das ganze mit der Zahl 1.0 mache, erhalte ich 
genau die Zahl 10000,0! Es muss also irgendein Rundungsfehler sein. Wie 
kann ich dieses Problem umgehen?

Ich verwende AVR Studio und Programmiere in C

Ich hoffe jemand kann mir da einen Tipp geben.

Gruß
René
OP #2592671
Lesenswert?

Danke für die schnellen Antworten!

Mit double hab ich es auch schon probiert, hat mein Problem auch nicht 
gelöst.
Das heißt also wenn ich mit float rechnen will, dass ich mit dem Fehler 
leben muss...

Handelt es sich eigentlich nur um einen Anzeigefehler oder tatsächlich 
um einen Rundungsfehler?

Ich habe mal folgendes probiert:
10000x +0,075
5000x -0,075
2000x +0,075
6000x -0,075
9000x +0,075
anschließend habe ich das Ergebnis verglichen mit meinem 1. Ergebnis 
(10000x +0,075) und es war genau das selbe, es müsste sich also um einen 
Anzeigefehler handeln. Bin ich da Richtig?
Gast #2592675
Lesenswert?

René P. schrieb:
> Bin ich da Richtig?
nein.


Dann wenn du erst + und - machst dann ist auch der fehler wieder weg. Er 
rechne nicht.

x + 0.075

sondern

x + 0.0749999995

damit kommt es zu einen fehler wenn man immer addiert, wenn du es aber 
wieder subtrahiest dann ist auch der fehler wieder weg.
Gast #2592678
Lesenswert?

Die frage ist warum du überhaupt in float/double rechnen willst, denn 
deine CNC Fräse liefer doch nur impulse. Warum soll denn der µC es erst 
in mm umrechnen, lasse es doch einfach schritte sein.
Gast #2592680
Lesenswert?

>Handelt es sich eigentlich nur um einen Anzeigefehler oder tatsächlich
>um einen Rundungsfehler?

Rundungsfehler.

>Ich habe mal folgendes probiert:
>10000x +0,075

Probier das mal:

0,075 kann man ja auch als 75/1000 darstellen.
Jetzt addierst du 10000x 75 in ein uint32_t.
Zum Schluß teilst du durch 1000. Du wirst exakt 750 rausbekommen.
OP #2592705
Lesenswert?

Peter II schrieb:
> Er rechne nicht.
>
> x + 0.075
>
> sondern
>
> x + 0.0749999995
>

Ok, das macht jetzt den Fehler etwas verständlicher.

Peter II schrieb:
> Die frage ist warum du überhaupt in float/double rechnen willst, denn
> deine CNC Fräse liefer doch nur impulse. Warum soll denn der µC es erst
> in mm umrechnen, lasse es doch einfach schritte sein.

Ich versuch es mal zu erklären... Die Fräse soll intelligent sein (kein 
Computer zur Ansteuerung benötigen) Jede Achse hat einen Intelligenten 
Motortreiber, das Fahren von Hand mit Joystick oder ähnlichem sollte 
auch möglich sein, Fräsprogramm zb. auf SD Karte gespeichert, usw.

Es ist mir auf jedenfall einiges klar geworden, jetzt wo ich weiß warum 
es zu dem Fehler kommt. Jetzt muss ich mal einges überdenken.

Danke!
Gast #2592707
Lesenswert?

René P. schrieb:
> Ich versuch es mal zu erklären... Die Fräse soll intelligent sein (kein
> Computer zur Ansteuerung benötigen) Jede Achse hat einen Intelligenten
> Motortreiber, das Fahren von Hand mit Joystick oder ähnlichem sollte
> auch möglich sein, Fräsprogramm zb. auf SD Karte gespeichert, usw.

und? für die anzeige kann man es immer noch in mm umrechnen. Aber doch 
bitte nicht intern.
OP #2592712
Lesenswert?

Peter II schrieb:
> René P. schrieb:
>> Ich versuch es mal zu erklären... Die Fräse soll intelligent sein (kein
>> Computer zur Ansteuerung benötigen) Jede Achse hat einen Intelligenten
>> Motortreiber, das Fahren von Hand mit Joystick oder ähnlichem sollte
>> auch möglich sein, Fräsprogramm zb. auf SD Karte gespeichert, usw.
>
> und? für die anzeige kann man es immer noch in mm umrechnen. Aber doch
> bitte nicht intern.

Und wie kann ich dann zb. G-Code interpretieren wenn ich zuerst alles in 
schritte umrechnen muss?
Persönliche Seite #2592717
Lesenswert?

René P. schrieb:

> ..., der Atmega8 rechnet zu der Zahl 0.0 insgesamt 10000x
> hintereinander immer 0.075 zu einer Float Variable hinzu,
> dies müsste die Zahl 750.0 ergeben. Danach gebe ich die
> Zahl über RS232 an den PC weiter zur Anzeige.
>
> Mein Problem an der Sache ist das bei mir am Computer 750,073059...
> angezeit wird.

Das Problem ist hier, daß sich die Fehler akkumulieren. Falls du nicht 
aus float verzichten willst, dann verwende eine Formel, die besser 
konditioniert ist, d.h. anstatt
zum Beispiel
Während bei der ersten Formel bei größeren x Auslöschung eintritt und 
sich die Fehler n mal akkumulieren, gibt's bei der zweiten Formel 
keine Auslöschung und die Fehler akkumulieren sich nicht.

http://de.wikipedia.org/wiki/Kondition_(Mathematik%29
http://de.wikipedia.org/wiki/Auslöschung_(numerische_Mathematik%29
Gast #2592756
Lesenswert?

René P. schrieb:
> nur wie
> bring ich Bresenham bei mit Positionen wie 123,456mm klar zu kommen?
> Bresenham arbeitet ja mit Pixeln

aus den Grund ja der Tip einfach pixel (INTs) zu verwenden. ob es nun 
1/5mm sind oder 1/7mm ist dabei egal. Nimm das was du als input zur 
verfügung hast. (Schritte von Stepper oder vom Drehgeber) wieviel mm das 
am ende sind ist egal. Es wird nur für ein Eingabe und ausgabe in mm 
umgerechnet.
Gast #2592765
Lesenswert?

>Über den Bresenham Algorithmus habe ich auch schon gelesen, nur wie
>bring ich Bresenham bei mit Positionen wie 123,456mm klar zu kommen?
>Bresenham arbeitet ja mit Pixeln

Immer noch nichts dazugelernt? Du rechnest nicht in mm sondern in um.
123,456mm = 123456um. Eine schöne ganze Zahl. Die kannst du addieren
so oft du willst ohne irgendwelche Rundungsfehler.
Persönliche Seite #2592767
Lesenswert?

Walter S. schrieb:
> Johann L. schrieb:
>> Während bei der ersten Formel bei größeren x Auslöschung eintritt und
>> sich die Fehler n mal akkumulieren, gibt's bei der zweiten Formel
>> keine Auslöschung und die Fehler akkumulieren sich nicht.
>
> wobei der Fehler dass delta x evtl. nicht exakt in float darstellbar
> ist, auch bei der 2.Formel bleibt

Ja, stimmt :-)
OP #2592787
Lesenswert?

Peter II schrieb:
> René P. schrieb:
>> nur wie
>> bring ich Bresenham bei mit Positionen wie 123,456mm klar zu kommen?
>> Bresenham arbeitet ja mit Pixeln
>
> aus den Grund ja der Tip einfach pixel (INTs) zu verwenden. ob es nun
> 1/5mm sind oder 1/7mm ist dabei egal. Nimm das was du als input zur
> verfügung hast. (Schritte von Stepper oder vom Drehgeber) wieviel mm das
> am ende sind ist egal. Es wird nur für ein Eingabe und ausgabe in mm
> umgerechnet.

ok, also rechne ich einfach die 123,456mm in Schritte um 1646,08 = 1646 
und berechne meine Sollposition über Bresenham?

Dann bin ich genau da, wo ich damals bei meiner 1. Überlegung war...
Aber was ich beim Bresenham noch nicht so ganz kapiert habe, wie mach 
ich einen Teil-Kreis (nicht in 1/8 Kreis schritten sondern noch genauer) 
Und wie mache ich eine Elypse?
Gast #2593312
Lesenswert?

moin moin,

also auf meiner CNC wird auch alles in float gerechnet. Ist halt 
einfacher bei der Fräsradienkorrektur. Lineare Strecken werden per 
Bresenham und Kreis(bogen) klassisch per sin/cos berechnet.
Läuft allerdings auf einem Gespann C8051F340/C8051F365.

zu  +0,075....

0,075d -> (9A 99 99 3D)float -> 0,075000x
ist bei Dir also ein Rundungsfehler.
lass doch mal nur 10 oder 100 laufen.

Mit Gruß
Pieter

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren