PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ESP32 berechnet floats falsch im Vergleich zu M4 und Due/M3



HaWe
30.04.2019, 07: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?

Ceos
30.04.2019, 07:54
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
(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

HaWe
30.04.2019, 08:11
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).

Ceos
30.04.2019, 08:21
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 :)

HaWe
30.04.2019, 08:39
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.

Moppi
30.04.2019, 08:40
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-Thread-Länge-der-Datentypen-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

HaWe
30.04.2019, 08:45
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.

Moppi
30.04.2019, 08:47
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

HaWe
30.04.2019, 08:49
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.

Moppi
30.04.2019, 08:51
Ich dachte, Du wolltest Fehler finden.
Dann bin ich mal wieder raus.


MfG

HaWe
30.04.2019, 08:53
Ich dachte, Du wolltest Fehler finden.
Dann bin ich mal wieder raus.


MfG

ja, vielen Dank, ich wollte den Fehler auf dem ESP32 (!!) finden. Auf M3 und M4 gibt es keinen Fehler.

Daher meine Anfrage:


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?

Ceos
30.04.2019, 09:00
ich habe mir leider nur meinen ESP8266 mitgenommen und habs gerade mal damit ausprobiert, seltsamerweise funktionierts damit auch :(
Chip mäßig sind die relativ ähnlich, muss wohl wirklich was ESP32 mäßiges sein, heute Nachmittag bin ich wieder zu Hause und kanns mal mit meinem 32er testen

aber da stimmt wirklich was mit den ausgaben nicht im programm er wandelt die floats nicht richtig um bei mir,d as sieht alles etwas kryptisch aus, aber wenigstens landet er ordentlich

HaWe
30.04.2019, 09:53
ja, esp8266 ist problematisch, evt. auch weil es Konflikte mit den WiFi-Scheduler gibt, auch die alten Core-Versionen haben teilw. Fehler.
Der ESP32 hat aber u.a. 2 cpus, einer davon ausschließlich für Wifi, sodass es das "eigentliche" Programm nicht stört wie beim ESP8266.
Auch Mega2560 funktioniert bei mir nicht (Flash/RAM, evt. auch wieder sprintf(..."%f"...)-Problem).

Daher habe ich mich bei mir auf M3, M4 und ESP32 beschränkt.

Bin neugierig, was bei dir beim ESP32 rauskommt!
(Wenn dein ESP32 auch 32.84... rechnet, liegt es an MEINEM ESP32, wenn du dann auch über 54000 rauskriegst, ist es ein ALLGEMEINES ESP32-Problem).

Aber auch auf weitere Ergebnisse von anderen Usern zu M3/M4- (und ESP32-) Tests bin ich gespannt!

- - - Aktualisiert - - -

edit:
habe es jetzt auch für Mega2560 hingekriegt mit einem sprintf-float-patch;
Flash/RAM sind extrem knapp, aber er errechnet ebenfalls nach etwas Hin und Her
32.843750

HaWe
30.04.2019, 18:22
sonst niemand hier, der einen Arduino-kompatiblen ESP32 hat und evtl sogar gegen einen Due oder einen Arduino-kompatiblen M4 testen kann?

Ceos
30.04.2019, 19:05
der Espressiv Server hat scheinbar noch ein 56k Modem für den Upload -.-


t.sec hi.m vVert vHoriz Burn tilt brake acc Fuel TBase.m
776.0 0 0 1 33% 0 2.1 -0.5 481 54197.343750

t.sec hi.m vVert vHoriz Burn tilt brake acc Fuel TBase.m
776.5 -1 1 1 0% 0 0.0 1.6 481 54196.625000


Very good but way off!

HaWe
30.04.2019, 20:36
ist ja irre!
derselbe Fehler!

Jetzt pass mal auf:
schau dir mal Zeile 109 an:

if( sHorzm<15600.0) burnPerc=0; // sHorzm<15600

hast du die gefunden?

umändern in:
if( sHorzm<=0) burnPerc=0; // oder ganz auskommentieren

ergibt: beim ESP32
69359.656250

Due und M4 (und sogar der Mega2560!) aber rechnen hier aus:
15197.906250


kann doch nicht sein, oder?

PS,
welches ESP32 modul has du verwendet?

HaWe
01.05.2019, 07:44
inzwischen konnte jemand anderes ebenfalls bestätigen, dass ein M4 ebenfalls wie bei mir auch Due, M4 und Mega2560
32.843750
messen:

Running on a Feather M4 Express, the final value of TBase.m was 32.843750.

Ceos
01.05.2019, 08:17
Sorry, war gestern abend von der Fahrt noch zu kaputt um noch irgendwas weiter zu probieren

ich hab mal spaßeshalber alles double und explizit float geamcht

an eingien Stellen hast du einen impliziten Integer im Divisir gehabt und ich habe vermutet dass der Compiler da mist baut und vielleicht das ERgebnis zu Int umcastet

hat aber auch nix gebracht .... heute ist Feiertag und den will ich genießen, aber vielleicht schlägt mich die Muße und ich guck mir mal die rEchenschritte an ... ich vermute irgendwo in der Math Umsetzung für den ESP32 einen Bug, die Zahlen die du ermittelt hast ergeben leider kein eindeutges Muster aber sie gebe einen Hinweis auf einen Überlauf in irgendeiner Funktion (vielleicht eine spezielle FPU Funktion die einen f16 erwartet aber mit einem f32 befüttert wird und dann einfach überläuft ... hab leider noch nciht herausgefunden wie man die FPU für den Compiler abschaltet, dann kann ich wenigstens sicherstellen dass die normale Math Library richtig funktioniert)

HaWe
01.05.2019, 09:10
ja klar, vielen Dank dafür!
Dass double vs. floats auch nichts groß ändern, deckt sich ebenfalls mit meinen Versuchen.
Bin ntl auch noch auf weitere Ergebnisse auch anderer User gespannt, tatsächlich kann es aber ja nicht sein, dass 1 cpu erheblich anders rechnet als 3 andere, insb. 1 davon mit fpu.
Woran es immer liegen mag - type casting, fp32, fp64, oder meinetwegen auch abweichende if...else... Auswertungen:
minimale Abweichungen an der letzten Selle wären sicher tolerabel, aber nicht wie hier 32 vs. 54196.

HaWe
01.05.2019, 18:10
ein weiterer User, der das unheimliche Ergebnis bestätigen kann,
diesmal ARM Cortex M0 vs. ESP32:
http://forum.arduino.cc/index.php?topic=613077.msg4157601#msg4157601

The Arduino Zero (ARM Cortex M0+) agrees with the other ARM microcontrollers and evaluates to 32.843750.
The ESP32 (WROOM32) generates 54196.625.

- - - Aktualisiert - - -

ich habe jetzt mal dieses "unerwartete" Verhalten im Expressiv-github Repo gemeldet:
https://github.com/espressif/esp-idf/issues/3405

würde mich freuen, wenn noch mehr User hier testen könnten.

@Ceos: was hast du für ein ESP32 board genau?

Ceos
01.05.2019, 18:14
nannte sich ESP32 Dev Board ... aber das hat mit dem Board nix zu tun, der Chip ist der gleiche, nur der Flash Speicher ist mal größer und mal kleiner ^^

as macht die Dinger ja so genial, nur ein Chip ... keine Peripherie Teile, kein Krimskrams ... einfach Chip drauf, PCB Antenne und Hühnerfutter für die Versorgung

Moppi
01.05.2019, 18:27
@HaWe

verwende doch mal ein long double als Datentyp, float und double weg. Da ich Dein Programm nicht kenne einmal der Hinweis: auch darauf achten, dass der mal nur mit long double - Werten rechnet und sich nicht was anderes in die Rechnung einmischt, wie int oder float oder double.

Vielleicht macht auch der Compiler irgendwas merkwürdiges. Da müsste der Maschinencode überprüft werden, der für die Berechnungen produziert wird. Würde etwas mehr Licht ins Dunkel bringen.


MfG

HaWe
01.05.2019, 19:03
danke, aber das macht momentan keinen Sinn:
Mega2560 kann nur fp32,
M0 + M3 machen fp32 + fp64 per C++ Software,
M4 macht fp32 per hardware-fpu und fp64 per C++ Software,

nur der ESP32 macht irgendwas, aber immer anders...
das muss als Vergleichsbasis reichen.... ;)

Übrigens kennst du mein Programm, es ist im TOP gepostet!


@Ceos:
hat der ESP32 eigentlich auch hardware-fpus?

Moppi
01.05.2019, 20:25
Übrigens kennst du mein Programm, es ist im TOP gepostet!

Schön, dort kann es auch noch viel länger stehen! ;)

Ich muss nicht zwangsweise alle Zeilen lesen. Ich weiß daher nicht, was Dein Programm tut.
Habe momentan viel zu tun, daher auch nicht die Zeit, mich überall reinzufitzeln.

Bin gespannt, was am Ende raus kommt!




MfG

Ceos
01.05.2019, 20:39
ja hat er und die FPU ist auch heiß diskutiert, da die verwendung unnötig viel maschinencode fabriziert .. das ding scheint fischig zu sein abre ich ha immer noch nichnt raus wie ich bei den baordfiles oder in arduino die FPU integration abschalte ... mein spinnensinn klingelt bei der FPU integration, wenn ich sie abschalten kann und die stnadard math verwenden könnte könnte man es ausschließen.

HaWe
01.05.2019, 21:06
ja hat er und die FPU ist auch heiß diskutiert, da die verwendung unnötig viel maschinencode fabriziert .. das ding scheint fischig zu sein abre ich ha immer noch nichnt raus wie ich bei den baordfiles oder in arduino die FPU integration abschalte ... mein spinnensinn klingelt bei der FPU integration, wenn ich sie abschalten kann und die stnadard math verwenden könnte könnte man es ausschließen.
ja, ich las gerade:

5.9.6 Floating Point Aritmetic
The ESP32 supports hardware acceleration of single precision floating point arithmetic (float) via Floating Point
Units (FPU, also known as coprocessors) attached to each core. The use of the FPUs imposes some behavioral
restrictions on ESP-IDF FreeRTOS.
ESP-IDF FreeRTOS implements Lazy Context Switching for FPUs. In other words, the state of a core's FPU registers
are not immediately saved when a context switch occurs. Therefore, tasks that utilize float must be pinned to a
particular core upon creation. If not, ESP-IDF FreeRTOS will automatically pin the task in question to whichever core
the task was running on upon the task's first use of float. Likewise due to Lazy Context Switching, interrupt service
routines must also not use float.

allerdings tritt der Fehler ja auch bei fp64 auf, was die 32bit-FPU nicht betreffen würde.... ::?

Ceos
02.05.2019, 08:43
Ich würde es gerne dennoch ausschließen, komme aber mit Sicherheit nicht vor dem Wochenende dran mich mit den Boardfiles und den innereien von Arduino zu beschäftigen um die Verwendung der "unmodifizierten" math library zu erzwingen ... es kann ja auch sein, dass in der Math Lib Variante für den ESP32 ein grundlegender Fehler existiert ... um für den ESP12 zu compilen benötigt man ja das Espressive Framework und da steckt ziemlich viel code drin der Fehlerbehaftet sein kann

HaWe
02.05.2019, 09:18
Ich würde es gerne dennoch ausschließen, komme aber mit Sicherheit nicht vor dem Wochenende dran mich mit den Boardfiles und den innereien von Arduino zu beschäftigen um die Verwendung der "unmodifizierten" math library zu erzwingen ... es kann ja auch sein, dass in der Math Lib Variante für den ESP32 ein grundlegender Fehler existiert ... um für den ESP12 zu compilen benötigt man ja das Espressive Framework und da steckt ziemlich viel code drin der Fehlerbehaftet sein kann

klar, perfekt wenn du darüber was rauskriegst!

HaWe
02.05.2019, 20:21
Ein User aus dem Arduino Forum hat die Ursache gefunden!
Es lag an der Funktion abs()
Bei Arduino kann die auch auf float angewendet werden, bei ESP32 aber nicht, hier muss man fabsf() für float bzw. fabs() für double verwenden.
http://forum.arduino.cc/index.php?topic=613077.msg4158633#msg4158633
Nun kommen endlich auch die ESP- und die Linux-Astronauten-Crews an der Tranquiity Base an! 8) 8) 8)

Ceos
03.05.2019, 06:31
das sind die Details die ich meine ... bei einem Pic kann man einfach "int32 / int8" rechnen und bekommt ein speicherfressendes befehlsmonster vom compiler oder aber man nimmt die spezielle Funktion nur für den Pic und bekommt eine schlanke Operation die ohne zusätzlichen Speicher auskommt und in nur ein paar Takten abgeschlossen ist

interessant aber dass abs tatsächlich nur für int definiert ist (was ich auf die schnelle aus 3 referenzen rausgelesen habe)
arduino das aber absolut typlos dokumentiert

HaWe
03.05.2019, 08:30
das sind die Details die ich meine ... bei einem Pic kann man einfach "int32 / int8" rechnen und bekommt ein speicherfressendes befehlsmonster vom compiler oder aber man nimmt die spezielle Funktion nur für den Pic und bekommt eine schlanke Operation die ohne zusätzlichen Speicher auskommt und in nur ein paar Takten abgeschlossen ist

interessant aber dass abs tatsächlich nur für int definiert ist (was ich auf die schnelle aus 3 referenzen rausgelesen habe)
arduino das aber absolut typlos dokumentiert

ja, und überraschend war ja auch, dass sogar ein Linux PC mit g++ den selben C++ Rechen-Code mit denselben (durch abs(float) verfälschten) Ergebnissen erzeugt hat, im Gegensatz zu Arduino-abs. Offenbar verwendet Arduino Macros dafür, anders als es in C/C++ <cmath> standardmäßig definiert ist
https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/Arduino.h#L94

edit: auch std:: kennt abs, fabs und fabsf
https://en.cppreference.com/w/cpp/numeric/math/fabs

erst ab C++17 gibt es ein abs() für alle:

(since C++17)
float abs( float arg );
(1)
double abs( double arg );