diff --git a/firmware/controllers/algo/airmass/lua_airmass.h b/firmware/controllers/algo/airmass/lua_airmass.h new file mode 100644 index 0000000000..3250ebde64 --- /dev/null +++ b/firmware/controllers/algo/airmass/lua_airmass.h @@ -0,0 +1,17 @@ +#pragma once + +#include "airmass.h" + +class LuaAirmass final : public AirmassModelBase { +public: + AirmassResult getAirmass(int /*rpm*/) override { + return m_airmass; + } + + void setAirmass(AirmassResult airmass) { + m_airmass = airmass; + } + +private: + AirmassResult m_airmass; +}; diff --git a/firmware/controllers/algo/fuel_math.cpp b/firmware/controllers/algo/fuel_math.cpp index be1d3293fa..0b85bd0482 100644 --- a/firmware/controllers/algo/fuel_math.cpp +++ b/firmware/controllers/algo/fuel_math.cpp @@ -38,6 +38,7 @@ #include "perf_trace.h" #include "sensor.h" #include "speed_density_base.h" +#include "lua_hooks.h" EXTERN_ENGINE; @@ -170,6 +171,9 @@ AirmassModelBase* getAirmassModel(engine_load_mode_e mode DECLARE_ENGINE_PARAMET case LM_SPEED_DENSITY: return &sdAirmass; case LM_REAL_MAF: return &mafAirmass; case LM_ALPHA_N: return &alphaNAirmass; +#if EFI_LUA + case LM_LUA: return &(getLuaAirmassModel()); +#endif #if EFI_UNIT_TEST case LM_MOCK: return engine->mockAirmassModel; #endif diff --git a/firmware/controllers/algo/rusefi_enums.h b/firmware/controllers/algo/rusefi_enums.h index f94d33ad6b..32e5c10135 100644 --- a/firmware/controllers/algo/rusefi_enums.h +++ b/firmware/controllers/algo/rusefi_enums.h @@ -501,6 +501,8 @@ typedef enum { LM_ALPHA_N = 5, + LM_LUA = 6, + // This mode is for unit testing only, so that tests don't have to rely on a particular real airmass mode LM_MOCK = 100, diff --git a/firmware/controllers/lua/lua_hooks.cpp b/firmware/controllers/lua/lua_hooks.cpp index 3007716af0..fd8df50c4f 100644 --- a/firmware/controllers/lua/lua_hooks.cpp +++ b/firmware/controllers/lua/lua_hooks.cpp @@ -7,6 +7,9 @@ #include "adc_inputs.h" #include "efilib.h" #include "tunerstudio_outputs.h" +#include "fuel_math.h" +#include "airmass.h" +#include "lua_airmass.h" #include "pwm_generator_logic.h" // Some functions lean on existing FSIO implementation @@ -64,6 +67,12 @@ static int lua_table3d(lua_State* l) { return 1; } +static LuaAirmass luaAirmass; + +AirmassModelBase& getLuaAirmassModel() { + return luaAirmass; +} + #if !EFI_UNIT_TEST static SimplePwm pwms[LUA_PWM_COUNT]; static OutputPin pins[LUA_PWM_COUNT]; @@ -177,6 +186,42 @@ static int lua_setDebug(lua_State* l) { return 0; } +static auto lua_getAirmassResolveMode(lua_State* l) { + if (lua_gettop(l) == 0) { + // zero args, return configured mode + return CONFIG(fuelAlgorithm); + } else { + return static_cast(luaL_checkinteger(l, 1)); + } +} + +static int lua_getAirmass(lua_State* l) { + auto airmassMode = lua_getAirmassResolveMode(l); + auto airmass = getAirmassModel(airmassMode); + + if (!airmass) { + return luaL_error(l, "null airmass"); + } + + auto rpm = Sensor::get(SensorType::Rpm).value_or(0); + auto result = airmass->getAirmass(rpm).CylinderAirmass; + + lua_pushnumber(l, result); + return 1; +} + +static int lua_setAirmass(lua_State* l) { + float airmass = luaL_checknumber(l, 1); + float engineLoadPercent = luaL_checknumber(l, 2); + + airmass = clampF(0, airmass, 10); + engineLoadPercent = clampF(0, engineLoadPercent, 1000); + + luaAirmass.setAirmass({airmass, engineLoadPercent}); + + return 0; +} + static int lua_stopEngine(lua_State*) { doScheduleStopEngine(); @@ -199,6 +244,8 @@ void configureRusefiLuaHooks(lua_State* l) { lua_register(l, "getFan", lua_fan); lua_register(l, "getDigital", lua_getDigital); lua_register(l, "setDebug", lua_setDebug); + lua_register(l, "getAirmass", lua_getAirmass); + lua_register(l, "setAirmass", lua_setAirmass); lua_register(l, "stopEngine", lua_stopEngine); #endif diff --git a/firmware/controllers/lua/lua_hooks.h b/firmware/controllers/lua/lua_hooks.h index ca2bca57c6..6e2f6dde8c 100644 --- a/firmware/controllers/lua/lua_hooks.h +++ b/firmware/controllers/lua/lua_hooks.h @@ -1,4 +1,8 @@ #pragma once +struct lua_State; void configureRusefiLuaHooks(lua_State*); void luaDeInitPins(); + +struct AirmassModelBase; +AirmassModelBase& getLuaAirmassModel(); diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 2ba2e4de2e..147818d4a7 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -616,7 +616,7 @@ end_struct int sensorSnifferRpmThreshold;+Disable sensor sniffer above this rpm;"RPM", 1, 0, 0, 30000, 0 int rpmHardLimit;set rpm_hard_limit X;"rpm", 1, 0, 0, 20000, 2 -#define engine_load_mode_e_enum "INVALID", "INVALID", "INVALID", "Speed Density", "MAF Air Charge", "Alpha-N", "INVALID" +#define engine_load_mode_e_enum "INVALID", "INVALID", "INVALID", "Speed Density", "MAF Air Charge", "Alpha-N", "Lua" custom engine_load_mode_e 4 bits, U32, @OFFSET@, [0:2], @@engine_load_mode_e_enum@@