Forum: Mikrocontroller und Digitale Elektronik Implementieren der arccos-Funktion


von Daniel (Gast)


Lesenswert?

Hallo Leute!

Wie programmiert man eine arccos-Funktion? Ich brauche für ein Programm
diese Funktion für Double Variablen. Da ich mit Bascom arbeite, habe ich
das Problem, daß die trigonometrischen Funktionen in dieser
Programmiersprache keine Doubles unterstützen, also ist selbermachen
angesagt. Einen Funktion für den Sinus zu erstellen war kein Problem,
da hab ich einfach eine Taylorreihe genommen. Das Problem bei der
arccos(x) ist, daß die Steigung gegen minus Unendlich geht, wenn x
gegen 1 geht. Ich kriege mit einer Taylorreihe, die auf einem AVR auch
noch verarbeitbar sein soll keine Genauigkeit von 10^-7 hin. Kann mir
jemand helfen?

Gruß

von Eckhard (Gast)


Lesenswert?

Hi,

google mal nach Cordic.
Das könnte was für Dich sein.

Eckhard

von Bri (Gast)


Lesenswert?

Ich hatte mal ein ähnliches Problem mit der inversen
Verteilungsdichtefunktion der Gaussverteilung. Die Lösung (im Internet
gefunden) war, die Funktion in drei Bereiche zu teilen und diese mit e
Funktionen anzunähern. Das war erstaunlich genau (10^-9). Ich könnte
mir vorstellen, dass du den arccos auch ganz gut mit e Funktionen
annähern kannst. Natürlich hast du dann noch das Problem, dass die
Reihenentwicklung für die e Funktion wahrscheinlich auch viel
Rechenleistung braucht.

von smartie (Gast)


Lesenswert?

ein avr dürfte da etwas überfordert werden. normalerweise macht man
sowas mit Tabellen, die man im Flash ablegt anstatt jeden Wert zu
berechnen.

von Alex (Gast)


Lesenswert?

Cordic nur wenn kein Hardware-Multiplizierer vorhanden ist, sonst nicht
zu gebrauchen. Gebrochen rationale Funktionen sind oft auch geeignet.

von Daniel (Gast)


Lesenswert?

Hmm, ich wollte das ganze auf nem Mega128 machen, aber der hat nen
Hardwaremultiplizierer. Ne Reihenentwicklung der e-Funktion ist kein
Problem. Es muß auch nicht superschnell gehen, hauptsache die
Genauigkeit stimmt. Das Cordic werde ich mich auch mal angucken. Wo
steht das genau mit den e-Funktionen? Jedenfalls Danke erstmal für die
Antworten.

Gruß

von A. D. (ad1)


Lesenswert?

Du musst die Taylorreihe für cos() um den Punkt pi/2 entwickeln.
Für arccos(x) ergibt sich dann (siehe z.B. Bronstein):

arccos(x) = pi/2-(x+x^3/6+3*x^5/40 ...)

von A. D. (ad1)


Lesenswert?

Ups, zu schnell gepostet/überlesen. Das mit den Bereichen stimmt schon.
Du mußt dann halt zwei verschiedene Reihen benutzen um auf die
Genauigkeit zu kommen. Die eine um cos(0), die andere um cos(pi/2).

von Franz josef V. (advors)


Lesenswert?

BASCOM-AVR hat sowohl den Datentyp DOUBLE, als auch die trigonometrische
Funktion arccos (ACOS) implementiert.

Dim d1 as Double, d2 as Double

d1 = 0.5
d2 = acos(d1)
print d2
end

ergibt 1.0471975511966


Zur Frage der Genauigkeit: EXCEL gibt hier exakt die gleiche Zahl aus.
Für DOUBLE werden AVR mit HW-MUL benötigt, dies sind alle Mega (ausser
der 103).

Viele Grüße
Josef

von Daniel (Gast)


Lesenswert?

Hallo Franz Josef!

Du hast doch die Bibliothek "double.lbx" für Bascom geschrieben,
oder?
Allerdings steht in der Hilfe nicht, daß die Bibliothek die
trigo.-Funktionen unterstützt. Ich hab das trotzdem versucht, aber eine
Fehlermeldung erhalten.

Das steht in der Hilfe:
The double.lbx (lib) is written by Josef Franz Vögel. The library
supports the basic operations :

·  Addition (+)

·  Substraction (-)

·  Multiplication (*)

