diff --git a/firmware/controllers/core/common_headers.h b/firmware/controllers/core/common_headers.h index c38305df68..dbdfa40778 100644 --- a/firmware/controllers/core/common_headers.h +++ b/firmware/controllers/core/common_headers.h @@ -39,6 +39,6 @@ #define DISPLAY_TEXT(x) #define DISPLAY_SENSOR(x) {} -#define DISPLAY_IF(x) {} +#define DISPLAY_IF(x) x #endif /* CONTROLLERS_CORE_COMMON_HEADERS_H_ */ diff --git a/firmware/controllers/math/speed_density.cpp b/firmware/controllers/math/speed_density.cpp index 2fb4eecca4..eb613c568b 100644 --- a/firmware/controllers/math/speed_density.cpp +++ b/firmware/controllers/math/speed_density.cpp @@ -37,7 +37,7 @@ float getTCharge(int rpm, float tps, float coolantTemp, float airTemp DECLARE_EN } - if ((engine->engineState./*DISPLAY_IF*/isTChargeAirModel = (CONFIG(tChargeMode) == TCHARGE_MODE_AIR_INTERP))) { + if ((engine->engineState.DISPLAY_IF(isTChargeAirModel) = (CONFIG(tChargeMode) == TCHARGE_MODE_AIR_INTERP))) { const floatms_t gramsPerMsToKgPerHour = (3600.0f * 1000.0f) / 1000.0f; // We're actually using an 'old' airMass calculated for the previous cycle, but it's ok, we're not having any self-excitaton issues floatms_t airMassForEngine = engine->engineState./***display*/airMass * CONFIG(specs.cylindersCount); @@ -45,20 +45,29 @@ float getTCharge(int rpm, float tps, float coolantTemp, float airTemp DECLARE_EN // And if the engine is stopped (0 rpm), then airFlow is also zero (avoiding NaN division) floatms_t airFlow = (rpm == 0) ? 0 : airMassForEngine * gramsPerMsToKgPerHour / getEngineCycleDuration(rpm PASS_ENGINE_PARAMETER_SUFFIX); // just interpolate between user-specified min and max coefs, based on the max airFlow value - engine->engineState.Tcharge_coff = interpolateClamped(0.0, CONFIG(tChargeAirCoefMin), CONFIG(tChargeAirFlowMax), CONFIG(tChargeAirCoefMax), airFlow); + DISPLAY_TEXT(interpolate_Air_Flow) + engine->engineState.DISPLAY_FIELD(airFlow) = airFlow; + DISPLAY_TEXT(Between) + engine->engineState.Tcharge_coff = interpolateClamped(0.0, + DISPLAY_TEXT(tChargeAirCoefMin) CONFIG(DISPLAY_CONFIG(tChargeAirCoefMin)), + DISPLAY_TEXT(tChargeAirFlowMax) CONFIG(DISPLAY_CONFIG(tChargeAirFlowMax)), + DISPLAY_TEXT(tChargeAirCoefMax) CONFIG(DISPLAY_CONFIG(tChargeAirCoefMax)), airFlow); // save it for console output (instead of MAF massAirFlow) - engine->engineState.airFlow = airFlow; } else/* DISPLAY_ELSE */ { // TCHARGE_MODE_RPM_TPS - DISPLAY_TEXT("interpolate(") + DISPLAY_TEXT(interpolate_RPM) DISPLAY_SENSOR(RPM) + DISPLAY_TEXT(and_TPS) DISPLAY_SENSOR(TPS) - float minRpmKcurrentTPS = interpolateMsg("minRpm", tpMin, CONFIG(DISPLAY_CONFIG(tChargeMinRpmMinTps)), tpMax, - CONFIG(DISPLAY_CONFIG(tChargeMinRpmMaxTps)), tps); + DISPLAY_TEXT(EOL) + DISPLAY_TEXT(Between) + float minRpmKcurrentTPS = interpolateMsg("minRpm", tpMin, + DISPLAY_TEXT(tChargeMinRpmMinTps) CONFIG(DISPLAY_CONFIG(tChargeMinRpmMinTps)), tpMax, DISPLAY_TEXT(EOL) + DISPLAY_TEXT(tChargeMinRpmMaxTps) CONFIG(DISPLAY_CONFIG(tChargeMinRpmMaxTps)), tps); float maxRpmKcurrentTPS = interpolateMsg("maxRpm", tpMin, CONFIG(DISPLAY_CONFIG(tChargeMaxRpmMinTps)), tpMax, CONFIG(DISPLAY_CONFIG(tChargeMaxRpmMaxTps)), tps); - DISPLAY_TEXT(")") + //ISPLAY_TEXT() engine->engineState.Tcharge_coff = interpolateMsg("Kcurr", rpmMin, minRpmKcurrentTPS, rpmMax, maxRpmKcurrentTPS, rpm); /* DISPLAY_ENDIF */ diff --git a/firmware/gen_config2.bat b/firmware/gen_config2.bat index 1248fea57e..83e4e18334 100644 --- a/firmware/gen_config2.bat +++ b/firmware/gen_config2.bat @@ -27,3 +27,9 @@ java -DSystemOut.name=gen_config2 ^ com.rusefi.ldmp.LiveDocsMetaParser ^ controllers/sensors/tps.cpp ^ "../" + +java -DSystemOut.name=gen_config2 ^ + -cp ../java_tools/ConfigDefinition.jar ^ + com.rusefi.ldmp.LiveDocsMetaParser ^ + controllers/math/speed_density.cpp ^ + "../" diff --git a/java_console/io/src/com/rusefi/ui/livedocs/LiveDocsRegistry.java b/java_console/io/src/com/rusefi/ui/livedocs/LiveDocsRegistry.java index 47f4ac5007..1d231a7360 100644 --- a/java_console/io/src/com/rusefi/ui/livedocs/LiveDocsRegistry.java +++ b/java_console/io/src/com/rusefi/ui/livedocs/LiveDocsRegistry.java @@ -3,7 +3,9 @@ package com.rusefi.ui.livedocs; import com.rusefi.binaryprotocol.BinaryProtocol; import com.rusefi.config.generated.Fields; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import static com.rusefi.binaryprotocol.BinaryProtocolCommands.COMMAND_GET_STRUCT; @@ -17,14 +19,14 @@ import static com.rusefi.binaryprotocol.IoHelper.swap16; public enum LiveDocsRegistry { INSTANCE; - private final Map liveDocs = new HashMap<>(); + private final List liveDocs = new ArrayList<>(); public void register(LiveDocHolder holder) { - liveDocs.put(holder.getId(), holder); + liveDocs.add(holder); } public void refresh(BinaryProtocol binaryProtocol) { - for (LiveDocHolder h : liveDocs.values()) { + for (LiveDocHolder h : liveDocs) { boolean visible = h.isVisible(); System.out.println(h + ": " + visible); if (visible) { diff --git a/java_console/models/src/com/rusefi/config/Field.java b/java_console/models/src/com/rusefi/config/Field.java index 24c5205f95..a0616127c6 100644 --- a/java_console/models/src/com/rusefi/config/Field.java +++ b/java_console/models/src/com/rusefi/config/Field.java @@ -188,7 +188,10 @@ public class Field { Objects.requireNonNull(ci); Number value; ByteBuffer wrapped = ci.getByteBuffer(getOffset(), type.getStorageSize()); - if (type == INT) { + if (bitOffset != NO_BIT_OFFSET) { + int packed = wrapped.getInt(); + value = (packed >> bitOffset) & 1; + } else if (type == INT) { value = wrapped.getInt(); } else if (type == INT16) { value = wrapped.getShort(); diff --git a/java_console/ui/src/com/rusefi/ldmp/generated/SpeedDensityMeta.java b/java_console/ui/src/com/rusefi/ldmp/generated/SpeedDensityMeta.java new file mode 100644 index 0000000000..5811b6370e --- /dev/null +++ b/java_console/ui/src/com/rusefi/ldmp/generated/SpeedDensityMeta.java @@ -0,0 +1,35 @@ +package com.rusefi.ldmp.generated; + +import com.rusefi.ldmp.*; + +public class SpeedDensityMeta { + public static final Request[] CONTENT = new Request[]{ + new IfRequest("isTChargeAirModel", + new Request[]{ + new TextRequest("interpolate_Air_Flow"), + new FieldRequest("airFlow"), + new TextRequest("Between"), + new TextRequest("tChargeAirCoefMin"), + new ConfigRequest("tChargeAirCoefMin"), + new TextRequest("tChargeAirFlowMax"), + new ConfigRequest("tChargeAirFlowMax"), + new TextRequest("tChargeAirCoefMax"), + new ConfigRequest("tChargeAirCoefMax"), +}, + new Request[]{ + new TextRequest("interpolate_RPM"), + new SensorRequest("RPM"), + new TextRequest("and_TPS"), + new SensorRequest("TPS"), + new TextRequest("EOL"), + new TextRequest("Between"), + new TextRequest("tChargeMinRpmMinTps"), + new ConfigRequest("tChargeMinRpmMinTps"), + new TextRequest("EOL"), + new TextRequest("tChargeMinRpmMaxTps"), + new ConfigRequest("tChargeMinRpmMaxTps"), + new ConfigRequest("tChargeMaxRpmMinTps"), + new ConfigRequest("tChargeMaxRpmMaxTps"), +}), + }; +} \ No newline at end of file diff --git a/java_console/ui/src/com/rusefi/ui/FormulasPane.java b/java_console/ui/src/com/rusefi/ui/FormulasPane.java index f804262a6a..d87e8b3e21 100644 --- a/java_console/ui/src/com/rusefi/ui/FormulasPane.java +++ b/java_console/ui/src/com/rusefi/ui/FormulasPane.java @@ -4,19 +4,14 @@ import com.opensr5.ConfigurationImage; import com.rusefi.FileLog; import com.rusefi.binaryprotocol.BinaryProtocol; import com.rusefi.binaryprotocol.BinaryProtocolHolder; -import com.rusefi.config.generated.EngineState; import com.rusefi.config.generated.Fields; -import com.rusefi.config.generated.ThermistorState; import com.rusefi.core.Sensor; import com.rusefi.core.SensorCentral; -import com.rusefi.ldmp.generated.ThermistorsMeta; -import com.rusefi.ldmp.generated.TpsMeta; import com.rusefi.ui.config.ConfigField; import com.rusefi.ui.livedocs.LiveDocPanel; import com.rusefi.ui.util.UiUtils; import com.rusefi.ui.widgets.IntGaugeLabel; import org.jetbrains.annotations.NotNull; -import org.putgemin.VerticalFlowLayout; import org.scilab.forge.jlatexmath.TeXConstants; import org.scilab.forge.jlatexmath.TeXFormula; import org.scilab.forge.jlatexmath.TeXIcon; @@ -43,20 +38,11 @@ public class FormulasPane { private final JPanel centerProxy = new JPanel(new BorderLayout()); private boolean isPaused; - private JPanel liveDocs = new JPanel(new VerticalFlowLayout()); + private JPanel liveDocs = LiveDocPanel.createLiveDocumentationPanel(); public FormulasPane() { content.add(centerProxy, BorderLayout.CENTER); - liveDocs.add(LiveDocPanel.getPanel("Coolant Sensor", "CLT", Fields.LDS_CLT_INDEX, - ThermistorState.VALUES, ThermistorsMeta.CONTENT)); - - liveDocs.add(LiveDocPanel.getPanel("Intake Air Sensor", "IAT", Fields.LDS_IAT_INDEX, - ThermistorState.VALUES, ThermistorsMeta.CONTENT)); - - liveDocs.add(LiveDocPanel.getPanel("Throttle Position Sensor", "", Fields.LDS_ENGINE_STATE_INDEX, - EngineState.VALUES, TpsMeta.CONTENT)); - centerProxy.add(new JLabel("Waiting for data..."), BorderLayout.CENTER); JButton saveImage = UiUtils.createSaveImageButton(); diff --git a/java_console/ui/src/com/rusefi/ui/livedocs/ActionPanel.java b/java_console/ui/src/com/rusefi/ui/livedocs/ActionPanel.java new file mode 100644 index 0000000000..d95f395a1d --- /dev/null +++ b/java_console/ui/src/com/rusefi/ui/livedocs/ActionPanel.java @@ -0,0 +1,44 @@ +package com.rusefi.ui.livedocs; + +import net.miginfocom.swing.MigLayout; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +public class ActionPanel { + List actionsList = new ArrayList<>(); + private final JPanel panel = new JPanel(new MigLayout()); + private JPanel currentLinePanel; + + public ActionPanel(String title) { + panel.setBorder(BorderFactory.createTitledBorder(title)); + } + + public ActionPanel(JPanel result, List combined) { + panel.add(result); + actionsList.addAll(combined); + } + + public JPanel getPanel() { + return panel; + } + + public void newLine() { + initIfNeeded(); + currentLinePanel = null; + } + + private void initIfNeeded() { + if (currentLinePanel == null) { + currentLinePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0)); + panel.add(currentLinePanel, "wrap"); + } + } + + public void addControl(JComponent component) { + initIfNeeded(); + currentLinePanel.add(component); + } +} diff --git a/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocPanel.java b/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocPanel.java index 4ca0382f23..7c942c8c9a 100644 --- a/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocPanel.java +++ b/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocPanel.java @@ -3,28 +3,30 @@ package com.rusefi.ui.livedocs; import com.opensr5.ConfigurationImage; import com.rusefi.binaryprotocol.BinaryProtocol; import com.rusefi.config.Field; +import com.rusefi.config.generated.EngineState; import com.rusefi.config.generated.Fields; -import com.rusefi.ldmp.ConfigRequest; -import com.rusefi.ldmp.FieldRequest; -import com.rusefi.ldmp.Request; -import com.rusefi.ldmp.TextRequest; -import net.miginfocom.swing.MigLayout; +import com.rusefi.config.generated.ThermistorState; +import com.rusefi.ldmp.*; +import com.rusefi.ldmp.generated.SpeedDensityMeta; +import com.rusefi.ldmp.generated.ThermistorsMeta; +import com.rusefi.ldmp.generated.TpsMeta; +import com.rusefi.ui.livedocs.controls.Toolbox; import org.jetbrains.annotations.NotNull; +import org.putgemin.VerticalFlowLayout; import javax.swing.*; import java.awt.*; -import java.util.*; +import java.util.ArrayList; import java.util.List; public class LiveDocPanel { @NotNull public static JPanel getPanel(String title, String instancePrefix, final int id, Field[] values, Request[] content) { - JPanel panel = new JPanel(new MigLayout()); - panel.setBorder(BorderFactory.createTitledBorder(title)); - List actions = createComponents(panel, content, values, instancePrefix); + ActionPanel ap = createComponents(title, content, values, instancePrefix); + JPanel panel = ap.getPanel(); - LiveDocHolder holder = new LiveDocHolder(id, actions, values) { + LiveDocHolder holder = new LiveDocHolder(id, ap.actionsList, values) { @Override public boolean isVisible() { boolean isVisible = !panel.getVisibleRect().isEmpty(); @@ -41,22 +43,23 @@ public class LiveDocPanel { return c.isVisible() && (parent == null || isRecursivelyVisible(parent)); } - private static List createComponents(JPanel panel, Request[] content, Field[] values, String instancePrefix) { - List actionsList = new ArrayList<>(); + private static ActionPanel createComponents(String title, Request[] content, Field[] values, String instancePrefix) { + ActionPanel result = new ActionPanel(title); + for (Request r : content) { if (r instanceof TextRequest) { TextRequest request = (TextRequest) r; if (request.isEol()) { - panel.add(new JLabel(), "wrap"); + result.newLine(); } else { - panel.add(new JLabel(request.getValue().replaceAll("_", " "))); + result.addControl(new JLabel(request.getValue().replaceAll("_", " "))); } } else if (r instanceof FieldRequest) { FieldRequest request = (FieldRequest) r; Field field = Field.findField(values, "", request.getField()); - JLabel label = new JLabel(field.getName()); - panel.add(label); - actionsList.add(new RefreshActions() { + JLabel label = new JLabel("*"); + result.addControl(label); + result.actionsList.add(new RefreshActions() { @Override public void refresh(BinaryProtocol bp, byte[] response) { Number fieldValue = field.getValue(new ConfigurationImage(response)); @@ -68,20 +71,90 @@ public class LiveDocPanel { ConfigRequest request = (ConfigRequest) r; Field field = Field.findField(Fields.VALUES, instancePrefix, request.getField()); - JLabel label = new JLabel(field.getName()); - actionsList.add(new RefreshActions() { + JLabel label = new JLabel("*"); + result.actionsList.add(new RefreshActions() { @Override public void refresh(BinaryProtocol bp, byte[] response) { String value = field.getAnyValue(bp.getController()).toString(); label.setText(value); } }); - panel.add(label); + result.addControl(label); + } else if (r instanceof SensorRequest) { + SensorRequest request = (SensorRequest) r; + result.addControl(new JLabel("*")); + } else if (r instanceof IfRequest) { + IfRequest request = (IfRequest) r; + ActionPanel panel = createIfRequestPanel(request, values); + + result.actionsList.addAll(panel.actionsList); + + result.addControl(panel.getPanel()); } else { throw new UnsupportedOperationException(r.toString()); } } - return actionsList; + return result; + } + + private static ActionPanel createIfRequestPanel(IfRequest request, Field[] values) { + + Field conditionField = Field.findField(values, "", request.getVariable()); + + JPanel result = new JPanel(new VerticalFlowLayout()); + + result.add(new JLabel(request.getVariable())); + + + ActionPanel trueAP = createComponents("", request.trueBlock.toArray(new Request[0]), values, ""); + ActionPanel falseAP = createComponents("", request.falseBlock.toArray(new Request[0]), values, ""); + + result.add(trueAP.getPanel()); + result.add(falseAP.getPanel()); + + List combined = new ArrayList<>(trueAP.actionsList); + combined.addAll(falseAP.actionsList); + + combined.add(new RefreshActions() { + @Override + public void refresh(BinaryProtocol bp, byte[] response) { + int value = (int) conditionField.getValue(new ConfigurationImage(response)); + JPanel active; + JPanel passive; + if (value == 1) { + active = trueAP.getPanel(); + passive = falseAP.getPanel(); + } else { + active = falseAP.getPanel(); + passive = trueAP.getPanel(); + } + active.setBorder(BorderFactory.createLineBorder(Color.green)); + passive.setBorder(BorderFactory.createLineBorder(Color.red)); + Toolbox.setEnabledRecursive(active, true); + Toolbox.setEnabledRecursive(passive, true); + } + }); + + return new ActionPanel(result, combined); + } + + @NotNull + public static JPanel createLiveDocumentationPanel() { + JPanel liveDocs = new JPanel(new VerticalFlowLayout()); + + liveDocs.add(getPanel("Coolant Sensor", "CLT", Fields.LDS_CLT_INDEX, + ThermistorState.VALUES, ThermistorsMeta.CONTENT)); + + liveDocs.add(getPanel("Intake Air Sensor", "IAT", Fields.LDS_IAT_INDEX, + ThermistorState.VALUES, ThermistorsMeta.CONTENT)); + + liveDocs.add(getPanel("Throttle Position Sensor", "", Fields.LDS_ENGINE_STATE_INDEX, + EngineState.VALUES, TpsMeta.CONTENT)); + + liveDocs.add(getPanel("tCharge", "", Fields.LDS_ENGINE_STATE_INDEX, + EngineState.VALUES, SpeedDensityMeta.CONTENT)); + + return liveDocs; } } diff --git a/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocsSandbox.java b/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocsSandbox.java index a4c7300351..44c828d3a9 100644 --- a/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocsSandbox.java +++ b/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocsSandbox.java @@ -66,9 +66,9 @@ public class LiveDocsSandbox { } @NotNull - private static JPanel wrapWithOffset(JPanel panel) { + public static JPanel wrapWithOffset(JPanel panel) { JPanel topWrapped = new JPanel(new FlowLayout()); - topWrapped.add(new JLabel("x")); + topWrapped.add(new JLabel(" ")); topWrapped.add(panel); return topWrapped; } diff --git a/java_tools/configuration_definition/.idea/runConfigurations/LiveDocsMetaParser.xml b/java_tools/configuration_definition/.idea/runConfigurations/LiveDocsMetaParser.xml index fb20ad5272..7fb9db5933 100644 --- a/java_tools/configuration_definition/.idea/runConfigurations/LiveDocsMetaParser.xml +++ b/java_tools/configuration_definition/.idea/runConfigurations/LiveDocsMetaParser.xml @@ -2,7 +2,7 @@