Skip to content

float computations (fp32, fp64) evaluate differently vs. ARM Cortex M0+M3+M4 & Mega2560 (IDFGH-1084) #3405

@dsyleixa

Description

@dsyleixa

Arduino IDE 1.8.8
different ESP32 MCUs (Adafruit Feather ESP32, ESP32 Dev Board, WROOM32)
vs.
different ARM Cortex boards (Adafruit Feather M4, Arduino Zero (M0), Arduino Due (ATSAM3X8E)
Arduino AVR Mega2560

In the following code all ARM Cortex Boards and the Arduino Mega evalutate to 32.843750,
whilst all ESP32 evaluate to 54196.625

Ref.:
"HaWe" (ESP32, M3, M4, Mega2560): https://www.roboternetz.de/community/threads/73360-ESP32-berechnet-floats-falsch-im-Vergleich-zu-M4-und-Due-M3

"Ceos" (ESP32): https://www.roboternetz.de/community/threads/73360-ESP32-berechnet-floats-falsch-im-Vergleich-zu-M4-und-Due-M3?p=651789&viewfull=1#post651789

"BDL" (M4): https://forums.adafruit.com/viewtopic.php?f=57&t=151070&p=746220#p746147

"MartinL" (ESP32, M0): http://forum.arduino.cc/index.php?topic=613077.msg4157601#msg4157601

(to be continued...)

application source code (issue coincidentally detected):
the questionable value is the last one in either Serial output line (TBase.m)

changing float (fp32) to double (fp64) makes no difference basically.

//  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();      
   }
  
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions