diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index 433517b674..694f216917 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -134,12 +134,12 @@ void printSensors(Engine *engine) { reportSensorF("afr", getAfr(), 2); reportSensorF("vref", getVRef(), 2); - reportSensorF("vbatt", getVBatt(), 2); + reportSensorF("vbatt", getVBatt(engineConfiguration), 2); reportSensorF("TRG_0_DUTY", getTriggerDutyCycle(0), 2); reportSensorF("TRG_1_DUTY", getTriggerDutyCycle(1), 2); - reportSensorF(getCaption(LP_THROTTLE), getTPS(engine->engineConfiguration), 2); + reportSensorF(getCaption(LP_THROTTLE), getTPS(engineConfiguration), 2); if (engineConfiguration->hasCltSensor) { reportSensorF(getCaption(LP_ECT), getCoolantTemperature(engine), 2); @@ -173,7 +173,7 @@ void printState(Engine *engine, int currentCkpEventCounter) { debugFloat(&logger, "fuel_base", baseFuel, 2); // debugFloat(&logger, "fuel_iat", getIatCorrection(getIntakeAirTemperature()), 2); // debugFloat(&logger, "fuel_clt", getCltCorrection(getCoolantTemperature()), 2); - debugFloat(&logger, "fuel_lag", getInjectorLag(engineConfiguration, getVBatt()), 2); + debugFloat(&logger, "fuel_lag", getInjectorLag(engineConfiguration, getVBatt(engineConfiguration)), 2); debugFloat(&logger, "fuel", getFuelMs(rpm, engine), 2); debugFloat(&logger, "timing", getAdvance(rpm, engineLoad), 2); @@ -319,7 +319,7 @@ static void showFuelInfo2(float rpm, float engineLoad, Engine *engine) { if (engine->rpmCalculator->isRunning()) { float iatCorrection = getIatCorrection(engineConfiguration, getIntakeAirTemperature(engine)); float cltCorrection = getCltCorrection(engineConfiguration, getCoolantTemperature(engine)); - float injectorLag = getInjectorLag(engineConfiguration, getVBatt()); + float injectorLag = getInjectorLag(engineConfiguration, getVBatt(engineConfiguration)); scheduleMsg(&logger2, "rpm=%f engineLoad=%f", rpm, engineLoad); scheduleMsg(&logger2, "baseFuel=%f", baseFuelMs); @@ -428,7 +428,7 @@ void updateTunerStudioState(Engine *engine, TunerStudioOutputChannels *tsOutputC tsOutputChannels->throttle_positon = tps; tsOutputChannels->mass_air_flow = getMaf(); tsOutputChannels->air_fuel_ratio = getAfr(); - tsOutputChannels->v_batt = getVBatt(); + tsOutputChannels->v_batt = getVBatt(engineConfiguration); tsOutputChannels->tsConfigVersion = TS_FILE_VERSION; tsOutputChannels->tpsADC = getTPS10bitAdc(); tsOutputChannels->atmospherePressure = getBaroPressure(); diff --git a/firmware/controllers/algo/fuel_math.cpp b/firmware/controllers/algo/fuel_math.cpp index 01af908996..061d2bcfa0 100644 --- a/firmware/controllers/algo/fuel_math.cpp +++ b/firmware/controllers/algo/fuel_math.cpp @@ -81,7 +81,7 @@ float getFuelMs(int rpm, Engine *engine) { float fuelPerCycle = getRunningFuel(baseFuel, engine, rpm); theoreticalInjectionLength = fuelPerCycle / getNumberOfInjections(engineConfiguration, engine->engineConfiguration->injectionMode); } - float injectorLag = getInjectorLag(engineConfiguration, getVBatt()); + float injectorLag = getInjectorLag(engineConfiguration, getVBatt(engineConfiguration)); return theoreticalInjectionLength + injectorLag; } diff --git a/firmware/controllers/core/le_functions.cpp b/firmware/controllers/core/le_functions.cpp index c01ee6f3c8..15099f093a 100644 --- a/firmware/controllers/core/le_functions.cpp +++ b/firmware/controllers/core/le_functions.cpp @@ -19,6 +19,7 @@ static LENameOrdinalPair leMoreEquals(LE_OPERATOR_MORE_OR_EQUAL, ">="); static LENameOrdinalPair leRpm(LE_METHOD_RPM, "rpm"); static LENameOrdinalPair leTps(LE_METHOD_TPS, "tps"); static LENameOrdinalPair leMaf(LE_METHOD_MAF, "maf"); +static LENameOrdinalPair leVBatt(LE_METHOD_VBATT, "vbatt"); static LENameOrdinalPair leFan(LE_METHOD_FAN, "fan"); static LENameOrdinalPair leCoolant(LE_METHOD_COOLANT, "coolant"); static LENameOrdinalPair leFanOnSetting(LE_METHOD_FAN_ON_SETTING, "fan_on_setting"); @@ -39,6 +40,12 @@ float getLEValue(Engine *engine, le_action_e action) { return engine->rpmCalculator->rpm(); case LE_METHOD_TIME_SINCE_BOOT: return getTimeNowSeconds(); + case LE_METHOD_FAN_OFF_SETTING: + return engine->engineConfiguration->fanOffTemperature; + case LE_METHOD_FAN_ON_SETTING: + return engine->engineConfiguration->fanOnTemperature; + case LE_METHOD_VBATT: + return getVBatt(engine->engineConfiguration); default: firmwareError("No value for %d", action); return NAN; diff --git a/firmware/controllers/core/le_functions.h b/firmware/controllers/core/le_functions.h index db0f716583..d534af2f9b 100644 --- a/firmware/controllers/core/le_functions.h +++ b/firmware/controllers/core/le_functions.h @@ -11,9 +11,19 @@ #include "engine.h" #include "logic_expression.h" +/** + * In human language that's + * (time_since_boot < 4) OR (rpm > 0) + */ // todo: the delay should probably be configurable? #define FUEL_PUMP_LOGIC "time_since_boot 4 < rpm 0 > OR" +/** + * In human language that's + * (fan and (coolant > fan_off_setting)) OR (coolant > fan_on_setting) + */ +#define FAN_CONTROL_LOGIC "todo" + float getLEValue(Engine *engine, le_action_e action); #endif /* LE_FUNCTIONS_H_ */ diff --git a/firmware/controllers/core/logic_expression.h b/firmware/controllers/core/logic_expression.h index 2f8598e6a2..4363694858 100644 --- a/firmware/controllers/core/logic_expression.h +++ b/firmware/controllers/core/logic_expression.h @@ -33,6 +33,7 @@ typedef enum { LE_METHOD_TPS = 106, LE_METHOD_MAF = 107, LE_METHOD_INTAKE_AIR = 108, + LE_METHOD_VBATT = 109, Force_4b_le_action = ENUM_SIZE_HACK, diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index c2ae7aabb8..bf04950e57 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -312,7 +312,7 @@ static void printAnalogInfo(void) { if (engineConfiguration->hasBaroSensor) { printAnalogChannelInfo("BARO", engineConfiguration->baroSensor.hwChannel); } - printAnalogChannelInfoExt("Vbatt", engineConfiguration->vbattAdcChannel, getVBatt()); + printAnalogChannelInfoExt("Vbatt", engineConfiguration->vbattAdcChannel, getVBatt(engineConfiguration)); } static THD_WORKING_AREA(csThreadStack, UTILITY_THREAD_STACK_SIZE); // declare thread stack diff --git a/firmware/controllers/lcd_controller.cpp b/firmware/controllers/lcd_controller.cpp index 01cc2ae2b4..ddb773bc63 100644 --- a/firmware/controllers/lcd_controller.cpp +++ b/firmware/controllers/lcd_controller.cpp @@ -33,7 +33,7 @@ char * appendStr(char *ptr, const char *suffix) { static char * prepareVBattMapLine(engine_configuration_s *engineConfiguration, char *buffer) { char *ptr = buffer; *ptr++ = 'V'; - ptr = ftoa(ptr, getVBatt(), 10.0f); + ptr = ftoa(ptr, getVBatt(engineConfiguration), 10.0f); ptr = appendStr(ptr, " M"); ptr = ftoa(ptr, getRawMap(), 10.0f); diff --git a/firmware/controllers/sensors/voltage.c b/firmware/controllers/sensors/voltage.c index 0ef1ee6af4..c170b72c35 100644 --- a/firmware/controllers/sensors/voltage.c +++ b/firmware/controllers/sensors/voltage.c @@ -20,6 +20,6 @@ float getVRef(void) { return getVoltageDivided(ADC_CHANNEL_VREF); } -float getVBatt(void) { +float getVBatt(engine_configuration_s *engineConfiguration) { return getVoltage(engineConfiguration->vbattAdcChannel) * engineConfiguration->vbattDividerCoeff; } diff --git a/firmware/controllers/sensors/voltage.h b/firmware/controllers/sensors/voltage.h index 13e1ffe612..68c1c3f48c 100644 --- a/firmware/controllers/sensors/voltage.h +++ b/firmware/controllers/sensors/voltage.h @@ -11,6 +11,7 @@ #define VOLTAGE_H_ #include "main.h" +#include "engine_configuration.h" #ifdef __cplusplus extern "C" @@ -18,7 +19,7 @@ extern "C" #endif /* __cplusplus */ float getVRef(void); -float getVBatt(void); +float getVBatt(engine_configuration_s *engineConfiguration); #ifdef __cplusplus } diff --git a/firmware/controllers/settings.cpp b/firmware/controllers/settings.cpp index 26a4e331b1..7243c7b6c6 100644 --- a/firmware/controllers/settings.cpp +++ b/firmware/controllers/settings.cpp @@ -119,8 +119,12 @@ void printConfiguration(engine_configuration_s *engineConfiguration, engine_conf boolToString(engineConfiguration->isManualSpinningMode), boolToString(engineConfiguration->isCylinderCleanupEnabled)); - scheduleMsg(&logger, "crankingChargeAngle=%f", engineConfiguration->crankingChargeAngle); - scheduleMsg(&logger, "crankingTimingAngle=%f", engineConfiguration->crankingTimingAngle); + if (engineConfiguration->useConstantDwellDuringCranking) { + scheduleMsg(&logger, "ignitionDwellForCrankingMs=%f", engineConfiguration->ignitionDwellForCrankingMs); + } else { + scheduleMsg(&logger, "crankingChargeAngle=%f", engineConfiguration->crankingChargeAngle); + scheduleMsg(&logger, "crankingTimingAngle=%f", engineConfiguration->crankingTimingAngle); + } scheduleMsg(&logger, "globalTriggerAngleOffset=%f", engineConfiguration->globalTriggerAngleOffset); // scheduleMsg(&logger, "analogChartMode: %d", engineConfiguration->analogChartMode); @@ -131,8 +135,7 @@ void printConfiguration(engine_configuration_s *engineConfiguration, engine_conf scheduleMsg(&logger, "idlePin: mode %s @ %s freq=%d", getPin_output_mode_e(boardConfiguration->idleValvePinMode), hwPortname(boardConfiguration->idleValvePin), boardConfiguration->idleSolenoidFrequency); - scheduleMsg(&logger, "malfunctionIndicatorn: %s mode=%s", - hwPortname(boardConfiguration->malfunctionIndicatorPin), + scheduleMsg(&logger, "malfunctionIndicatorn: %s mode=%s", hwPortname(boardConfiguration->malfunctionIndicatorPin), pinModeToString(boardConfiguration->malfunctionIndicatorPinMode)); scheduleMsg(&logger, "fuelPumpPin: mode %s @ %s", getPin_output_mode_e(boardConfiguration->fuelPumpPinMode), @@ -306,7 +309,8 @@ static void printTPSInfo(void) { scheduleMsg(&logger, "tps min %d/max %d v=%f @%s%d", engineConfiguration->tpsMin, engineConfiguration->tpsMax, getTPSVoltage(), portname(port), pin); #endif - scheduleMsg(&logger, "current 10bit=%d value=%f rate=%f", getTPS10bitAdc(), getTPS(engineConfiguration), getTpsRateOfChange()); + scheduleMsg(&logger, "current 10bit=%d value=%f rate=%f", getTPS10bitAdc(), getTPS(engineConfiguration), + getTpsRateOfChange()); } static void printTemperatureInfo(void) { diff --git a/java_console/models/src/com/autsia/bracer/BracerParser.java b/java_console/models/src/com/autsia/bracer/BracerParser.java index 1407a9d05a..babe49b027 100644 --- a/java_console/models/src/com/autsia/bracer/BracerParser.java +++ b/java_console/models/src/com/autsia/bracer/BracerParser.java @@ -20,10 +20,7 @@ package com.autsia.bracer; import java.text.ParseException; -import java.util.Collection; -import java.util.Collections; -import java.util.Stack; -import java.util.StringTokenizer; +import java.util.*; /** * Class for parsing and evaluating math expressions @@ -186,12 +183,17 @@ public class BracerParser { case "/": stackAnswer.push(Double.toString(b / (a))); break; + case ">": + stackAnswer.push(Integer.toString(b > a ? 1 : 0)); + break; case "|": stackAnswer.push(String.valueOf(aBoolean || bBoolean ? "1" : "0")); break; case "&": stackAnswer.push(String.valueOf(aBoolean && bBoolean ? "1" : "0")); break; + default: + throw new IllegalStateException("Do not know " + token); } } else if (isFunction(token)) { Double a = Double.valueOf(stackAnswer.pop()); @@ -357,4 +359,15 @@ public class BracerParser { } return 2; } + + public String getRusEfi() { + List list = new ArrayList<>(getStackRPN()); + ListIterator li = list.listIterator(list.size()); + List reverse = new ArrayList<>(); + while (li.hasPrevious()) { + reverse.add(li.previous()); + } + String result = reverse.toString(); + return result.substring(1, result.length() - 1); + } } diff --git a/java_console/models/src/com/autsia/bracer/test/BracerParserTest.java b/java_console/models/src/com/autsia/bracer/test/BracerParserTest.java index c043dba092..9fc308e80a 100644 --- a/java_console/models/src/com/autsia/bracer/test/BracerParserTest.java +++ b/java_console/models/src/com/autsia/bracer/test/BracerParserTest.java @@ -25,6 +25,8 @@ import org.junit.Test; import com.autsia.bracer.BracerParser; +import static org.junit.Assert.assertEquals; + /** * Test class. * User: Dmytro @@ -43,55 +45,69 @@ public class BracerParserTest { @Test public void testEvaluateNoVar() throws Exception { bracerParser.parse(INPUT_NOVAR); - Assert.assertEquals("-0.6570194619480038", bracerParser.evaluate()); + assertEquals("-0.6570194619480038", bracerParser.evaluate()); } @Test public void testSimpleBoolean() throws Exception { bracerParser.parse("true or false"); - Assert.assertEquals("1", bracerParser.evaluate()); + assertEquals("1", bracerParser.evaluate()); + assertEquals("1, 0, |", bracerParser.getRusEfi()); + + bracerParser.parse("true > false"); + assertEquals("1", bracerParser.evaluate()); + assertEquals("1, 0, >", bracerParser.getRusEfi()); + + bracerParser.parse("(true > false)"); + assertEquals("1", bracerParser.evaluate()); + assertEquals("1, 0, >", bracerParser.getRusEfi()); + + bracerParser.parse("(rpm > false)"); + // todo: that's weird + assertEquals("0, >, rpm", bracerParser.getRusEfi()); } @Test public void testBoolean() throws Exception { bracerParser.parse("( ( true and ( false or ( true and ( ( true ) or ( false ) ) ) ) ) and ( ( false ) ) )"); - Assert.assertEquals("0", bracerParser.evaluate()); + assertEquals("0", bracerParser.evaluate()); Collection stackRPN = bracerParser.getStackRPN(); - Assert.assertEquals("[&, 0, &, |, &, |, 0, 1, 1, 0, 1]", stackRPN.toString()); + assertEquals("[&, 0, &, |, &, |, 0, 1, 1, 0, 1]", stackRPN.toString()); } @Test public void testBooleanNot1() throws Exception { bracerParser.parse("not( ( true and ( false or ( true and ( not( true ) or ( false ) ) ) ) ) and ( ( false ) ) )"); - Assert.assertEquals("1", bracerParser.evaluate()); + assertEquals("1", bracerParser.evaluate()); } @Test public void testRusEfi() throws ParseException { bracerParser.parse("(time_since_boot < 4) | (rpm > 0)"); + assertEquals("4, <, time_since_boot, 0, >, rpm, |", bracerParser.getRusEfi()); - Assert.assertEquals("[|, rpm, >, 0, time_since_boot, <, 4]", bracerParser.getStackRPN().toString()); - + bracerParser.parse("(fan and (coolant > fan_off_setting)) OR (coolant > fan_on_setting)"); + assertEquals("fan_off_setting, >, coolant, &, fan, fan_on_setting, >, coolant, OR", bracerParser.getRusEfi()); bracerParser.parse("(time_since_boot <= 4) | (rpm > 0)"); - Assert.assertEquals("[|, rpm, >, 0, time_since_boot, <=, 4]", bracerParser.getStackRPN().toString()); + assertEquals("4, <=, time_since_boot, 0, >, rpm, |", bracerParser.getRusEfi()); bracerParser.parse("(time_since_boot <= 4) | (rpm > 0)"); - Assert.assertEquals("[|, rpm, >, 0, time_since_boot, <=, 4]", bracerParser.getStackRPN().toString()); + assertEquals("4, <=, time_since_boot, 0, >, rpm, |", bracerParser.getRusEfi()); bracerParser.parse("(time_since_boot <= 4) OR (rpm > 0)"); - Assert.assertEquals("[OR, rpm, >, 0, time_since_boot, <=, 4]", bracerParser.getStackRPN().toString()); + assertEquals("4, <=, time_since_boot, 0, >, rpm, OR", bracerParser.getRusEfi()); } @Test public void testBooleanNot2() throws Exception { bracerParser.parse("(((true | false) & not(false)) | (true | false))"); - Assert.assertEquals("1", bracerParser.evaluate()); + assertEquals("1", bracerParser.evaluate()); Collection stackRPN = bracerParser.getStackRPN(); - Assert.assertEquals("[|, |, 0, 1, &, not, 0, |, 0, 1]", stackRPN.toString()); + assertEquals("[|, |, 0, 1, &, not, 0, |, 0, 1]", stackRPN.toString()); } } diff --git a/unit_tests/main.h b/unit_tests/main.h index d3580e2528..bc61b1a1a1 100644 --- a/unit_tests/main.h +++ b/unit_tests/main.h @@ -46,7 +46,6 @@ void assertTrueM(const char *msg, float actual); void assertFalse(float actual); void assertFalseM(const char *msg, float actual); -float getVBatt(void); float getMaf(void); #define systicks2ms(x) (0) diff --git a/unit_tests/test_fuel_map.cpp b/unit_tests/test_fuel_map.cpp index 5493c046da..e9e257a65a 100644 --- a/unit_tests/test_fuel_map.cpp +++ b/unit_tests/test_fuel_map.cpp @@ -78,7 +78,7 @@ void testFuelMap(void) { assertEqualsM("IAT", 2, iatCorrection); float cltCorrection = getCltCorrection(engineConfiguration, getCoolantTemperature(ð.engine)); assertEqualsM("CLT", 1, cltCorrection); - float injectorLag = getInjectorLag(engineConfiguration, getVBatt()); + float injectorLag = getInjectorLag(engineConfiguration, getVBatt(engineConfiguration)); assertEquals(0, injectorLag); testMafValue = 5;