implement `StagedInjectionTest` #6972 (#7087)

This commit is contained in:
kifir23917 2024-11-20 21:07:50 +02:00 committed by GitHub
parent ec83526370
commit 5731cdd6dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 341 additions and 1 deletions

View File

@ -4,6 +4,8 @@
#pragma once
#include "batt_lag_corr_curve.h"
namespace engine_configuration_defaults {
/* A/C Settings: */
constexpr float AC_DELAY = 0.5f;
@ -28,4 +30,16 @@ namespace engine_configuration_defaults {
constexpr bool LAUNCH_ACTIVATE_PIN_INVERTED = false;
constexpr launchActivationMode_e LAUNCH_ACTIVATION_MODE = SWITCH_INPUT_LAUNCH;
constexpr int LAUNCH_SPEED_THRESHOLD = 0;
/* Injector */
constexpr bool INJECTOR_FLOW_AS_MASS_FLOW = false;
constexpr float INJECTOR_FLOW = 200.0f;
constexpr BattLagCorrCurve INJECTOR_BATT_LAG_CURR { 3.371f, 1.974f, 1.383f, 1.194f, 1.04f, 0.914f, 0.797f, 0.726 };
/* Secondary injector: */
constexpr float INJECTOR_SECONDARY_FLOW = INJECTOR_FLOW;
constexpr BattLagCorrCurve INJECTOR_SECONDARY_BATT_LAG_CURR = INJECTOR_BATT_LAG_CURR;
/* Staged injection: */
constexpr bool ENABLE_STAGED_INJECTION = false;
}

View File

@ -0,0 +1,9 @@
//
// Created by kifir on 11/19/24.
//
#pragma once
#include <array>
using BattLagCorrCurve = std::array<float, VBAT_INJECTOR_CURVE_SIZE>;

View File

@ -0,0 +1,92 @@
//
// Created by kifir on 11/18/24.
//
#include "pch.h"
#include "util/test_base.h"
namespace {
constexpr uint8_t TEST_STAGE2_FRACTION = 17;
constexpr float TEST_INJECTION_MASS = 12.34f;
constexpr float TEST_PRIMARY_INJECTOR_DEAD_TIME = 5.6f;
constexpr float TEST_PRIMARY_INJECTOR_FLOW = 239.17f;
constexpr float TEST_PRIMARY_INJECTOR_BASE_DURATION = TEST_INJECTION_MASS / TEST_PRIMARY_INJECTOR_FLOW * 1000;
constexpr float TEST_SECONDARY_INJECTOR_DEAD_TIME = 7.8;
constexpr float TEST_SECONDARY_INJECTOR_FLOW = 174.17f;
constexpr float TEST_SECONDARY_INJECTOR_BASE_DURATION = TEST_INJECTION_MASS / TEST_SECONDARY_INJECTOR_FLOW * 1000;
BattLagCorrCurve generateConstantBattLagCorrCurve(const float value) {
BattLagCorrCurve testBattLagCorrCurve;
testBattLagCorrCurve.fill(value);
return testBattLagCorrCurve;
}
const BattLagCorrCurve TEST_PRIMARY_INJECTOR_BATT_LAG_CORR_CURVE = generateConstantBattLagCorrCurve(
TEST_PRIMARY_INJECTOR_DEAD_TIME
);
const BattLagCorrCurve TEST_SECONDARY_INJECTOR_BATT_LAG_CORR_CURVE = generateConstantBattLagCorrCurve(
TEST_SECONDARY_INJECTOR_DEAD_TIME
);
const EngineConfig TEST_ENGINE_CONFIG = EngineConfig()
.setInjectorFlowAsMassFlow(true)
.setInjectorFlow(TEST_PRIMARY_INJECTOR_FLOW)
.setInjectorBattLagCorr(TEST_PRIMARY_INJECTOR_BATT_LAG_CORR_CURVE)
.setInjectorSecondaryFlow(TEST_SECONDARY_INJECTOR_FLOW)
.setInjectorSecondaryBattLagCorr(TEST_SECONDARY_INJECTOR_BATT_LAG_CORR_CURVE);
class StagedInjectionTest : public TestBase {
protected:
void SetUp() override;
};
void StagedInjectionTest::SetUp() {
TestBase::SetUp();
InjectorStagingTable testInjectorStagingTable;
for (int i = 0; i < INJ_STAGING_COUNT; i++) {
for (int j = 0; j < INJ_STAGING_COUNT; j++) {
testInjectorStagingTable[i][j] = TEST_STAGE2_FRACTION;
}
};
getTestPersistentConfiguration().setInjectorStagingTable(testInjectorStagingTable);
getTestEngineState().setLuaFuelAdd(TEST_INJECTION_MASS);
}
TEST_F(StagedInjectionTest, checkDisabledStagedInjection) {
setUpEngineConfiguration(TEST_ENGINE_CONFIG);
periodicFastCallback();
EXPECT_EQ(getTestEngineState().getInjectionStage2Fraction(), 0.0f);
EXPECT_NEAR(
getTestEngineState().getInjectionDuration(),
TEST_PRIMARY_INJECTOR_BASE_DURATION + TEST_PRIMARY_INJECTOR_DEAD_TIME,
EPS5D
);
EXPECT_EQ(getTestEngineState().getInjectionDurationStage2(), 0.0f);
}
TEST_F(StagedInjectionTest, checkEnabledStagedInjection) {
setUpEngineConfiguration(TEST_ENGINE_CONFIG.clone().setStagedInjectionEnabled(true));
periodicFastCallback();
const float injectionStage2Fraction = getTestEngineState().getInjectionStage2Fraction();
EXPECT_EQ(injectionStage2Fraction, TEST_STAGE2_FRACTION * 0.01f);
EXPECT_NEAR(
getTestEngineState().getInjectionDuration(),
TEST_PRIMARY_INJECTOR_BASE_DURATION * (1 - injectionStage2Fraction) + TEST_PRIMARY_INJECTOR_DEAD_TIME,
EPS5D
);
EXPECT_NEAR(
getTestEngineState().getInjectionDurationStage2(),
TEST_SECONDARY_INJECTOR_BASE_DURATION * injectionStage2Fraction + TEST_SECONDARY_INJECTOR_DEAD_TIME,
EPS5D
);
}
}

View File

@ -48,8 +48,10 @@ TESTS_SRC_CPP = \
tests/ignition_injection/test_injector_model.cpp \
tests/ignition_injection/test_odd_firing_engine.cpp \
tests/ignition_injection/test_three_cylinder.cpp \
testa/ignition_injection/test_staged_injection.cpp \
tests/util/test_base.cpp \
tests/util/test_engine_configuration.cpp \
tests/util/engine_config.cpp \
tests/util/test_persistent_configuration.cpp \
tests/util/test_engine_state.cpp \
tests/ac/ac_test_base.cpp \

View File

@ -0,0 +1,41 @@
//
// Created by kifir on 11/18/24.
//
#include "pch.h"
#include "engine_config.h"
EngineConfig EngineConfig::clone() const {
return *this;
}
EngineConfig EngineConfig::setInjectorFlowAsMassFlow(const std::optional<bool> injectorFlowAsMassFlow) {
m_injectorFlowAsMassFlow = injectorFlowAsMassFlow;
return *this;
}
EngineConfig EngineConfig::setInjectorFlow(const std::optional<float> flow) {
m_injectorFlow = flow;
return *this;
}
EngineConfig EngineConfig::setInjectorBattLagCorr(const std::optional<BattLagCorrCurve> battLagCorr) {
m_injectorBattLagCorrCurve = battLagCorr;
return *this;
}
EngineConfig EngineConfig::setInjectorSecondaryFlow(const std::optional<float> flow) {
m_injectorSecondaryFlow = flow;
return *this;
}
EngineConfig EngineConfig::setInjectorSecondaryBattLagCorr(const std::optional<BattLagCorrCurve> battLagCorr) {
m_injectorSecondaryBattLagCorrCurve = battLagCorr;
return *this;
}
EngineConfig EngineConfig::setStagedInjectionEnabled(const std::optional<bool> value) {
m_isStagedInjectionEnabled = value;
return *this;
}

View File

@ -0,0 +1,51 @@
//
// Created by kifir on 11/18/24.
//
#pragma once
#include "batt_lag_corr_curve.h"
class EngineConfig {
public:
EngineConfig clone() const;
// Injector
std::optional<float> getInjectorFlow() const { return m_injectorFlow; }
std::optional<BattLagCorrCurve> getInjectorBattLagCorr() const { return m_injectorBattLagCorrCurve; }
std::optional<bool> getInjectorFlowAsMassFlow() const { return m_injectorFlowAsMassFlow; }
// Secondary injector
std::optional<float> getInjectorSecondaryFlow() const { return m_injectorSecondaryFlow; }
std::optional<BattLagCorrCurve> getInjectorSecondaryBattLagCorr() const { return m_injectorSecondaryBattLagCorrCurve; }
// Staged injection
std::optional<bool> getStagedInjectionEnabled() const { return m_isStagedInjectionEnabled; }
// We do not core about performance in tests, but we want to use builder-like style, so setters return new instance
// of configuration:
// Injector
EngineConfig setInjectorFlowAsMassFlow(std::optional<bool> injectorFlowAsMassFlow);
EngineConfig setInjectorFlow(std::optional<float> flow);
EngineConfig setInjectorBattLagCorr(std::optional<BattLagCorrCurve> battLagCorr);
// Secondary injector
EngineConfig setInjectorSecondaryFlow(std::optional<float> flow);
EngineConfig setInjectorSecondaryBattLagCorr(std::optional<BattLagCorrCurve> battLagCorr);
// Staged injection
EngineConfig setStagedInjectionEnabled(std::optional<bool> value);
private:
// Injector
std::optional<float> m_injectorFlow;
std::optional<BattLagCorrCurve> m_injectorBattLagCorrCurve;
std::optional<bool> m_injectorFlowAsMassFlow;;
// Secondary injector
std::optional<float> m_injectorSecondaryFlow;
std::optional<BattLagCorrCurve> m_injectorSecondaryBattLagCorrCurve;
// Staged injection
std::optional<bool> m_isStagedInjectionEnabled;
};

View File

@ -26,6 +26,20 @@ TestEngineState& TestBase::getTestEngineState() {
return TestEngineState::getInstance();
}
void TestBase::setUpEngineConfiguration(const EngineConfig& config) {
// Injector
getTestEngineConfiguration().configureInjectorFlowAsMassFlow(config.getInjectorFlowAsMassFlow());
getTestEngineConfiguration().configureInjectorFlow(config.getInjectorFlow());
getTestEngineConfiguration().configureInjectorBattLagCorr(config.getInjectorBattLagCorr());
// Secondary injector
getTestEngineConfiguration().configureInjectorSecondaryFlow(config.getInjectorSecondaryFlow());
getTestEngineConfiguration().configureInjectorSecondaryBattLagCorr(config.getInjectorSecondaryBattLagCorr());
// Staged injection
getTestEngineConfiguration().configureEnableStagedInjection(config.getStagedInjectionEnabled());
}
void TestBase::periodicFastCallback() {
// run the ignition math
engine->periodicFastCallback();

View File

@ -7,6 +7,7 @@
#include "test_engine_configuration.h"
#include "test_engine_state.h"
#include "test_persistent_configuration.h"
#include "engine_config.h"
class TestBase : public testing::Test {
protected:
@ -17,6 +18,8 @@ protected:
TestEngineState& getTestEngineState();
TestPersistentConfiguration& getTestPersistentConfiguration();
void setUpEngineConfiguration(const EngineConfig& config);
void periodicFastCallback();
void periodicSlowCallback();

View File

@ -252,6 +252,77 @@ void TestEngineConfiguration::configureTorqueReductionIgnitionRetard(const std::
}
}
void TestEngineConfiguration::configureInjectorFlowAsMassFlow(const std::optional<bool> injectorFlowAsMassFlow) {
if (injectorFlowAsMassFlow.has_value()) {
engineConfiguration->injectorFlowAsMassFlow = injectorFlowAsMassFlow.value();
} else {
ASSERT_EQ(
engineConfiguration->injectorFlowAsMassFlow,
engine_configuration_defaults::INJECTOR_FLOW_AS_MASS_FLOW
); // check default value
}
}
void TestEngineConfiguration::configureInjectorFlow(const std::optional<float> flow) {
if (flow.has_value()) {
engineConfiguration->injector.flow = flow.value();
} else {
ASSERT_EQ(engineConfiguration->injector.flow, engine_configuration_defaults::INJECTOR_FLOW); // check default value
}
}
void TestEngineConfiguration::configureInjectorBattLagCorr(const std::optional<BattLagCorrCurve> battLagCorr) {
if (battLagCorr.has_value()) {
std::copy(
std::begin(battLagCorr.value()),
std::end(battLagCorr.value()),
std::begin(engineConfiguration->injector.battLagCorr)
);
} else {
EXPECT_THAT(
engineConfiguration->injector.battLagCorr,
testing::ElementsAreArray(engine_configuration_defaults::INJECTOR_BATT_LAG_CURR)
);
}
}
void TestEngineConfiguration::configureInjectorSecondaryFlow(const std::optional<float> flow) {
if (flow.has_value()) {
engineConfiguration->injectorSecondary.flow = flow.value();
} else {
ASSERT_EQ(
engineConfiguration->injectorSecondary.flow,
engine_configuration_defaults::INJECTOR_SECONDARY_FLOW
); // check default value
}
}
void TestEngineConfiguration::configureInjectorSecondaryBattLagCorr(const std::optional<BattLagCorrCurve> battLagCorr) {
if (battLagCorr.has_value()) {
std::copy(
std::begin(battLagCorr.value()),
std::end(battLagCorr.value()),
std::begin(engineConfiguration->injectorSecondary.battLagCorr)
);
} else {
EXPECT_THAT(
engineConfiguration->injectorSecondary.battLagCorr,
testing::ElementsAreArray(engine_configuration_defaults::INJECTOR_SECONDARY_BATT_LAG_CURR)
);
}
}
void TestEngineConfiguration::configureEnableStagedInjection(const std::optional<bool> isStagedInjectionEnabled) {
if (isStagedInjectionEnabled.has_value()) {
engineConfiguration->enableStagedInjection = isStagedInjectionEnabled.value();
} else {
ASSERT_EQ(
engineConfiguration->enableStagedInjection,
engine_configuration_defaults::ENABLE_STAGED_INJECTION
); // check default value
}
}
TestEngineConfiguration::TestEngineConfiguration() {
}

View File

@ -4,7 +4,7 @@
#pragma once
#include "pch.h"
#include "batt_lag_corr_curve.h"
class TestEngineConfiguration {
public:
@ -41,6 +41,18 @@ public:
void configureTorqueReductionArmingApp(std::optional<float> armingApp);
void configureTorqueReductionIgnitionCut(std::optional<int8_t> ignitionCut);
void configureTorqueReductionIgnitionRetard(std::optional<int8_t> ignitionRetard);
// Injector
void configureInjectorFlow(std::optional<float> flow);
void configureInjectorBattLagCorr(std::optional<BattLagCorrCurve> battLagCorr);
void configureInjectorFlowAsMassFlow(std::optional<bool> injectorFlowAsMassFlow);
// Secondary Injector
void configureInjectorSecondaryFlow(std::optional<float> flow);
void configureInjectorSecondaryBattLagCorr(std::optional<BattLagCorrCurve> battLagCorr);
// Staged injection
void configureEnableStagedInjection(std::optional<bool> isStagedInjectionEnabled);
private:
TestEngineConfiguration();
static TestEngineConfiguration instance;

View File

@ -10,6 +10,18 @@ TestEngineState& TestEngineState::getInstance() {
return instance;
}
float TestEngineState::getInjectionStage2Fraction() const {
return engine->engineState.injectionStage2Fraction;
}
floatms_t TestEngineState::getInjectionDuration() const {
return engine->engineState.injectionDuration;
}
floatms_t TestEngineState::getInjectionDurationStage2() const {
return engine->engineState.injectionDurationStage2;
}
void TestEngineState::setLuaSoftSparkSkip(const float value) {
engine->engineState.luaSoftSparkSkip = value;
}
@ -18,6 +30,10 @@ void TestEngineState::setLuaHardSparkSkip(const float value) {
engine->engineState.luaHardSparkSkip = value;
}
void TestEngineState::setLuaFuelAdd(const float value) {
engine->engineState.lua.fuelAdd = value;
}
TestEngineState::TestEngineState() {
}

View File

@ -8,8 +8,13 @@ class TestEngineState {
public:
static TestEngineState& getInstance();
float getInjectionStage2Fraction() const;
floatms_t getInjectionDuration() const;
floatms_t getInjectionDurationStage2() const;
void setLuaSoftSparkSkip(float value);
void setLuaHardSparkSkip(float value);
void setLuaFuelAdd(float value);
private:
TestEngineState();
static TestEngineState instance;

View File

@ -18,4 +18,12 @@ void TestPersistentConfiguration::setIgnitionTable(const IgnitionTable& ignition
}
}
void TestPersistentConfiguration::setInjectorStagingTable(const InjectorStagingTable& injectorStaging) {
for (int i = 0; i < INJ_STAGING_COUNT; i++) {
for (int j = 0; j < INJ_STAGING_COUNT; j++) {
config->injectorStagingTable[i][j] = injectorStaging[i][j];
}
}
}
TestPersistentConfiguration TestPersistentConfiguration::instance;

View File

@ -5,12 +5,14 @@
#pragma once
using IgnitionTable = std::array<std::array<float, IGN_LOAD_COUNT>, IGN_RPM_COUNT>;
using InjectorStagingTable = std::array<std::array<uint8_t, INJ_STAGING_COUNT>, INJ_STAGING_COUNT>;
class TestPersistentConfiguration {
public:
static TestPersistentConfiguration& getInstance();
void setIgnitionTable(const IgnitionTable& ignitions);
void setInjectorStagingTable(const InjectorStagingTable& ingectorStaging);
private:
static TestPersistentConfiguration instance;
};