diff --git a/firmware/console/binary/tunerstudio_configuration.h b/firmware/console/binary/tunerstudio_configuration.h index 7e487b92f5..5692e7dea4 100644 --- a/firmware/console/binary/tunerstudio_configuration.h +++ b/firmware/console/binary/tunerstudio_configuration.h @@ -85,25 +85,27 @@ typedef struct { egt_values_s egtValues; float rpmAcceleration; float massAirFlowValue; - float veValue; // current volumetric efficiency + float veValue; // current volumetric efficiency, offset 112 float deltaTps; int triggerErrorsCounter; float currentMapAccelDelta; - float tpsAccelFuel; + float tpsAccelFuel; // offset 128 float baroCorrection; float pedalPosition; float injectorDutyCycle; int knockCount; - float fuelLevel; + float fuelTankGauge; float knockLevel; int totalTriggerErrorCounter; - float wallFuelAmount; - float totalFuelCorrection; - floatms_t wallFuelCorrection; + float wallFuelAmount; // 160 + float iatCorrection; // 164 + floatms_t wallFuelCorrection; // 168 float idlePosition; float currentTargetAfr; float chargeAirMass; - int unused3[3]; + float cltCorrection; + float runningFuel; + int unused3[1]; } TunerStudioOutputChannels; #endif /* TUNERSTUDIO_CONFIGURATION_H_ */ diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index 354ce5d69d..17f60879a7 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -568,7 +568,6 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_ float intake = getIntakeAirTemperature(PASS_ENGINE_PARAMETER_F); float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_F); - float baseFuelMs = getBaseFuel(rpm PASS_ENGINE_PARAMETER); // header tsOutputChannels->tsConfigVersion = TS_FILE_VERSION; @@ -595,7 +594,7 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_ tsOutputChannels->engineLoad = engineLoad; tsOutputChannels->rpmAcceleration = engine->rpmCalculator.getRpmAcceleration(); tsOutputChannels->currentMapAccelDelta = engine->mapAccelEnrichment.getMapEnrichment(PASS_ENGINE_PARAMETER_F) * 100 / getMap(); - tsOutputChannels->tpsAccelFuel = engine->tpsAccelEnrichment.getTpsEnrichment(PASS_ENGINE_PARAMETER_F); + tsOutputChannels->tpsAccelFuel = engine->engineState.tpsAccelEnrich; tsOutputChannels->deltaTps = engine->tpsAccelEnrichment.getDelta(); tsOutputChannels->triggerErrorsCounter = engine->triggerCentral.triggerState.totalTriggerErrorCounter; tsOutputChannels->baroCorrection = engine->engineState.baroCorrection; @@ -603,13 +602,16 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_ tsOutputChannels->knockCount = engine->knockCount; tsOutputChannels->knockLevel = engine->knockVolts; tsOutputChannels->injectorDutyCycle = getInjectorDutyCycle(rpm PASS_ENGINE_PARAMETER); - tsOutputChannels->fuelLevel = engine->engineState.fuelLevel; + tsOutputChannels->fuelTankGauge = engine->engineState.fuelTankGauge; tsOutputChannels->hasFatalError = hasFirmwareError(); tsOutputChannels->totalTriggerErrorCounter = engine->triggerCentral.triggerState.totalTriggerErrorCounter; tsOutputChannels->wallFuelAmount = wallFuel.getWallFuel(0); - tsOutputChannels->totalFuelCorrection = engine->totalFuelCorrection; - tsOutputChannels->wallFuelCorrection = engine->wallFuelCorrection; + tsOutputChannels->iatCorrection = ENGINE(engineState.iatFuelCorrection); + tsOutputChannels->cltCorrection = ENGINE(engineState.cltFuelCorrection); + tsOutputChannels->runningFuel = ENGINE(engineState.runningFuel); + + tsOutputChannels->wallFuelCorrection = engine->wallFuelCorrection; tsOutputChannels->checkEngine = hasErrorCodes(); #if EFI_PROD_CODE || defined(__DOXYGEN__) @@ -651,7 +653,7 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_ float timing = engine->engineState.timingAdvance; tsOutputChannels->ignitionAdvance = timing > 360 ? timing - 720 : timing; tsOutputChannels->sparkDwell = ENGINE(engineState.sparkDwell); - tsOutputChannels->baseFuel = baseFuelMs; + tsOutputChannels->baseFuel = engine->engineState.baseFuel; tsOutputChannels->pulseWidthMs = ENGINE(actualLastInjection); tsOutputChannels->crankingFuelMs = getCrankingFuel(PASS_ENGINE_PARAMETER_F); tsOutputChannels->chargeAirMass = engine->engineState.airMass; diff --git a/firmware/controllers/algo/engine.cpp b/firmware/controllers/algo/engine.cpp index 1e7ea23b9c..c6468b6cc4 100644 --- a/firmware/controllers/algo/engine.cpp +++ b/firmware/controllers/algo/engine.cpp @@ -43,7 +43,7 @@ void Engine::updateSlowSensors() { if (engineConfiguration->fuelLevelSensor != EFI_ADC_NONE) { float fuelLevelVoltage = getVoltageDivided("fuel", engineConfiguration->fuelLevelSensor); - engineState.fuelLevel = interpolate(boardConfiguration->fuelLevelEmptyTankVoltage, 0, + engineState.fuelTankGauge = interpolate(boardConfiguration->fuelLevelEmptyTankVoltage, 0, boardConfiguration->fuelLevelFullTankVoltage, 100, fuelLevelVoltage); } diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index 694515c0d7..4e546cb2b3 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -96,7 +96,7 @@ public: /** * that's fuel in tank - just a gauge */ - percent_t fuelLevel; + percent_t fuelTankGauge; ThermistorMath iatCurve; ThermistorMath cltCurve; @@ -139,6 +139,13 @@ public: */ float baseFuel; + /** + * Fuel with CLT, IAT and TPS acceleration corrections. + */ + float runningFuel; + + float tpsAccelEnrich; + angle_t injectionOffset; }; @@ -207,7 +214,6 @@ public: * Fuel injection duration for current engine cycle, without wall wetting */ floatms_t fuelMs; - float totalFuelCorrection; floatms_t wallFuelCorrection; /** diff --git a/firmware/controllers/algo/fuel_math.cpp b/firmware/controllers/algo/fuel_math.cpp index 16932917bb..fd86ad6983 100644 --- a/firmware/controllers/algo/fuel_math.cpp +++ b/firmware/controllers/algo/fuel_math.cpp @@ -70,8 +70,9 @@ float getRealMafFuel(float airSpeed, int rpm DECLARE_ENGINE_PARAMETER_S) { return 1000 * fuelMassGramm / injectorFlowRate; } +// todo: rename this method since it's now base+TPSaccel floatms_t getBaseFuel(int rpm DECLARE_ENGINE_PARAMETER_S) { - floatms_t tpsAccelEnrich = ENGINE(tpsAccelEnrichment.getTpsEnrichment(PASS_ENGINE_PARAMETER_F)); + ENGINE(engineState.tpsAccelEnrich) = ENGINE(tpsAccelEnrichment.getTpsEnrichment(PASS_ENGINE_PARAMETER_F)); if (CONFIG(algorithm) == LM_SPEED_DENSITY) { engine->engineState.baseFuel = getSpeedDensityFuel(rpm PASS_ENGINE_PARAMETER); @@ -82,7 +83,7 @@ floatms_t getBaseFuel(int rpm DECLARE_ENGINE_PARAMETER_S) { engine->engineState.baseFuel = engine->engineState.baseTableFuel; } - return tpsAccelEnrich + engine->engineState.baseFuel; + return ENGINE(engineState.tpsAccelEnrich) + ENGINE(engineState.baseFuel); } float getinjectionOffset(int rpm DECLARE_ENGINE_PARAMETER_S) { @@ -134,9 +135,9 @@ floatms_t getRunningFuel(floatms_t baseFuel, int rpm DECLARE_ENGINE_PARAMETER_S) float iatCorrection = ENGINE(engineState.iatFuelCorrection); float cltCorrection = ENGINE(engineState.cltFuelCorrection); - engine->totalFuelCorrection = cltCorrection * iatCorrection; + ENGINE(engineState.runningFuel) = baseFuel * iatCorrection * cltCorrection; - return baseFuel * engine->totalFuelCorrection; + return ENGINE(engineState.runningFuel); } /** diff --git a/firmware/rusefi.cpp b/firmware/rusefi.cpp index 6db015cbd2..58250795e1 100644 --- a/firmware/rusefi.cpp +++ b/firmware/rusefi.cpp @@ -275,5 +275,5 @@ int getRusEfiVersion(void) { return 123; // this is here to make the compiler happy about the unused array if (UNUSED_CCM_SIZE[0] * 0 != 0) return 3211; // this is here to make the compiler happy about the unused array - return 20151224; + return 20151226; } diff --git a/java_console/models/src/com/rusefi/core/Sensor.java b/java_console/models/src/com/rusefi/core/Sensor.java index de39c97314..85b3303452 100644 --- a/java_console/models/src/com/rusefi/core/Sensor.java +++ b/java_console/models/src/com/rusefi/core/Sensor.java @@ -66,7 +66,6 @@ public enum Sensor { DUTY0("Duty0", SensorCategory.SNIFFING, "%", 0, 100, BackgroundColor.RED), DUTY1("Duty1", SensorCategory.SNIFFING, "%", 0, 100, BackgroundColor.RED), FUEL("Fuel", SensorCategory.OPERATIONS, "ms", 0, 30), - FUEL_BASE("Fuel Base", SensorCategory.OPERATIONS, "ms", 0, 30), FUEL_IAT("F IAT", SensorCategory.OPERATIONS, "", 0, 10), FUEL_CLT("F CLT", SensorCategory.OPERATIONS, "", 0, 10), FUEL_LAG("F Lag", SensorCategory.OPERATIONS, "", 0, 30), @@ -86,6 +85,7 @@ public enum Sensor { INJECTOR_3_DWELL("inj #3", SensorCategory.SNIFFING), INJECTOR_4_DWELL("inj #4", SensorCategory.SNIFFING), + FUEL_BASE(SensorCategory.OPERATIONS, FieldType.FLOAT, 48, BackgroundColor.MUD, 0, 30, "ms"), T_CHARGE(SensorCategory.OPERATIONS, FieldType.FLOAT, 52, BackgroundColor.MUD, 30, 140), DWELL(SensorCategory.OPERATIONS, FieldType.FLOAT, 60, BackgroundColor.MUD, 1, 10), CURRENT_VE(SensorCategory.OPERATIONS, FieldType.FLOAT, 112, BackgroundColor.MUD), @@ -93,11 +93,13 @@ public enum Sensor { TPS_ACCEL_FUEL(SensorCategory.OPERATIONS, FieldType.FLOAT, 128, BackgroundColor.MUD), Injector_duty(SensorCategory.OPERATIONS, FieldType.FLOAT, 140, BackgroundColor.MUD), WALL_FUEL(SensorCategory.OPERATIONS, FieldType.FLOAT, 160, BackgroundColor.MUD), - temperatureFuelCorrection(SensorCategory.OPERATIONS, FieldType.FLOAT, 164, BackgroundColor.MUD, 0, 5), + iatCorrection(SensorCategory.OPERATIONS, FieldType.FLOAT, 164, BackgroundColor.MUD, 0, 5), wallFuelCorrection(SensorCategory.OPERATIONS, FieldType.FLOAT, 168, BackgroundColor.MUD), idlePosition(SensorCategory.OPERATIONS, FieldType.FLOAT, 172, BackgroundColor.MUD), TARGET_AFR(SensorCategory.OPERATIONS, FieldType.FLOAT, 176, BackgroundColor.MUD), CHARGE_AIR_MASS(SensorCategory.OPERATIONS, FieldType.FLOAT, 180, BackgroundColor.MUD), + cltCorrection(SensorCategory.OPERATIONS, FieldType.FLOAT, 184, BackgroundColor.MUD, 0, 5), + runningFuel(SensorCategory.OPERATIONS, FieldType.FLOAT, 188, BackgroundColor.MUD, 0, 15, "ms"), INJ_1_2_DELTA("inj 1-2 delta", SensorCategory.SNIFFING), INJ_3_4_DELTA("inj 3-4 delta", SensorCategory.SNIFFING), @@ -112,17 +114,21 @@ public enum Sensor { private final FieldType type; private final int offset; - Sensor(SensorCategory category, FieldType type, int offset, BackgroundColor color, double minValue, double maxValue) { + Sensor(SensorCategory category, FieldType type, int offset, BackgroundColor color, double minValue, double maxValue, String units) { name = name(); this.type = type; this.offset = offset; this.category = category; this.color = color; - units = "n/a"; + this.units = units; this.minValue = minValue; this.maxValue = maxValue; } + Sensor(SensorCategory category, FieldType type, int offset, BackgroundColor color, double minValue, double maxValue) { + this(category, type, offset, color, minValue, maxValue, "n/a"); + } + Sensor(SensorCategory category, FieldType type, int offset, BackgroundColor color) { this(category, type, offset, color, 0, 100); } diff --git a/java_console/ui/src/com/rusefi/ui/FormulasPane.java b/java_console/ui/src/com/rusefi/ui/FormulasPane.java index 7913d53411..079cd3d55d 100644 --- a/java_console/ui/src/com/rusefi/ui/FormulasPane.java +++ b/java_console/ui/src/com/rusefi/ui/FormulasPane.java @@ -6,6 +6,8 @@ import com.rusefi.config.Fields; import com.rusefi.core.Sensor; import com.rusefi.core.SensorCentral; import com.rusefi.ui.config.ConfigField; +import com.rusefi.ui.util.UiUtils; +import org.jetbrains.annotations.NotNull; import org.scilab.forge.jlatexmath.TeXConstants; import org.scilab.forge.jlatexmath.TeXFormula; import org.scilab.forge.jlatexmath.TeXIcon; @@ -16,24 +18,55 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; +import static com.rusefi.ui.util.LocalizedMessages.PAUSE; + public class FormulasPane { private final JPanel content = new JPanel(new BorderLayout()); private final JPanel centerProxy = new JPanel(new BorderLayout()); + private final String newLine = "\r\n \\\\ "; + private boolean isPaused; public FormulasPane() { content.add(centerProxy, BorderLayout.CENTER); + final JButton pauseButton = new JButton(PAUSE.getMessage()); + pauseButton.setMnemonic('p'); + pauseButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + isPaused = !isPaused; + UiUtils.setPauseButtonText(pauseButton, isPaused); + } + }); + JPanel top = new JPanel(new FlowLayout()); + top.add(pauseButton); + content.add(top, BorderLayout.NORTH); + updateFormula(); new Timer(200, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - updateFormula(); + if (!isPaused) + updateFormula(); } }).start(); } - private void updateFormula() { + enum engine_load_mode_e { + LM_PLAIN_MAF("Plain MAF"), + LM_ALPHA_N("Alpha-N/TPS"), + LM_MAP("Plain MAP"), + LM_SPEED_DENSITY("Speed Density/MAP"), + LM_REAL_MAF("MAF"); + private final String title; + + engine_load_mode_e(String title) { + this.title = title; + } + } + + private void updateFormula() { BinaryProtocol bp = BinaryProtocol.instance; if (bp == null) return; @@ -41,8 +74,32 @@ public class FormulasPane { if (ci == null) return; + int algorithm = ConfigField.getValue(ci, Fields.ALGORITHM).intValue(); + engine_load_mode_e algo = engine_load_mode_e.values()[algorithm]; + String page; + if (algo == engine_load_mode_e.LM_SPEED_DENSITY) { + page = getSpeedDensity(ci); + } else { + page = "todo"; + } + TeXFormula formula = new TeXFormula("\r\n" + + algo.title + newLine + newLine + newLine + page + ""); + TeXIcon icon = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, 20); + + BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = image.createGraphics(); + g2.setColor(Color.white); + g2.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight()); + JLabel label = new JLabel(icon); + + centerProxy.removeAll(); + centerProxy.add(label, BorderLayout.CENTER); + } + + @NotNull + private String getSpeedDensity(ConfigurationImage ci) { String IAT = oneDecimal(Sensor.IAT); String MAP = oneDecimal(Sensor.MAP); String T_CHARGE = oneDecimal(Sensor.T_CHARGE); @@ -57,7 +114,7 @@ public class FormulasPane { float displacement = (Float) ConfigField.getValue(ci, Fields.DISPLACEMENT); int cylinderCount = (int) ConfigField.getValue(ci, Fields.CYLINDERSCOUNT); String cylinderDisplacement = oneDecimal(displacement / cylinderCount); - String injectorFlow = oneDecimal((float)ConfigField.getValue(ci, Fields.INJECTOR_FLOW)); + String injectorFlow = oneDecimal((float) ConfigField.getValue(ci, Fields.INJECTOR_FLOW)); String tCharge = "$Tcharge=f(CLT=" + oneDecimal(Sensor.CLT) + "C,IAT=" + IAT + "C,TPS=" + tpsStr + "\\%, RPM = " + RPM + ")=" + T_CHARGE + "C$"; @@ -71,29 +128,30 @@ public class FormulasPane { chargeAirMass + "$"; - String injTime = "$Injection_Time (ms) = \\frac{" + + String baseFuelStr = oneDecimal(Sensor.FUEL_BASE); + String baseFuel = "$Base_Fuel (ms) = \\frac{" + "($Airmass = " + chargeAirMass + ")" + "}{" + "(TargetAFR (" + rpm_map + ") = " + TARGET_AFR + ")" + " * (injectorFlow = " + injectorFlow + " cc/min)" + - "} = " + "yyy" + "ms$"; + "} = " + baseFuelStr + "ms$"; - String newLine = "\r\n \\\\ "; - String page = tCharge + newLine + newLine + newLine + - mCharge + newLine + newLine + newLine + + String IATcorr = oneDecimal(Sensor.iatCorrection); + String CLTcorr = oneDecimal(Sensor.cltCorrection); + String tpsAccel = oneDecimal(Sensor.TPS_ACCEL_FUEL); + + String runningFuel = oneDecimal(Sensor.runningFuel); + + String tempCorrections = " * cltCorr(" + CLTcorr + ") * iatCorr(" + IATcorr + ")"; + + String injTime = "$Fuel (ms) = " + + "(Base_Fuel (" + baseFuelStr + "ms) + Tps_Accel_Corr = (" + tpsAccel + "ms))" + tempCorrections + + " = " + runningFuel + "ms$"; + + return tCharge + newLine + + mCharge + newLine + + baseFuel + newLine + injTime + newLine; - - TeXFormula formula = new TeXFormula(page); - TeXIcon icon = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, 20); - - BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics2D g2 = image.createGraphics(); - g2.setColor(Color.white); - g2.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight()); - JLabel label = new JLabel(icon); - - centerProxy.removeAll(); - centerProxy.add(label, BorderLayout.CENTER); } private String oneDecimal(Sensor sensor) {