correct batch fuel cylinder pairing (#1595)
* correct batch fuel cylinder pairing * param * only change behavior on two wire batch * Add tests for two wire batch & sequential * improve testing a little bit * comments Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
parent
ca885d2a3b
commit
ee6cb2c97a
|
@ -151,24 +151,23 @@ bool FuelSchedule::addFuelEventsForCylinder(int i DECLARE_ENGINE_PARAMETER_SUFF
|
|||
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(baseAngle), "NaN baseAngle", false);
|
||||
assertAngleRange(baseAngle, "baseAngle_r", CUSTOM_ERR_6554);
|
||||
|
||||
int injectorIndex;
|
||||
|
||||
injection_mode_e mode = engine->getCurrentInjectionMode(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
||||
int injectorIndex;
|
||||
if (mode == IM_SIMULTANEOUS || mode == IM_SINGLE_POINT) {
|
||||
// These modes only have one injector
|
||||
injectorIndex = 0;
|
||||
} else if (mode == IM_SEQUENTIAL) {
|
||||
} else if (mode == IM_SEQUENTIAL || (mode == IM_BATCH && CONFIG(twoWireBatchInjection))) {
|
||||
// Map order index -> cylinder index (firing order)
|
||||
injectorIndex = getCylinderId(i PASS_ENGINE_PARAMETER_SUFFIX) - 1;
|
||||
} else if (mode == IM_BATCH) {
|
||||
// does not look exactly right, not too consistent with IM_SEQUENTIAL
|
||||
// Loop over the first half of the firing order twice
|
||||
injectorIndex = i % (engineConfiguration->specs.cylindersCount / 2);
|
||||
} else {
|
||||
firmwareError(CUSTOM_OBD_UNEXPECTED_INJECTION_MODE, "Unexpected injection mode %d", mode);
|
||||
injectorIndex = 0;
|
||||
}
|
||||
|
||||
bool isSimultanious = mode == IM_SIMULTANEOUS;
|
||||
|
||||
assertAngleRange(baseAngle, "addFbaseAngle", CUSTOM_ADD_BASE);
|
||||
|
||||
int cylindersCount = CONFIG(specs.cylindersCount);
|
||||
|
@ -186,13 +185,18 @@ bool FuelSchedule::addFuelEventsForCylinder(int i DECLARE_ENGINE_PARAMETER_SUFF
|
|||
/**
|
||||
* also fire the 2nd half of the injectors so that we can implement a batch mode on individual wires
|
||||
*/
|
||||
int secondIndex = injectorIndex + (CONFIG(specs.cylindersCount) / 2);
|
||||
// Compute the position of this cylinder's twin in the firing order
|
||||
// Each injector gets fired as a primary (the same as sequential), but also
|
||||
// fires the injector 360 degrees later in the firing order.
|
||||
int secondOrder = (i + (CONFIG(specs.cylindersCount) / 2)) % CONFIG(specs.cylindersCount);
|
||||
int secondIndex = getCylinderId(secondOrder PASS_ENGINE_PARAMETER_SUFFIX) - 1;
|
||||
secondOutput = &enginePins.injectors[secondIndex];
|
||||
} else {
|
||||
secondOutput = NULL;
|
||||
secondOutput = nullptr;
|
||||
}
|
||||
|
||||
InjectorOutputPin *output = &enginePins.injectors[injectorIndex];
|
||||
bool isSimultanious = mode == IM_SIMULTANEOUS;
|
||||
|
||||
if (!isSimultanious && !output->isInitialized()) {
|
||||
// todo: extract method for this index math
|
||||
|
|
|
@ -566,12 +566,27 @@ TEST(misc, testTriggerDecoder) {
|
|||
|
||||
extern fuel_Map3D_t fuelMap;
|
||||
|
||||
static void assertInjectionEvent(const char *msg, InjectionEvent *ev, int injectorIndex, int eventIndex, angle_t angleOffset) {
|
||||
static void assertInjectionEventBase(const char *msg, InjectionEvent *ev, int injectorIndex, int eventIndex, angle_t angleOffset) {
|
||||
ASSERT_EQ(injectorIndex, ev->outputs[0]->injectorIndex) << msg << "inj index";
|
||||
assertEqualsM4(msg, " event index", eventIndex, ev->injectionStart.triggerEventIndex);
|
||||
assertEqualsM4(msg, " event offset", angleOffset, ev->injectionStart.angleOffsetFromTriggerEvent);
|
||||
}
|
||||
|
||||
static void assertInjectionEvent(const char *msg, InjectionEvent *ev, int injectorIndex, int eventIndex, angle_t angleOffset) {
|
||||
assertInjectionEventBase(msg, ev, injectorIndex, eventIndex, angleOffset);
|
||||
|
||||
// There should NOT be a second injector configured
|
||||
EXPECT_EQ(nullptr, ev->outputs[1]);
|
||||
}
|
||||
|
||||
static void assertInjectionEventBatch(const char *msg, InjectionEvent *ev, int injectorIndex, int secondInjectorIndex, int eventIndex, angle_t angleOffset) {
|
||||
assertInjectionEventBase(msg, ev, injectorIndex, eventIndex, angleOffset);
|
||||
|
||||
// There should be a second injector - confirm it's the correct one
|
||||
ASSERT_NE(nullptr, ev->outputs[1]);
|
||||
EXPECT_EQ(secondInjectorIndex, ev->outputs[1]->injectorIndex);
|
||||
}
|
||||
|
||||
static void setTestBug299(EngineTestHelper *eth) {
|
||||
setupSimpleTestEngineWithMafAndTT_ONE_trigger(eth);
|
||||
Engine *engine = ð->engine;
|
||||
|
@ -959,9 +974,57 @@ TEST(big, testFuelSchedulerBug299smallAndMedium) {
|
|||
doTestFuelSchedulerBug299smallAndMedium(1000);
|
||||
}
|
||||
|
||||
TEST(big, testDifferentInjectionModes) {
|
||||
printf("*************************************************** testDifferentInjectionModes\r\n");
|
||||
TEST(big, testTwoWireBatch) {
|
||||
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||
setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð);
|
||||
|
||||
engineConfiguration->injectionMode = IM_BATCH;
|
||||
engineConfiguration->twoWireBatchInjection = true;
|
||||
|
||||
eth.fireTriggerEventsWithDuration(20);
|
||||
// still no RPM since need to cycles measure cycle duration
|
||||
eth.fireTriggerEventsWithDuration(20);
|
||||
eth.clearQueue();
|
||||
|
||||
/**
|
||||
* Trigger up - scheduling fuel for full engine cycle
|
||||
*/
|
||||
eth.fireRise(20);
|
||||
|
||||
FuelSchedule * t = &ENGINE(injectionEvents);
|
||||
|
||||
assertInjectionEventBatch("#0", &t->elements[0], 0, 3, 1, 153); // Cyl 1 and 4
|
||||
assertInjectionEventBatch("#1_i_@", &t->elements[1], 2, 1, 1, 153 + 180); // Cyl 3 and 2
|
||||
assertInjectionEventBatch("#2@", &t->elements[2], 3, 0, 0, 153); // Cyl 4 and 1
|
||||
assertInjectionEventBatch("inj#3@", &t->elements[3], 1, 2, 0, 153 + 180); // Cyl 2 and 3
|
||||
}
|
||||
|
||||
|
||||
TEST(big, testSequential) {
|
||||
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||
setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð);
|
||||
|
||||
engineConfiguration->injectionMode = IM_SEQUENTIAL;
|
||||
|
||||
eth.fireTriggerEventsWithDuration(20);
|
||||
// still no RPM since need to cycles measure cycle duration
|
||||
eth.fireTriggerEventsWithDuration(20);
|
||||
eth.clearQueue();
|
||||
|
||||
/**
|
||||
* Trigger up - scheduling fuel for full engine cycle
|
||||
*/
|
||||
eth.fireRise(20);
|
||||
|
||||
FuelSchedule * t = &ENGINE(injectionEvents);
|
||||
|
||||
assertInjectionEvent("#0", &t->elements[0], 0, 1, 126); // Cyl 1
|
||||
assertInjectionEvent("#1_i_@", &t->elements[1], 2, 1, 126 + 180); // Cyl 3
|
||||
assertInjectionEvent("#2@", &t->elements[2], 3, 0, 126); // Cyl 4
|
||||
assertInjectionEvent("inj#3@", &t->elements[3], 1, 0, 126 + 180); // Cyl 2
|
||||
}
|
||||
|
||||
TEST(big, testDifferentInjectionModes) {
|
||||
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||
setTestBug299(ð);
|
||||
ASSERT_EQ( 4, engine->executor.size()) << "Lqs#0";
|
||||
|
|
Loading…
Reference in New Issue