HaWe
30.04.2019, 08:29
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.
:shock:
Dies ist der relevante 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?
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.
:shock:
Dies ist der relevante 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?