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é
>Es muss also irgendein Rundungsfehler sein. Richtig. >Wie kann ich dieses Problem umgehen? Mit float jedenfalls nicht.
@ René P. (speedy909) >genau die Zahl 10000,0! Es muss also irgendein Rundungsfehler sein. Jo. > Wie kann ich dieses Problem umgehen? Nimm Festkommaarithmetik @ Daniel (Gast) >double? Ist beim AVR-GCC indentisch mit float und single, 32 Bit floating point. MfG Falk
auch dann kann nicht jede Zahl exakt dargestellt werden, sondern nur die nächstliegende. Und ob double überhaupt unterstützt wird?
H.joachim Seifert schrieb: > Und ob double überhaupt unterstützt wird? 0.075 ist auch als double nicht exakt darstellbar. Die Masse macht's hier nicht.
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?
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.
Die Anzeige wird korrekt sein. Am besten du nimmst tatsächlich Festkomma, passt bequem in eine 32Bit Variable.
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.
>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.
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!
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.
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?
René P. schrieb: > Und wie kann ich dann zb. G-Code interpretieren wenn ich zuerst alles in > schritte umrechnen muss? richtig gut erkannt.
René P. schrieb: > Ich versuch es mal zu erklären... > <snip> Das alles erfordert aber keinerlei float-Berechnungen. Eher im Gegenteil. Oliver
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
Oliver schrieb: > René P. schrieb: >> Ich versuch es mal zu erklären... >> <snip> > > Das alles erfordert aber keinerlei float-Berechnungen. Eher im > Gegenteil. > > Oliver Nein, das nicht aber ich dachte bisher das dies die einfachste Lösung wäre, seit ich aber gesehen habe was da für Probleme dahinter stecken, muss ich das nochmals alles überdenken.
32Bit Zahlen mit 1 Mikrometer Einheit macht +/- 2m Zahlenbereich. Für Rampen und Verfahrwege gibt es Herrn Bresenham.
Falk Brunner schrieb: > 32 mit 1 Mikrometer Einheit macht +/- 2m Zahlenbereich. Für Rampen und > Verfahrwege gibt es Herrn Bresenham. ist aber dumm wenn der drehgeber 2.37 Mikrometer je Takt ergibt
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
Falk Brunner schrieb: > 32Bit Zahlen mit 1 Mikrometer Einheit macht +/- 2m Zahlenbereich. Für > Rampen und Verfahrwege gibt es Herrn Bresenham. Ü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
Peter II schrieb: >> 32 mit 1 Mikrometer Einheit macht +/- 2m Zahlenbereich. Für Rampen und >> Verfahrwege gibt es Herrn Bresenham. > ist aber dumm wenn der drehgeber 2.37 Mikrometer je Takt ergibt um so besser, dann hat man ja schon mehr als +/- 4m Verfahrweg
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.
>Ü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.
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 :-)
holger schrieb: > Du rechnest nicht in mm sondern in um. > 123,456mm = 123456um. und nun? wenn der Drehgeben aber 5,7µm ergibt? Es ist nicht sinnvoll sich ein irgendwelche einheiten zu klammern.
@ Peter II (Gast) >ist aber dumm wenn der drehgeber 2.37 Mikrometer je Takt ergibt Kann man auf 64 Bit aufbohren oder gescheit kaskadieren, rechnet man halt beim Bresenham mit Angström ;-) http://de.wikipedia.org/wiki/%C3%85ngstr%C3%B6m_%28Einheit%29
>und nun? wenn der Drehgeben aber 5,7µm ergibt? Es ist nicht sinnvoll >sich ein irgendwelche einheiten zu klammern. Dann rechne in Nanometern. Alles eine Frage des Bezugspunktes.
holger schrieb: > Dann rechne in Nanometern. Alles eine Frage des Bezugspunktes. und wozu? Einfach als einheit "schritte" verwenden. Das ist das kleinste was die Hardware hergibt also kann man es auch als kleinste einheit nutzen.
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?
René P. schrieb: > ok, also rechne ich einfach die 123,456mm in Schritte um 1646,08 = 1646 > und berechne meine Sollposition über Bresenham? ja
René P. schrieb: > 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? keine ahnung, aber hier scheint es zu stehen: http://de.wikipedia.org/wiki/Rasterung_von_Kreisen
Falk Brunner schrieb: > @ Daniel (Gast) > >>double? > > Ist beim AVR-GCC indentisch mit float und single, 32 Bit floating point. Oh! Danke, das wusste ich nicht; gebe zu, noch nie auf einem µC Fließkomma benutzt zu haben (war vielleicht intuitiv auch richtig). Deshalb war mein "double"-Vorschlag schon etwas provokativ.
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
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.