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:
Matthew Kennedy 2020-07-13 11:46:55 -07:00 committed by GitHub
parent ca885d2a3b
commit ee6cb2c97a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 11 deletions

View File

@ -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

View File

@ -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 = &eth->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(&eth);
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(&eth);
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(&eth);
ASSERT_EQ( 4, engine->executor.size()) << "Lqs#0";