www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik floating point coprocessor


Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?p...

Hat jemand Erfahrungen mit sowas gemacht? Oder kennt jemand vielleicht 
ein besseres Modell?

Gruß, Yaro

Autor: avr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: apfel_tanne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs mal mit Festkommaarithmetik

Und vor allem sag mal, wieviel Berechungen du in welcher Zeit glaubst 
durchführen zu müssen.

MFG
Falk

Autor: Pieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: apfel_tanne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja: Andere Compiler andere Libraries. Vielleicht findet sich ein 
AVR-Compiler, dessen Floating-Point Libs deutlich fixer sind als beim 
bisher verwendeten.

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich werde mich mal umschauen.

Vielen Dank für die zahlreichen und schnellen Antworten

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: vlad (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: avr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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).

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: vlad (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Yaro G. (yaro)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@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.
void setdeg(int8_t x1signed,uint8_t x2,uint8_t x3, uint8_t *alpha1, uint8_t *alpha2, uint8_t *alpha3){
  uint8_t x1,a1,a2,a2m,a2p,a3, neg = 0;
  float ds,d12,d123,temp1,temp2;
  uint8_t os = 130, us = 150, s = 28;

  if(x1signed < 0){
    x1 = (uint8_t)(x1signed * (-1)) * 2;
    neg = 1;
  }else{
    x1 = (uint8_t)x1signed * 2;
  }

  d12 = (float)sqrt((float)((uint32_t)(uint16_t)(x1*x1) + (uint32_t)(uint16_t)(x2*x2)));
  a1 = arccos1024flash((uint16_t)(((x2*256)/d12)*4), arccostab1024flash);
  if(a1 <= 10){
    a1 = arccos4096flashmini((uint16_t)(((uint32_t)x2*4096)/d12), arccostab4096flashmini);
  }
  ds = d12 - s;
  d123 = (float)sqrt((float)(ds*ds + (uint32_t)(uint16_t)(x3*x3)));
  a2m = arccos1024flash((uint16_t)((ds*128/d123)*8), arccostab1024flash);
  if(a2m <= 10){
    a2m = arccos4096flashmini((uint16_t)(ds*4096/d123), arccostab4096flashmini);
  }
  a2p = arccos1024flash((uint16_t)(((uint16_t)(os*os)+d123*d123-(uint16_t)(us*us))*514/(os*d123)), arccostab1024flash);
  if(a2p <= 10){
    a2p = arccos4096flashmini((uint16_t)(((uint16_t)(os*os)+d123*d123-(uint16_t)(us*us))*2048/(os*d123)), arccostab4096flashmini);
  }
  a2 = a2p - a2m;
  a3 = arccos1024flash((uint16_t)(((uint16_t)(us*us)+(uint16_t)(os*os)-d123*d123)*514/((uint16_t)(us*os))), arccostab1024flash);
  if(a3 <= 10){
    a3 = arccos4096flashmini((uint16_t)(((uint16_t)(us*us)+(uint16_t)(os*os)-d123*d123)*2048/((uint16_t)(us*os))), arccostab4096flashmini);
  }


  if(neg){
    a1 = 90 - a1;
  }else{
    a1 += 90;
  }

  a2 += 90;

  *alpha1 = a1;
  *alpha2 = a2;
  *alpha3 = a3;
}

@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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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"

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
/**
 * FUNCTION: 
 *   setDeg
 *
 * DESCRIPTION:
 *   Berechnet den Winkel für die Servos.
 *
 * PARAMETER:
 *   x1sgined  X-Koordinate, vorzeichenbehaftet
 *   x2        X-Koordinate, vorzeichenlos
 *   x3        X-Koordinate, vorzeichenlos
 *   *alpha1   Zeiger auf den Winkel für 1. Servo
 *   *alpha2   Zeiger auf den Winkel für 2. Servo
 *   *alpha3   Zeiger auf den Winkel für 3. Servo
 *
 * RESULT:
 *   (kein Rückgabewert)
 */

void setdeg(int8_t x1signed, uint8_t x2, uint8_t x3, uint8_t *alpha1, uint8_t *alpha2, uint8_t *alpha3)
{
  uint8_t a1;     /* 1. Winkel  */
  uint8_t a2;     /* 2. Winkel */
  uint8_t a2m; 
  uint8_t a2p;
  uint8_t a3;     /* 3. Winkel */
  uint32_t x1_2;  /* Quadrat der Koordinate X1 */
  uint32_t x2_2;  /* Quadrat der Korrdinate X2 */
  uint32_t x3_2;  /* Quadrat der Koordinate X3 */
  uint8_t os = 130, us = 150, s = 28;
  uint16_t os_2 = 16900, us = 22500, s = 784, us_os = 19500;
  float ds,d12,d123;

  /* X1-Koordinate vorbereiten */
  uint8_t x1 = (uint8_t)x1signed;
  
  if(x1signed < 0)
  {
    x1 *= -2;
  }
  else
  {
    x1 *= 2;
  }
  
  /* Koordinaten quadrieren */
  x1_2 = x1 * x1;
  x2_2 = x2 * x2;
  x3_2 = x3 * x3;
  
  /* Hilfsvariable d12 berechnen */
  d12 = sqrt((float)(x1_2 + x2_2));
  
  /* Winkel a1 berechnen */
  a1 = arccos1024flash((uint16_t)(1024*x2/d12), arccostab1024flash);
  
  if(a1 <= 10)
  {
    a1 = arccos4096flashmini(4096*(uint16_t)((uint32_t)x2/d12), arccostab4096flashmini);
  }
  
  /* Hilfsvariablen ds und d123 berechnen */
  ds = d12 - s;
  d123 = sqrt((float)(ds*ds + x3_2));
  
  /* winkel a2 berechnen */
  uint16_t h1 = (uint16_t)(ds / d123);
  a2m = arccos1024flash(1024 * h1, arccostab1024flash);
  
  if(a2m <= 10)
  {
    a2m = arccos4096flashmini(4096 * h1, arccostab4096flashmini);
  }
  
  uint16_t h2 = (uint16_t)((os_2 + d123 * d123-us_2)) / (os * d123);
  
  a2p = arccos1024flash(514 * h2), arccostab1024flash);
  
  if(a2p <= 10)
  {
    a2p = arccos4096flashmini(2048 * h2), arccostab4096flashmini);
  }
  
  a2 = a2p - a2m;
  
  /* Winkel a3 berechnen */
  uint16_t h3 = (uint16_t)((us_2 + os_2-d123*d123)/us_os);
  
  a3 = arccos1024flash(514 * h3, arccostab1024flash);
  
  if(a3 <= 10)
  {
    a3 = arccos4096flashmini(2048 * h3, arccostab4096flashmini);
  }


  /* Winkel a1 und a2 spiegeln */
  if(x1signed < 0)
  {
    a1 = 90 - a1;
  }
  else
  {
    a1 += 90;
  }

  a2 += 90;

  /* Winkel an den Aufrufer zurückgeben */
  *alpha1 = a1;
  *alpha2 = a2;
  *alpha3 = a3;
}

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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:
/* X1-Koordinate vorbereiten */
  uint8_t x1 = (uint8_t)x1signed;
  
  if(x1signed < 0)
  {
    x1 *= -2;
  }
  else
  {
    x1 *= 2;
  }
habe ich zum Anlass genommen, diese Routine noch weiter zu verbessern:
  /* X1-Koordinate vorbereiten */
  if(x1signed < 0){
    neg = 1;
  }
  x1 = (uint8_t)(x1signed << 1);

das hier:
a1 = arccos1024flash((uint16_t)(1024*x2/d12), arccostab1024flash);
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:
/* winkel a2 berechnen */
  uint16_t h1 = (uint16_t)(ds / d123);
  a2m = arccos1024flash(1024 * h1, arccostab1024flash);
  
  if(a2m <= 10)
  {
    a2m = arccos4096flashmini(4096 * h1, arccostab4096flashmini);
  }
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

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Pieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: pfft... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Patrick Weinberger (seennoob)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal eine andere Frage ?
Können deine aktoren eine solche genauigkeit überhaupst wiedergeben ?

MFG

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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 ?

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISP = SPI

Autor: Patrick Weinberger (seennoob)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Patrick Weinberger (seennoob)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was wird den sonst verwendet ?

Autor: Patrick Weinberger (seennoob)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Alexander Schmidt (esko) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: approximationsformeln (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Patrick Weinberger (seennoob)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Termite (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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/fachw...

und viel spass noch

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Hier findet man die Library für verschiedene Auflösungen:
http://www.moshier.net/#Cephes

Gruß,
Martin

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.