mirror of https://github.com/rusefi/rusefi-1.git
Idle timing PID control & TPS-based VE table (#713)
* Add new config settings for idleTimingPidControl & TPSBasedVeTable * Add dialogs for idleTimingPidControl settings * Add dialogs for TPSBasedVeTable settings * Share the code for getTargetRpmForIdleCorrection() and move it from idle_thread.cpp * Implement TPSBasedVeTable * Add PID to advance_map.cpp * Implement idleTimingPidControl * Make getAdvanceCorrections() visible to unit-tests * Unit-tests! Yeah!
This commit is contained in:
parent
b3ad684bd6
commit
984fc12f73
|
@ -19,13 +19,17 @@
|
|||
*/
|
||||
|
||||
#include "global.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "engine.h"
|
||||
#include "advance_map.h"
|
||||
#include "interpolation.h"
|
||||
#include "efilib2.h"
|
||||
#include "engine_math.h"
|
||||
#include "tps.h"
|
||||
#include "idle_thread.h"
|
||||
|
||||
EXTERN_ENGINE;
|
||||
EXTERN_ENGINE
|
||||
;
|
||||
|
||||
#if EFI_TUNER_STUDIO || defined(__DOXYGEN__)
|
||||
extern TunerStudioOutputChannels tsOutputChannels;
|
||||
|
@ -36,6 +40,10 @@ static ign_Map3D_t advanceMap("advance");
|
|||
static ign_tps_Map3D_t advanceTpsMap("advanceTps", 1.0 / ADVANCE_TPS_STORAGE_MULT);
|
||||
static ign_Map3D_t iatAdvanceCorrectionMap("iat corr");
|
||||
|
||||
// Init PID later (make it compatible with unit-tests)
|
||||
static Pid idleTimingPid;
|
||||
static bool shouldResetTimingPid = false;
|
||||
|
||||
static int minCrankingRpm = 0;
|
||||
|
||||
static const float iatTimingRpmBins[IGN_LOAD_COUNT] = {880, 1260, 1640, 2020, 2400, 2780, 3000, 3380, 3760, 4140, 4520, 5000, 5700, 6500, 7200, 8000};
|
||||
|
@ -104,24 +112,56 @@ static angle_t getRunningAdvance(int rpm, float engineLoad DECLARE_ENGINE_PARAME
|
|||
return advanceAngle;
|
||||
}
|
||||
|
||||
static angle_t getAdvanceCorrections(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
angle_t getAdvanceCorrections(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
float iatCorrection;
|
||||
if (cisnan(engine->sensors.iat)) {
|
||||
iatCorrection = 0;
|
||||
} else {
|
||||
iatCorrection = iatAdvanceCorrectionMap.getValue((float) rpm, engine->sensors.iat);
|
||||
}
|
||||
// PID Ignition Advance angle correction
|
||||
float pidTimingCorrection = 0.0f;
|
||||
if (CONFIGB(useIdleTimingPidControl)) {
|
||||
int targetRpm = getTargetRpmForIdleCorrection(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
int rpmDelta = absI(rpm - targetRpm);
|
||||
float tps = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
if (tps >= CONFIGB(idlePidDeactivationTpsThreshold)) {
|
||||
// we are not in the idle mode anymore, so the 'reset' flag will help us when we return to the idle.
|
||||
shouldResetTimingPid = true;
|
||||
}
|
||||
else if (rpmDelta > CONFIG(idleTimingPidDeadZone) && rpmDelta < CONFIG(idleTimingPidWorkZone) + CONFIG(idlePidFalloffDeltaRpm)) {
|
||||
// We're now in the idle mode, and RPM is inside the Timing-PID regulator work zone!
|
||||
// So if we need to reset the PID, let's do it now
|
||||
if (shouldResetTimingPid) {
|
||||
idleTimingPid.reset();
|
||||
shouldResetTimingPid = false;
|
||||
}
|
||||
// get PID value (this is not an actual Advance Angle, but just a additive correction!)
|
||||
percent_t timingRawCorr = idleTimingPid.getOutput(targetRpm, rpm, engineConfiguration->idleTimingPid.periodMs);
|
||||
// tps idle-running falloff
|
||||
pidTimingCorrection = interpolateClamped(0.0f, timingRawCorr, CONFIGB(idlePidDeactivationTpsThreshold), 0.0f, tps);
|
||||
// rpm falloff
|
||||
pidTimingCorrection = interpolateClamped(0.0f, pidTimingCorrection, CONFIG(idlePidFalloffDeltaRpm), 0.0f, rpmDelta - CONFIG(idleTimingPidWorkZone));
|
||||
} else {
|
||||
shouldResetTimingPid = true;
|
||||
}
|
||||
} else {
|
||||
shouldResetTimingPid = true;
|
||||
}
|
||||
|
||||
if (engineConfiguration->debugMode == DBG_IGNITION_TIMING) {
|
||||
#if EFI_TUNER_STUDIO || defined(__DOXYGEN__)
|
||||
tsOutputChannels.debugFloatField1 = iatCorrection;
|
||||
tsOutputChannels.debugFloatField2 = engine->engineState.cltTimingCorrection;
|
||||
tsOutputChannels.debugFloatField3 = engine->fsioState.fsioTimingAdjustment;
|
||||
tsOutputChannels.debugFloatField4 = pidTimingCorrection;
|
||||
#endif /* EFI_TUNER_STUDIO */
|
||||
}
|
||||
|
||||
return iatCorrection
|
||||
+ engine->fsioState.fsioTimingAdjustment
|
||||
+ engine->engineState.cltTimingCorrection
|
||||
+ pidTimingCorrection
|
||||
// todo: uncomment once we get useable knock - engine->knockCount
|
||||
;
|
||||
}
|
||||
|
@ -197,6 +237,8 @@ void initTimingMap(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
config->ignitionRpmBins);
|
||||
iatAdvanceCorrectionMap.init(config->ignitionIatCorrTable, config->ignitionIatCorrLoadBins,
|
||||
config->ignitionIatCorrRpmBins);
|
||||
// init timing PID
|
||||
idleTimingPid = Pid(&CONFIG(idleTimingPid));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,5 +16,6 @@ void initTimingMap(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
|||
float getTopAdvanceForBore(chamber_style_e style, int octane, double compression, double bore);
|
||||
float getInitialAdvance(int rpm, float map, float advanceMax);
|
||||
void buildTimingMap(float advanceMax DECLARE_CONFIG_PARAMETER_SUFFIX);
|
||||
angle_t getAdvanceCorrections(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX);
|
||||
|
||||
#endif /* ADVANCE_H_ */
|
||||
|
|
|
@ -202,7 +202,7 @@ void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
/**
|
||||
* *0.01 because of https://sourceforge.net/p/rusefi/tickets/153/
|
||||
*/
|
||||
float rawVe = veMap.getValue(rpm, map);
|
||||
float rawVe = veMap.getValue(rpm, CONFIGB(useTPSBasedVeTable) ? tps : map);
|
||||
// get VE from the separate table for Idle
|
||||
if (CONFIG(useSeparateVeForIdle)) {
|
||||
float idleVe = interpolate2d("idleVe", rpm, config->idleVeBins, config->idleVe, IDLE_VE_CURVE_SIZE);
|
||||
|
|
|
@ -619,6 +619,18 @@ void setTargetRpmCurve(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|||
setLinearCurve(engineConfiguration->cltIdleRpm, CLT_CURVE_SIZE, rpm, rpm, 10);
|
||||
}
|
||||
|
||||
int getTargetRpmForIdleCorrection(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
float clt = engine->sensors.clt;
|
||||
int targetRpm;
|
||||
if (cisnan(clt)) {
|
||||
// error is already reported, let's take first value from the table should be good enough error handing solution
|
||||
targetRpm = CONFIG(cltIdleRpm)[0];
|
||||
} else {
|
||||
targetRpm = interpolate2d("cltRpm", clt, CONFIG(cltIdleRpmBins), CONFIG(cltIdleRpm), CLT_CURVE_SIZE);
|
||||
}
|
||||
return targetRpm + engine->fsioState.fsioIdleTargetRPMAdjustment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Global default engine configuration
|
||||
* This method sets the global engine configuration defaults. These default values are then
|
||||
|
|
|
@ -51,6 +51,7 @@ typedef struct {
|
|||
void prepareVoidConfiguration(engine_configuration_s *activeConfiguration);
|
||||
void setDefaultConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
||||
void setTargetRpmCurve(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX);
|
||||
int getTargetRpmForIdleCorrection(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
||||
void setAfrMap(afr_table_t table, float value);
|
||||
/**
|
||||
* See also setLinearCurve()
|
||||
|
|
|
@ -205,16 +205,7 @@ static percent_t automaticIdleController() {
|
|||
}
|
||||
|
||||
// get Target RPM for Auto-PID from a separate table
|
||||
float clt = engine->sensors.clt;
|
||||
int targetRpm;
|
||||
if (cisnan(clt)) {
|
||||
// error is already reported, let's take first value from the table should be good enough error handing solution
|
||||
targetRpm = CONFIG(cltIdleRpm)[0];
|
||||
} else {
|
||||
targetRpm = interpolate2d("cltRpm", clt, CONFIG(cltIdleRpmBins), CONFIG(cltIdleRpm), CLT_CURVE_SIZE);
|
||||
}
|
||||
targetRpm += engine->fsioState.fsioIdleTargetRPMAdjustment;
|
||||
|
||||
int targetRpm = getTargetRpmForIdleCorrection(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
||||
// check if within the dead zone
|
||||
int rpm = GET_RPM();
|
||||
|
@ -256,8 +247,8 @@ static percent_t automaticIdleController() {
|
|||
int idlePidLowerRpm = targetRpm + CONFIG(idlePidRpmDeadZone);
|
||||
if (CONFIG(idlePidRpmUpperLimit) > 0) {
|
||||
idleState = PID_UPPER;
|
||||
if (CONFIGB(useIacTableForCoasting)) {
|
||||
percent_t iacPosForCoasting = interpolate2d("iacCoasting", clt, CONFIG(iacCoastingBins), CONFIG(iacCoasting), CLT_CURVE_SIZE);
|
||||
if (CONFIGB(useIacTableForCoasting) && !cisnan(engine->sensors.clt)) {
|
||||
percent_t iacPosForCoasting = interpolate2d("iacCoasting", engine->sensors.clt, CONFIG(iacCoastingBins), CONFIG(iacCoasting), CLT_CURVE_SIZE);
|
||||
newValue = interpolateClamped(idlePidLowerRpm, newValue, idlePidLowerRpm + CONFIG(idlePidRpmUpperLimit), iacPosForCoasting, rpm);
|
||||
} else {
|
||||
// Well, just leave it as is, without PID regulation...
|
||||
|
|
|
@ -574,8 +574,8 @@ bit is_enabled_spi_2
|
|||
bit coastingFuelCutEnabled
|
||||
bit useIacTableForCoasting
|
||||
bit useNoiselessTriggerDecoder
|
||||
bit unused_board_984_24
|
||||
bit unused_board_984_25
|
||||
bit useIdleTimingPidControl
|
||||
bit useTPSBasedVeTable
|
||||
bit unused_board_984_26
|
||||
bit unused_board_984_27
|
||||
bit unused_board_984_28
|
||||
|
@ -804,7 +804,7 @@ custom pin_mode_e 1 bits, U08, @OFFSET@, [0:5], @@pin_mode_e_enum@@
|
|||
float throttlePedalWOTVoltage;+Pedal in the floor;"voltage", 1, 0, -6, 6, 2
|
||||
|
||||
int16_t startUpFuelPumpDuration;+on ECU start turn fuel pump on to build fuel pressure;"seconds", 1, 0, 0, 6000, 0
|
||||
int16_t idlePidRpmDeadZone;If RPM is close enough let's leave IAC alone;"RPM", 1, 0, 0, 1000, 0
|
||||
int16_t idlePidRpmDeadZone;If RPM is close enough let's leave IAC alone, and maybe engage timing PID correction;"RPM", 1, 0, 0, 1000, 0
|
||||
|
||||
|
||||
float[CLT_CURVE_SIZE] cltIdleRpmBins;CLT-based target RPM for automatic idle controller;"C", 1, 0, -100.0, 250.0, 2
|
||||
|
@ -984,8 +984,15 @@ tChargeMode_e tChargeMode;
|
|||
int16_t etb_iTermMax;iTerm max value;"", 1, 0, -30000, 30000.0, 0
|
||||
float etbDeadband;;"", 1, 0, 0, 100.0, 2
|
||||
etb_io etb2
|
||||
int[622] mainUnusedEnd;
|
||||
|
||||
pid_s idleTimingPid;See useIdleTimingPidControl
|
||||
int16_t idleTimingPidWorkZone;The timing correction works only if RPM is close enough, otherwise the IAC correction works;"RPM", 1, 0, 0, 1000, 0
|
||||
int16_t idleTimingPidDeadZone;If RPM is too perfect, let's leave the advance angle alone to avoid oscillation;"RPM", 1, 0, 0, 1000, 0
|
||||
int16_t idlePidFalloffDeltaRpm;Added to the work zone for smooth correction falloff;"RPM", 1, 0, 0, 1000, 0
|
||||
int16_t unusedIdleTimingPid;
|
||||
|
||||
int[615] mainUnusedEnd;
|
||||
|
||||
|
||||
end_struct
|
||||
|
||||
|
|
|
@ -7,15 +7,20 @@
|
|||
; this should stop TS from looking for the CAN ID in the 2nd byte location and allow the page reads to work correctly.
|
||||
enable2ndByteCanID = false
|
||||
|
||||
#unset tuneByMAF
|
||||
;#unset tuneByMAF
|
||||
|
||||
;[SettingGroups]
|
||||
[SettingGroups]
|
||||
; the referenceName will over-ride previous, so if you are creating a
|
||||
; settingGroup with a reference name of lambdaSensor, it will replace the
|
||||
; setting group defined in the settingGroups.xml of the TunerStudio config
|
||||
; folder. If is is an undefined referenceName, it will be added.
|
||||
; keyword = referenceName, DisplayName
|
||||
|
||||
settingGroup = tuneVeMode, "VE Autotune Mode"
|
||||
settingOption = tuneByTPS, "TPS-Based (See Injection -> Inj.Settings)"
|
||||
settingOption = tuneByMAF, "MAF-Based"
|
||||
settingOption = tuneByLoad, "Load-Based (Default)"
|
||||
|
||||
; settingGroup = fAlgorithmSetting, "Fuel Logic / Tables"
|
||||
; settingOption = FA_PLAIN_MAF, "Plain MAF"
|
||||
; settingOption = FA_TPS, "AlphaN/TPS"
|
||||
|
@ -685,7 +690,11 @@ fileVersion = { 20171101 }
|
|||
table = veTableTbl, veTableMap, "VE Table", 1
|
||||
; constant, variable
|
||||
xBins = veRpmBins, RPMValue
|
||||
#if tuneByTPS
|
||||
yBins = ignitionTpsBins, TPSValue
|
||||
#else
|
||||
yBins = veLoadBins, MAPValue
|
||||
#endif
|
||||
zBins = veTable
|
||||
; gridHeight = 2.0
|
||||
gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees.
|
||||
|
@ -1100,6 +1109,7 @@ menuDialog = main
|
|||
subMenu = idleVeCurve, "Idle VE", 0, {useSeparateVeForIdle == 1}
|
||||
subMenu = idleAdvanceCurve, "Idle Ignition Advance", 0, {useSeparateAdvanceForIdle == 1}
|
||||
subMenu = std_separator
|
||||
subMenu = idleTimingPidCorrDialog, "Closed-loop Idle timing correction"
|
||||
subMenu = cltIdleCurve, "Warmup Idle multiplier"
|
||||
subMenu = iacCoastingCurve, "Coasting IAC Position for Auto-Idle", 0, {useIacTableForCoasting == 1}
|
||||
|
||||
|
@ -1291,6 +1301,12 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00"
|
|||
field = "Mode", injectionMode, {isInjectionEnabled == 1}
|
||||
field = "#Batch injection with individual wiring"
|
||||
field = "Two wire batch emulation", twoWireBatchInjection, {isInjectionEnabled == 1 && injectionMode == 2}
|
||||
#if tuneByTPS
|
||||
field = "Use TPS instead of Load for VE table", useTPSBasedVeTable, {isInjectionEnabled == 1 && fuelAlgorithm == LM_SPEED_DENSITY}
|
||||
#else
|
||||
field = "#Enabled for TPS-Based 'VE Autotune Mode' in Project Settings"
|
||||
field = "Use TPS instead of Load for VE table", useTPSBasedVeTable, {0}
|
||||
#endif
|
||||
|
||||
dialog = ignitionSettings, "Ignition Settings"
|
||||
field = "Enabled", isIgnitionEnabled
|
||||
|
@ -1804,6 +1820,22 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00"
|
|||
field = "#See Warmup idle multiplier"
|
||||
slider = "Manual IAC Position", manIdlePosition, horizontal
|
||||
|
||||
dialog = idleTimingPidCorrDialog, "", yAxis
|
||||
field = "!This timing correction mode is Alpha Version"
|
||||
field = "Use Auto-PID ignition advance control", useIdleTimingPidControl
|
||||
field = "#See Idle Target RPM Curve"
|
||||
field = "P-factor", idleTimingPid_pFactor, {useIdleTimingPidControl == 1}
|
||||
field = "I-factor", idleTimingPid_iFactor, {useIdleTimingPidControl == 1}
|
||||
field = "D-factor", idleTimingPid_dFactor, {useIdleTimingPidControl == 1}
|
||||
field = "Offset", idleTimingPid_offset, {useIdleTimingPidControl == 1}
|
||||
field = "Min Delta", idleTimingPid_minValue, {useIdleTimingPidControl == 1}
|
||||
field = "Max Delta", idleTimingPid_maxValue, {useIdleTimingPidControl == 1}
|
||||
field = "period", idleTimingPid_periodMs, {useIdleTimingPidControl == 1}
|
||||
field = "#See RPM dead zone to deactivate IAC pid"
|
||||
field = "RPM working zone for timing pid", idleTimingPidWorkZone, {useIdleTimingPidControl == 1}
|
||||
field = "RPM working zone falloff", idlePidFalloffDeltaRpm, {useIdleTimingPidControl == 1}
|
||||
field = "RPM dead zone to deactivate timing pid", idleTimingPidDeadZone, {useIdleTimingPidControl == 1}
|
||||
|
||||
; Engine->Fan Settings
|
||||
dialog = fanSetting, "Fan Settings"
|
||||
field = "Fan On Temperature", fanOnTemperature
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
|
||||
#include "engine_test_helper.h"
|
||||
#include "advance_map.h"
|
||||
#include "tps.h"
|
||||
#include "pid.h"
|
||||
|
||||
TEST(idle, pid) {
|
||||
|
@ -62,3 +64,84 @@ TEST(idle, pid) {
|
|||
ASSERT_EQ( 0, pid.iTerm) << "target=50, input=50 iTerm";
|
||||
|
||||
}
|
||||
|
||||
TEST(idle, timingPid) {
|
||||
print("******************************************* testTimingPidController\r\n");
|
||||
|
||||
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||
// basic engine setup
|
||||
setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð);
|
||||
|
||||
// set PID settings
|
||||
pid_s pidS;
|
||||
pidS.pFactor = 0.1;
|
||||
pidS.iFactor = 0;
|
||||
pidS.dFactor = 0;
|
||||
pidS.offset = 0;
|
||||
pidS.minValue = -20;
|
||||
pidS.maxValue = +20;
|
||||
pidS.periodMs = 1;
|
||||
|
||||
// setup TimingPid settings
|
||||
engineConfiguration->idleTimingPidDeadZone = 10;
|
||||
engineConfiguration->idleTimingPidWorkZone = 100;
|
||||
engineConfiguration->idlePidFalloffDeltaRpm = 30;
|
||||
|
||||
// setup target rpm curve (we need only 1 value when CLT sensor is disabled)
|
||||
const int idleRpmTarget = 700;
|
||||
engineConfiguration->cltIdleRpm[0] = idleRpmTarget;
|
||||
|
||||
// setup other settings
|
||||
engineConfiguration->idleTimingPid = pidS;
|
||||
eth.engine.fsioState.fsioTimingAdjustment = 0;
|
||||
eth.engine.fsioState.fsioIdleTargetRPMAdjustment = 0;
|
||||
eth.engine.engineState.cltTimingCorrection = 0;
|
||||
|
||||
// configure TPS
|
||||
engineConfiguration->tpsMin = 0;
|
||||
engineConfiguration->tpsMax = 100;
|
||||
engineConfiguration->bc.idlePidDeactivationTpsThreshold = 10;
|
||||
setMockTpsPosition(0);
|
||||
|
||||
// disable temperature sensors
|
||||
eth.engine.sensors.clt = NAN;
|
||||
eth.engine.sensors.iat = NAN;
|
||||
|
||||
// all corrections disabled, should be 0
|
||||
engineConfiguration->bc.useIdleTimingPidControl = false;
|
||||
angle_t corr = getAdvanceCorrections(idleRpmTarget PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
ASSERT_EQ(0, corr) << "getAdvanceCorrections#1";
|
||||
|
||||
// basic IDLE PID correction test
|
||||
engineConfiguration->bc.useIdleTimingPidControl = true;
|
||||
int baseTestRpm = idleRpmTarget + engineConfiguration->idleTimingPidWorkZone;
|
||||
corr = getAdvanceCorrections(baseTestRpm PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
// (delta_rpm=-100) * (p-factor=0.1) = -10 degrees
|
||||
ASSERT_EQ(-10, corr) << "getAdvanceCorrections#2";
|
||||
|
||||
// check if rpm is too close to the target
|
||||
corr = getAdvanceCorrections((idleRpmTarget + engineConfiguration->idleTimingPidDeadZone) PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
ASSERT_EQ(0, corr) << "getAdvanceCorrections#3";
|
||||
|
||||
// check if rpm is too high (just outside the workzone and even falloff) so we disable the PID correction
|
||||
int tooHighRpm = idleRpmTarget + engineConfiguration->idleTimingPidWorkZone + engineConfiguration->idlePidFalloffDeltaRpm;
|
||||
corr = getAdvanceCorrections(tooHighRpm PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
ASSERT_EQ(0, corr) << "getAdvanceCorrections#4";
|
||||
|
||||
// check if rpm is within the falloff zone
|
||||
int falloffRpm = idleRpmTarget + engineConfiguration->idleTimingPidWorkZone + (engineConfiguration->idlePidFalloffDeltaRpm / 2);
|
||||
corr = getAdvanceCorrections(falloffRpm PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
// -(100+30/2) * 0.1 / 2 = -5.75
|
||||
ASSERT_FLOAT_EQ(-5.75f, corr) << "getAdvanceCorrections#5";
|
||||
|
||||
// check if PID correction is disabled in running mode (tps > threshold):
|
||||
setMockTpsPosition(engineConfiguration->bc.idlePidDeactivationTpsThreshold + 1);
|
||||
corr = getAdvanceCorrections(idleRpmTarget PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
ASSERT_EQ(0, corr) << "getAdvanceCorrections#6";
|
||||
|
||||
// check if PID correction is interpolated for transient idle-running TPS positions
|
||||
setMockTpsPosition(engineConfiguration->bc.idlePidDeactivationTpsThreshold / 2);
|
||||
corr = getAdvanceCorrections(baseTestRpm PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
ASSERT_FLOAT_EQ(-5.0f, corr) << "getAdvanceCorrections#7";
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue