scale tables using type system (#1776)

* store scale in the type

* efi ratio

* boost control scaling

* fix boost tests
This commit is contained in:
Matthew Kennedy 2020-09-10 15:44:10 -07:00 committed by GitHub
parent 6ef1065bdf
commit eebded8caa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 34 deletions

View File

@ -32,8 +32,8 @@
EXTERN_ENGINE; EXTERN_ENGINE;
static Logging *logger; static Logging *logger;
static boostOpenLoop_Map3D_t boostMapOpen("boostmapopen", 1); static boostOpenLoop_Map3D_t boostMapOpen("boostmapopen");
static boostOpenLoop_Map3D_t boostMapClosed("boostmapclosed", 1); static boostOpenLoop_Map3D_t boostMapClosed("boostmapclosed");
static SimplePwm boostPwmControl("boost"); static SimplePwm boostPwmControl("boost");
void BoostController::init(SimplePwm* pwm, const ValueProvider3D* openLoopMap, const ValueProvider3D* closedLoopTargetMap, pid_s* pidParams) { void BoostController::init(SimplePwm* pwm, const ValueProvider3D* openLoopMap, const ValueProvider3D* closedLoopTargetMap, pid_s* pidParams) {
@ -82,7 +82,7 @@ expected<float> BoostController::getSetpoint() const {
return unexpected; return unexpected;
} }
return m_closedLoopTargetMap->getValue(rpm / RPM_1_BYTE_PACKING_MULT, tps.Value / TPS_1_BYTE_PACKING_MULT) * LOAD_1_BYTE_PACKING_MULT; return m_closedLoopTargetMap->getValue(rpm / RPM_1_BYTE_PACKING_MULT, tps.Value / TPS_1_BYTE_PACKING_MULT);
} }
expected<percent_t> BoostController::getOpenLoop(float target) const { expected<percent_t> BoostController::getOpenLoop(float target) const {
@ -100,7 +100,7 @@ expected<percent_t> BoostController::getOpenLoop(float target) const {
return unexpected; return unexpected;
} }
percent_t openLoop = m_openLoopMap->getValue(rpm / RPM_1_BYTE_PACKING_MULT, tps.Value / TPS_1_BYTE_PACKING_MULT) * LOAD_1_BYTE_PACKING_MULT; percent_t openLoop = m_openLoopMap->getValue(rpm / RPM_1_BYTE_PACKING_MULT, tps.Value / TPS_1_BYTE_PACKING_MULT);
#if EFI_TUNER_STUDIO #if EFI_TUNER_STUDIO
if (engineConfiguration->debugMode == DBG_BOOST) { if (engineConfiguration->debugMode == DBG_BOOST) {

View File

@ -91,7 +91,7 @@
#endif /* ETB_MAX_COUNT */ #endif /* ETB_MAX_COUNT */
static LoggingWithStorage logger("ETB"); static LoggingWithStorage logger("ETB");
static pedal2tps_t pedal2tpsMap("Pedal2Tps", 1); static pedal2tps_t pedal2tpsMap("Pedal2Tps");
EXTERN_ENGINE; EXTERN_ENGINE;

View File

@ -28,7 +28,7 @@ EXTERN_ENGINE;
fuel_Map3D_t veMap("VE"); fuel_Map3D_t veMap("VE");
fuel_Map3D_t ve2Map("VE2"); fuel_Map3D_t ve2Map("VE2");
afr_Map3D_t afrMap("AFR", 1.0f / PACK_MULT_AFR_CFG); afr_Map3D_t afrMap("AFR");
baroCorr_Map3D_t baroCorrMap("baro"); baroCorr_Map3D_t baroCorrMap("baro");
#define tpMin 0 #define tpMin 0

View File

@ -11,6 +11,7 @@
#include "error_handling.h" #include "error_handling.h"
#include "interpolation.h" #include "interpolation.h"
#include "efilib.h" #include "efilib.h"
#include "efi_ratio.h"
// popular left edge of CLT-based correction curves // popular left edge of CLT-based correction curves
#define CLT_CURVE_RANGE_FROM -40 #define CLT_CURVE_RANGE_FROM -40
@ -24,22 +25,20 @@ public:
/** /**
* this helper class brings together 3D table with two 2D axis curves * this helper class brings together 3D table with two 2D axis curves
*/ */
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType> template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType, typename TValueMultiplier = efi::ratio<1>>
class Map3D : public ValueProvider3D { class Map3D : public ValueProvider3D {
public: public:
explicit Map3D(const char*name); explicit Map3D(const char*name);
Map3D(const char*name, float multiplier);
void init(vType table[RPM_BIN_SIZE][LOAD_BIN_SIZE], const kType loadBins[LOAD_BIN_SIZE], const kType rpmBins[RPM_BIN_SIZE]); void init(vType table[RPM_BIN_SIZE][LOAD_BIN_SIZE], const kType loadBins[LOAD_BIN_SIZE], const kType rpmBins[RPM_BIN_SIZE]);
float getValue(float xRpm, float y) const override; float getValue(float xRpm, float y) const override;
void setAll(vType value); void setAll(vType value);
vType *pointers[LOAD_BIN_SIZE]; vType *pointers[LOAD_BIN_SIZE];
private: private:
void create(const char*name, float multiplier); void create(const char*name);
const kType *loadBins = NULL; const kType *loadBins = NULL;
const kType *rpmBins = NULL; const kType *rpmBins = NULL;
bool initialized = false; bool initialized = false;
const char *name; const char *name;
float multiplier;
}; };
/* /*
@ -80,8 +79,8 @@ void Table2D<SIZE>::preCalc(float *bin, float *values) {
} }
*/ */
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType> template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType, typename TValueMultiplier>
void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType>::init(vType table[RPM_BIN_SIZE][LOAD_BIN_SIZE], void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType, TValueMultiplier>::init(vType table[RPM_BIN_SIZE][LOAD_BIN_SIZE],
const kType loadBins[LOAD_BIN_SIZE], const kType loadBins[LOAD_BIN_SIZE],
const kType rpmBins[RPM_BIN_SIZE]) { const kType rpmBins[RPM_BIN_SIZE]) {
// this method cannot use logger because it's invoked before everything // this method cannot use logger because it's invoked before everything
@ -96,45 +95,39 @@ void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType>::init(vType table[RPM_BIN_
this->rpmBins = rpmBins; this->rpmBins = rpmBins;
} }
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType> template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType, typename TValueMultiplier>
float Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType>::getValue(float xRpm, float y) const { float Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType, TValueMultiplier>::getValue(float xRpm, float y) const {
efiAssert(CUSTOM_ERR_ASSERT, initialized, "map not initialized", NAN); efiAssert(CUSTOM_ERR_ASSERT, initialized, "map not initialized", NAN);
if (cisnan(y)) { if (cisnan(y)) {
warning(CUSTOM_PARAM_RANGE, "%s: y is NaN", name); warning(CUSTOM_PARAM_RANGE, "%s: y is NaN", name);
return NAN; return NAN;
} }
// todo: we have a bit of a mess: in TunerStudio, RPM is X-axis // todo: we have a bit of a mess: in TunerStudio, RPM is X-axis
return multiplier * interpolate3d<vType, kType>(y, loadBins, LOAD_BIN_SIZE, xRpm, rpmBins, RPM_BIN_SIZE, pointers); return interpolate3d<vType, kType>(y, loadBins, LOAD_BIN_SIZE, xRpm, rpmBins, RPM_BIN_SIZE, pointers) * TValueMultiplier::asFloat();
} }
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType> template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType, typename TValueMultiplier>
Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType>::Map3D(const char *name) { Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType, TValueMultiplier>::Map3D(const char *name) {
create(name, 1); create(name);
} }
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType> template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType, typename TValueMultiplier>
Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType>::Map3D(const char *name, float multiplier) { void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType, TValueMultiplier>::create(const char *name) {
create(name, multiplier);
}
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType>
void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType>::create(const char *name, float multiplier) {
this->name = name; this->name = name;
this->multiplier = multiplier;
memset(&pointers, 0, sizeof(pointers)); memset(&pointers, 0, sizeof(pointers));
} }
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType> template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType, typename TValueMultiplier>
void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType>::setAll(vType value) { void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE, vType, kType, TValueMultiplier>::setAll(vType value) {
efiAssertVoid(CUSTOM_ERR_6573, initialized, "map not initialized"); efiAssertVoid(CUSTOM_ERR_6573, initialized, "map not initialized");
for (int l = 0; l < LOAD_BIN_SIZE; l++) { for (int l = 0; l < LOAD_BIN_SIZE; l++) {
for (int r = 0; r < RPM_BIN_SIZE; r++) { for (int r = 0; r < RPM_BIN_SIZE; r++) {
pointers[l][r] = value / multiplier; pointers[l][r] = value / TValueMultiplier::asFloat();
} }
} }
} }
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType> template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE, typename vType, typename kType, typename TValueMultiplier = efi::ratio<1>>
void copy2DTable(const vType source[LOAD_BIN_SIZE][RPM_BIN_SIZE], vType destination[LOAD_BIN_SIZE][RPM_BIN_SIZE]) { void copy2DTable(const vType source[LOAD_BIN_SIZE][RPM_BIN_SIZE], vType destination[LOAD_BIN_SIZE][RPM_BIN_SIZE]) {
for (int k = 0; k < LOAD_BIN_SIZE; k++) { for (int k = 0; k < LOAD_BIN_SIZE; k++) {
for (int rpmIndex = 0; rpmIndex < RPM_BIN_SIZE; rpmIndex++) { for (int rpmIndex = 0; rpmIndex < RPM_BIN_SIZE; rpmIndex++) {
@ -143,12 +136,12 @@ void copy2DTable(const vType source[LOAD_BIN_SIZE][RPM_BIN_SIZE], vType destinat
} }
} }
typedef Map3D<FUEL_RPM_COUNT, FUEL_LOAD_COUNT, uint8_t, float> afr_Map3D_t; typedef Map3D<FUEL_RPM_COUNT, FUEL_LOAD_COUNT, uint8_t, float, efi::ratio<1, PACK_MULT_AFR_CFG>> afr_Map3D_t;
typedef Map3D<IGN_RPM_COUNT, IGN_LOAD_COUNT, float, float> ign_Map3D_t; typedef Map3D<IGN_RPM_COUNT, IGN_LOAD_COUNT, float, float> ign_Map3D_t;
typedef Map3D<FUEL_RPM_COUNT, FUEL_LOAD_COUNT, float, float> fuel_Map3D_t; typedef Map3D<FUEL_RPM_COUNT, FUEL_LOAD_COUNT, float, float> fuel_Map3D_t;
typedef Map3D<BARO_CORR_SIZE, BARO_CORR_SIZE, float, float> baroCorr_Map3D_t; typedef Map3D<BARO_CORR_SIZE, BARO_CORR_SIZE, float, float> baroCorr_Map3D_t;
typedef Map3D<PEDAL_TO_TPS_SIZE, PEDAL_TO_TPS_SIZE, uint8_t, uint8_t> pedal2tps_t; typedef Map3D<PEDAL_TO_TPS_SIZE, PEDAL_TO_TPS_SIZE, uint8_t, uint8_t> pedal2tps_t;
typedef Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t> boostOpenLoop_Map3D_t; typedef Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t, efi::ratio<LOAD_1_BYTE_PACKING_MULT>> boostOpenLoop_Map3D_t;
typedef Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t> boostClosedLoop_Map3D_t; typedef Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t> boostClosedLoop_Map3D_t;
typedef Map3D<IAC_PID_MULT_SIZE, IAC_PID_MULT_SIZE, uint8_t, uint8_t> iacPidMultiplier_t; typedef Map3D<IAC_PID_MULT_SIZE, IAC_PID_MULT_SIZE, uint8_t, uint8_t> iacPidMultiplier_t;
typedef Map3D<GPPWM_RPM_COUNT, GPPWM_LOAD_COUNT, uint8_t, uint8_t> gppwm_Map3D_t; typedef Map3D<GPPWM_RPM_COUNT, GPPWM_LOAD_COUNT, uint8_t, uint8_t> gppwm_Map3D_t;

View File

@ -0,0 +1,17 @@
#pragma once
namespace efi {
template <int TNum, int TDenom = 1>
class ratio {
private:
static constexpr int num = TNum;
static constexpr int den = TDenom;
public:
static float asFloat() {
return (float)num / den;
}
};
} // namespace efi

View File

@ -12,7 +12,7 @@ TEST(BoostControl, Setpoint) {
// Just pass TPS input to output // Just pass TPS input to output
EXPECT_CALL(targetMap, getValue(_, _)) EXPECT_CALL(targetMap, getValue(_, _))
.WillRepeatedly([](float xRpm, float tps) { return tps; }); .WillRepeatedly([](float xRpm, float tps) { return tps * 2; });
WITH_ENGINE_TEST_HELPER(TEST_ENGINE); WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
@ -54,7 +54,7 @@ TEST(BoostControl, OpenLoop) {
// Just pass MAP input to output // Just pass MAP input to output
EXPECT_CALL(openMap, getValue(_, _)) EXPECT_CALL(openMap, getValue(_, _))
.WillRepeatedly([](float xRpm, float tps) { return tps; }); .WillRepeatedly([](float xRpm, float tps) { return tps * 2; });
WITH_ENGINE_TEST_HELPER(TEST_ENGINE); WITH_ENGINE_TEST_HELPER(TEST_ENGINE);