diff --git a/firmware/controllers/algo/defaults/default_fuel.cpp b/firmware/controllers/algo/defaults/default_fuel.cpp index edf5ee7259..e992d8d8fb 100644 --- a/firmware/controllers/algo/defaults/default_fuel.cpp +++ b/firmware/controllers/algo/defaults/default_fuel.cpp @@ -287,10 +287,7 @@ void setDefaultFuel() { setLinearCurve(config->mapEstimateTpsBins, 0, 100); setTable(config->mapEstimateTable, 60); - // most of rusEFI installations are still port injected, for GDI see 'setGDIFueling' - // -400 will close the injector just before TDC at the end of the exhaust stroke, - // around the time the intake valve opens. - setTable(config->injectionPhase, -400.0f); + setTable(config->injectionPhase, PORT_INJECTION_OFFSET); // Charge temperature estimation engineConfiguration->tChargeMinRpmMinTps = 0.25; diff --git a/firmware/controllers/algo/defaults/defaults.h b/firmware/controllers/algo/defaults/defaults.h index d55214c688..9f39212146 100644 --- a/firmware/controllers/algo/defaults/defaults.h +++ b/firmware/controllers/algo/defaults/defaults.h @@ -14,6 +14,11 @@ void setInline4(); #define DEFAULT_CRANKING_DWELL_MS 6 #define DEFAULT_CRANKING_ANGLE 6 + // most of rusEFI installations are still port injected, for GDI see 'setGDIFueling' + // -400 will close the injector just before TDC at the end of the exhaust stroke, + // around the time the intake valve opens. +#define PORT_INJECTION_OFFSET -400.0f + void setPPSInputs(adc_channel_e pps1, adc_channel_e pps2); void setPPSCalibration(float primaryUp, float primaryDown, float secondaryUp, float secondaryDown); diff --git a/unit_tests/tests/ignition_injection/test_odd_firing_engine.cpp b/unit_tests/tests/ignition_injection/test_odd_firing_engine.cpp index 2e31fc8309..53c949692c 100644 --- a/unit_tests/tests/ignition_injection/test_odd_firing_engine.cpp +++ b/unit_tests/tests/ignition_injection/test_odd_firing_engine.cpp @@ -1,6 +1,10 @@ #include "pch.h" #include "spark_logic.h" #include "harley.h" +#include "fuel_math.h" +#include "defaults.h" + +using ::testing::_; TEST(OddFire, hd) { EngineTestHelper eth(engine_type_e::HARLEY); @@ -13,6 +17,9 @@ TEST(OddFire, hd) { angle_t timing = 1; setTable(config->ignitionTable, timing); + EXPECT_CALL(*eth.mockAirmass, getAirmass(/*any rpm*/_, _)) + .WillRepeatedly(Return(AirmassResult{0.1008f, 50.0f})); + engineConfiguration->crankingTimingAngle = timing; engine->tdcMarkEnabled = false; engineConfiguration->camInputs[0] = Gpio::Unassigned; @@ -22,29 +29,35 @@ TEST(OddFire, hd) { LimpState limitedSparkState = getLimpManager()->allowIgnition(); ASSERT_TRUE(limitedSparkState.value); ASSERT_EQ(limitedSparkState.reason, ClearReason::None); + ASSERT_EQ(IM_SIMULTANEOUS, getCurrentInjectionMode()); // still spinning up + ASSERT_NEAR(0.027, getInjectionMass(200), EPS3D); // ASSERT_NEAR(-220.0, eth.timeToAngle(-73.333333), EPS3D); +// ASSERT_NEAR(140, eth.timeToAngle(46.66666), EPS3D); // ASSERT_NEAR(-200.0, eth.timeToAngle(-66.66666), EPS3D); // ASSERT_NEAR(160.0, eth.timeToAngle(53.333333), EPS3D); // ASSERT_NEAR(-168.0, eth.timeToAngle(-56.0), EPS3D); // ASSERT_NEAR(32, eth.timeToAngle(10.66666666), EPS3D); - float expectedAngle3 = -180 + cylinderTwo - timing; + angle_t expectedAngle3 = -180 + cylinderTwo - timing; ASSERT_EQ( 8, engine->executor.size()); eth.assertEvent5("spark down#3", 3, (void*)fireSparkAndPrepareNextSchedule, eth.angleToTimeUs(expectedAngle3)); - float expectedAngle7 = 180 - cylinderOne - timing; + angle_t expectedAngle7 = 180 - cylinderOne - timing; eth.assertEvent5("spark down#7", 7, (void*)fireSparkAndPrepareNextSchedule, eth.angleToTimeUs(expectedAngle7)); - eth.assertRpm( 500, "spinning-RPM#1"); engine->executor.executeAll(eth.getTimeNowUs() + MS2US(1000000)); - - expectedAngle3 = 180 - cylinderOne - timing; eth.fireTriggerEvents2(2 /* count */ , 60 /* ms */); - ASSERT_EQ( 4, engine->executor.size()); - eth.assertEvent5("spark down2#3", 3, (void*)fireSparkAndPrepareNextSchedule, eth.angleToTimeUs(expectedAngle3)); + ASSERT_EQ(IM_SEQUENTIAL, getCurrentInjectionMode()); + ASSERT_NEAR(0.0069257142022, getInjectionMass(200), EPS3D); + + ASSERT_EQ( 8, engine->executor.size()); + eth.assertEvent5("fuel down2#1", 1, (void*)turnInjectionPinLow, eth.angleToTimeUs(180 + PORT_INJECTION_OFFSET)); + eth.assertEvent5("spark down2#3", 3, (void*)fireSparkAndPrepareNextSchedule, eth.angleToTimeUs(-180 + cylinderTwo - timing)); + eth.assertEvent5("fuel down2#5", 5, (void*)turnInjectionPinLow, eth.angleToTimeUs(540 + PORT_INJECTION_OFFSET)); + eth.assertEvent5("spark down2#7", 7, (void*)fireSparkAndPrepareNextSchedule, eth.angleToTimeUs(180 - cylinderOne - timing)); } diff --git a/unit_tests/tests/trigger/test_fasterEngineSpinningUp.cpp b/unit_tests/tests/trigger/test_fasterEngineSpinningUp.cpp index d8745b31ee..c99d0592fc 100644 --- a/unit_tests/tests/trigger/test_fasterEngineSpinningUp.cpp +++ b/unit_tests/tests/trigger/test_fasterEngineSpinningUp.cpp @@ -5,6 +5,7 @@ */ #include "pch.h" +#include "fuel_math.h" TEST(cranking, testFasterEngineSpinningUp) { EngineTestHelper eth(engine_type_e::TEST_ENGINE); @@ -33,6 +34,7 @@ TEST(cranking, testFasterEngineSpinningUp) { ASSERT_EQ(IM_WASTED_SPARK, getCurrentIgnitionMode()); // check if the engine has the right state ASSERT_EQ(SPINNING_UP, engine->rpmCalculator.getState()); + ASSERT_NEAR(0, getInjectionMass(200), EPS5D); // check RPM eth.assertRpm( 0, "RPM=0"); // the queue should be empty, no trigger events yet @@ -87,6 +89,8 @@ TEST(cranking, testFasterEngineSpinningUp) { // Now perform a fake VVT sync and check that ignition mode changes to sequential engine->triggerCentral.syncAndReport(2, 0); ASSERT_EQ(IM_SEQUENTIAL, getCurrentIgnitionMode()); + // still cranking fuel + ASSERT_NEAR(0.0039, getInjectionMass(200), EPS3D); // skip, clear & advance 1 more revolution at higher RPM eth.fireFall(60); @@ -100,6 +104,7 @@ TEST(cranking, testFasterEngineSpinningUp) { eth.assertRpm( 1000, "RPM#3"); // check if the injection mode is back to sequential now ASSERT_EQ(IM_SEQUENTIAL, getCurrentInjectionMode()); + ASSERT_NEAR(0.0, getInjectionMass(200), EPS3D); // in this test fuel calculation is not active in running mode // 4 sequential injections for the full cycle ASSERT_EQ( 8, engine->executor.size()) << "plain#3";