Hallo Leute, ich brauche für mein Projekt sehr viele Berechnungen, die ich in kürzester Zeit rechnen muss. Ich verwende einen 8bit-AVR(die bekanntlich nicht die schnellsten sind). Auf einen ARM oder ähnliches umzusteigen ist schon zu spät. Lohnt es sich, einen math-Coprocessor zu benutzen? Hat man dadurch große Ersparnisse? Ich habe an sowas wie den hier gedacht: http://www.sparkfun.com/commerce/pr.....info.php?products_id=8129 Hat jemand Erfahrungen mit sowas gemacht? Oder kennt jemand vielleicht ein besseres Modell? Gruß, Yaro
Gast
#1312936
Hier gibt es so eine FPU (soll angeblich ein DSPIC sein) mit Beispielen: http://www.micromegacorp.com/atmel.html Aber man sollte eigentlich VORHER die Rechenleistung abschätzen und dann erst den µC auswählen. avr
Gast
#1312951
Die FPU ist selber nicht die schnellste und wahrscheinlich nur eine Software-FPU. Alternativ kann man auch schnellere uCs nehmen z.B. mit 20Mhz oder eine extra uC als FPU programmieren. Es gibt auch Look up Tabellen.
Ja... den Rechenaufwand abschätzen ist nicht ganz so einfach, wie ich es mir vorgestellt hatte... Hatte noch nie ein so Zeitintensives Projekt, dass ich jeden einzelnen Takt zählen musste, wie ich es jetzt tue. Aber man lernt bekanntlich nie aus. Ist die Zeitersparniss mit diesem CoProzessor groß genug, dass es sich empfielt, ihn zu benutzen? Gruß, Yaro
Ich benutze schon einen 20MHz AVR. Ich denke, ein FPU ist schneller, weil es 32bit Architektur hat. Lookup-Tabellen habe ich schon einige implementiert, aber für einige Anwendungen müssten sie so groß sein, dass sie nicht in den Flash passen. Gruß, Yaro Edit: der Link am Anfang hat nicht funktioniert, hier ist er nochmal: http://www.sparkfun.com/commerce/product_info.php?products_id=8129
Versuchs mal mit Festkommaarithmetik Und vor allem sag mal, wieviel Berechungen du in welcher Zeit glaubst durchführen zu müssen. MFG Falk
Gast
#1312983
moin moin, als FPU nutze ich einen C8051F365( 1Takt Core) der mit 98MHz tackert. In einem 8051ED2 (22MHz, 6Takte-Core) braucht ein SIN ca. 900µs. Die FPU ist über SPI angebunden, der MainMC kann also auch was anderes sein. Mit FPU inklusive SPI braucht es für einen SIN-Wert nur 95µs. Die FloatLib ist auch im MC vorhanden, teilweise rechnen beide gleichzeitig und das spart. Mit Gruß Pieter
Gast
#1313060
Eine gute FPU bringt sicher Zeitersparnis. Aber diese FPU ist nicht sonderlich schnell (siehe Datenblatt). Sinus berechnen 100 µs - ohne senden, empfangen, sonstiges. Evtl kannst du mehrere nehmen oder eine andere. Oder zusätzliche Lookup Tabelle in externem EEpron etc...
an einen AVR ne FPU stricken, naja... Wenn man merkt, es reicht hinten und vorne nicht - umsteigen. Ich behaupte mal, den Performance-Gewinn büsst du durch Transferzeiten wieder ein. Sinn macht es erst dann, wenn du Funktionen auslagern kannst, in der Zwischenzeit was anderes machst und dann weiter im eigentlichen Text. Ob ein AVR-Compiler sowas kann? Eher wirst du stupide warten müssen. Gibt Rechenleistung satt, ARM.
Gast
#1313071
> Hatte noch nie ein so Zeitintensives Projekt, dass ich jeden einzelnen
Takt zählen musste,
Ja was rechnest du denn ?
Wirklich floating point, oder taete es auch soundsoviel bit fixed point
?
Sinus und Wurzel, oder nur Addition und Multiplikation ?
Eine richtige floating-point-implementation auf einem 8 bit Rechner ist
langsam, locker 1000 mal langsamer als ein arithmetic-coprozessor, der
es meist in 1 Takt macht, aber in vielen Faellen braucht man gar keine
floating point Funktionen um etwas korrekt auszurechnen.
Ich brauche öfters Winkelfunktionen (sin, cos usw.), und muss auch ab und zu floats teilen und multiplizieren. Wurzeln brauche ich auch manchmal, aber meißt mit einer nicht ganz so großen genauigkeit, da habe ich eine Ersatzfunktion geschrieben, die deutlich schneller ist. Lookup-Tabellen habe ich auch schon einige erstellt, klappt aber leider nicht für alle anwendungen. Optimirt habe ich auch schonn einge Menge, nur scheints, als ob das alles nicht genug sein wird. Ich komme im Moment mit der Leistung zwar noch hin, aber das sollte nicht mehr lange der Fall sein, denn ich brauche immer mehr Winkelfunktionen, die ich kaum ersetzen kann, und die Genaugkeit der floats ist auch z.T. notwendig. Der co.Prozessor hat eine 32bit Architektur, deswegen habe ich gehofft, dass er viel schneller ist. Aber 100µs für einen sin, ist ja genausoviel, wie ein ATmega (mit 16MHz) braucht, da kann ich ja gleich einen zweiten ATmega anschließen... Wie kann denn sowas eigentlich sein? das Ding arbeitet mit 30MHz mit einer 32bit Architektur, und ist dabei genauso schnell, wie ein AVR mit einer 8bit Architektur und 16MHz Kennt jemand eine FPU, die deutlich schneller ist, als diese hier? Den sonnst lohnt es sich ja wirklich nicht, sie anzuschließen... Gruß, Yaro
Yaroslav Gevorkov schrieb: > Wie kann denn sowas eigentlich sein? das Ding arbeitet mit 30MHz mit > einer 32bit Architektur, und ist dabei genauso schnell, wie ein AVR mit > einer 8bit Architektur und 16MHz An 32 Bits glaube ich eher nicht. Das Äussere passt aber prima zu Microchips 16bittern dsPIC30F2011 und 3012. Das Tempo auch.
Yaroslav Gevorkov schrieb: > Kennt jemand eine FPU, die deutlich schneller ist, als diese hier? > Den sonnst lohnt es sich ja wirklich nicht, sie anzuschließen... Anno 386/486 gab es mal ein paar fixe externe Varianten. Von Weitek und so. Könnte aber sein, dass dir beim Anschluss rasch die Pins ausgehen. ;-) Schnelle externe FPU und pinsparender serieller Anschluss beisst sich etwas. Aber komplette Controller, die sich für sowas ähnlich der uM-FPU programmieren lassen, gibt es durchaus. Diverse ARM7 und Cortex-M3 in TQFP48 beispielsweise. Weniger Pins gibt es zwar auch, aber kleiner ist ein SO28 effektiv auch nicht.
Pins sind nicht das große Problem, 9 Stück hätte ich übrig, aber es sollte am liebsten ein DIP-Gehäuse sein. Gruß, Yaro
Dann dürte das schnellste der Parallax Propeller sein, gibt's als DIP40. Da streiten sich dann 8 Stück 32bit Prozessoren mit je 20 MIPS darum, wer den Job übernehmen darf. Könnte bei geeigneter Programmierung schnell genug sein, wobei aber kein Hardware-Multiplier mitspielt. Das Interface darfst du selbst erfinden, denn konzeptbedingt hat der kein vordefiniertes, und programmieren darfst du das in Assembler. Grösstenteils jedenfalls. Andere 32bit Typen als DIP kenne ich nicht. Höchstens als Header-Board.
Die neben dem Propeller vielleicht am fixesten rechnenden Controller in DIP dürften die dsPIC33 sein. 40MHz 16-Bit, und die DSP-Funktionalität nützt dir vielleicht sogar was.
Ich habe schon mit ASM Programmiert... nur habe ich für dieses Projekt nicht sooo viel Zeit.. Fazit ist also, einfach einen zweiten (oder dritten) AVR anschließen, und sich nicht so viel Zeit verschwenden. Richtig? Gruß, Yaro
Richtig, denn bei allen diesen Lösungen kommt erst der Schweiss, dann die Freude. Denn programmieren musst du sie erst einmal. Und wenn du keine Zeit hast, dann bringt das alles wenig.
Ach ja: Andere Compiler andere Libraries. Vielleicht findet sich ein AVR-Compiler, dessen Floating-Point Libs deutlich fixer sind als beim bisher verwendeten.
Ich werde mich mal umschauen. Vielen Dank für die zahlreichen und schnellen Antworten
Yaroslav Gevorkov schrieb: > ich brauche für mein Projekt sehr viele Berechnungen, die ich in > kürzester Zeit rechnen muss. Das ist Wischiwaschi ohne jede Aussage. Bevor Du ein Problem löst, mußt Du es erstmal kennen. Also schätze mal ab, wieviel Rechnungen welcher Art Du in welcher Zeit benötigst. Insbesondere beim Zeitbedarf verschätzen sich viele. Letztens war hier auch einer, der wollte alle 10ms Werte auf ein LCD ausgeben. Also völlig unsinnig schnell, das hätte keiner ablesen können. Bei ergonomischer Ausgabe ergab sich dann eine CPU-Auslastung von gerade mal 1%. Peter
Gast
#1314160
> Pins sind nicht das große Problem, 9 Stück hätte ich übrig,
Für mindestens 32 bit float coprozesor ?
Du beliebst zu scherzen.
Wie wäre es mit 102 pins ? 32 a Wert, 32 b Wert 32 Ergebnis, und 6 für
die Operation.
Vergiss den Ansatz, wechsel den Prozessor, gleich in einem mit schneller
Arithmetik.
Gast
#1314194
Was ich nicht verstehe: Warum ist es zu spät den µC zu wechseln, wenn du aber bereit bist noch mal grundlegend die Hardwarekonfiguration (FPU hinzufügen) zu ändern? Ich hab mal auf nem 32bit DSP (Blackfin) gemessen, was ne floatingpoint library braucht und wies mit fixpoint arithmetik das verhältnis war 1:1000 also wirds mit nem 8bit processor mindestens 5 mal so lange dauern. Aber insgesammt schließe ich mich meinem vorschrebern an: lös das ganze von anfang an in fixpoint. was hast du den nfür ne anwendung? erzähl mal! wo kommen die Eingangsdaten daten und was machst du damit und was soll rauskommen. Es gibt zwar extreme Fälle, wo es mit 32bit fixpoint enorm schwierig ist und man auf 64 asuweichen muss, aber die sind sehr speziell. Im extremfall nimm nen SPI flash (SD-Karte) mit ein paar MB und pack den randvoll mit LUTs für alle deine Funktionen. musst dann halt so programmieren, dass due das ergebnis ein paar zyklen vorher anforderst. Hab aber keine Ahnung ob sich das lohnt, oder ob die Kommunikation zu langsam ist.
Gast
#1314198
Wenn es bei einem AVR 8Bit bleiben muß (warum auch immer) ist der XMega z.Zt. das schnellste (intern 32 MHz) und kann durch DMA und Eventsystem den Kern deutlich entlasten. Wenn es um große Tabellen geht wäre so ein Dataflasch mit SPI eine Lösung: http://www.atmel.com/products/DataFlash/default.asp avr
Gast
#1314199
@Yaroslav überlege vllt dochmal nochmal ein externes flash (z.b. at45db161, das hat 2mbyte) zu verwenden. ich brauche z.b. filterkoeffizienten die ich im avr berechnen möchte. die ursprüngliche formel enthält x^y (wobei x keineswegs eine schöne gerade zahl ist, sondern 1,095irgendwas), tan div. divisionen multiplikationen und additionen. ein sprung war es die berechnung von x^y und tan in eine tabelle zu packen ... das hat mir einen enormen geschwindigkeitszuwachs gegeben. nur bin ich aus speicherplatzgründen dazu übergegangen die filterkoeffizienten vorberechnet in das flash zu packen. von den 2 mbyte sind somit gerademal 128kbyte übriggeblieben. nun hab ich 4 verschiedene filtertypen mit 512 frequenz und jeweils 64 verschiedenen resonanzpunkten. und die geschwindigkeitssteigerung möcht ich gar nicht erst erwähnen. ok ich habs noch nicht ermittelt wie schnell es ist, aber ich habe für eine berechnung vorher 1.5ms benötigt (schon die erste optimierungsstufe) und nun muß ich nur ein paar bytes an das dataflash schicken und habe einen fast fertigen koeffizienten-satz (besteht aus 4 long worten).
@vlad: zu Spät den Controller zu wechseln ist es, weil ich das Projekt zum Herbst fertig haben muss, und mir einfach die Zeit fehlt, 2Wochen zu investiren, um z.B. mit einem ARM gut genug umgehen zu können. Eine FPU kann ich über SPI anbinden und brauche nichtmal das fertig-designte Board umzudesignen (es ist auch so schon kein Platz mehr drauf). Das mit externem Speicher habe ich mir auch schon überlegt, aber mir scheint die Lösung mit 2 Prozessoren besser. (aber ich werde noch weiter drüber nachdenken) Das Projekt ist ein Hexapod. Er hat ziemlich lange beine und soll mit denen auch elegant umgehen können. Dafür braucht man undglaublich viel Mathematik, und leider auch sehr viele Winkelfunktionen. @avr: Die xmegas sind schon tolle Dinger! Leider gibt es sie aber nur in SMD, und auch auf sie muss man sich erstmal umstellen. Ich verwende einen ATmega 644 mit 20MHz, das Board ist schon fertig. Aber über den Dataflash werde ich nochmal nachdenken. @TheMason:Ich habe auch schon einige Funktionen so beschleunigt, aber bisher nur da, wo ich nur wenig Genauigkeit brauchte. Das Problem beim jetzigen Projekt ist, dass ich wirklich die volle Bandbreite der sin und arcsin Funktionen ausnutzen muss. Ich werde mir nochmal überlegen, welche Genauigkeit ich brauche, und vielleicht einen externen speicher verwenden. Gruß, Yaro
Gast
#1314410
>Eine FPU kann ich über SPI anbinden und brauche nichtmal das >fertig-designte Board umzudesignen (es ist auch so schon kein Platz mehr >drauf). wenn kein Platz ist, wie bekommst du dann die FPU drauf? aber egal Ich würd wie gesagt das ganze in fixpoint rechnen. Was ist das für ein Projekt? Uni/privat/job? kannst du den Code Zeigen? interessiert mich einfach ob das wirklic so schwierig ist. Was für ein AVR hast du? wenn du ne komplette float lib (sin, tan, sqrt, ...) verwendest muss der doch schon davon recht voll sein. Machen auf Arbeit bei uns auch alles in fixpoint, weil unser Blackfin (32bit 500MHz dualcore DSP - derer sind es zwei) keine FPU hat. Und es geht natürlich auch.
Gast
#1314445
> Das Projekt ist ein Hexapod. Er hat ziemlich lange beine und soll mit > denen auch elegant umgehen können. Dafür braucht man > undglaublich viel Mathematik, und leider auch sehr viele > Winkelfunktionen. Und die müssen unbedingt in float sein? Du schriebst was von Genauigkeit. float ist weniger genau als 32bit fixed-point. Nur der Wertebereich ist größer, da sich die Schrittweite an den Wert anpasst. > Das Problem beim jetzigen Projekt ist, dass ich wirklich die volle > Bandbreite der sin und arcsin Funktionen ausnutzen muss. Naja, das Ergebnis eines sin liegt z.B. im Bereich +/- 1. Da würde dir ein 32-bit-fixed-point-Wert eine Schrittweite von 4,7*10^-10 geben. Floating-Point hatte da nur bei sehr kleinen Werten Vorteile, sonst nur Nachteile, da die Mantisse inklusive Vorzeichen nur 24 Bit hat.
@vlad: ich benutze einen ATmega644p, er hat 64kB Flash, also genug Platz, um funktionen unterzubringen. tan brauche ich nicht, nur sin cos und arccos. Außerdem brauche ich öfters Wurzeln. Bei arccos brauche ich keine große Genauigkeit, deswegen habe ich das mit einer lookup-Tabelle gemacht. (diese Funktionen habe ich nciht mit reingestellt, weil sie nur sehr wenig Takte brauchen). Die zusätzliche FPU hätte ich an ein seperates Board gehängt, dass ich sowieso verwende. mit SPI könnte ich es dann gut anschließen. Ich kann hier ja mal ein Beispiel geben (im Anhang). Dies ist eine Funktion, der man einen bestimmten Punkt im Raum angibt, und sie dann die jeweiligen Wiinkel der 3 Servos rausgibt. Hier habe ich auch die erwähnten arccos lookups verwendet. Nicht über die vielen Casts wundern, sie sind tatsächlich notwendig =). Die ausführung dieser Funktion dauert zwischen 3 und 6 Tausend Takten (abhängig vom Punkt, der angefahren werden soll). Im moment bin ich gerade noch dabei, den Code zu schreiben, er ist also lange noch nicht fertig, deswgen kann ich auch keinen vollen Code zeigen. Gerade jetzt arbeite ich daran, funktionen für den gang um einen bestimmten Radius zu erstellen. Diese habe ich zwar zum großen Teil schon auf Pappier, aber noch nicht in Code umgesetzt. Wenn ich das aber tuhe, stoße ich bald schon an die leistungsgrenze. Ich habe auch noch vor, sehr viele andere funktionen zu schreiben, die sicherlich noch mehr Leistung brauchen werden, deswegen bemühe ich mich jetzt schon darum, vorzusorgen, um später nicht das Nachsehen zu haben.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
@Rolf: Das Projekt ist eigentlich Privat, aber ich will es als "besondere Lernleistung" ins ABI mit einbringen, deswegen muss es auch im Herbst fertig sein. Mit fixpoint habe ich leider noch nie zutun gehabt, gut Möglich, dass es tatsächlich besser geeignet ist. Edit: ich habe mir gerade ein Tutorial angeschaut, und wenn das, was dort gesagt urde richtig ist, dann habe ich Fixpoint schon verwendet, nämlich bei meinen arccos-funktionen (habe dann allerdings die Nachkommastellen vernachlässigt, weil ich sie nicht brauche). Ich bruache insgesammt keine extrem große genauigkeit, allerdings brauche ich bei einigen eher seltenen Anwendungen schon so ca. 10 Nachkommastellen. Deswegen habe ich da, wo ich diese Nachkommastellen brauche, auch floats eingesetzt. Kann man sin und cos in fixedpoint rechnen? Wenn ja, wieviel schneller wird es dadurch (wenn man genauigkeit ungefähr beibehalten will)? Insgesammt habe ich jetzt überlegt die Aufteilung der Rechenleistung besser zu gestalten, indem ich auf Reaktionszeit verzichte. So wie ich mir das jetzt überlegt habe (mit 2 Controllern), wobei der eine die dringenden Aufgaben rechnet, und der andere die, die etwas warten können, sollte ich mit der Zeit ganz gut hinkommen.
Gast
#1314571
> brauche ich bei einigen eher seltenen Anwendungen schon so ca. > 10 Nachkommastellen. Deswegen habe ich da, wo ich diese > Nachkommastellen brauche, auch floats eingesetzt. Diese Genauigkeit hat float aber gar nicht. Etwa 6 signifikante Stellen (also Vor- und Nachkommastellen zusammen) hast du bei float. > Kann man sin und cos in fixedpoint rechnen? Klar. Vielleicht hilft dir das: AVR-CORDIC könnte interessant sein, gefunden über Beitrag "Sinus und Cosinus in einem µC ohne Fließkomma berechnen"
Im selben forum habe ich folgendes gelesen: Der Hauptvorteil vom CORDIC ist, dass man keine Multiplikationen braucht, deshalb wird er gerne für Hardwareimplementierungen verwendet. Wenn man aber sowieso schon einen Multiplizierer im Controller hat ist Cordic nicht mehr unbedingt die beste Wahl. Die ATmegas haben einen hardware-multiplikator. Aber der Einwand mit den Floats ist richtig! Die sin-Funktion der Bibliothek liefert ja sowieso double zurück, da kann ich dann ja auch gleich double verwenden, bringt ja nicht viel mehr Aufwand (außer später dann, beim rechnen damit). Aber wie gesagt, ich habe die Strukturierung des Programms nochmal überdacht, und dadurch (allerdings mit einigen kleinen Verlusten bei der Performance) eine Menge Zeit gewonnen. Die 1500Takte, die sin braucht, wirken sich dann nicht mehr so dramatisch aus. Gruß, Yaro
double ist auf dem AVR das selbe wie float. schreib mal was zu den eingangsdaten, was für wertebereich, skalierung? da du int8 werte reingibst und die du erwartest wette ich, dass sich das ganze komplett in fixpoints rechnen lässt.
Gast
#1314660
Ich denke, Du kannst noch einiges kürzen. Dadurch wird der Code auch schneller. Habe den folgenden Code leider nicht compilieren können, da ich auf den System, auf dem ich hier arbeite, keinen C Compiler habe. Bin mir deshalb fast sicher, dass noch ein paar Syntaxfehler drin sind. Aber Du kannst Dir ja mal anschauen was ich gemacht habe, um die Idee zu verstehen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
Wofür ich so genaue wert brauche ist z.B. folgendes: Der Hexa muss um einen bestimmten Radius gehen (Kurve), dabei müssen die Füße auch einem bestimmten Radius folgen. Der Radius solltte nicht größer als 3m werden. Die auflösung, in der die Füße bewegt werden sollen, soll 1-2mm sein. Die Drehung mache ich mit einer Drehmatrix, die sin und cos des Winkels braucht, um den gedreht werden soll. Bei maximalem Radius 2m und bester Auflösung 1mm ergibt sich mit arctan(1/2000) ein Winkel von 0.02864788737°. Da der Radius so weit weg ist, machen sich sogar kleine Veränderungen des Winkels auf die Schrittweite bemerkbar. Bei kleinerem Radius ist die Genauigkeit dann nicht mehr so wichtig. Der Sinus von diesem (kleinstnötigen)Winkel ist 0,000499999°. Eine Genauigkeit von mindestens 6 Nachkommastellen würde wahrscheinlich ausreichen. Wieso die Auflösung so ganau sein muss ist leicht zu erklären: wenn der fuß auf dem Boden steht, und sich bewegt (d.h. den Körper bewegt), muss er ziemlich genau sein, damit sich die Füße in ihrer gesammteheit nicht in verscheidene Richtungen bewegen, und damit Spannungen erzeugen. Kennt ihr vielleicht ein gutet tutorial, wo man fixpointrechnung gut lernen kann? Gruß, Yaro Edit: hallo "Gast", du hast deinen Beitrag gerade dann geschrieben, als ich meinen geschrieben habe, ich lese ihn mir gleich durch, und beantworte ihn auch schnellstmöglich.
@Gast: Erstmal vielen Dank, dass du dir so viel Mühe gemacht hast, den Code zu überarbeiten! Viele Sachen, die du geändert hast, bringen aber leider keine Verbesserung, weil der Preprozessor sie schon rechnet. Zum beispiel das quadrieren der Konstanten gehört dazu. Moderne Compiler berücksichtigen sowas. das hier:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
habe ich zum Anlass genommen, diese Routine noch weiter zu verbessern:
1 | |
2 | |
3 | |
4 | |
5 | |
das hier:
1 | |
ist wirklich schlauer, als das, was ich gemacht habe. (mit 256 und dann mit 4 multipliziert). Gedacht war es von mir eigentlich so: warum eine 16bit Multiplikation machen, wenn man eine 8bit Multiplikationen machen kann und sie dann 2 mal logisch nach links schieben kann (das mach der Compiler, wenn man *4 rechnet), was schneller ist (allerdings würde damit auch genauigkeit eingebüßt werden). Berücksichtigt habe ich nicht, dass 256 ja keine 8bit mehr sind... das hier:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
verfehlt den Zweck, denn so gibt es keinen genauigkeitsgewinn von arccos1024flash auf arccos4096flashmini, weil der Wert gerundet wird, bevor er mit 1024/4096 multipliziert wird. Er muss zuerst multipliziert und anschlißend geteilt werden, sodass wenigstens einige Nachkommastellen mehr vorhanden sind. Genauso ist es bei den folgenden Berechnungen. Totzdem einen herzlihen Dank, dass du dir die Mühe gemacht hast! Verbessern kann man Code immer, egal wie durchdacht er ist! Gruß, Yaro
Gast
#1314729
> Kennt ihr vielleicht ein gutet tutorial, wo man fixpointrechnung gut
lernen kann?
Aber Jaroslav, Rechnen mit ganzen Zahlen sollte man in der Grundschule
gelernt haben. Du stellst deine Rechnungen so um, dass mit ganzen Zahlen
in ZehntelMillimeter und Bogensekunden gerechnet wird (dafür wirst du
dann mehr als 8 bit brauchen, selbst 32bit werden teilweise nicht
reichen), und fertig ist deine Fixpunktberechnung. Sie ist nur eine
Frage der Maßeinheit.
>Kennt ihr vielleicht ein gutet tutorial, wo man fixpointrechnung gut lernen kann?
Du scheinst ja von Mathematik etwas zu verstehen.
Somit sollte die grundlagen recht einfach zu verstehen sein.
der trick ist halt, dass man sich für seine Variable eine gewisse
skalierung sucht.
du willst eine genauigkeit von 0,0005 haben.
das sind 1/2000.
Das heißt am gbesten skalierst du diese Zahl mit 2048, das heißt 11bit
das heißt ab dem 12. beginnt dann der vorkomma-anteil.
24.54233 entspräche 50262
-> 24.54233 * 2048 = 24.54233 * 2^11 = 24.54233 * (1<<11)
wenn du zahlen addierst musst du darauf chaten, dass sie die selbe
skalierung haben.
beim Multiplizieren addieren sich die exponenten.
zu beachten ist immer, dass der wertebereich nicht überläuft.
Das härteste sind die mathematischen Basisfunktionen (integerwurzel,
fixpoint-sin, cos, tan, acos, asin) die man natürlich selbst
implementieren muss, oder man sucht sich ne kleine Bibliothek
Alles klar, dann ist es ja wirklich so einfach, wie ich es bereits angewendet habe =) Dabei ergebit sich dann das erwähnte Problem, dass man auf den Überlauf achten muss. Ein weiteres, weit größeres problem ist, dass der Code deutlich unübersichtlicher wird. Das ist es, was mich die ganze Zeit davon abhällt, Festkommazahlen zu verwenden. Die eine Sache ist, eine Seite Code damit zu schreiben, aber eine andere ist es, 20Seiten Code so zu schreiben. Ich werde mir das alles nochmal anschauen, und dann entscheiden, wie ich es mache. Wahrscheinlich wird es darauf hinauslaufen, dass ich meißtens float benutzen werde, und in Fällen, wo ich besondere Genauigkeit brauche, dann mit Festkommazahlen Rechnen werde. Vielen Dank für die kompetente Hilfe!
Yaroslav Gevorkov schrieb: > Ein weiteres, weit größeres problem ist, dass der Code deutlich > unübersichtlicher wird. Das ist es, was mich die ganze Zeit davon > abhällt, Festkommazahlen zu verwenden. Die eine Sache ist, eine Seite > Code damit zu schreiben, aber eine andere ist es, 20Seiten Code so zu > schreiben. Tja, umsonst ist nur der Tod ;-) > > Ich werde mir das alles nochmal anschauen, und dann entscheiden, wie ich > es mache. > Wahrscheinlich wird es darauf hinauslaufen, dass ich meißtens float > benutzen werde, und in Fällen, wo ich besondere Genauigkeit brauche, > dann mit Festkommazahlen Rechnen werde. Ich würde es genau umgedreht machen. In derregel fixpoint und nur bei besonders kniffligen stellen floats benutzen. Das float per se ungenauer sind asl Fixpoint würd ich nicht behaupten. In den meisten fällen ist es wahrscheinlich umgekehrt. die genauigkeit von float, richtet sich nicht größe der Zahl. Float ist quasi sowas wie die wissenschaftliche schreibweise mit mantisse und exponenten. 1.434e+10. Wobei es so definiert ist, dass es nur eine stelle vor dem Komma gibt. also statt 100.23e+3 wird 1.0023e+5 gespeichert da die erste Stelle ist immer 1 und wird nicht gespeichert. das heist für den Nachkommateil der Zahl gibt es 23bit dH wenn deine Zahl 1.irgendwas ist, sind 23bit tatsächlich Nachkommapäzision, wenn du 100.irgendwas hast sind es nur noch 16bit. bei 16.7Mio hast du gar keine Nachkommapräzision mehr. Bei fixpoint, hast du zwar immer eine feste nachkommapräzision, allerdings wirst du die Variablen nicht mit 2^16 skalieren wollen, da dann multiplikationen schon kritisch werden, was überläufe angeht, da ja eine 1 schon 17bit braucht und man 2 solche zahlen nicht mehr in 32bit multiplizieren kann. Bei fixpoint muss man halt bei jeder Rechenoperation wissen, was sind die maximalen/minimalen Werte die eingehen können. Nur so kann man Über- und Unterläufe verhindern. Unterläufe treten auf, wenn man zB zwei fixpoints multipliziert und dann auf die Ursprüngliche skalierung zurückschiftet. Wenn di Zahlen zu klein waren ist das ergebnis 0.
Das mit den floats ist mir klar. Das gute ist, dass ich (in den meißten Fällen) nur bei kleinen Winkeln hohe Präzision brauche, bei großen Winkeln brauche ich nur wenige Nachkommastellen. Wenn mi die 23bit der floats mal nicht ausreichen, werde ich auf fixpoint zurückgreifen. Gruß, Yaro
Gast
#1314934
moin moin,
>>kleinen Winkeln hohe Präzision brauche
kann man so nicht sagen. Mein dicker Bartsch (Matheformeln) sagt dazu:
Näherungsformeln für kleine Winkel
sin a ~ a ~ tan a
sin n a ~ n sin a
Die Berechnung zu den Füßen ist vergleichbar mit der
Fräsradienkorrektur.
Zum Platzbedarf: Der C8051F365 ist 5x5mm, braucht 3,3V.
Gruß
Pieter
Große Genauigkeit bei kleinen Winkeln brauche ich, weil: Kleine Winkel habe ich (im Fall der gehens um einen Radius) dann, wenn der Radius groß ist. Dann nämlich wirkt sich die änderung des Winkels sehr stark auf den Bogen aus, der sich gegenüber dem Winkel öffnet, den ich dazu benutze, meine Schritte zu setzten. Bei kleinem Radius (und dabei dann großem Schrittwinkel) wirken sich kleine Ungenauigkeiten weit weniger aus. Gruß, Yaro
Gast
#1315100
nur mal so als gedankenansatz : - arbeite komplett mit fixed-point - lege dir eine viertel sinusschwingung bei maximaler auflösung (32bit) in ein 2mbyte daten-flash (das macht bei 4bytes pro wert -> 500k-werte .. bei einer viertel schwingung (90°) -> 0,000171° auflösung) - bilde sinus-cosinus-fkt aus dieser viertel schwinung - bilde arccos/arcsin per wägeverfahren aus der sinus/cosinusfkt (selbst wenn ich mich mit dem wägeverfahren nun in die nesseln setze, aber ist brute-force und sollte auf jedenfall in akzeptabler zeit zum ergebnis führen) ich denke du wirst wenn du das konsequent anwendest mit 32-bit auflösung am besten gehen bzw fahren :-) vor allem hast du dann das genauigkeits-problem gelöst und bist zudem noch ne ganze ecke schneller als floating point.
Gast
#1315116
Zur Praezision von float und Integern. Also single precision float hat eine mantisse von 23 bit, und einen exponent von 8 bit, plus ein sign. Das naechst groessere ist double precision, mit etwas mehr von beidem. Der Vorteil von integern ist, dass man deren Groesse selbst anpassen kann. Einen 40, 48 oder 56 bit integer mit seinen Additions- und Multiplikations- grundfunktionen sind schnell und einfach geschrieben. Falls Single nicht hinkommt, sollte man sich den Schritt zu 64bit gut ueberlegen.
Mal eine andere Frage ? Können deine aktoren eine solche genauigkeit überhaupst wiedergeben ? MFG
Gast
#1315397
Wenn man die Winkelfunktionen nur bei kleinen Werten braucht, dann ist die Potenzreihen Entwicklung gut: sin x = x - 1/3 x^3 + 1/5 x^5 ... Wobei man bei kleinen Werten halt schon relativ früh (z.B. schon nach x^3) aufhören kann. Der Arctan ist allerdings nicht ganz so gutmütig und braicht oft mehr glieder.
Du kannst natürlich auch einen Mega32/644 o.ä. als Coprozessor per ISP anbinden, der könnte intern mit FixPoint rechnen und dir das Ergebnis dann einfach als Floatingpoint zurückgeben. Ansosnten soll sich Fixedpoint vereinfachen wenn man alles auf 1... -1skaliert, einige AVR haben sogar extra Multiplikationsbefehle dafür.
Gast
#1315480
> als Coprozessor per ISP anbinden
ISP ?
In System Programming ?
Also jedesmal vor der Berechnung den Code rüberladen und brennen ?
Wozu, und warum sollte das schneller sein ?
ISP = SPI
Jetzt mal ein kleiner Mathe Grundkurs Mathematik. Man verwendet für die Berechnung von Wickelfunktionen und Co die sog. Taylorreihe. http://de.wikipedia.org/wiki/Taylorreihe Diese reihe ermöglicht eine "APROXIMATION" für eine Funktion f(x). Also das ist das was der Ulrich für den sin(x) aufgeschrieben hat. Noch ne Kleinigkeit es ist blödsinn wenn man einem "Coprozessor" nur dazu benutzt um die Winkelfunktionen zu berechnen. Sinnvoller wäre gewisse Algorythmen direkt auf den zweiten Controller auszulagern zB die Berechnung von 4 Füssen von den insgesamt 8 oder so ähnlich. Denn dan würde die Latenzzeit wegen der Kommunikationsschnittstelle nicht mehr so ins Gewicht fallen. MFG Patrick
Gast
#1315656
> Man verwendet für die Berechnung von Wickelfunktionen und Co die sog.
Taylorreihe.
Wer ist man?
Der Mathe-Professor?
Vielleicht.
Ein Micro(computer/controller/coprozessor) ?
Sicher nicht, konvergiert viel zu langsam, nicht effizient genug.
Was wird den sonst verwendet ?
Also MaWin du meinst sicher Cordic ? Auf das hab ich ganz vergessen mir sind spontan nur Taylorreihen eingefallen. Zu cordic gibt hier auch nen Artikel http://www.mikrocontroller.net/articles/AVR-CORDIC MFG Patrick
Gast
#1315758
Taschenrechner und FPGAs meist Cordic, aber Pentiums verwenden wohl relativ grosse Tabellen um die Iterationsanzahl seit dem 486 zu zehnteln und einen speziell dafür entwickelten Algorithmus.
Gast
#1315816
In Softwarebibliotheken werden zur Berechnung von Winkelfunktionen meist Potenzreihen verwendet, deren Koeffizienten aber von den Taylor-Reihen der zu approximierenden Funktionen geringfügig abweichen (mit steigendem Index prozentual immer mehr). Die Koeffizienten sind daraufhin optimiert, dass der maximale Fehler im genutzten Wertebereich minimal wird. Taylor-Reihen, die nach n Gliedern abgeschnitten werden, schneiden hierbei deutlich schlechter ab. So beträgt bspw. der maximale Fehler des Sinus aus der AVR-Libc nur etwa 4% des Fehlers der Taylor-Reihe, die auf die gleiche Anzahl von Gliedern (6) begrenzt wird.
Gast
#1315953
Es gibt für die Winkelfunktionen die beiden Möglichkeiten Cordic oder Taylorreihe. Welche Methode man nimmt hängt davon ab, was man braucht (Sin und Cos, oder nur Sin), und was die Hardware gut kann. Die AVRs haben einen HW Muplipier, aber keine Hardware füs Shiften. Das spricht etwas für die Taylorreihen. Bei den Taylorreihen wird normalerweise erst einmal dafür gesorgt, das das Argument klein ist, um einen gute Konvergenz zu erreichen. Beim Sinus / Cosinus wird man wohl wenigstens dafür sorgen, dass man unter 45 Grad (ca. 0.79 im Bogenmaß) bleibt. Man kann eventuell auch noch weiter runter gehen durch Ausnutzen von anderen Identitäten. Die Reihen für Sinus und Cosinus konvergieren dann schon nicht so schlecht. Gerade wenn man nur kleine Winkel braucht sind die Taylorreihen die Methode der Wahl. Einige Reihen gehen dabei gut (exp, sin, cos), andere weniger gut (Arctan, Wurzel, Logarithmus). Wenn man geschickt rechnet, sind auch 5 oder mehr Glieder im Polynom kein großes Problem. Hab gerade gesehn: oben ist eine Fehler drin: die Vorfaktoren sind -1/3! , 1/5! usw. die gehen also recht schnell gegen Null.
Das mit der Taylor-Reihe ist ja eine richtig tolle Erfindung! Bei kleinen Winkeln sollte das mit einem AVR relativ schnell gemacht sein. Schwierig wird es bei größeren Winkeln. Problem ist aber auch hier: auf Grund der Brüche (z.B. 1/3*x³) muss man einen relativ roßen skallierungsfaktor nehmen, um genug genauigkeit hinzubekommen. Großer Skallierungsfaktor bedeutet große Variablen, was widerum einen großen Rechenaufwand bedeutet. Ich bin gerade dabei, das Programm zu schreiben, welches diese sinusfunktionen braucht, ich werde mal testen, welche Genauigkeit ich brauche, und welches Verfahren ich dann nehme. Werde bei sehr kleinen Winkeln wahrscheinlich Taylor nehmen (mit fixpoint) und bei den anderen wahrscheinlich die math-funktionen mit float. Gruß, Yaro
Patrick Weinberger schrieb: > Mal eine andere Frage ? > Können deine aktoren eine solche genauigkeit überhaupst wiedergeben ? Das habe ich mich in dem Thread das erste mal gefragt, als das Wort Hexapod fiel. Ist die Hardware schon fertig und merkst du, dass die ungenauen Rechnungen den Roboter schlecht machen? Das kann ich nämlich nicht glauben.
Gast
#1317302
Du kannst auch Approximationsformeln aus diesem Buch nehmen für Sinus, Cosinus und Arctan. Wahrscheinlich sind sie besser als Taylorreihen. http://www.nrbook.com/abramowitz_and_stegun/page_76.htm
Naja ich weiß Modellbauservos haben eine genuigkeit von 270°/5000=0,054. Wegen 0,054 mach ich mir doch keine gedanken über einen genauen Algorythmus ? MFG
Gast
#1317418
Moin hat sich mal schon jeman die mühe gemacht eine Fehler / Toleranz berechnung / bewertung zu machen? ggf ist das ganze mit der 7ten nachkommastelle gar nicht so wichtig, wenn die hinterher gar nicht mehr dargestellt werden können (8 bit ausgangswerte). bzw aufgrund von mechanik, elektronik sowieso mehr fehler reinkommen, als einem lieb ist. nur mal so zur info, der unterschied zwischen 8 16 und 32 bit 32 bit soll angeblich 48 mal schneller sein bei einer multiplikation als ein 8 bitter ( nur von der anzahl der befehle ) http://www.elektroniknet.de/home/bauelemente/fachwissen/uebersicht/aktive-bauelemente/mikrocontroller-prozessoren-dsps/32-bit-mcu-soll-8-und-16-bit-markt-angreifen/druckversion/ und viel spass noch
Gast
#1317468
Hallo, ich habe für Winkelfunktionen auf dem AVR die 'Cephes Lib' benutzt. Die darin verwendeten Reihenentwicklungen sind keine Taylorreihen, sondern es werden zunächst die Argumente transformiert, bevor dann eine Reihe mit wenigen Gliedern zum Einsatz kommt. Als meine Assemblerroutinen fertig waren, habe ich sie gegen den PC mit Zufallswerten geprüft und die Ergebnisse waren fast immer auf 15 Dezimalen identisch. Meine Anwendung (Teleskopsteuerung) benutzt das 64bit Floating Point Format, daher sind die Routinen wohl unnötig genau und vor allem zu langsam für den Hexapod. Hier sind meine Floating Point Routinen: http://www.martin-cibulski.de/atm/mount_controller_4/mc_4_asm_main/index_de.htm Hier findet man die Library für verschiedene Auflösungen: http://www.moshier.net/#Cephes Gruß, Martin
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.