parent
ec83526370
commit
5731cdd6dc
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
//
|
||||
// Created by kifir on 11/19/24.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
using BattLagCorrCurve = std::array<float, VBAT_INJECTOR_CURVE_SIZE>;
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue