mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik asin funktion Programmieren


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche gerade mal eine asin funktion zu Programmieren,
in der GCC Lib habe ich für den AVR folgendes gefunden:

/*---------------------------------------------------------------------- 
------

 asin(x) = pi/2 - (1 - x)^2 (P0 + x(P1 + x(P2 + x(P3 + x(P4 + x(P5 +
                                                       x(P6 +
x(P7))))))))
 *
 * P0 :  1.57079 63050    [3FC90FDA]
 * P1 : -0,21459 88016    [BE5BBFCA]
 * P2 :  0.08897 89874    [3DB63A9E]
 * P3 : -0.05017 43046    [BD4D8392]
 * P4 :  0.03089 18810    [3CFD10F8]
 * P5 : -0.01708 81256    [BC8BFC66]
 * P6 :  0.00667 00901    [3BDA90C5]
 * P7 : -0.00126 24911    [BAA57A2C]
 */

ich habe das so implementiert:
const float P0= 1.57079;
const float P1= -0.21459;
const float P2= 0.08897;
const float P3= -0.05017;
const float P4= 0.03089;
const float P5= -0.01708;
const float P6= 0.00667;
const float P7= -0.00126;

float Asin(float winkel){
    float result= _PI/2;

    float temp= P7;

    temp *= winkel;
    temp += P6;
    temp *= winkel;
    temp += P5;
    temp *= winkel;
    temp += P4;
    temp *= winkel;
    temp += P3;
    temp *= winkel;
    temp += P2;
    temp *= winkel;
    temp += P1;
    temp *= winkel;
    temp += P0;
    temp *= winkel;

    temp *= ((1-winkel) * (1-winkel));  //(1-x)^2
    result -= temp;                  //pi/2 - -->

    return(result);
}


leider kommt da nur müll bei raus,
kann mir vielleicht jemand etwas auf die sprünge helfen?

Sebastian

Autor: Karl heinz Buchegger (heinzi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
liegt vielleicht daran, dass man in asin keinen Winkel
hineinstopft, sondern ein Winkel (in Radianten) herauskommt.
Die Umsetzung der Formel sieht auf den ersten Blick gut
aus. Ob die Formel stimmt hab ich allerdings nicht geprueft.

Autor: Barti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur ein Tipp: Hast Du das nur interessehalber programmiert? Wenn es auf
Geschwindigkeit ankommt nimmt man bei kleinen Mikrocontrollern gern
Sinus-Tabellen. Geht schneller.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ne das muss ich implemtieren da ich einen compiler bentze der das nicht
kann, aber ich mit winkeln rechnen muss.
Das mann in RAD rechen muss ist klar, sagt ja auch der C Standart.
Aber 0,707 als eingang müsse so 0,785~ rauskommen, --> 45°.
Aber die kommen nicht raus das sind irgendwas um die 1.5...  .
Ich habe die Formel von oben einfach mal in C++ (Win) eingegeben und da
kommt das gleiche falsche ergebniss raus.

Ich will für modellbau 2 servos synchron steuen, die liegen aber in
Variablen winklen zueinander.
Oben ist sogar noch ein keiner fehler drinn:
  temp += P0;
  temp *= winkel;   <-- FALSCH, ist zuviel

aber die funktion geht immer noch nicht.
Hat jemand vielleicht ne idee wie man das sonst noch so machen kann?

Und wie implementiert man am besten sqrt(), also wurzel 2, ich kann ja
auch pow(n, 1/2); nehmen, nur ist das wesentlich auffwendiger zur
laufzeit.

Sebastian

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könntest du vielleicht einfach mal dein Problem / deine Aufgabe
formulieren (das mit den Servos). Ich denke, dass für Servos wegen der
geringen Auflösung keine asin-Funktion programmiert werden muß.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht darum:
eine frei beweglich steuerdüse mit flachem ausftritt soll in 2
richtungen gesteuert werden.
Wenn 2 servos gegeneinander drehen dann dreht sich die düse um die z
Achse.
Wenn beide servos jetzt im mit dieser verschränkung in die gleiche
richtung drehen kann man um die X Achse schwenken.

Das problem ist:
man muss eine kompensation der wege machen da sich die hebel der Sevos
im kreis bewegen, aber eine lineare bewegung ausgeführt werden soll,
dazu die winkelfunktionen.
Um den gleichen X weg zu fahren müssen beide Servos unterschiedliche
winkel fahren. Und das wollte ich halt in echtzeit berechnen und keine
tabellen nehmen, wenn man was am system andert (mechanik) dann muss man
alle tabellen neu machen, so muss man nur die abstände neu eingeben.
Die Mechanik dazu funktioniert, jetzt muss halt nur noch der Controller
programmiert werden.

Sebastian

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So wie ich deine Mechanik verstehe, steckt deine Düse in etwas einem
Differntial ähnlichen Aufbau: Wenn die Drehrichtung gleich ist, dann
schwenkt die Düse (Geradeausfahrt). Wenn es einen Drehzahlunterschied
gibt, dann verdreht sich die Düse (Differentialkorb dreht sich;
Kurvenfahrt).

Wie sollen denn drehende Bewegungen ohne eine Längenänderung eine
lineare Bewegung ausführen?
Das erinnert mich an einen Sinus-Antrieb...

Da die Änderung der Kompenation des Antriebs ja eigentlich nur bei
Änderung der Mechanik auftritt, solltest du doch den Weg der Tabelle
gehen, was die Geschwindigkeit wesentlich erhöhen würde.

Autor: sackgesicht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
/++ zitat
Und das wollte ich halt in echtzeit berechnen und keine
tabellen nehmen, wenn man was am system andert (mechanik) dann muss man
alle tabellen neu machen,
/-- zitat

Warum sollte sich eine asin-Tabelle ändern, wenn du was an deinem
System machst? Der asin(0.707) ist immer 0,785... egal wie du dein
System verbiegst.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nach einigem googeln hab ich eine
Reihenentwicklung fuer Asin gefunden

wildegg.com/papers/WrongTrig.pdf

Die Funktion sieht dann so aus

double MyAsin( double x )
{
  double Result =  x
                   + 1.0/6.0     * x*x*x
                   + 3.0/40.0    * x*x*x*x*x
                   + 5.0/112.0   * x*x*x*x*x*x*x
                   + 35.0/1152.0 * x*x*x*x*x*x*x*x*x
                   + 63.0/2816.0 * x*x*x*x*x*x*x*x*x*x*x;
  return Result;
}

(Das Anwenden des Horner-Schemas zur Vereinfachung der
Berechnung der Potenzen bleibt als Uebung fuer den Leser).

Ich hab aber auch noch weiteres gefunden:
Meist wird nicht so eine Entwicklung benutzt, den die konvergiert
nur schlecht. Meist wird stattdessen ein ganz simples Newton
Verfahren angewendet (zusammen mit einer Reihenentwicklung
fuer Sinus). Mit dem koennte man dann auch die Wurzel berechnen:

myweb.lmu.edu/dmsmith/MComp89.pdf


Aber ehrlich: Du solltest Dir die Verwendung von Tabellen
noch mal gruendlich ueberlegen. Grade da Du das Ganze in
'Echtzeit' brauchst. Das da ist alles andere als 'schnell
mal eben berechnet'.

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aus dem Bronstein:


                   x^3     1*3 x^5     1*3*5 x^7
  arcsin x =  x + ----- + --------- + ----------- + ...
                   2*3      2*4*5       2*4*6*7

                   1*3*5 ... (2n-1) x^(2n+1)
                + --------------------------- + ...
                     2*4*6 ... (2n) (2n+1)


Naja, das ganze kannst Du natürlich ausfaktorisieren...

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.