·  Division (/)

·  Val() , INPUT

·  Str() , PRINT

·  Int()

·  Frac()

·  Fix()

·  Round()

·  Conversion from double to single and long

·  Conversion from single and long to double

The double library uses special Mega instructions not available in all
AVR chips. But as the old chips are not manufactured anymore, this
should not be a problem.

Mit dem HW-Mul ist kein Problem, da ich den Mega128 verwende.

Gruß

von Franz josef V. (advors)


Lesenswert?

Hallo Daniel,

im letzten Help-File ist noch der Satz angefügt:

All Trig() functions are supported by the double too.

Poste bitt mal den Programmteil, welcher den Fehler verursacht.
Welche BASCOM-AVR Version verwendest Du? Wenn ich mich richtig erinnere
wurden die trigonometischen Funktionen mit 1.11.7.8 implementiert.

Mit Taylor-Reihen kann man im Prinzip die Funktionen berechnen. Manche
Funktionen haben aber den Nachteil, dass Sie sehr langsam konvergieren.
Ausserdem ist generell die Laufzeit wesentlich höher als wenn die
Funktionen mit speziellen Formelsätzen im ASM implementiert werden. Die
ACOS benötigt bei einem 16MHZ Takt 1,35mSec.

von Daniel (Gast)


Lesenswert?

Guten Morgen!
Da haben wir ja schon den Fehler. Ich habe nur die Version 1.11.7.6.
Das merkwürdige ist allerdings, das mir der Updatewizard sagt, es gäbe
keine neue Version; komisch... Jedenfalls vielen Dank erstmal.

Gruß

von Franz josef V. (advors)


Lesenswert?

Hallo Daniel,

Du musst zuerst den UpDate-Wizard mit einer neuen LIC-Datei füttern
(version 1.11.8.0) damit er das richtige Update findet. Eventuell musst
Du Dich auch neu registrieren. Schau mal auf
http://www.grote.net/bascom/frm25476.html

BTW: Könntest Du bitte noch kurz verraten, für welche Art von
Applikation Du trigonometrischen Funktionen in DOUBLE verwendest.

Viele Grüße
Josef

von Daniel (Gast)


Lesenswert?

Hallo Franz,

Danke für Deine Hilfe, ich werde mich da gleich mal drum kümmern.
Zur Anwendung: Ich habe ein kleine GPS-Gerät gebaut, zunächst erstmal
noch auf dem STK500 mit einem MEGA128. Das Teil kann position
Geschwindigkeit und Kurs anzeigen. Zusätzlich zeigt ein Pfeil in
Nordrichtung. Jetzt will ich noch eine Funktion programmieren, sodaß
ich Wegpunkte eingeben kann und mir das Gerät Entfernung und Richtung
zu diesem Punkt anzeigen kann. Und für diese Berechnungen brauche ich
trigonometrische Funktionen, die Doubles verarbeiten können.

Gruß

von Mark S. (struberg)


Lesenswert?

eventuell findest du in der avr_libc bei der Funktion acos() nähere
Implementierungsdetails. Zu finden unter savannah.nongnu.org

von Reiner (Gast)


Lesenswert?


von Reiner (Gast)


Lesenswert?


von Daniel (Gast)


Lesenswert?

Danke für alle Infos. Ich hab mich bei Mcselec erstmal neu registriert.
jetzt muß ich erstmal warten, bis ich die Bestätigung bekomme, dann
werde ich mir die neuste Version von Bascom ziehen. So komme ich dann
hoffentlich um die Implementierung rum.

Gruß

von Daniel (Gast)


Lesenswert?

Moinmoin.

Nochmal so nebenbei. Ich habe Probleme die neue Version zu
installieren.  Nach dem Updaten krieg ich ne Fehlermeldung, daß die
Dateil BASC-AVR.DLL keine gültige Windowsdatei ist. Also hab ich
nochmal die Vollversion runtergeladen. wenn ich die Aber installieren
will, sagt mit das Installationsprogramm, daß es die Datei bascavrl.dll
nicht öffnen kann. Hat jemand von euch ähnliche Probleme gehabt?

Gruß

von Franz josef V. (advors)


Lesenswert?

Hallo Daniel,

