diff --git a/firmware/CHANGELOG.md b/firmware/CHANGELOG.md index 1444dd6c47..07a2cfba29 100644 --- a/firmware/CHANGELOG.md +++ b/firmware/CHANGELOG.md @@ -25,6 +25,9 @@ Release template (copy/paste this for new release): ## Unreleased +### Added + - Flexible ignition adder/trim tables #4586 + ## September 2022 Release - "Day 203" ### Added diff --git a/firmware/console/binary/output_channels.txt b/firmware/console/binary/output_channels.txt index a4f25fb050..1247e06b07 100644 --- a/firmware/console/binary/output_channels.txt +++ b/firmware/console/binary/output_channels.txt @@ -337,6 +337,9 @@ uint16_t rpmAcceleration;dRPM;"RPM/s",1, 0, 0, 5, 0 uint8_t extiOverflowCount;;"", 1, 0, 0, 255, 0 + uint8_t[IGN_BLEND_COUNT iterate] autoscale ignBlendBias;;"%", 0.5, 0, 0, 100, 1 + uint16_t[IGN_BLEND_COUNT iterate] autoscale ignBlendOutput;;"deg", 0.01, 0, -300, 300, 2 + bit coilState1 bit coilState2 bit coilState3 diff --git a/firmware/controllers/actuators/gppwm/gppwm_channel.h b/firmware/controllers/actuators/gppwm/gppwm_channel.h index 2dbf1ee25f..3750e92738 100644 --- a/firmware/controllers/actuators/gppwm/gppwm_channel.h +++ b/firmware/controllers/actuators/gppwm/gppwm_channel.h @@ -27,3 +27,5 @@ private: OutputPin* m_output = nullptr; const ValueProvider3D* m_table = nullptr; }; + +expected readGppwmChannel(gppwm_channel_e channel); diff --git a/firmware/controllers/algo/advance_map.cpp b/firmware/controllers/algo/advance_map.cpp index c13e157a63..e018350611 100644 --- a/firmware/controllers/algo/advance_map.cpp +++ b/firmware/controllers/algo/advance_map.cpp @@ -23,12 +23,39 @@ #include "advance_map.h" #include "idle_thread.h" #include "launch_control.h" +#include "gppwm_channel.h" #if EFI_ENGINE_CONTROL // todo: reset this between cranking attempts?! #2735 int minCrankingRpm = 0; +struct BlendResult { + // Bias in percent (0-100%) + float Bias; + + // Result value (bias * table value) + float Value; +}; + +BlendResult calculateBlend(blend_table_s& cfg, float rpm, float load) { + auto value = readGppwmChannel(cfg.blendParameter); + + if (!value) { + return { 0, 0 }; + } + + float tableValue = interpolate3d( + cfg.table, + cfg.loadBins, load, + cfg.rpmBins, rpm + ); + + float blendFactor = interpolate2d(value.Value, cfg.blendBins, cfg.blendValues); + + return { blendFactor, 0.01f * blendFactor * tableValue }; +} + /** * @return ignition timing angle advance before TDC */ @@ -44,12 +71,23 @@ static angle_t getRunningAdvance(int rpm, float engineLoad) { efiAssert(CUSTOM_ERR_ASSERT, !cisnan(engineLoad), "invalid el", NAN); + // compute base ignition angle from main table float advanceAngle = interpolate3d( config->ignitionTable, config->ignitionLoadBins, engineLoad, config->ignitionRpmBins, rpm ); + // Add any adjustments if configured + for (size_t i = 0; i < efi::size(config->ignBlends); i++) { + auto result = calculateBlend(config->ignBlends[i], rpm, engineLoad); + + engine->outputChannels.ignBlendBias[i] = result.Bias; + engine->outputChannels.ignBlendOutput[i] = result.Value; + + advanceAngle += result.Value; + } + // get advance from the separate table for Idle if (engineConfiguration->useSeparateAdvanceForIdle && engine->module()->isIdlingOrTaper()) { diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 776ec0b56c..10ba7d4e45 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -1727,6 +1727,20 @@ uint8_t[6 x 6] autoscale maxKnockRetardTable;;"deg", 0.25, 0, 0, 30, 2 uint8_t[6] maxKnockRetardLoadBins;;"%", 1, 0, 0, 250, 0 uint8_t[6] autoscale maxKnockRetardRpmBins;;"RPM", 100, 0, 0, 25000, 0 +struct blend_table_s + int16_t[8 x 8] autoscale table;;"", 0.1, 0, -100, 100, 1 + uint16_t[8] loadBins;;"Load", 1, 0, 0, 500, 0 + uint16_t[8] rpmBins;;"RPM", 1, 0, 0, 18000, 0 + + gppwm_channel_e blendParameter + + int16_t[8] autoscale blendBins;;"", 0.1, 0, -1000, 1000, 1 + uint8_t[8] autoscale blendValues;;"%", 0.5, 0, 0, 100, 1 +end_struct + +#define IGN_BLEND_COUNT 4 +blend_table_s[IGN_BLEND_COUNT iterate] ignBlends + end_struct ! Pedal Position Sensor diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 870d9da21f..8315645d2a 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -194,6 +194,11 @@ enable2ndByteCanID = false gppwm3_load = {(gppwm3_loadAxis == 0) ? 0 : (gppwm3_loadAxis == 1) ? TPSValue : (gppwm3_loadAxis == 2) ? MAPValue : (gppwm3_loadAxis == 3) ? coolant : (gppwm3_loadAxis == 4) ? intake : (gppwm3_loadAxis == 5) ? fuelingLoad : (gppwm3_loadAxis == 6) ? ignitionLoad : (gppwm3_loadAxis == 7) ? auxTemp1 : (gppwm3_loadAxis == 8) ? auxTemp2 : (gppwm3_loadAxis == 9) ? throttlePedalPosition : (gppwm3_loadAxis == 10) ? VBatt : (gppwm3_loadAxis == 11) ? vvtPositionB1I : (gppwm3_loadAxis == 12) ? vvtPositionB1E : (gppwm3_loadAxis == 13) ? vvtPositionB2I : (gppwm3_loadAxis == 14) ? vvtPositionB2E : (gppwm3_loadAxis == 15) ? flexPercent : (gppwm3_loadAxis == 16) ? auxLinear1 : (gppwm3_loadAxis == 17) ? auxLinear2 : 0} gppwm4_load = {(gppwm4_loadAxis == 0) ? 0 : (gppwm4_loadAxis == 1) ? TPSValue : (gppwm4_loadAxis == 2) ? MAPValue : (gppwm4_loadAxis == 3) ? coolant : (gppwm4_loadAxis == 4) ? intake : (gppwm4_loadAxis == 5) ? fuelingLoad : (gppwm4_loadAxis == 6) ? ignitionLoad : (gppwm4_loadAxis == 7) ? auxTemp1 : (gppwm4_loadAxis == 8) ? auxTemp2 : (gppwm4_loadAxis == 9) ? throttlePedalPosition : (gppwm4_loadAxis == 10) ? VBatt : (gppwm4_loadAxis == 11) ? vvtPositionB1I : (gppwm4_loadAxis == 12) ? vvtPositionB1E : (gppwm4_loadAxis == 13) ? vvtPositionB2I : (gppwm4_loadAxis == 14) ? vvtPositionB2E : (gppwm4_loadAxis == 15) ? flexPercent : (gppwm4_loadAxis == 16) ? auxLinear1 : (gppwm4_loadAxis == 17) ? auxLinear2 : 0} + ignBlends1_blendVal = {(ignBlends1_blendParameter == 0) ? 0 : (ignBlends1_blendParameter == 1) ? TPSValue : (ignBlends1_blendParameter == 2) ? MAPValue : (ignBlends1_blendParameter == 3) ? coolant : (ignBlends1_blendParameter == 4) ? intake : (ignBlends1_blendParameter == 5) ? fuelingLoad : (ignBlends1_blendParameter == 6) ? ignitionLoad : (ignBlends1_blendParameter == 7) ? auxTemp1 : (ignBlends1_blendParameter == 8) ? auxTemp2 : (ignBlends1_blendParameter == 9) ? throttlePedalPosition : (ignBlends1_blendParameter == 10) ? VBatt : (ignBlends1_blendParameter == 11) ? vvtPositionB1I : (ignBlends1_blendParameter == 12) ? vvtPositionB1E : (ignBlends1_blendParameter == 13) ? vvtPositionB2I : (ignBlends1_blendParameter == 14) ? vvtPositionB2E : (ignBlends1_blendParameter == 15) ? flexPercent : (ignBlends1_blendParameter == 16) ? auxLinear1 : (ignBlends1_blendParameter == 17) ? auxLinear2 : 0} + ignBlends2_blendVal = {(ignBlends2_blendParameter == 0) ? 0 : (ignBlends2_blendParameter == 1) ? TPSValue : (ignBlends2_blendParameter == 2) ? MAPValue : (ignBlends2_blendParameter == 3) ? coolant : (ignBlends2_blendParameter == 4) ? intake : (ignBlends2_blendParameter == 5) ? fuelingLoad : (ignBlends2_blendParameter == 6) ? ignitionLoad : (ignBlends2_blendParameter == 7) ? auxTemp1 : (ignBlends2_blendParameter == 8) ? auxTemp2 : (ignBlends2_blendParameter == 9) ? throttlePedalPosition : (ignBlends2_blendParameter == 10) ? VBatt : (ignBlends2_blendParameter == 11) ? vvtPositionB1I : (ignBlends2_blendParameter == 12) ? vvtPositionB1E : (ignBlends2_blendParameter == 13) ? vvtPositionB2I : (ignBlends2_blendParameter == 14) ? vvtPositionB2E : (ignBlends2_blendParameter == 15) ? flexPercent : (ignBlends2_blendParameter == 16) ? auxLinear1 : (ignBlends2_blendParameter == 17) ? auxLinear2 : 0} + ignBlends3_blendVal = {(ignBlends3_blendParameter == 0) ? 0 : (ignBlends3_blendParameter == 1) ? TPSValue : (ignBlends3_blendParameter == 2) ? MAPValue : (ignBlends3_blendParameter == 3) ? coolant : (ignBlends3_blendParameter == 4) ? intake : (ignBlends3_blendParameter == 5) ? fuelingLoad : (ignBlends3_blendParameter == 6) ? ignitionLoad : (ignBlends3_blendParameter == 7) ? auxTemp1 : (ignBlends3_blendParameter == 8) ? auxTemp2 : (ignBlends3_blendParameter == 9) ? throttlePedalPosition : (ignBlends3_blendParameter == 10) ? VBatt : (ignBlends3_blendParameter == 11) ? vvtPositionB1I : (ignBlends3_blendParameter == 12) ? vvtPositionB1E : (ignBlends3_blendParameter == 13) ? vvtPositionB2I : (ignBlends3_blendParameter == 14) ? vvtPositionB2E : (ignBlends3_blendParameter == 15) ? flexPercent : (ignBlends3_blendParameter == 16) ? auxLinear1 : (ignBlends3_blendParameter == 17) ? auxLinear2 : 0} + ignBlends4_blendVal = {(ignBlends4_blendParameter == 0) ? 0 : (ignBlends4_blendParameter == 1) ? TPSValue : (ignBlends4_blendParameter == 2) ? MAPValue : (ignBlends4_blendParameter == 3) ? coolant : (ignBlends4_blendParameter == 4) ? intake : (ignBlends4_blendParameter == 5) ? fuelingLoad : (ignBlends4_blendParameter == 6) ? ignitionLoad : (ignBlends4_blendParameter == 7) ? auxTemp1 : (ignBlends4_blendParameter == 8) ? auxTemp2 : (ignBlends4_blendParameter == 9) ? throttlePedalPosition : (ignBlends4_blendParameter == 10) ? VBatt : (ignBlends4_blendParameter == 11) ? vvtPositionB1I : (ignBlends4_blendParameter == 12) ? vvtPositionB1E : (ignBlends4_blendParameter == 13) ? vvtPositionB2I : (ignBlends4_blendParameter == 14) ? vvtPositionB2E : (ignBlends4_blendParameter == 15) ? flexPercent : (ignBlends4_blendParameter == 16) ? auxLinear1 : (ignBlends4_blendParameter == 17) ? auxLinear2 : 0} + [PcVariables] tuneCrcPcVariable = continuousChannelValue, tuneCrc16 @@ -697,6 +702,34 @@ curve = 32Curve, "3-2 Shift Solenoid Percent by Speed" xBins = tcu_32SpeedBins, vehicleSpeedKph yBins = tcu_32Vals + curve = ignAdder1Bias, "Ignition adder 1 bias" + columnLabel = "param", "bias" + xAxis = 0, 100, 11 + yAxis = 0, 100, 5 + xBins = ignBlends1_blendBins, ignBlends1_blendVal + yBins = ignBlends1_blendValues + + curve = ignAdder2Bias, "Ignition adder 2 bias" + columnLabel = "param", "bias" + xAxis = 0, 100, 11 + yAxis = 0, 100, 5 + xBins = ignBlends2_blendBins, ignBlends2_blendVal + yBins = ignBlends2_blendValues + + curve = ignAdder3Bias, "Ignition adder 3 bias" + columnLabel = "param", "bias" + xAxis = 0, 100, 11 + yAxis = 0, 100, 5 + xBins = ignBlends3_blendBins, ignBlends3_blendVal + yBins = ignBlends3_blendValues + + curve = ignAdder4Bias, "Ignition adder 4 bias" + columnLabel = "param", "bias" + xAxis = 0, 100, 11 + yAxis = 0, 100, 5 + xBins = ignBlends4_blendBins, ignBlends4_blendVal + yBins = ignBlends4_blendValues + [TableEditor] ; table_id, map3d_id, "title", page @@ -766,6 +799,30 @@ curve = 32Curve, "3-2 Shift Solenoid Percent by Speed" gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees. upDownLabel = "(RICHER)", "(LEANER)" + table = ignAdder1Table, ignAdder1Map, "Ignition adder 1", 1 + xBins = ignBlends1_rpmBins, RPMValue + yBins = ignBlends1_loadBins, ignitionLoad + zBins = ignBlends1_table + gridOrient = 250, 0, 340 + + table = ignAdder2Table, ignAdder2Map, "Ignition adder 2", 1 + xBins = ignBlends2_rpmBins, RPMValue + yBins = ignBlends2_loadBins, ignitionLoad + zBins = ignBlends2_table + gridOrient = 250, 0, 340 + + table = ignAdder3Table, ignAdder3Map, "Ignition adder 3", 1 + xBins = ignBlends3_rpmBins, RPMValue + yBins = ignBlends3_loadBins, ignitionLoad + zBins = ignBlends3_table + gridOrient = 250, 0, 340 + + table = ignAdder4Table, ignAdder4Map, "Ignition adder 4", 1 + xBins = ignBlends4_rpmBins, RPMValue + yBins = ignBlends4_loadBins, ignitionLoad + zBins = ignBlends4_table + gridOrient = 250, 0, 340 + table = ignitionIatCorrTableTbl, ignitionIatCorrTableMap, "Ignition Intake Air Temp correction", 1 ; constant, variable xBins = ignitionIatCorrRpmBins, RPMValue @@ -1491,6 +1548,16 @@ menuDialog = main subMenu = ignitionTableTbl, "Ignition advance", 0, {isIgnitionEnabled} + groupMenu = "Ignition Adders" + groupChildMenu = ignAdder1Cfg, "Adder 1 bias" + groupChildMenu = ignAdder1Table, "Ignition adder 1", 0, { ignBlends1_blendParameter != 0 } + groupChildMenu = ignAdder2Cfg, "Adder 2 bias" + groupChildMenu = ignAdder2Table, "Ignition adder 2", 0, { ignBlends2_blendParameter != 0 } + groupChildMenu = ignAdder3Cfg, "Adder 3 bias" + groupChildMenu = ignAdder3Table, "Ignition adder 3", 0, { ignBlends3_blendParameter != 0 } + groupChildMenu = ignAdder4Cfg, "Adder 4 bias" + groupChildMenu = ignAdder4Table, "Ignition adder 4", 0, { ignBlends4_blendParameter != 0 } + groupMenu = "Cylinder ign trims" groupChildMenu = ignTrimTbl1, "Ignition trim cyl 1" groupChildMenu = ignTrimTbl2, "Ignition trim cyl 2" @@ -2220,6 +2287,22 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@@@ts_command_e_TS_ panel = multisparkMain panel = multisparkDwellParams + dialog = ignAdder1Cfg, "Ignition adder 1 config" + field = "Blend parameter", ignBlends1_blendParameter + panel = ignAdder1Bias + + dialog = ignAdder2Cfg, "Ignition adder 2 config" + field = "Blend parameter", ignBlends2_blendParameter + panel = ignAdder2Bias + + dialog = ignAdder3Cfg, "Ignition adder 3 config" + field = "Blend parameter", ignBlends3_blendParameter + panel = ignAdder3Bias + + dialog = ignAdder4Cfg, "Ignition adder 4 config" + field = "Blend parameter", ignBlends4_blendParameter + panel = ignAdder4Bias + dialog = dwellSettings, "", yAxis panel = dwellCorrection panel = dwellVoltageCorrection