mirror of https://github.com/rusefi/rusefi-1.git
commit
7db7c9487a
|
@ -595,6 +595,8 @@ case LM_REAL_MAF:
|
||||||
return "LM_REAL_MAF";
|
return "LM_REAL_MAF";
|
||||||
case LM_SPEED_DENSITY:
|
case LM_SPEED_DENSITY:
|
||||||
return "LM_SPEED_DENSITY";
|
return "LM_SPEED_DENSITY";
|
||||||
|
case LM_ALPHA_N_2:
|
||||||
|
return "LM_ALPHA_N_2";
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include "alphan_airmass.h"
|
||||||
|
#include "sensor.h"
|
||||||
|
|
||||||
|
AirmassResult AlphaNAirmass::getAirmass(int rpm) {
|
||||||
|
auto tps = Sensor::get(SensorType::Tps1);
|
||||||
|
|
||||||
|
if (!tps.Valid) {
|
||||||
|
// We are fully reliant on TPS - if the TPS fails, stop the engine.
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// In this case, VE directly describes the cylinder filling relative to the ideal
|
||||||
|
float ve = getVe(rpm, tps.Value);
|
||||||
|
|
||||||
|
// TODO: should this be barometric pressure and/or temperature compensated?
|
||||||
|
float airmass = getAirmassImpl(
|
||||||
|
ve / 100.0f,
|
||||||
|
101.325f, // std atmosphere pressure
|
||||||
|
273.0f + 20.0f // std atmosphere pressure
|
||||||
|
PASS_ENGINE_PARAMETER_SUFFIX
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
airmass,
|
||||||
|
tps.Value
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "speed_density_base.h"
|
||||||
|
|
||||||
|
class AlphaNAirmass : public SpeedDensityBase {
|
||||||
|
public:
|
||||||
|
AlphaNAirmass(const ValueProvider3D& veTable) : SpeedDensityBase(veTable) {}
|
||||||
|
|
||||||
|
AirmassResult getAirmass(int rpm) override;
|
||||||
|
};
|
|
@ -12,6 +12,7 @@ CONTROLLERS_ALGO_SRC_CPP = $(PROJECT_DIR)/controllers/algo/advance_map.cpp \
|
||||||
$(PROJECT_DIR)/controllers/gauges/lcd_menu_tree.cpp \
|
$(PROJECT_DIR)/controllers/gauges/lcd_menu_tree.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/event_registry.cpp \
|
$(PROJECT_DIR)/controllers/algo/event_registry.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/airmass/airmass.cpp \
|
$(PROJECT_DIR)/controllers/algo/airmass/airmass.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/algo/airmass/alphan_airmass.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/airmass/maf_airmass.cpp \
|
$(PROJECT_DIR)/controllers/algo/airmass/maf_airmass.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/airmass/speed_density_airmass.cpp \
|
$(PROJECT_DIR)/controllers/algo/airmass/speed_density_airmass.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/airmass/speed_density_base.cpp \
|
$(PROJECT_DIR)/controllers/algo/airmass/speed_density_base.cpp \
|
||||||
|
|
|
@ -733,6 +733,8 @@ case LM_REAL_MAF:
|
||||||
return "LM_REAL_MAF";
|
return "LM_REAL_MAF";
|
||||||
case LM_SPEED_DENSITY:
|
case LM_SPEED_DENSITY:
|
||||||
return "LM_SPEED_DENSITY";
|
return "LM_SPEED_DENSITY";
|
||||||
|
case LM_ALPHA_N_2:
|
||||||
|
return "LM_ALPHA_N_2";
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "airmass.h"
|
#include "airmass.h"
|
||||||
|
#include "alphan_airmass.h"
|
||||||
#include "maf_airmass.h"
|
#include "maf_airmass.h"
|
||||||
#include "speed_density_airmass.h"
|
#include "speed_density_airmass.h"
|
||||||
#include "fuel_math.h"
|
#include "fuel_math.h"
|
||||||
|
@ -171,11 +172,13 @@ float getInjectionDurationForAirmass(float airMass, float afr DECLARE_ENGINE_PAR
|
||||||
|
|
||||||
static SpeedDensityAirmass sdAirmass(veMap);
|
static SpeedDensityAirmass sdAirmass(veMap);
|
||||||
static MafAirmass mafAirmass(veMap);
|
static MafAirmass mafAirmass(veMap);
|
||||||
|
static AlphaNAirmass alphaNAirmass(veMap);
|
||||||
|
|
||||||
AirmassModelBase* getAirmassModel(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
AirmassModelBase* getAirmassModel(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||||
switch (CONFIG(fuelAlgorithm)) {
|
switch (CONFIG(fuelAlgorithm)) {
|
||||||
case LM_SPEED_DENSITY: return &sdAirmass;
|
case LM_SPEED_DENSITY: return &sdAirmass;
|
||||||
case LM_REAL_MAF: return &mafAirmass;
|
case LM_REAL_MAF: return &mafAirmass;
|
||||||
|
case LM_ALPHA_N_2: return &alphaNAirmass;
|
||||||
default: return nullptr;
|
default: return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,7 +196,9 @@ floatms_t getBaseFuel(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||||
|
|
||||||
floatms_t baseFuel;
|
floatms_t baseFuel;
|
||||||
|
|
||||||
if ((CONFIG(fuelAlgorithm) == LM_SPEED_DENSITY) || (engineConfiguration->fuelAlgorithm == LM_REAL_MAF)) {
|
if ((CONFIG(fuelAlgorithm) == LM_SPEED_DENSITY) ||
|
||||||
|
(engineConfiguration->fuelAlgorithm == LM_REAL_MAF) ||
|
||||||
|
(engineConfiguration->fuelAlgorithm == LM_ALPHA_N_2)) {
|
||||||
// airmass modes - get airmass first, then convert to fuel
|
// airmass modes - get airmass first, then convert to fuel
|
||||||
auto model = getAirmassModel(PASS_ENGINE_PARAMETER_SIGNATURE);
|
auto model = getAirmassModel(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||||
efiAssert(CUSTOM_ERR_ASSERT, model != nullptr, "Invalid airmass mode", 0.0f);
|
efiAssert(CUSTOM_ERR_ASSERT, model != nullptr, "Invalid airmass mode", 0.0f);
|
||||||
|
|
|
@ -443,6 +443,9 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
LM_REAL_MAF = 4,
|
LM_REAL_MAF = 4,
|
||||||
|
|
||||||
|
// todo: rename after LM_ALPHA_N is removed
|
||||||
|
LM_ALPHA_N_2 = 5,
|
||||||
|
|
||||||
Force_4_bytes_size_engine_load_mode = ENUM_32_BITS,
|
Force_4_bytes_size_engine_load_mode = ENUM_32_BITS,
|
||||||
} engine_load_mode_e;
|
} engine_load_mode_e;
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ float getEngineLoadT(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||||
case LM_SPEED_DENSITY:
|
case LM_SPEED_DENSITY:
|
||||||
return getMap(PASS_ENGINE_PARAMETER_SIGNATURE);
|
return getMap(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||||
case LM_ALPHA_N:
|
case LM_ALPHA_N:
|
||||||
|
case LM_ALPHA_N_2:
|
||||||
return Sensor::get(SensorType::Tps1).value_or(0);
|
return Sensor::get(SensorType::Tps1).value_or(0);
|
||||||
case LM_REAL_MAF:
|
case LM_REAL_MAF:
|
||||||
return getRealMaf(PASS_ENGINE_PARAMETER_SIGNATURE);
|
return getRealMaf(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||||
|
|
|
@ -457,7 +457,7 @@ int sensorSnifferRpmThreshold;+Disable sensor sniffer above this rpm;"RPM",
|
||||||
int rpmHardLimit;set rpm_hard_limit X;"rpm", 1, 0, 0, 20000.0, 2
|
int rpmHardLimit;set rpm_hard_limit X;"rpm", 1, 0, 0, 20000.0, 2
|
||||||
|
|
||||||
|
|
||||||
#define engine_load_mode_e_enum "MAF", "Alpha-N/TPS", "INVALID", "SPEED DENSITY", "MAF Air Charge", "INVALID", "INVALID"
|
#define engine_load_mode_e_enum "MAF", "Alpha-N/TPS", "INVALID", "SPEED DENSITY", "MAF Air Charge", "Alpha-N", "INVALID"
|
||||||
|
|
||||||
|
|
||||||
custom engine_load_mode_e 4 bits, U32, @OFFSET@, [0:2], @@engine_load_mode_e_enum@@
|
custom engine_load_mode_e 4 bits, U32, @OFFSET@, [0:2], @@engine_load_mode_e_enum@@
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fuel_math.h"
|
#include "fuel_math.h"
|
||||||
#include "maf_airmass.h"
|
|
||||||
#include "trigger_structure.h"
|
#include "trigger_structure.h"
|
||||||
#include "allsensors.h"
|
#include "allsensors.h"
|
||||||
#include "engine_math.h"
|
#include "engine_math.h"
|
||||||
|
@ -19,27 +18,6 @@
|
||||||
|
|
||||||
using ::testing::FloatNear;
|
using ::testing::FloatNear;
|
||||||
|
|
||||||
TEST(misc, testMafFuelMath) {
|
|
||||||
WITH_ENGINE_TEST_HELPER(FORD_ASPIRE_1996);
|
|
||||||
engineConfiguration->fuelAlgorithm = LM_REAL_MAF;
|
|
||||||
engineConfiguration->injector.flow = 200;
|
|
||||||
setAfrMap(config->afrTable, 13);
|
|
||||||
|
|
||||||
MockVp3d veTable;
|
|
||||||
// Ensure that the correct cell is read from the VE table
|
|
||||||
EXPECT_CALL(veTable, getValue(6000, FloatNear(70.9814f, EPS4D)))
|
|
||||||
.WillOnce(Return(75.0f));
|
|
||||||
|
|
||||||
MafAirmass dut(veTable);
|
|
||||||
INJECT_ENGINE_REFERENCE(&dut);
|
|
||||||
|
|
||||||
auto airmass = dut.getAirmassImpl(200, 6000);
|
|
||||||
|
|
||||||
// Check results
|
|
||||||
EXPECT_NEAR(0.277777f * 0.75f, airmass.CylinderAirmass, EPS4D);
|
|
||||||
EXPECT_NEAR(70.9814f, airmass.EngineLoadPercent, EPS4D);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(misc, testFuelMap) {
|
TEST(misc, testFuelMap) {
|
||||||
printf("Setting up FORD_ASPIRE_1996\r\n");
|
printf("Setting up FORD_ASPIRE_1996\r\n");
|
||||||
WITH_ENGINE_TEST_HELPER(FORD_ASPIRE_1996);
|
WITH_ENGINE_TEST_HELPER(FORD_ASPIRE_1996);
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
#include "engine_test_helper.h"
|
#include "engine_test_helper.h"
|
||||||
#include "fuel_math.h"
|
#include "fuel_math.h"
|
||||||
|
#include "alphan_airmass.h"
|
||||||
|
#include "maf_airmass.h"
|
||||||
|
#include "mocks.h"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
using ::testing::StrictMock;
|
||||||
|
using ::testing::FloatNear;
|
||||||
|
|
||||||
TEST(FuelMath, getStandardAirCharge) {
|
TEST(FuelMath, getStandardAirCharge) {
|
||||||
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||||
|
|
||||||
|
@ -29,3 +35,66 @@ TEST(FuelMath, getStandardAirCharge) {
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(4.782959f, getStandardAirCharge(PASS_ENGINE_PARAMETER_SIGNATURE));
|
EXPECT_FLOAT_EQ(4.782959f, getStandardAirCharge(PASS_ENGINE_PARAMETER_SIGNATURE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(AirmassModes, AlphaNNormal) {
|
||||||
|
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||||
|
// 4 cylinder 4 liter = easy math
|
||||||
|
engineConfiguration->specs.displacement = 4.0f;
|
||||||
|
engineConfiguration->specs.cylindersCount = 4;
|
||||||
|
|
||||||
|
StrictMock<MockVp3d> veTable;
|
||||||
|
|
||||||
|
EXPECT_CALL(veTable, getValue(1200, FloatNear(0.71f, EPS4D)))
|
||||||
|
.WillOnce(Return(35.0f));
|
||||||
|
|
||||||
|
AlphaNAirmass dut(veTable);
|
||||||
|
INJECT_ENGINE_REFERENCE(&dut);
|
||||||
|
|
||||||
|
Sensor::setMockValue(SensorType::Tps1, 0.71f);
|
||||||
|
|
||||||
|
// Mass of 1 liter of air * VE
|
||||||
|
float expectedAirmass = 1.2047f * 0.35f;
|
||||||
|
|
||||||
|
auto result = dut.getAirmass(1200);
|
||||||
|
EXPECT_NEAR(result.CylinderAirmass, expectedAirmass, EPS4D);
|
||||||
|
EXPECT_NEAR(result.EngineLoadPercent, 0.71f, EPS4D);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(AirmassModes, AlphaNFailedTps) {
|
||||||
|
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||||
|
|
||||||
|
// Shouldn't get called
|
||||||
|
StrictMock<MockVp3d> veTable;
|
||||||
|
|
||||||
|
AlphaNAirmass dut(veTable);
|
||||||
|
INJECT_ENGINE_REFERENCE(&dut);
|
||||||
|
|
||||||
|
// explicitly reset the sensor
|
||||||
|
Sensor::resetMockValue(SensorType::Tps1);
|
||||||
|
// Ensure that it's actually failed
|
||||||
|
ASSERT_FALSE(Sensor::get(SensorType::Tps1).Valid);
|
||||||
|
|
||||||
|
auto result = dut.getAirmass(1200);
|
||||||
|
EXPECT_EQ(result.CylinderAirmass, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(misc, MafNormal) {
|
||||||
|
WITH_ENGINE_TEST_HELPER(FORD_ASPIRE_1996);
|
||||||
|
engineConfiguration->fuelAlgorithm = LM_REAL_MAF;
|
||||||
|
engineConfiguration->injector.flow = 200;
|
||||||
|
setAfrMap(config->afrTable, 13);
|
||||||
|
|
||||||
|
MockVp3d veTable;
|
||||||
|
// Ensure that the correct cell is read from the VE table
|
||||||
|
EXPECT_CALL(veTable, getValue(6000, FloatNear(70.9814f, EPS4D)))
|
||||||
|
.WillOnce(Return(75.0f));
|
||||||
|
|
||||||
|
MafAirmass dut(veTable);
|
||||||
|
INJECT_ENGINE_REFERENCE(&dut);
|
||||||
|
|
||||||
|
auto airmass = dut.getAirmassImpl(200, 6000);
|
||||||
|
|
||||||
|
// Check results
|
||||||
|
EXPECT_NEAR(0.277777f * 0.75f, airmass.CylinderAirmass, EPS4D);
|
||||||
|
EXPECT_NEAR(70.9814f, airmass.EngineLoadPercent, EPS4D);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue