[Lua] Winkelfunktionen nachrüsten

CHDK-Skripte, CHDK-Entwicklung, PC-Zusatzprogramme, Informationen für Tüftler

Winkelfunktionen nachrüsten

Beitragvon rudi » 04.11.2012, 19:31

Hallo zusammen,

schon mehrfach ist die Frage nach Winkelfunktionen unter LUA aufgetaucht. Zufällig habe ich den Artikel bei Wikipedia zum CORDIC-Algorithmus und die hier beschriebene C++ Umsetzung (Absatz: Programm: Festkomma Bibliothek) gelesen. Das Verfahren ist für Integerrechnung und Schiebeoperationen entwickelt worden.
Um einen Eindrück von der Leistungsfähigkeit zu bekommen, ist dabei eine LUA-Bibliothek entstanden.

Größtes Problem in LUA unter CHDK ist die Zahlendarstelleung ohne Nachkommateil und der Wertebereich von -2^31 .. 2^31-1. Alle Berechnungen mit der Bibliothek cordicLib.lua erfolgen mit um 10^3 erweiterten Werten, welche damit drei Nachkommastellen repräsentieren. Intern arbeitet die Bibliothek mit vier Nachkommastellen. Weiterhin wurde die übliche Winkelangabe im Bogenmaß durch das Gradmaß ersetzt, was die Berechnung um mehr als eine Nachkommastelle verbessert. Der Genauigkeit wirken die üblichen Probleme mit der Umrechnung zwischen Dezimal- und Dualsystem entgegen.

Einen Eindruck vermittelt das Testproramm cordic.lua. Es werden alle implementirten Winkelfunktionen benutzt. Zusätzlich wurde die Funktion Int2Str() neu geschrieben.
Ausgabe cordic.lua:
Code: Alles auswählen
CORDIC LIBRARY Version 0.3

Konstanten:
Multiplikator = 1000
2*PI = 6.283
PI = 3.141
PI/2 = 1.570

Funktionen:
DEG(30) -> RAD(0.523)
RAD(0.523) -> DEG(29.980)
4/3 = 1.333

Winkelfunktionen im Bogenmaß (RAD):
SINR(0.523) = 0.499
COSR(0.523) = 0.866
TANR(0.523) = 0.576

ASINR(0.499) = 0.522
ACOSR(0.866) = 0.523
ATANR(0.576) = 0.522

RECR(4.000, 3.000) = POLR(5.000, 0.643)
POLR(5.000, 0.643) = RECR(4.001, 2.997)

Winkelfunktionen in Grad (DEG):
SIND(30) = 0.500
COSD(30) = 0.866
TAND(30) = 0.577

ASIND(0.500) = 29.992
ACOSD(0.866) = 30.006
ATAND(0.577) = 29.992

RECD(4.000, 3.000) = POLD(5.000, 36.865)
POLD(5.000, 36.865) = RECD(4.000, 2.999)


Zu tun bleibt die Ermittlung der Arbeitsbereiche der Winkelfunktionen und die daraus resultierende Konvertierung der Werte in die richtigen Quadranten.
Arbeitsbereiche:
Code: Alles auswählen
  sind(ALL) = -0.999..+0.999
  cosd(ALL) = -0.999..+0.999
  tand(ALL) = -3332.666..3332.666 (90°/270° = -3332.666)

  asind(-0.986..+0.986) = -90°..+90°
  acosd(-0.986..+0.986) = 0°..+180°
  atand(-214747..+214747) = -90°..+90°

  recd(0..21, ALL) = pold(-21..+21, -21..+21)
  pold(-10..+10, -10..+10) = recd(0..14.14, 0°..360°)

[EDIT 28.11.2012]
Version 0.3:
  • Den Winkelfunktionen für Winkel in Grad wir ein "d" (für deg) angehangen, wie tand().
  • Winkelfunktionen im Bogenmaß (rad) hinzugefügt. Bsp. tanr()
  • Umrechnungsfunktionen fur deg <-> rad hinzugefügt.
  • Vorbeugung für Überlauf überarbeitet und als Funktion integer_mul_div () = a * b / c zugänglich gemacht.
  • Konstanten für 2*PI, PI und PI/2 hinterlegt.
[/EDIT]
[EDIT 30.11.2012]
Version 0.4:
  • Bugfix in Funktion integer_mul_div().
  • Funktion integer_mul_div() um gemischte Brüche erweitert.
[/EDIT]
[EDIT 02.12.2012]
Version 0.5:
  • Bugfix in Funktion integer_mul_div()-Abschnitt gmischte Brüche.
  • Laufzeiten optimiert in der Funktion integer_mul_div().
[/EDIT]

Gruß rudi
Dateianhänge
cordicLib.zip
cordicLib Version 0.5
(4.55 KiB) 103-mal heruntergeladen
Zuletzt geändert von rudi am 02.12.2012, 17:07, insgesamt 5-mal geändert.
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 500
Registriert: 11.09.2009, 12:27
Kamera(s): A590IS_101B, SX260_100B

Re: Winkelfunktionen nachrüsten

Beitragvon Sinter » 07.11.2012, 16:12

Hallo Rudi,

erst vergangene Woche hatte ich noch im Stillen gegrübelt, dass Winkelfunktionen unter Lua doch recht hilfreich sein könnten. Eine großartige Entwicklung, dass du nun die Winkelfunktionen möglich gemacht hast. Vielen Dank für diesen weiteren Meilenstein! Die Umsetzung erscheint mir durchdacht und hinreichend genau zu sein. Für spezielle Features sind die Winkelfunktionen sehr willkommen.

Viele Grüße,
Sinter
Ixus 60 (SD600) Firmware 1.00a
CHDK-DE aktuelle Version
Benutzeravatar
Sinter
CHDK-Begeisterter
CHDK-Begeisterter
 
Beiträge: 416
Bilder: 2
Registriert: 14.08.2009, 14:16
Wohnort: München

Re: Winkelfunktionen nachrüsten

Beitragvon rudi » 21.11.2012, 19:15

Hallo,

die CordicLib liegt jetzt in Version 0.2 vor (siehe erster Beitrag). Alle Winkel werden für die Cordic-Routine in den 1. Quadranten konvertiert und anschließend die Ergebnisse quadrantenrichtig mit dem Vorzeichen versehen, oder etsprechend umgekehrt.
Der Arcussinus und Arcuscosinus besitzten einen eingeschränkten Arbeitsbereich! Eine Umsetzung in C könnte das Problem beheben, denn dort steht die Wurzelfunktion zur Verfügung. Dadurch kann ASIN und ACOS über die besser arbeitende cordic_atan-Funktion ermitteln.

Gruß rudi
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 500
Registriert: 11.09.2009, 12:27
Kamera(s): A590IS_101B, SX260_100B

Re: Winkelfunktionen nachrüsten

Beitragvon msl » 21.11.2012, 22:23

Hallo rudi,

auch von mir ein Danke für diese großartige Bibliothek.

Das bringt mich ein Stück weiter, was Berechnungen zur "blauen Stunden" betrifft. Die im Thread zu den erweiterten GPS-Funktionen avisierten Funktionen scheinen ja in irgendwelchen dunklen Kellern vor sich hinzudümpeln. ;)

Ich möchte einfach meine Standortkoordinaten eingeben und dazu passend dann Sonnenauf- und Untergang berechnen, was zwingend Winkelfunktionen erfordert. Siehe dazu diese gut dokumentierte Berechnung: http://lexikon.astronomie.info/zeitgleichung/

Ich würde mir nun noch wünschen, dass man optional mit Bogenmaß rechnen kann.

Gruß msl
■ "Hey you, don't tell me there's no hope at all. Together we stand, divided we fall."CHDK inside FAQCHDK-Neuigkeiten auf Twitter
Benutzeravatar
msl
Super-Mod
Super-Mod
 
Beiträge: 4512
Bilder: 271
Registriert: 22.02.2008, 12:47
Wohnort: Leipzig
Kamera(s): A720 1.00c
SX220 1.01a

Re: Winkelfunktionen nachrüsten

Beitragvon Belichter » 22.11.2012, 18:47

msl hat geschrieben: Siehe dazu diese gut dokumentierte Berechnung: http://lexikon.astronomie.info/zeitgleichung/

Hallo msl,

genau die habe ich auch schon mal nachvollzogen.
Die Ergebnisse waren für mich allemal genau genug.
Zum 'debuggen' meiner Routinen habe ich CalSky zu Rate gezogen, das war sehr hilfreich.

bis dann
IXUS 970 IS 100b
Belichter
CHDK-Begeisterter
CHDK-Begeisterter
 
Beiträge: 170
Bilder: 11
Registriert: 21.05.2009, 10:21
Wohnort: Solingen
Kamera(s): ixus 970 IS 100b

Re: Winkelfunktionen nachrüsten

Beitragvon rudi » 22.11.2012, 21:22

Hallo msl,

ich glaube nicht, dass eine Umstellung auf Bogenmaß sinnvoll ist. Zum einen verliert man, durch die geringe Nachkommastellenzahl, Genauigkeit um etwa Faktor 50, zum anderen erfolgt in der "blaue Stunde"-Formel mehrfach die Umwandlung von Grad nach Bogenmaß (Faktor RAD * ... und Konstanten pi, pi2 und RAD).
Als größere Herausforderung sehe ich die Umsetzung der erforderlichen Nachkommastellen in LUA-Integerwerte. Für jede Variable müsste eine getrennte Betrachtung des Arbeitsbereiches durchgeführt werden, um einen Über-, Unterlauf bei maximaler Genauigkeit zu gewährleisten. Auch deutet die Anzahl der benutzten Nachkommastellen auf einen entsprechenden Bedarf für die Genauigkeit hin.

Gruß rudi
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 500
Registriert: 11.09.2009, 12:27
Kamera(s): A590IS_101B, SX260_100B

Re: Winkelfunktionen nachrüsten

Beitragvon Werner_O » 24.11.2012, 12:57

Hallo zusammen,

ich habe mal eine Frage zu http://lexikon.astronomie.info/zeitgleichung/:

Wie berechnet man eigentlich die Horizonthöhe h, welche vom Datum und dem gewählten Breitengrad abhängen muß?
Eine Formel dazu finde ich auf dieser Seite nicht, und im Zahlenbeispiel zu Berlin am 30. Jan. steht dazu nur "Sonnenaufgang h=-50 Bogenminuten = -0,0145 rad". Als Breitengrad für Berlin wird im Beispiel übrigens 52,5° Nord verwendet.

Ich versuche nämlich gerade dazu ein Programm für meinen HP48 zu schreiben und komme an dieser Stelle leider nicht weiter.

Nachtrag 12:12 Uhr
Das Problem hat sich glaube ich erledigt, da anscheinend für h ein fixer Wert entsprechend der geometrischen Horizonthöhe verwendet wird.

liebe Grüße
Werner_O
Benutzeravatar
Werner_O
CHDK-Legende
CHDK-Legende
 
Beiträge: 1013
Registriert: 22.10.2010, 14:12
Wohnort: Köln
Kamera(s): SX20 1.02d
SX240 1.01a
S100 1.01a
S3 1.00a

Re: Winkelfunktionen nachrüsten

Beitragvon TobiMarg » 27.11.2012, 22:58

Hallo,

die Winkelfunktionen sind eine sehr gute Bereicherung der Scriptfunktion. Es gibt aber für die GPS-Funktionen verschiedenes davon schon in "core/gps_math.c".
Ich würde deswegen eher alles in C schreiben und in "lib/math/*" tun, um es überall und nicht nur in Scripten zu Verfügung zu haben.

Gruss
TobiMarg
TobiMarg
CHDK-Begeisterter
CHDK-Begeisterter
 
Beiträge: 102
Registriert: 24.09.2011, 16:17
Kamera(s): SX230HS 1.01c

Re: Winkelfunktionen nachrüsten

Beitragvon rudi » 28.11.2012, 22:05

Hallo,

die CordicLib (Version: 0.3) abeitet nun mit Winkeln in Grad und im Bogenmaß. Weitere Neuheiten siehe EDIT-Abschnitt im ersten Beitrag.

@TobiMarg
An der C-Portierung arbeite ich bereits. Mit der CordicLib habe ich mir die Grundlagen erarbeitet. Für die Genauigkeit wird es fünf Nachkommastellen geben, die asin/acos-Funktionen sollten dann keine Einschränkungen mehr besitzen und ein Überlauf ist dank "double" in mul_scaled/div_scaled nicht zu befürchten. Wahlweise werden alle Argumente als "int" oder "double"-Werte verarbeitet.
Derzeit fehlen noch die Quadrantenkonvertierung und LUA-Integration.

Gruß rudi
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 500
Registriert: 11.09.2009, 12:27
Kamera(s): A590IS_101B, SX260_100B

Re: Winkelfunktionen nachrüsten

Beitragvon rudi » 30.11.2012, 10:38

Hallo zusammen,
ich habe ein Fehler in der Unterfunktion is_mul_overflow() berichtigt. Aktuell ist nun CordicLib (Version: 0.4).

Gruß rudi
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 500
Registriert: 11.09.2009, 12:27
Kamera(s): A590IS_101B, SX260_100B

Re: Winkelfunktionen nachrüsten

Beitragvon rudi » 02.12.2012, 17:13

Hallo zusammen,
es wurde ein Fehler in der Unterfunktion is_mul_overflow() berichtigt. Der Abschnitt "gemischter Bruch" wird nur durchlaufen, wenn die Werte auch in einen gemischten Bruch umgewandelt werden können.
Aktuell ist nun CordicLib Version: 0.5.

Gruß rudi
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 500
Registriert: 11.09.2009, 12:27
Kamera(s): A590IS_101B, SX260_100B

Re: Winkelfunktionen sind nachgerüstet

Beitragvon rudi » 22.01.2013, 14:05

Hallo zusammen,

bezugnehmend auf diesen Beitrag zur CHDK-Version 1.2 (Revision 2453) möchte ich hier noch die Arbeitsbereiche der direkt in LUA benutzbaren imath-Bibliothek nachtragen.

Code: Alles auswählen
lua imath Bibliothek - Ganzzahlberechnugen mit 3 Nachkommastellen durch Erweiterung mit 1000
    Hinweis zur Darstellung: ' = kennzeichnet das gedachte Komma

Konstanten
imath.scale = 1'000         alle Werte sind um 1000 erweitert um 3 Nachkommastellen darzustellen
imath.pi2   = 6'283         2*PI
imath.pi    = 3'142         PI
imath.pi_2  = 1'571         PI/2

Hilfsfunktionen
x = imath.muldiv(a, b, c)   -2147352'576 <= x, a, b, c <= 2147352'576; c<>0; x=(a x b / c)
x = imath.mul(a, b)         -2147352'576 <= x, a, b <= 2147352'576; x=(a x b)
x = imath.div(a, c)         -2147352'576 <= x, a, c <= 2147352'576; c<>0; x=(a / c)

Umwandlungen
res = imath.rad(x)          -16383'999 <= x <= 16383'999; -285'938 <= res <= 285'938
res = imath.deg(x)          -285'938 <= x <= 285'938; -16383'999 <= res <= 16383'999

Winkelfunktionen für Bogenmaß (RAD)
x = imath.sinr(phi)         -16383'999 <= phi <= 16383'999; -1'000 <= x <= 1'000
x = imath.cosr(phi)         -16383'999 <= phi <= 16383'999; -1'000 <= x <= 1'000
x = imath.tanr(phi)         -16383'999 <= phi <= 16383'999; -5698'696 <= x <= 2674'857;
                            phi=PI/2 oder 3*PI/2 -> x<>Unendlich [tanr(PI/2)=-5698'696, tanr(3*PI/2)=2674'857]
phi = imath.asinr(x)        -1'000 <= x <= 1'000; -PI/2 <= phi <= PI/2
phi = imath.acosr(x)        -1'000 <= x <= 1'000; 0 <= phi <= PI
phi = imath.atanr(x)        -7035'005 <= x <= 7035'005; -PI/2 <= phi <= PI/2
r, theta = imath.polr(x, y) -7035'005 <= x, y <= 7035'005; 0 < r <= 9948'767 (0 = Überlauf); -PI/2 <= theta <= PI/2
x, y = imath.recr(r, theta) -16383'999 <= r, theta, x, y <= 16383'999; r<>0

Winkelfunktionen für Grad (DEG)
x = imath.sind(phi)         -16383'999 <= phi <=16383'999; -1'000 <= x <= 1'000
x = imath.cosd(phi)         -16383'999 <= phi <=16383'999; -1'000 <= x <= 1'000
x = imath.tand(phi)         -16383'999 <= phi <=16383'999; -16383'000 <= x <= 16383'000;
                            phi=90'000 oder 270'000 -> x<>Unendlich [tand(90'000|270'000)=-16383'000]
phi = imath.asind(x)        -1'000 <= x <= 1'000; -90'000 <= phi <= 90'000
phi = imath.acosd(x)        -1'000 <= x <= 1'000, 0 <= phi <= 180'000
phi = imath.atand(x)        -7035'005 <= x <= 7035'005; phi = -90'000 <= phi <= 90'000
r, theta = imath.pold(x, y) -7035'005 <= x, y <= 7035'005; 0 < r <= 9948'767 (0 = Überlauf); -90'000 <= theta <= 90'000
x, y = imath.recd(r, theta) -16383'999 <= r, theta, x, y <= 16383'999; r<>0

zusätzliche Funktionen
res = imath.pow(x, y)       -16383'000 <= x^y <= 16383'000
res = imath.log(x)          0 < x <= 16383'999; 0 <= res <= 9'704
res = imath.log2(x)         0 < x <= 16384'000; 0 <= res <= 14'000
res = imath.log10(x)        0 < x <= 16383'999; 0 <= res <= 4'214
res = imath.sqrt(x)         0 <= x <= 16384'000; 0 <= res <= 128'000


Gruß rudi
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 500
Registriert: 11.09.2009, 12:27
Kamera(s): A590IS_101B, SX260_100B

Re: Winkelfunktionen nachrüsten

Beitragvon Sinter » 04.02.2013, 19:06

Hallo Rudi,

deine neuen Winkelfunktionen haben sich in der Anwendung in Twilight und dem Live-OSD inzwischen bereits massenhaft bewährt. Die neuen Befehle möchte ich nicht mehr missen.

Herzlichen Dank dafür und viele Grüße,
Sinter
Ixus 60 (SD600) Firmware 1.00a
CHDK-DE aktuelle Version
Benutzeravatar
Sinter
CHDK-Begeisterter
CHDK-Begeisterter
 
Beiträge: 416
Bilder: 2
Registriert: 14.08.2009, 14:16
Wohnort: München


Zurück zu Code-Ecke

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste