Prel code for formula creation

This commit is contained in:
Magnus Persson
2022-01-03 18:30:57 +01:00
parent 48f71bd59a
commit d075fe2117
26 changed files with 626 additions and 61 deletions

View File

@ -24,14 +24,91 @@ SOFTWARE.
#include "calc.h"
#include "helper.h"
#include "config.h"
#include "tinyexpr.h"
#include <tinyexpr.h>
#include "tempsensor.h"
#include <curveFitting.h>
#define FORMULA_MAX_DEVIATION 1.5
//
// Use values to derive a formula
//
int createFormula( RawFormulaData& fd, char *formulaBuffer, int order ) {
int noAngles = 0;
// Check how many valid values we have got
if( fd.a[0]>0 && fd.a[1]>0 && fd.a[2]>0 && fd.a[3]>0 && fd.a[4]>0 )
noAngles = 5;
else if( fd.a[0]>0 && fd.a[1]>0 && fd.a[2]>0 && fd.a[3]>0 )
noAngles = 4;
else if( fd.a[0]>0 && fd.a[1]>0 && fd.a[2]>0 )
noAngles = 3;
#if LOG_LEVEL==6
Log.verbose(F("CALC: Trying to create formula using order = %d, found %d angles" CR), order, noAngles);
#endif
if( !noAngles ) {
Log.error(F("CALC: Not enough values for deriving formula" CR));
return ERR_FORMULA_NOTENOUGHVALUES;
} else {
double coeffs[order+1];
int ret = fitCurve(order, noAngles, fd.a, fd.g, sizeof(coeffs)/sizeof(double), coeffs);
//Returned value is 0 if no error
if( ret == 0 ) {
if( noAngles==5 )
sprintf( formulaBuffer, "%.8f*tilt^3+%.8f*tilt^2+%.8f*tilt+%.8f", coeffs[0], coeffs[1], coeffs[2], coeffs[3] );
else if( noAngles==4 )
sprintf( formulaBuffer, "%.8f*tilt^2+%.8f*tilt+%.8f", coeffs[0], coeffs[1], coeffs[2] );
else // ==3
sprintf( formulaBuffer, "%.8f*tilt+%.8f", coeffs[0], coeffs[1] );
bool valid = true;
for( int i = 0; i < 5; i++ ) {
if( fd.a[i]==0 && valid )
break;
double g = calculateGravity( fd.a[i], 0, formulaBuffer );
double dev = (g-fd.g[i])<0 ? (fd.g[i]-g) : (g-fd.g[i]);
// If the deviation is more than 2 degress we mark it as failed.
if( dev*1000 > FORMULA_MAX_DEVIATION )
valid = false;
}
if( !valid ) {
Log.error(F("CALC: Deviation to large, formula rejected." CR));
return ERR_FORMULA_UNABLETOFFIND;
}
Log.info(F("CALC: Found formula '%s'." CR), formulaBuffer );
return 0;
}
}
Log.error(F("CALC: Internal error finding formula." CR));
return ERR_FORMULA_INTERNAL;
}
//
// Calculates gravity according to supplied formula, compatible with iSpindle/Fermentrack formula
//
double calculateGravity( double angle, double temp ) {
double calculateGravity( double angle, double temp, const char *tempFormula ) {
const char* formula = myConfig.getGravityFormula();
if( tempFormula != 0 ) {
#if LOG_LEVEL==6
Log.verbose(F("CALC: Using temporary formula." CR));
#endif
formula = tempFormula;
}
#if LOG_LEVEL==6
Log.verbose(F("CALC: Calculating gravity for angle %F, temp %F." CR), angle, temp);
Log.verbose(F("CALC: Formula %s." CR), formula);