- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 10 von 14

Thema: Problem Sinus durch eigene Funktion ersetzen

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521

    Problem Sinus durch eigene Funktion ersetzen

    Ich will diese Funktion
    Code:
    r=(double)(richtung_temp); //in Radiant*1000
            r=r/1000; //in Radiant
    
            
            sin_x =(long)(128*sin(r));
    durch diese ersetzen:

    Code:
    richtung_temp=(richtung_temp*2)/35; // von Radiant*1000 in Grad, zB 3141*2/35= 179, 1° Fehler ist egal
    
            sin_x =sinus(richtung_temp);
    Code:
    #include <sincos.h>
    #include <avr/pgmspace.h> 
    
    static const short sinusdaten[92] PROGMEM = 
    {0,2,4,7,9,11,13,16,18,20,22,24,27,29,31
    ,33,35,37,40,42,44,46,48,50,52,54,56,58
    ,60,62,64,66,68,70,72,73,75,77,79,81,82
    ,84,86,87,89,91,92,94,95,97,98,99,101
    ,102,104,105,106,107,109,110,111,112,113
    ,114,115,116,117,118,119,119,120,121,122
    ,122,123,124,124,125,125,126,126,126,127
    ,127,127,128,128,128,128,128,128};
    
    short sinus(short winkel)
    {
    short result=0;
    if (winkel>360) winkel=winkel-360;
    if (winkel<360) winkel=winkel+360;
    
    if (winkel<=90) result = (short)(pgm_read_word(&sinusdaten[winkel]));
    if ((winkel>90)&&(winkel<=180)) result = (short)(pgm_read_word(&sinusdaten[180-winkel]));
    if ((winkel>180)&&(winkel<=270)) result = -(short)(pgm_read_word(&sinusdaten[winkel-180]));
    if (winkel>270) result = -(short)(pgm_read_word(&sinusdaten[360-winkel]));
    
    return (result);
    
    short cosinus(short winkel)
    {
    short result=0;
    if (winkel>360) winkel=360;
    
    if (winkel<=90) result = (short)(pgm_read_word(&sinusdaten[90-winkel]));
    if ((winkel>90)&&(winkel<=180)) result = -(short)(pgm_read_word(&sinusdaten[winkel-90]));
    if ((winkel>180)&&(winkel<=270)) result = -(short)(pgm_read_word(&sinusdaten[270-winkel]));
    if (winkel>270) result = (short)(pgm_read_word(&sinusdaten[winkel-270]));
    
    return (result);
    }
    sin_x soll also immer den Sinuswert*128 entsprechen.

    1. Grund ist Umstellung meiner Fahrfunktionen auf Grad ( also drehe 20° nach links) da ich mich mit Radiant noch nie anfreunden konnte.
    2. Grund: die Eigenbau Berechnung läuft viel schneller als Fließkomma, die Genauigkeit ist ausreichend.

    Problem: funktioniert nicht, die nachfolgende Positionsberechnung errechnet mehrere Meter Fahrweg anstatt nur cm.
    Wenn man wieder die normale Sinus/Cosinus Berechnung nimmt rechnet es richtig, also liegt es nur an dieser Funktion

    Ist die Tabelle falsch angelegt?
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    33
    Beiträge
    1.192
    Hallo,
    hier würde ich ansetzen:
    Code:
    if (winkel<360) winkel=winkel+360;
    Müsste das nicht so aussehen:
    Code:
    if (winkel<0) winkel=winkel+360;


    Noch besser wäre eine while-Schleife, damit es z.B. auch für Winkel -500° oder +999° klappt? Mit den ersten beiden Abfragen wird ja nur 1x subtrahiert/addiert um den Winkel in den Bereich 0...360° zu bekommen.
    Code:
    while(winkel<0){winkel+=360;}
    while(winkel>=360){winkel-=360;}
    Die 4 IF-Abfragen kann man noch optimieren.
    In deinem Fall werden ja immer alle 4 Abfragen geprüft.
    Werden die letzten drei IF-Abfragen mit ELSEIF gemacht, dann werden im Durchschnitt nur noch 2,5 IF-Abfragen geprüft.
    Mit einer sog. binären Suche werden immer nur 2 IF-Abfragen geprüft.
    Das bringt noch einen klitzekleinen Geschwindigkeitsvorteil
    Code:
    if(winkel<=180)
    {
      if(winkel<=90){/* 0...90° */}
      else{/* 90...180° */}
    }
    else
    {
      if(winkel<=270){/* 180...270° */}
      else{/* 270...360° */}
    }
    Gibt deine Funktion dann die richtigen Werte für sinus(0), sinus(90), sinus(180), sinus(270), sinus(360), ... aus?

    Die Cosinus-Funktion musst du auch entsprechend anpassen, oder einfach
    Code:
    short cosinus(short winkel)
    {
      return sinus(winkel+90);
    }
    verwenden.

    Ich hoffe, das hilft dir weiter
    Grüße, Bernhard
    "Im Leben geht es nicht darum, gute Karten zu haben, sondern auch mit einem schlechten Blatt gut zu spielen." R.L. Stevenson

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    Danke, das hilft mir einiges weiter!

    Kann gut sein dass die Eingangskorrektur zu klein war, die while Schleifen sind sicher besser.

    Die Cosinus-Funktion musst du auch entsprechend anpassen, oder einfach
    Code:
    short cosinus(short winkel)
    {
    return sinus(winkel+90);
    }
    verwenden.
    Das der Funktionen nur um 90° versetzt sind weiß ich ja, aber diese einfache Lösung ist mir überhaupt nicht eingefallen. Hatte wohl ein paar Bretter vorm Kopf

    LG Werner
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    zu früh gefreut, rechnet wieder nur Mist
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  5. #5
    HaWe
    Gast
    ich habe da sicher was nicht richtig mitgekriegt... aber was genau macht die Funktion/der array
    Code:
    static const short sinusdaten[92] PROGMEM = 
    {0,2,4,7,9,11,13,16,18,20,22,24,27,29,31
    ,33,35,37,40,42,44,46,48,50,52,54,56,58
    ,60,62,64,66,68,70,72,73,75,77,79,81,82
    ,84,86,87,89,91,92,94,95,97,98,99,101
    ,102,104,105,106,107,109,110,111,112,113
    ,114,115,116,117,118,119,119,120,121,122
    ,122,123,124,124,125,125,126,126,126,127
    ,127,127,128,128,128,128,128,128};
    ?

    einen Sinuswert erhält man doch doch dadurch sicher nicht, denn Sinuswerte liegen ja immer zwischen -1 bis +1.

    Aber was macht das dann?

    edit - ah, jetzt hab ichs:
    "sin_x soll also immer den Sinuswert*128 entsprechen.".
    ok.

    dann schreib doch mal eine Funktion, die die echten Sinuswerte für 0...360 deinen Tabellenwerten gegenüberstellt bzw. die Fehlerdifferenz ausgibt!
    Geändert von HaWe (11.09.2015 um 18:00 Uhr)

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    33
    Beiträge
    1.192
    @HaWe Eigentlich hat er es ja schon begründet:
    ... soll also immer den Sinuswert*128 entsprechen.
    Das Rechnen mit Vielfachen ist sinnvoll, weil die Berechnung mit Ganzzahlen deutlich schneller abläuft als die Fließkomma-Berechnung.
    Die Genauigkeit ist bei den meisten Anwendungen ausreichend.

    @damfino: Zeige nochmal deinen aktuellen Code, wie genau hast du den Code getestet? Keine Panik, das bekommen wir schon hin

    Grüße, Bernhard
    "Im Leben geht es nicht darum, gute Karten zu haben, sondern auch mit einem schlechten Blatt gut zu spielen." R.L. Stevenson

Ähnliche Themen

  1. 1600MHz RAM durch 1333MHz RAM ersetzen?
    Von Thor_ im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 0
    Letzter Beitrag: 10.08.2012, 19:45
  2. Sinus-Funktion Fehlerhaft?!
    Von Che Guevara im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 15.07.2009, 17:24
  3. Wait durch Timer ersetzen?
    Von TobiasBlome im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 26
    Letzter Beitrag: 05.02.2009, 21:03
  4. Funreichweite AM durch FM ersetzen?
    Von Tido im Forum Elektronik
    Antworten: 15
    Letzter Beitrag: 27.12.2006, 08:45
  5. atmel 90s1200 durch attiny2313 ersetzen problem
    Von Morpheus85 im Forum Assembler-Programmierung
    Antworten: 7
    Letzter Beitrag: 06.10.2006, 09:55

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad