diff --git a/firmware/CHANGELOG.md b/firmware/CHANGELOG.md index 61fa70c66a..435a0e267e 100644 --- a/firmware/CHANGELOG.md +++ b/firmware/CHANGELOG.md @@ -31,6 +31,7 @@ Release template (copy/paste this for new release): ### Added - Detected gear and wastegate position to CAN format - Y axis override for Idle VE table. Helps with idle quality on ITB setups. #94 + - Blend tables for boost open and closed loop control #73 ### Fixed - Sensor checker wasn't checking sensors diff --git a/firmware/console/binary/output_channels.txt b/firmware/console/binary/output_channels.txt index d4e8878080..f734f1f618 100644 --- a/firmware/console/binary/output_channels.txt +++ b/firmware/console/binary/output_channels.txt @@ -325,14 +325,22 @@ uint16_t rpmAcceleration;dRPM;"RPM/s",1, 0, 0, 5, 2 int16_t autoscale rawBattery;;"V",{1/@@PACK_MULT_VOLTAGE@@}, 0, 0, 5, 3 - int16_t[IGN_BLEND_COUNT iterate] autoscale ignBlendParameter;;"", 0.1, 0, -3000, 3000, 1 + int16_t[IGN_BLEND_COUNT iterate] autoscale ignBlendParameter;;"", 0.1, 0, -1000, 1000, 1 uint8_t[IGN_BLEND_COUNT iterate] autoscale ignBlendBias;;"%", 0.5, 0, 0, 100, 1 int16_t[IGN_BLEND_COUNT iterate] autoscale ignBlendOutput;;"deg", 0.01, 0, -300, 300, 2 - int16_t[VE_BLEND_COUNT iterate] autoscale veBlendParameter;;"", 0.1, 0, -3000, 3000, 1 + int16_t[VE_BLEND_COUNT iterate] autoscale veBlendParameter;;"", 0.1, 0, -1000, 1000, 1 uint8_t[VE_BLEND_COUNT iterate] autoscale veBlendBias;;"%", 0.5, 0, 0, 100, 1 int16_t[VE_BLEND_COUNT iterate] autoscale veBlendOutput;;"%", 0.01, 0, -50, 50, 2 + int16_t[BOOST_BLEND_COUNT iterate] autoscale boostOpenLoopBlendParameter;;"", 0.1, 0, -1000, 1000, 1 + uint8_t[BOOST_BLEND_COUNT iterate] autoscale boostOpenLoopBlendBias;;"%", 0.5, 0, 0, 100, 1 + int8_t[BOOST_BLEND_COUNT iterate] autoscale boostOpenLoopBlendOutput;;"%", 1, 0, -100, 100, 0 + + int16_t[BOOST_BLEND_COUNT iterate] autoscale boostClosedLoopBlendParameter;;"", 0.1, 0, -1000, 1000, 1 + uint8_t[BOOST_BLEND_COUNT iterate] autoscale boostClosedLoopBlendBias;;"%", 0.5, 0, 0, 100, 1 + int16_t[BOOST_BLEND_COUNT iterate] autoscale boostClosedLoopBlendOutput;;"%", 0.1, 0, -1000, 1000, 1 + bit coilState1 bit coilState2 bit coilState3 diff --git a/firmware/controllers/actuators/boost_control.cpp b/firmware/controllers/actuators/boost_control.cpp index 0694b7582b..436c64300c 100644 --- a/firmware/controllers/actuators/boost_control.cpp +++ b/firmware/controllers/actuators/boost_control.cpp @@ -67,7 +67,20 @@ expected BoostController::getSetpoint() { efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_closedLoopTargetMap != nullptr, "boost closed loop target", unexpected); - return m_closedLoopTargetMap->getValue(rpm, driverIntent.Value) * luaTargetMult + luaTargetAdd; + float target = m_closedLoopTargetMap->getValue(rpm, driverIntent.Value); + + // Add any blends if configured + for (size_t i = 0; i < efi::size(config->boostClosedLoopBlends); i++) { + auto result = calculateBlend(config->boostClosedLoopBlends[i], rpm, driverIntent.Value); + + engine->outputChannels.boostClosedLoopBlendParameter[i] = result.BlendParameter; + engine->outputChannels.boostClosedLoopBlendBias[i] = result.Bias; + engine->outputChannels.boostClosedLoopBlendOutput[i] = result.Value; + + target += result.Value; + } + + return target * luaTargetMult + luaTargetAdd; } expected BoostController::getOpenLoop(float target) { @@ -85,9 +98,21 @@ expected BoostController::getOpenLoop(float target) { efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_openLoopMap != nullptr, "boost open loop", unexpected); - openLoopPart = luaOpenLoopAdd + m_openLoopMap->getValue(rpm, driverIntent.Value); + float openLoop = luaOpenLoopAdd + m_openLoopMap->getValue(rpm, driverIntent.Value); - return openLoopPart; + // Add any blends if configured + for (size_t i = 0; i < efi::size(config->boostOpenLoopBlends); i++) { + auto result = calculateBlend(config->boostOpenLoopBlends[i], rpm, driverIntent.Value); + + engine->outputChannels.boostOpenLoopBlendParameter[i] = result.BlendParameter; + engine->outputChannels.boostOpenLoopBlendBias[i] = result.Bias; + engine->outputChannels.boostOpenLoopBlendOutput[i] = result.Value; + + openLoop += result.Value; + } + + openLoopPart = openLoop; + return openLoop; } percent_t BoostController::getClosedLoopImpl(float target, float manifoldPressure) { diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index b5a4682330..0f36e21e2d 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -1700,6 +1700,9 @@ blend_table_s[VE_BLEND_COUNT iterate] veBlends uint16_t[12] autoscale throttleEstimateEffectiveAreaBins;;"%", 0.1, 0, 0, 100, 1 uint16_t[12] autoscale throttleEstimateEffectiveAreaValues;In units of g/s normalized to choked flow conditions;"g/s", 0.1, 0, 0, 6500, 1 +blend_table_s[BOOST_BLEND_COUNT iterate] boostOpenLoopBlends +blend_table_s[BOOST_BLEND_COUNT iterate] boostClosedLoopBlends + end_struct ! Pedal Position Sensor diff --git a/firmware/integration/rusefi_config_shared.txt b/firmware/integration/rusefi_config_shared.txt index 09e5bf1b14..5aa73de4b8 100644 --- a/firmware/integration/rusefi_config_shared.txt +++ b/firmware/integration/rusefi_config_shared.txt @@ -30,6 +30,7 @@ #define LUA_ANALOG_INPUT_COUNT 8 #define IGN_BLEND_COUNT 4 #define VE_BLEND_COUNT 4 +#define BOOST_BLEND_COUNT 2 #define LUA_GAUGE_COUNT 2 diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 17847e1d29..99795cbe6e 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -761,6 +761,34 @@ curve = 32Curve, "3-2 Shift Solenoid Percent by Speed" xBins = veBlends4_blendBins, veBlendParameter4 yBins = veBlends4_blendValues + curve = boostOpenLoopBlend1Bias, "Boost open loop blend 1 bias" + columnLabel = "param", "bias" + xAxis = 0, 100, 11 + yAxis = 0, 100, 5 + xBins = boostOpenLoopBlends1_blendBins, boostOpenLoopBlendParameter1 + yBins = boostOpenLoopBlends1_blendValues + + curve = boostOpenLoopBlend2Bias, "Boost open loop blend 2 bias" + columnLabel = "param", "bias" + xAxis = 0, 100, 11 + yAxis = 0, 100, 5 + xBins = boostOpenLoopBlends2_blendBins, boostOpenLoopBlendParameter2 + yBins = boostOpenLoopBlends2_blendValues + + curve = boostClosedLoopBlend1Bias, "Boost Closed loop blend 1 bias" + columnLabel = "param", "bias" + xAxis = 0, 100, 11 + yAxis = 0, 100, 5 + xBins = boostClosedLoopBlends1_blendBins, boostClosedLoopBlendParameter1 + yBins = boostClosedLoopBlends1_blendValues + + curve = boostClosedLoopBlend2Bias, "Boost Closed loop blend 2 bias" + columnLabel = "param", "bias" + xAxis = 0, 100, 11 + yAxis = 0, 100, 5 + xBins = boostClosedLoopBlends2_blendBins, boostClosedLoopBlendParameter2 + yBins = boostClosedLoopBlends2_blendValues + curve = throttleEffectiveArea, "Throttle effective area" columnLabel = "TPS", "normalized flow" xAxis = 0, 100, 11 @@ -904,6 +932,30 @@ curve = 32Curve, "3-2 Shift Solenoid Percent by Speed" zBins = veBlends4_table gridOrient = 250, 0, 340 + table = boostOpenBlend1Table, boostOpenBlend1Map, "Boost open loop blend 1", 1 + xBins = boostOpenLoopBlends1_rpmBins, RPMValue + yBins = boostOpenLoopBlends1_loadBins, TPSValue + zBins = boostOpenLoopBlends1_table + gridOrient = 250, 0, 340 + + table = boostOpenBlend2Table, boostOpenBlend2Map, "Boost open loop blend 2", 1 + xBins = boostOpenLoopBlends2_rpmBins, RPMValue + yBins = boostOpenLoopBlends2_loadBins, TPSValue + zBins = boostOpenLoopBlends2_table + gridOrient = 250, 0, 340 + + table = boostClosedBlend1Table, boostClosedBlend1Map, "Boost closed loop blend 1", 1 + xBins = boostClosedLoopBlends1_rpmBins, RPMValue + yBins = boostClosedLoopBlends1_loadBins, TPSValue + zBins = boostClosedLoopBlends1_table + gridOrient = 250, 0, 340 + + table = boostClosedBlend2Table, boostClosedBlend2Map, "Boost closed loop blend 2", 1 + xBins = boostClosedLoopBlends2_rpmBins, RPMValue + yBins = boostClosedLoopBlends2_loadBins, TPSValue + zBins = boostClosedLoopBlends2_table + gridOrient = 250, 0, 340 + table = ignitionIatCorrTableTbl, ignitionIatCorrTableMap, "Ignition Intake Air Temp correction", 1 ; constant, variable xBins = ignitionIatCorrTempBins, intake @@ -1717,6 +1769,17 @@ menuDialog = main subMenu = boostOpenLoopDialog, "Boost control open loop", { isBoostControlEnabled } subMenu = boostPidDialog, "Boost control PID", { isBoostControlEnabled && boostType == 1 } subMenu = boostTargetDialog, "Boost control target", { isBoostControlEnabled && boostType == 1 } + + groupMenu = "Boost blend tables" + groupChildMenu = boostOpenBlend1Cfg, "Open loop 1 bias", { isBoostControlEnabled } + groupChildMenu = boostOpenBlend1Table, "Open loop 1 adder", { isBoostControlEnabled && boostOpenLoopBlends1_blendParameter != 0 } + groupChildMenu = boostOpenBlend2Cfg, "Open loop 2 bias", { isBoostControlEnabled } + groupChildMenu = boostOpenBlend2Table, "Open loop 2 adder", { isBoostControlEnabled && boostOpenLoopBlends2_blendParameter != 0 } + groupChildMenu = boostClosedBlend1Cfg, "Closed loop 1 bias", { isBoostControlEnabled && boostType == 1 } + groupChildMenu = boostClosedBlend2Table, "Closed loop 1 adder", { isBoostControlEnabled && boostType == 1 && boostClosedLoopBlends1_blendParameter != 0 } + groupChildMenu = boostClosedBlend2Cfg, "Closed loop 2 bias", { isBoostControlEnabled && boostType == 1 } + groupChildMenu = boostClosedBlend2Table, "Closed loop 2 adder", { isBoostControlEnabled && boostType == 1 && boostClosedLoopBlends2_blendParameter != 0 } + subMenu = boostEtbPid, "ETB-style Wastegate Actuator", { etbFunctions1 == @@dc_function_e_DC_Wastegate@@ || etbFunctions2 == @@dc_function_e_DC_Wastegate@@ } subMenu = std_separator @@ -2467,6 +2530,46 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@@@ts_command_e_TS_ field = "Blend parameter", veBlends4_blendParameter panel = veBlend4Bias + dialog = boostOpenBlend1Cfg, "Boost open loop blend 1 config" + field = "#The bias table controls how much of the blend table" + field = "#is mixed in to the open loop boost table. For example, a value of" + field = "#+10 in the table, with 50 as the current bias will result" + field = "#in +5.0 added to the boost open loop %." + field = "#The X axis of the bias table is controlled by the selected blend" + field = "#parameter below." + field = "Blend parameter", boostOpenLoopBlends1_blendParameter + panel = boostOpenLoopBlend1Bias + + dialog = boostOpenBlend2Cfg, "Boost open loop blend 2 config" + field = "#The bias table controls how much of the blend table" + field = "#is mixed in to the open loop boost table. For example, a value of" + field = "#+10 in the table, with 50 as the current bias will result" + field = "#in +5.0 added to the boost open loop %." + field = "#The X axis of the bias table is controlled by the selected blend" + field = "#parameter below." + field = "Blend parameter", boostOpenLoopBlends2_blendParameter + panel = boostOpenLoopBlend2Bias + + dialog = boostClosedBlend1Cfg, "Boost closed loop blend 1 config" + field = "#The bias table controls how much of the blend table" + field = "#is mixed in to the closed loop boost table. For example, a value of" + field = "#+10 in the table, with 50 as the current bias will result" + field = "#in +5.0 added to the boost closed loop %." + field = "#The X axis of the bias table is controlled by the selected blend" + field = "#parameter below." + field = "Blend parameter", boostClosedLoopBlends1_blendParameter + panel = boostClosedLoopBlend1Bias + + dialog = boostClosedBlend2Cfg, "Boost closed loop blend 2 config" + field = "#The bias table controls how much of the blend table" + field = "#is mixed in to the closed loop boost table. For example, a value of" + field = "#+10 in the table, with 50 as the current bias will result" + field = "#in +5.0 added to the boost closed loop %." + field = "#The X axis of the bias table is controlled by the selected blend" + field = "#parameter below." + field = "Blend parameter", boostClosedLoopBlends2_blendParameter + panel = boostClosedLoopBlend2Bias + dialog = dwellSettings, "", yAxis panel = dwellCorrection panel = dwellVoltageCorrection