- LiTime Speicher und Akkus         
Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 31

Thema: ESP32 berechnet floats falsch im Vergleich zu M4 und Due/M3

  1. #1
    HaWe
    Gast

    [gelöst] ESP32 berechnet floats falsch vs. M4 und Due/M3

    Anzeige

    Praxistest und DIY Projekte
    hi,
    Mein ESP32 berechnet floats in einem Programm falsch im Vergleich zu meinem M4 und meinem M3 / Due
    (Arduino IDE 1.8.8 )

    nach einer langen Berechnung (1264 Schritte) durch den M4 erhalte ich das Ergebnis 32.843750,
    während der ESP32 54196.625 berechnet
    Ich habe das auch mit dem Due nochmals getestet und hier bekomme ich auch das Ergebnis 32.843750, genau wie beim M4.



    Dies ist der relevante Code:

    Code:
    //  Lunar Lander
    
      
    // preprocessor defaults for time sync: 
    //#define SYNC_REALTIME      // real time sync; outcomment for time lapse
    
    
    #if defined (SAM)
       #include "avr/dtostrf.h"   // sprintf() and dtostrf() for floats
    #endif
    
    
    //----------------------------------------------------
    // flight control
    //----------------------------------------------------
    // public:
    float mFuel=8200;          // fuel mass in kg for landing
    float hi=15300;            // act height in m
    float vHorz=1685;          // Horizontal orbital speed m/s 
    
    float sTargm=470000;       // horizontal way to target landing place
    
    float burnPerc=0;          // user input: burnrate %
    float ftilt;               // tilt horiz...vert -1...0...+1
    float tiltDeg;             // tilt degrees -90°...0...+90°
    
    //----------------------------------------------------
    // private: 
    float ti=0.0, dt=0.5;       // act time, delta time in sec
    
    const float g=1.62;               // Moon gravity
    const float MoonRad=3476000/2.0;  // Moon radius
    const float mLander=6500;         // lander mass in kg with launch fuel
    const float Isp=3050;             // Rocket engine Specific Impulse
    const float FBrake=45000;         // Rocket engine max Propulsion Force 
    
    float burnMax=FBrake/Isp;   // absolute max fuel burnrate 
    float mTotal=mLander+mFuel; // brutto weight with full tanks  
    float rBrake;               // user Rocket brake force 100%, percentual
    float dFuel=0;              // delta fuel
    float burnf=0;              // burnrate factor 0.0 ... 1.0
    
    float dh=0.0;               // delta height in m
    float scaleH=hi/100;        // scaler for tft.hight=100%
    float vVert=0.0;            // Impact speed in m/s   
    float accVert=0;            // vertical accel (sum)
    float accBrake=0;           // acc by break rockets
    float fCentrifug=0;         // centrifugal force by orbital speed
    float accCentrif=0;         // centrifugal accel by orbital speed
    
    float sHorzm=0.0;           // horizontal way flown in m
    
    
    
    //----------------------------------------------------
    // Serial LogBook
    //----------------------------------------------------
    void LogBook(){
       char sbuf1[50], sbuf2[50] ;   
       char* headline1 = "t.sec  hi.m vVert vHoriz   ";
       char* headline2 = "Burn tilt    brake acc  Fuel TBase.m";
       
       Serial.print(headline1);
       Serial.println(headline2);
       
       sprintf(sbuf1,    "%5.1f %5d %4d  %4d     ", 
                        ti, (int)hi, (int)vVert, (int)vHorz);
       sprintf(sbuf2,    "%3d%% %4d     %3.1f %4.1f %5d %f", 
                        (int)burnPerc, (int)(ftilt*90), accBrake, accVert, 
                        (int)mFuel, (float)(sTargm-sHorzm));
                        
       Serial.print(sbuf1); Serial.println(sbuf2);  
       Serial.println();  
    }
    
    
    
    uint32_t dtime;
    
    //----------------------------------------------------
    // Lander Move
    //----------------------------------------------------
    void LanderMove() {  
       static float t0=ti;     
       
       dtime=millis();
       if(hi>0) { 
    
          // Burn Ratio:
          // 100 = 100% == full brake power
          //  50 =  50% == half brake power
          //  0  =  0%  == zero brake power
          //  or anything in between
          //
          // 100% BURN RATIO (BRAKE  POWER) 
          //     => 45000kN propulsion force
          //     => 14,75 kg Fuel burn per second
          //     => brake accelation = 3m/s²
          
          // XEROX Board Computer program, debug:    
          if( sHorzm<15600.0) burnPerc=0;  //  sHorzm<15600    
          else
          if( vVert>60||vHorz>30 ) burnPerc=100;  //  
          else
          if(vVert>50) burnPerc=65;
          else       
          if(vVert>40&&hi<3000) burnPerc=45; 
          else
          if(vVert>35&&hi<1800) burnPerc=40; 
          else
          if(vVert>10&&hi<1100) burnPerc=35; 
          else
          if(vVert>=1&&hi<120) burnPerc=33; 
          else      
          burnPerc=0;
    
          // calculate control
    
          fCentrifug=vHorz*vHorz*mTotal/(MoonRad+hi);
          accCentrif=fCentrifug/mTotal;
          
          if(mFuel==0) burnPerc=0;          // no fuel, no burn ;)      
          burnf = burnPerc/100.0;           // factor  0...1
    
      //  vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 
          dFuel=  burnMax*burnf*dt;        // try burnrate: enough fuel? 
          dFuel = min(dFuel, mFuel);       // calc available rest fuel 
          
          burnf = (dFuel/burnMax)/dt;       // re-calc burnrate by rest fuel
          burnPerc = burnf*100;
          
          rBrake= FBrake*burnf;           // rel brake force  
          accBrake= rBrake/mTotal;        // rocket brake acceleration
          
          mFuel = max(mFuel-dFuel, (float)0);     // rest fuel >=0          
          mTotal= mLander+mFuel;          // new total mass   
      
          if(vVert>=5  ) {
            if(vVert>=40 && vHorz>2 )  ftilt=0.65; // 58.5°
            else 
            
            if(vVert>=30 && vHorz>2 )  ftilt=0.75; // 67.5°          
            else 
            if(vVert>=20 && vHorz>2 )  ftilt=0.80; // 72.0°                 
     
            else
            if(vHorz<=2 && vHorz>=-2) ftilt=0.0; 
            else        
            if(vHorz<0)    ftilt=0.0; 
        
            else ftilt=0.85;    // 76.5°          
          }
          else 
          if(vVert<5&&vHorz>20 )  ftilt=1; 
          else ftilt=0; 
    
          accVert = g - (1-abs(ftilt))*accBrake -accCentrif;
          vVert = vVert + accVert*dt;        // fractional vertical brake
          
          if(vHorz>0) 
          vHorz = vHorz - (ftilt)*accBrake*dt;   // fractional horizonal brake
    
          //  vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 
          sHorzm = sHorzm + vHorz*dt;            // horizontal way flown      
          dh = 0.5*accVert*dt*dt + vVert*dt ;    // delta height by res. grav+centrifug.+brake acc.
          hi = hi-dh;                            // new resulting height
    
          //-----------------------------------------------         
          // pause
          #ifdef SYNC_REALTIME  
             while( millis()-dtime < dt*1000 );  
          #endif   
          //-----------------------------------------------
                    
          ti+=dt;       
          LogBook();
          t0=ti;           
       
          //-----------------------------------------------
          // Landing specs/ratings
          
                                                         
          if ( (( hi<=0 && vVert>=5 ) && vVert<8) )   // Damage              
          {  
            Serial.println();
            Serial.println(" !! Damage !!");    
        
          }
          
          else       
          if ( hi<=0 && vVert<5 && abs(sTargm-sHorzm)>100) {  // very good Landing but way off
            burnPerc=0;                
            Serial.println();
            Serial.println("Very good but way off!");    
          }
    
          else       
          if ( hi<=0 && vVert<5) {               // Perfect Landing
            burnPerc=0;                
            Serial.println();
            Serial.println("Perfect Landing!");      
          }
    
    
          else  
          if ( hi<=0 )        // B L A S T
          {  
            Serial.println();
            Serial.println(" !!! B L A S T !!!");          
          }
       }    
    }
    
    
    //----------------------------------------------------
    // setup
    //----------------------------------------------------
    void setup() {
      #if defined (SAM)
         asm(".global _printf_float"); // sprintf() and dtostrf() for floats
      #endif
      
      Serial.begin(115200);
      delay(2000);
      Serial.println("Serial started!"); 
    
      sHorzm=0; // way flown 
      
      Serial.println();
       
      delay(dt*1000);  
      
      fCentrifug=vHorz*vHorz*mTotal/(MoonRad+hi);
      accCentrif=fCentrifug/mTotal;
      accVert=g-accBrake-accCentrif;
      LogBook();  
    }
    
    
    //----------------------------------------------------
    // loop
    //----------------------------------------------------   
    void loop(void) {  
              
       if (hi>0)  {
          LanderMove();      
       }
      
    }
    Der fragliche Wert ist der letzte in den seriellen Ausgabezeilen (TBase.m).
    Eigentlich müsste das M4- und Due-Ergebnis eher das richtige sein ...!

    Hat jemand so etwas schon einmal gehört oder gelesen und kann die Rechenergebnisse ggf nachprüfen bzw für M3, M4 und ESP32-Plattformen bestätigen?
    Geändert von HaWe (02.05.2019 um 21:22 Uhr)

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    spontan finde ich nur 2 Hinweise

    1. float in printf bugged https://github.com/esp8266/Arduino/issues/73
    2. FPU in ISR bugged https://github.com/espressif/esp-idf/issues/722

    schreib doch erstmal ein einfacheres Programm und prüf ob die einfache Berechnung von pi auf allen copntrollern das gleiche Ergebnis bringt und wie weit sie identisch sind ... vielleicht liegt es an compiler einstellungen
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  3. #3
    HaWe
    Gast
    einfache Programme habe ich schon mal probiert, z.B. 100000 aufeinanderfolgende float-Multiplikationen mit Konstanten - kein Unterschied.
    Es ist auch nicht nur ein Serial print Bug, denn er meldet ja die "Landung" mit "way off!" - kein Wunder, wenn man die Tranquility Base um 54,196km verfehlt hat....

    Möglicherweise ist auch die Float-Falschberechnung kein ausschließlicher (primärer) Float-Rechenfehler, sondern es hängt mit irgendwelchen if/else Randbedingungen ab, die falsch ausgewertet werden.... (?)

    Aber hier hat doch sicher jemand einen M3, M4 und/oder (vor allem auch) einen ESP32 zum Austesten meines Programms bei sich selber zuhause?

    - - - Aktualisiert - - -

    PS,
    ich habe es auch mit fp64 double ausprobiert, gleiche Ergebnisse bei allen Plattformen: M3+M4 gleich, ESP32 völlig anders.
    Das ist um so interessanter, als der M4 ja einen fp32-Coprozessor hat, nicht aber für fp64 (hier rechnet er über C++ Software Routinen), trotzdem rechnet der M4 für fp32 und fp64 gleich (Stellen-Genauigkeit außen vor).
    Geändert von HaWe (30.04.2019 um 09:21 Uhr)

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    z.B. 100000 float-Multiplikationen mit Konstanten
    vorsicht ob da der compiler nicht was wegotimiert XD dann steht da vielleicht nur eine einfache zuweisung weil der compiler das schon vorberechnet hat
    bei solchen experimenten rate ich immer alle variablen vorsorglich als volatile zu deklarieren um sicher zu gehen dass er daran nichts optimiert (vielleicht behebt das auch dein problem beim ESP, versuchs mal)

    manchmal macht auch der compiler komische sachen
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  5. #5
    HaWe
    Gast
    Zitat Zitat von Ceos Beitrag anzeigen
    vorsicht ob da der compiler nicht was wegotimiert XD dann steht da vielleicht nur eine einfache zuweisung weil der compiler das schon vorberechnet hat
    bei solchen experimenten rate ich immer alle variablen vorsorglich als volatile zu deklarieren um sicher zu gehen dass er daran nichts optimiert (vielleicht behebt das auch dein problem beim ESP, versuchs mal)

    manchmal macht auch der compiler komische sachen
    nein, macht er nicht, weil nach jeder Multiplikation ein Serial.println() erfolgt, man kann alles Schritt für Schritt verfolgen - aber auch volatile verhindert das ansonsten, das mache ich schon immer so. Daran liegt es nicht (habe da schon ein paar Erfahrungen aus meinen Benchmark-Programmen... ).

    Aber zurück zum Ausgangsproblem: hier hat doch sicher jemand einen M3, M4 und/oder (vor allem auch) einen ESP32 zum Austesten meines Programms bei sich selber zuhause?
    Zunächst mal wäre es nämlich auch wichtig, das eine oder andere Ergebnis überhaupt einmal (v.a. per Arduino IDE) zu bestätigen.

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.643
    Zitat Zitat von HaWe Beitrag anzeigen
    hi,
    Mein ESP32 berechnet floats in einem Programm falsch im Vergleich zu meinem M4 und meinem M3 / Due
    (Arduino IDE 1.8.8 )

    nach einer langen Berechnung (1264 Schritte) durch den M4 erhalte ich das Ergebnis 32.843750,
    während der ESP32 54196.625 berechnet
    Ich habe das auch mit dem Due nochmals getestet und hier bekomme ich auch das Ergebnis 32.843750, genau wie beim M4.
    nach einer langen Berechnung (1264 Schritte) durch den M4 erhalte ich das Ergebnis 32.843750,
    während der ESP32 54196.625 berechnet

    Ergebnis(e) in welcher(n) Variable(n)?

    Eventuell gibt es Unterschiede. Zuerst würde ich prüfen, ob alle Datentypen identisch sind, auf den unterschiedlichen Systemen. Ein Beispiel dazu, wie das geht gibts hier im Thread: https://www.arduinoforum.de/arduino-...n-beim-ESP8266

    Wenn es Unterschiede gibt, gilt es zu überlegen, welche Auswirkungen dies bei langen rekursiven Berechnungen hat. Also welche Fehlergröße sich einschleichen könnte.

    Da der Unterschied aber enorm ist, wäre auch denkbar, dass es ein systemspezifisches Problem gibt, indem Code erzeugt wird, der ein anderes Ergebnis liefert.
    Wenn gar nichts hilft, kann man das Programm Schritt um Schritt neu aufbauen, um irgendwann an den Punkt zu kommen, wo es nicht mehr funktioniert, also das Ergebnis auf den Systemen unterschiedlich ist. Dann hat man einen weiteren Anhaltspunkt.


    MfG

  7. #7
    HaWe
    Gast
    ja, die Datentypen sind völlig identisch.
    fp32 ist überall fp32, aber ich erwähnte ja bereits, dass auch ein Wechsel zu fp64 nichts ändert.
    Alles andere steht im TOP.
    Aber zurück zum Ausgangsproblem: hier hat doch sicher jemand einen M3, M4 und/oder (vor allem auch) einen ESP32 zum Austesten meines Programms bei sich selber zuhause?
    Zunächst mal wäre es nämlich auch wichtig, das eine oder andere Ergebnis überhaupt einmal (v.a. per Arduino IDE) zu bestätigen.

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.643
    Das wäre auch mein nächster Vorschlag. Man muss mal sehen, was dabei herauskommen sollte. Dazu gehe ich gerne Programme von Hand durch, nehme mir Zettel und Bleistift und rechne das mit Taschenrechner nach. Dazu gehe ich den gesamten Programmablauf durch, Befehl für Befehl.

    MfG

  9. #9
    HaWe
    Gast
    Zitat Zitat von Moppi Beitrag anzeigen
    Das wäre auch mein nächster Vorschlag. Man muss mal sehen, was dabei herauskommen sollte. Dazu gehe ich gerne Programme von Hand durch, nehme mir Zettel und Bleistift und rechne das mit Taschenrechner nach. Dazu gehe ich den gesamten Programmablauf durch, Befehl für Befehl.

    MfG
    Moppi, bitte keine Allgemeinplätze. Das Programm ist dasselbe auf allen Plattformen, also kein Unterschied, alle Variablen werden identisch auf M3,M4 und ESP32 definiert. Trotzdem ein Ausreißer-Ergebnis ausschließlich auf ESP32.
    Bitte antworte nur exakt auf meine exakten Fragen.

    Also zurück zum Ausgangsproblem: hier hat doch sicher jemand einen M3, M4 und/oder (vor allem auch) einen ESP32 zum Austesten meines Programms bei sich selber zuhause?
    Zunächst mal wäre es nämlich auch wichtig, das eine oder andere Ergebnis überhaupt einmal (v.a. per Arduino IDE) zu bestätigen.

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.643
    Ich dachte, Du wolltest Fehler finden.
    Dann bin ich mal wieder raus.


    MfG

Seite 1 von 4 123 ... LetzteLetzte

Ähnliche Themen

  1. Integer oder Floats in Bytes auftrennen
    Von ElchiMtr im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 30.05.2013, 21:52
  2. Wie berechnet man das Haltemoment?
    Von Elvid im Forum Motoren
    Antworten: 5
    Letzter Beitrag: 08.11.2012, 11:08
  3. Antworten: 5
    Letzter Beitrag: 07.08.2008, 17:38
  4. Wie wurde der Spannungsverdoppler berechnet?
    Von Charly_cs im Forum Elektronik
    Antworten: 4
    Letzter Beitrag: 31.08.2005, 13:19
  5. [ERLEDIGT] Wie berechnet man Geschwindigkeit
    Von Alexander im Forum Mechanik
    Antworten: 6
    Letzter Beitrag: 28.02.2004, 23:06

Berechtigungen

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

LiTime Speicher und Akkus