diff --git a/firmware/controllers/actuators/idle_thread.cpp b/firmware/controllers/actuators/idle_thread.cpp index eae659d8e9..4728d82b50 100644 --- a/firmware/controllers/actuators/idle_thread.cpp +++ b/firmware/controllers/actuators/idle_thread.cpp @@ -58,8 +58,6 @@ Pid * getIdlePid() { return &industrialWithOverrideIdlePid; } -static iacPidMultiplier_t iacPidMultMap; - #if ! EFI_UNIT_TEST void idleDebug(const char *msg, percent_t value) { @@ -367,7 +365,11 @@ float IdleController::getClosedLoop(IIdleController::Phase phase, float tpsPos, // Apply PID Multiplier if used if (engineConfiguration->useIacPidMultTable) { float engineLoad = getFuelingLoad(); - float multCoef = iacPidMultMap.getValue(rpm / RPM_1_BYTE_PACKING_MULT, engineLoad); + float multCoef = interpolate3d( + engineConfiguration->iacPidMultTable, + engineConfiguration->iacPidMultLoadBins, engineLoad, + engineConfiguration->iacPidMultRpmBins, rpm + ); // PID can be completely disabled of multCoef==0, or it just works as usual if multCoef==1 newValue = interpolateClamped(0, 0, 1, newValue, multCoef); } @@ -477,7 +479,6 @@ void IdleController::onSlowCallback() { static void applyPidSettings() { getIdlePid()->updateFactors(engineConfiguration->idleRpmPid.pFactor, engineConfiguration->idleRpmPid.iFactor, engineConfiguration->idleRpmPid.dFactor); - iacPidMultMap.init(engineConfiguration->iacPidMultTable, engineConfiguration->iacPidMultLoadBins, engineConfiguration->iacPidMultRpmBins); } void setDefaultIdleParameters() { diff --git a/firmware/controllers/algo/advance_map.cpp b/firmware/controllers/algo/advance_map.cpp index c27dddc9bd..877c98611f 100644 --- a/firmware/controllers/algo/advance_map.cpp +++ b/firmware/controllers/algo/advance_map.cpp @@ -26,9 +26,6 @@ #if EFI_ENGINE_CONTROL -static ign_Map3D_t advanceMap; -static ign_Map3D_t iatAdvanceCorrectionMap; - // todo: reset this between cranking attempts?! #2735 int minCrankingRpm = 0; @@ -47,7 +44,11 @@ static angle_t getRunningAdvance(int rpm, float engineLoad) { efiAssert(CUSTOM_ERR_ASSERT, !cisnan(engineLoad), "invalid el", NAN); - float advanceAngle = advanceMap.getValue((float) rpm, engineLoad); + float advanceAngle = interpolate3d( + config->ignitionTable, + config->ignitionLoadBins, engineLoad, + config->ignitionRpmBins, rpm + ); // get advance from the separate table for Idle if (engineConfiguration->useSeparateAdvanceForIdle && @@ -86,7 +87,11 @@ angle_t getAdvanceCorrections(int rpm) { if (!iatValid) { iatCorrection = 0; } else { - iatCorrection = iatAdvanceCorrectionMap.getValue(rpm, iat); + iatCorrection = interpolate3d( + config->ignitionIatCorrTable, + config->ignitionIatCorrLoadBins, iat, + config->ignitionIatCorrRpmBins, rpm + ); } float pidTimingCorrection = engine->module().unmock().getIdleTimingAdjustment(rpm); @@ -201,14 +206,6 @@ size_t getMultiSparkCount(int rpm) { } } -void initTimingMap() { - // We init both tables in RAM because here we're at a very early stage, with no config settings loaded. - advanceMap.init(config->ignitionTable, config->ignitionLoadBins, - config->ignitionRpmBins); - iatAdvanceCorrectionMap.init(config->ignitionIatCorrTable, config->ignitionIatCorrLoadBins, - config->ignitionIatCorrRpmBins); -} - /** * @param octane gas octane number * @param bore in mm diff --git a/firmware/controllers/algo/advance_map.h b/firmware/controllers/algo/advance_map.h index 21f565a74b..b25883d37a 100644 --- a/firmware/controllers/algo/advance_map.h +++ b/firmware/controllers/algo/advance_map.h @@ -8,7 +8,6 @@ #pragma once angle_t getAdvance(int rpm, float engineLoad); -void initTimingMap(); float getTopAdvanceForBore(chamber_style_e style, int octane, double compression, double bore); float getInitialAdvance(int rpm, float map, float advanceMax); void buildTimingMap(float advanceMax); diff --git a/firmware/controllers/algo/fuel_math.cpp b/firmware/controllers/algo/fuel_math.cpp index 41cf836fbe..df172ebeb1 100644 --- a/firmware/controllers/algo/fuel_math.cpp +++ b/firmware/controllers/algo/fuel_math.cpp @@ -34,10 +34,8 @@ #include "speed_density_base.h" #include "lua_hooks.h" -static fuel_Map3D_t fuelPhaseMap; extern fuel_Map3D_t veMap; extern lambda_Map3D_t lambdaMap; -extern baroCorr_Map3D_t baroCorrMap; static mapEstimate_Map3D_t mapEstimationTable; #if EFI_ENGINE_CONTROL @@ -182,7 +180,11 @@ angle_t getInjectionOffset(float rpm, float load) { return 0; // error already reported } - angle_t value = fuelPhaseMap.getValue(rpm, load); + angle_t value = interpolate3d( + config->injectionPhase, + config->injPhaseLoadBins, load, + config->injPhaseRpmBins, rpm + ); if (cisnan(value)) { // we could be here while resetting configuration for example @@ -304,15 +306,9 @@ static FuelComputer fuelComputer(lambdaMap); * is to prepare the fuel map data structure for 3d interpolation */ void initFuelMap() { - - engine->fuelComputer = &fuelComputer; mapEstimationTable.init(config->mapEstimateTable, config->mapEstimateTpsBins, config->mapEstimateRpmBins); - -#if (IGN_LOAD_COUNT == FUEL_LOAD_COUNT) && (IGN_RPM_COUNT == FUEL_RPM_COUNT) - fuelPhaseMap.init(config->injectionPhase, config->injPhaseLoadBins, config->injPhaseRpmBins); -#endif /* (IGN_LOAD_COUNT == FUEL_LOAD_COUNT) && (IGN_RPM_COUNT == FUEL_RPM_COUNT) */ } /** @@ -401,7 +397,12 @@ float getBaroCorrection() { // Default to 1atm if failed float pressure = Sensor::get(SensorType::BarometricPressure).value_or(101.325f); - float correction = baroCorrMap.getValue(GET_RPM(), pressure); + float correction = interpolate3d( + engineConfiguration->baroCorrTable, + engineConfiguration->baroCorrPressureBins, pressure, + engineConfiguration->baroCorrRpmBins, GET_RPM() + ); + if (cisnan(correction) || correction < 0.01) { warning(OBD_Barometric_Press_Circ_Range_Perf, "Invalid baro correction %f", correction); return 1; diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index f3df8c892d..5139306e98 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -109,7 +109,6 @@ Engine * engine; void initDataStructures() { #if EFI_ENGINE_CONTROL initFuelMap(); - initTimingMap(); initSpeedDensity(); #endif // EFI_ENGINE_CONTROL } diff --git a/firmware/controllers/math/speed_density.cpp b/firmware/controllers/math/speed_density.cpp index b67bb2937a..7e7f5cb0ee 100644 --- a/firmware/controllers/math/speed_density.cpp +++ b/firmware/controllers/math/speed_density.cpp @@ -20,7 +20,6 @@ fuel_Map3D_t veMap; lambda_Map3D_t lambdaMap; -baroCorr_Map3D_t baroCorrMap; #define tpMin 0 #define tpMax 100 @@ -94,5 +93,4 @@ void initSpeedDensity() { veMap.init(config->veTable, config->veLoadBins, config->veRpmBins); // ve2Map.init(engineConfiguration->ve2Table, engineConfiguration->ve2LoadBins, engineConfiguration->ve2RpmBins); lambdaMap.init(config->lambdaTable, config->lambdaLoadBins, config->lambdaRpmBins); - baroCorrMap.init(engineConfiguration->baroCorrTable, engineConfiguration->baroCorrPressureBins, engineConfiguration->baroCorrRpmBins); } diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 44a6452d8b..1578dde9ff 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -1415,7 +1415,7 @@ tChargeMode_e tChargeMode; uint8_t[IAC_PID_MULT_SIZE x IAC_PID_MULT_SIZE] iacPidMultTable;;"%", 1, 0, 0, 999, 2 uint8_t[IAC_PID_MULT_SIZE] iacPidMultLoadBins;;"Load", 1, 0, 0, 500, 2 - uint8_t[IAC_PID_MULT_SIZE] iacPidMultRpmBins;;"RPM", @@RPM_1_BYTE_PACKING_MULT@@, 0, 0, 12000, 0 + uint8_t[IAC_PID_MULT_SIZE] autoscale iacPidMultRpmBins;;"RPM", @@RPM_1_BYTE_PACKING_MULT@@, 0, 0, 12000, 0 custom can_vss_nbc_e 4 bits, U32, @OFFSET@, [0:0], "BMW_e46", "W202" can_vss_nbc_e canVssNbcType;set can_vss X diff --git a/firmware/util/containers/table_helper.h b/firmware/util/containers/table_helper.h index 303a7d0a9c..7d1c0c2832 100644 --- a/firmware/util/containers/table_helper.h +++ b/firmware/util/containers/table_helper.h @@ -118,13 +118,10 @@ private: }; typedef Map3D> lambda_Map3D_t; -typedef Map3D ign_Map3D_t; typedef Map3D fuel_Map3D_t; -typedef Map3D baroCorr_Map3D_t; typedef Map3D pedal2tps_t; typedef Map3D> boostOpenLoop_Map3D_t; typedef Map3D boostClosedLoop_Map3D_t; -typedef Map3D iacPidMultiplier_t; typedef Map3D gppwm_Map3D_t; typedef Map3D> mapEstimate_Map3D_t; diff --git a/unit_tests/test_basic_math/test_interpolation_3d.cpp b/unit_tests/test_basic_math/test_interpolation_3d.cpp index 0b0e3a42bd..6cca21c54d 100644 --- a/unit_tests/test_basic_math/test_interpolation_3d.cpp +++ b/unit_tests/test_basic_math/test_interpolation_3d.cpp @@ -12,7 +12,7 @@ #include "interpolation.h" float rpmBins[5] = { 100, 200, 300, 400, 500 }; -scaled_channel rpmBinsScaledByte[5] = { 100, 200, 30, 400, 500}; +scaled_channel rpmBinsScaledByte[5] = { 100, 200, 300, 400, 500}; float mafBins[4] = { 1, 2, 3, 4 }; scaled_channel mafBinsScaledInt[4] = { 1, 2, 3, 4 }; @@ -52,6 +52,14 @@ are we missing something in Map3D? float result4 = x4.getValue(rpm, maf); EXPECT_NEAR_M4(result1, result4); */ + + float result4 = interpolate3d( + map, + mafBinsScaledInt, maf, + rpmBinsScaledByte, rpm + ); + EXPECT_NEAR_M4(result1, result4); + return result1; }