ich selbst hatte nicht solche Probleme. Das Linzenz-File bscavrl.dll
muss sich in dem Pfad befinden, in welchem BASCOM-AVR installiert
werden soll. Vielleicht ist bscavrl.dll noch von einem früheren
unsauberen Ausstieg aus BASCOM-AVR gesperrt. Vielleicht hilft hier ein
System-Neustart.

Gruß Josef

von Daniel (Gast)


Lesenswert?

Hmm, aber wenn ich die komplette version installieren will? Ich habe die
alte erstmal nicht deinstalliert, weil ich das erst tun wollte, wenn die
neue version läuft. Vielleicht sollte ich das doch mal tun...

Gruß

von Franz josef V. (advors)


Lesenswert?

Hallo Daniel,

ich habe eigentlich noch nie eine bisherige Version deinstalliert.

Ich lege einen neuen Pfad an. Wenn schon mal mit dem LIC-File
installiert wurde, musst Du die Zeile "verified=1" auf "verified=0"
setzen, damit er erneut den Installationspfad abfrägt. In diesem neuen
Pfad muss dann aber schon die bscavrl.dll gespeichert sein.

Alternativ kannst Du auch den gesamten bisherigen BASCOM-AVR Pfad mit
den Unterverzeichnissen (insbesonder LIB) in einen neuen Pfad kopieren.
Damit hast Du die bisherige Installation gesichert und kannst auch damit
weiterarbeiten. Dann kannst Du das Update über die bisherige
Installation darüberinstallieren.

von Daniel (Gast)


Lesenswert?

Das Update habe ich ganz am Anfang in den vorhandenen Ordner
installiert. Da trat aber dieses Problem auf. Die komplette Version
wollte ich in ein anderes Verzeichnis installieren, was ja aber auch
fehlgeschlagen ist.

Gruß

von mmmtr (Gast)


Lesenswert?

smartie:
"ein avr dürfte da etwas überfordert werden. normalerweise macht man
sowas mit Tabellen, die man im Flash ablegt anstatt jeden Wert zu
berechnen."

Solche Aussagen liest man hier öfter. Sie sind aber grundsätzlich
Quatsch, wenn keine Rahmenbedingungen gegeben sind wie: Der µC muss
soundsoviele dieser Operationen/Sekunde ausführen.

Es gibt etliche Anwendungen, bei denen man recht komplexe mathematische
Ausdrücke auswerten muß (evtl. auch mit hoher Genauigkeit), wofür jedoch
sehr viel Zeit zur verfügung steht.

Gruß, Michael

von Reiner (Gast)


Lesenswert?

>>Zur Anwendung: Ich habe ein kleine GPS-Gerät gebaut, zunächst
>>erstmal noch auf dem STK500 mit einem MEGA128. Das Teil kann
>>position Geschwindigkeit und Kurs anzeigen. Zusätzlich zeigt ein
>>Pfeil in Nordrichtung. Jetzt will ich noch eine Funktion
>>programmieren, sodaß ich Wegpunkte eingeben kann und mir das Gerät
>>Entfernung und Richtung zu diesem Punkt anzeigen kann. Und für diese
>>Berechnungen brauche ich trigonometrische Funktionen, die Doubles
>>verarbeiten können.

Zu der Performancefrage:  Ich habe eine solche Anwendung am laufen.
AT90S8515 @4Mhz, WINAVR, fplib mit eingebunden.  Der AT empfängt nicht
nur die NMEA-sentences vom GPS sondern muß sich auch noch um Log-,
Echolot- und Windinstrument-sentences kümmern (4800 Bd). Für einige
Ausgaben findet eine wahre Fließkomma-Trigonometrieschlacht statt.
Und ..  der AT90S8515 langweilt sich wahrlich dabei ):-

Zu der Genauigkeitsfrage: Selbst bei DGPS (+/-3m Genauigkeit) reicht
float vollkommen aus.

Reiner

von Daniel (Gast)


Lesenswert?

Ich habe ausgerechnet, daß ich für 1m Auflösung (ok, GPS hat
wahrscheinlich nicht die Genauigkeit, wohl aber die Auflösung)eine
Genauigkeit von 4*10^-6 benötige. Zur Sicherheit wollte ich mit 1*10^-7
rechnen. Zu genau schadet ja nicht. Im Moment muß ich aber erstmal das
Updateproblem in den Griff bekommen.

Grüße

von Daniel (Gast)


Lesenswert?

Ich hab jetzt mal die alte BASC-AVR.dll ins Verzeichnis kopiert. Jetzt
kann ich Bascom starten und es steht auch die neue Version da, aber ich
weis jetzt nicht, ob alles in Ordnung ist; oder ob dadurch Probleme
entstehen...

von Franz josef V. (advors)


Lesenswert?

Das schaut mal schon vielversprechend aus. Wenn Du in der IDE normal
arbeiten kannst und der Simulator auch geht, glaube ich, dass es
geklappt hat.

Gruß Josef

von Daniel (Gast)


Lesenswert?

Hmm, ich glaube nicht, daß es so optimal geht. Ich kriege beim
kompilieren alter Programme komische Fehlermeldungen in Zeilen, in
denen kein Code steht. Außerdem meckert der Compiler bei Codezeilen,
wie:

Dim X as double

x=x/10                   <--- Das mag er nicht

Der Compiler beschwert sich, wenn man durch einen festen Wert teilt,
wenn ich aber statt der 10 eine andere Doublevariable nehme geht es.

Gruß

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Probier mal
  x = x/10.0

von Daniel (Gast)


Lesenswert?

Habe ich schon probiert, gibt aber auch eine Fehlermeldung.

Gruß

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Seltsamer Compiler.

von Daniel (Gast)


Lesenswert?

Ja, deswegen gehe ich davon aus, daß man die alte DLL nicht so einfach
rüberziehen kann, aber die neue ist ja irgendwie kaputt...

von Franz josef V. (advors)


Lesenswert?

Hallo Daniel,

Dim X as Double
X = X / 10

müsste anstandlos akzeptiert werden.

Du hast in BASCOM-Pfad 2 DLL Dateien.

Die bscavrl.dll ist die Lizenzdatei und hat wenige KB. Diese hast Du
mit der Lizenz erhalten und wird in allen Programmversionen verwendet.


Die zweite DLL BASC-AVR.dll gehört zum Programm und wird auch mit jedem
Update erneuert. Diese darfst Du dann natürlich nicht aus der früheren
Version nehmen, sondern aus dem aktuellen Update.

Gruß Josef

von Daniel (Gast)


Lesenswert?

Ja, das hab ich mir auch schon gedacht, das Problem ist ja aber, daß die
neue BASC-AVR.dll, die durch das Updaten raufgespielt wird ehler
auslöst. Sie hat auch keinen Inhalt.

Gruß

von Daniel (Gast)


Lesenswert?

Juhu!!!! Jetzt geht es. Ich hatte von einem Verzeichnis aus installiert,
in dem die bascayrl.dll gefehlt hat.

Gruß und danke für alle Hilfe

von Daniel (Gast)


Lesenswert?

Hmm, wie das immer so ist: hat man ein Problem gelöst, tritt ein neues
auf (oder mehrere). Ich kann mein programm jetzt vernünftig
kompilieren, aber die trigonometrischen Funktionen funktionieren im
Simulator nicht. Wenn man im Simulator die Zeile mit der Funktion
ausführt, dann stoppt der Simulator und springt zum Anfang des
Programms zurück. Ist der Simulator noch nicht soweit, oder stimmt was
bei mir nicht?
Hier einmal ein Beispielcode der nicht geht:

Dim D As Double
Dim C As Double


Start:
D = 1.5322

C = Sin(d)

Goto Start

Gruß

von Franz josef V. (advors)


Lesenswert?

Hallo Daniel,

Das liegt wahrscheinlich am zu geringen Stacks.
Das sind relativ aufwändige Berechnungen, wobei Zwischenergebnisse am
Stack (Frame) abgelegt werden.
Wenn Du für
Frame mindestens 96 Bytes
Softstack mindestens 64 Bytes
HardStack mindestens 64 Byte

bist Du etwas auf der sicheren Seite für die Double-Funktionen.
Was Deine Applikation sonst noch braucht, musst Du natürlich auch noch
berücksichtigen.

Schau mal in der Hilfe unter $DBG und DBG.

Ich nehme generell für alle drei den Wert 128 wenn ich mit dem SRAM
nicht geizen muss.

Wenn die Stacks zu klein sind, wird zuerst der Soft-Stack und dann der
Hard-Stack von den Framewerten überschreiben, was unweigerlich zu einem
Programmabsturz führt

Gruß Josef

von Daniel (Gast)


Lesenswert?

Super, jetzt funktioniert es! Vielen Dank Franz, Du hast mir echt sehr
geholfen.

Gruß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.