diff --git a/firmware/config/engines/custom_engine.cpp b/firmware/config/engines/custom_engine.cpp index 16ea042403..3c31446c26 100644 --- a/firmware/config/engines/custom_engine.cpp +++ b/firmware/config/engines/custom_engine.cpp @@ -241,6 +241,36 @@ void setFrankensoBoardTestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { } +void setBoschVNH2SP30Curve(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + engineConfiguration->etbBiasBins[0] = 0; + engineConfiguration->etbBiasBins[1] = 1; + engineConfiguration->etbBiasBins[2] = 2; + /** + * This specific throttle has default position of about 7% open + */ + engineConfiguration->etbBiasBins[3] = 4; + engineConfiguration->etbBiasBins[4] = 7; + engineConfiguration->etbBiasBins[5] = 98; + engineConfiguration->etbBiasBins[6] = 99; + engineConfiguration->etbBiasBins[7] = 100; + + /** + * Some negative bias for below-default position + */ + engineConfiguration->etbBiasValues[0] = -20; + engineConfiguration->etbBiasValues[1] = -18; + engineConfiguration->etbBiasValues[2] = -17; + /** + * Zero bias for index which corresponds to default throttle position, when no current is applied + * This specific throttle has default position of about 7% open + */ + engineConfiguration->etbBiasValues[3] = 0; + engineConfiguration->etbBiasValues[4] = 20; + engineConfiguration->etbBiasValues[5] = 21; + engineConfiguration->etbBiasValues[6] = 22; + engineConfiguration->etbBiasValues[7] = 25; +} + // ETB_BENCH_ENGINE // set engine_type 58 void setEtbTestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { @@ -266,7 +296,8 @@ void setEtbTestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { CONFIGB(etb1.controlPin1) = GPIOE_14; #if EFI_ELECTRONIC_THROTTLE_BODY - setDefaultEtbParameters(PASS_CONFIG_PARAMETER_SIGNATURE); + setBoschVNH2SP30Curve(PASS_CONFIG_PARAMETER_SIGNATURE); +// setDefaultEtbParameters(PASS_CONFIG_PARAMETER_SIGNATURE); // values are above 100% since we have feedforward part of the total summation engineConfiguration->etb.minValue = -200; engineConfiguration->etb.maxValue = 200; diff --git a/java_console/ui/src/com/rusefi/etb/EtbTarget.java b/java_console/ui/src/com/rusefi/etb/EtbTarget.java index e84c39dbfe..49d5cb9e93 100644 --- a/java_console/ui/src/com/rusefi/etb/EtbTarget.java +++ b/java_console/ui/src/com/rusefi/etb/EtbTarget.java @@ -9,8 +9,8 @@ public class EtbTarget extends TestSequenceStep { private final double position; private final Runnable onEachStep; - public EtbTarget(long duration, double position, Runnable onEachStep) { - super(duration); + public EtbTarget(long duration, double position, Runnable onEachStep, Condition condition) { + super(duration, condition); this.position = position; this.onEachStep = onEachStep; } @@ -24,7 +24,7 @@ public class EtbTarget extends TestSequenceStep { @Override public String toString() { return "EtbTarget{" + - "duration=" + duration + + "nextStepDelay=" + nextStepDelay + ", position=" + position + '}'; } diff --git a/java_console/ui/src/com/rusefi/etb/StandardTestSequence.java b/java_console/ui/src/com/rusefi/etb/StandardTestSequence.java index 9837743446..ddcc0b8765 100644 --- a/java_console/ui/src/com/rusefi/etb/StandardTestSequence.java +++ b/java_console/ui/src/com/rusefi/etb/StandardTestSequence.java @@ -18,47 +18,47 @@ public class StandardTestSequence { ); } - public static TestSequenceStep addSequence(TestSequenceStep first_step, Runnable onEachStep) { - TestSequenceStep secondStep = new TestSequenceStep(SECOND) { + public static TestSequenceStep addSequence(TestSequenceStep first_step, Runnable onEachStep, TestSequenceStep.Condition condition) { + TestSequenceStep secondStep = new TestSequenceStep(SECOND, EtbTarget.Condition.YES) { @Override protected void doJob() { metric.reset(); } }; TestSequenceStep result = first_step.addNext(secondStep) - .addNext(10 * SECOND, 4 /*position*/, onEachStep) - .addNext(5 * SECOND, 6, /*position*/onEachStep) - .addNext(5 * SECOND, 8, /*position*/onEachStep) - .addNext(5 * SECOND, 6, /*position*/onEachStep) - .addNext(5 * SECOND, 4, /*position*/onEachStep) - .addNext(5 * SECOND, 2, /*position*/onEachStep) - .addNext(5 * SECOND, 0, /*position*/onEachStep) - .addNext(5 * SECOND, 10, /*position*/onEachStep) - .addNext(3 * SECOND, 0, /*position*/onEachStep) - .addNext(1 * SECOND, 6, /*position*/onEachStep) - .addNext(1 * SECOND, 8, /*position*/onEachStep) - .addNext(1 * SECOND, 6, /*position*/onEachStep) - .addNext(1 * SECOND, 4, /*position*/onEachStep) - .addNext(1 * SECOND, 2, /*position*/onEachStep) - .addNext(1 * SECOND, 0, /*position*/onEachStep) - .addNext(1 * SECOND, 10, /*position*/onEachStep) - .addNext(3 * SECOND, 7, /*position*/onEachStep) - .addNext(3 * SECOND, 6, /*position*/onEachStep) - .addNext(3 * SECOND, 5, /*position*/onEachStep) - .addNext(3 * SECOND, 4, /*position*/onEachStep) - .addNext(3 * SECOND, 3, /*position*/onEachStep) - .addNext(3 * SECOND, 2, /*position*/onEachStep) - .addNext(3 * SECOND, 1, /*position*/onEachStep) - .addNext(3 * SECOND, 0, /*position*/onEachStep) - .addNext(10 * SECOND, 6, /*position*/onEachStep) - .addNext(10 * SECOND, 30, /*position*/onEachStep) - .addNext(10 * SECOND, 50, /*position*/onEachStep) - .addNext(10 * SECOND, 70, /*position*/onEachStep) - .addNext(10 * SECOND, 95, /*position*/onEachStep) - .addNext(10 * SECOND, 50, /*position*/onEachStep) - .addNext(10 * SECOND, 70, /*position*/onEachStep) - .addNext(10 * SECOND, 4, /*position*/onEachStep) - .addNext(10 * SECOND, 0, /*position*/onEachStep) + .addNext(10 * SECOND, 4 /*position*/, onEachStep, condition) + .addNext(5 * SECOND, 6, /*position*/onEachStep, condition) + .addNext(5 * SECOND, 8, /*position*/onEachStep, condition) + .addNext(5 * SECOND, 6, /*position*/onEachStep, condition) + .addNext(5 * SECOND, 4, /*position*/onEachStep, condition) + .addNext(5 * SECOND, 2, /*position*/onEachStep, condition) + .addNext(5 * SECOND, 0, /*position*/onEachStep, condition) + .addNext(5 * SECOND, 10, /*position*/onEachStep, condition) + .addNext(3 * SECOND, 0, /*position*/onEachStep, condition) + .addNext(1 * SECOND, 6, /*position*/onEachStep, condition) + .addNext(1 * SECOND, 8, /*position*/onEachStep, condition) + .addNext(1 * SECOND, 6, /*position*/onEachStep, condition) + .addNext(1 * SECOND, 4, /*position*/onEachStep, condition) + .addNext(1 * SECOND, 2, /*position*/onEachStep, condition) + .addNext(1 * SECOND, 0, /*position*/onEachStep, condition) + .addNext(1 * SECOND, 10, /*position*/onEachStep, condition) + .addNext(3 * SECOND, 7, /*position*/onEachStep, condition) + .addNext(3 * SECOND, 6, /*position*/onEachStep, condition) + .addNext(3 * SECOND, 5, /*position*/onEachStep, condition) + .addNext(3 * SECOND, 4, /*position*/onEachStep, condition) + .addNext(3 * SECOND, 3, /*position*/onEachStep, condition) + .addNext(3 * SECOND, 2, /*position*/onEachStep, condition) + .addNext(3 * SECOND, 1, /*position*/onEachStep, condition) + .addNext(3 * SECOND, 0, /*position*/onEachStep, condition) + .addNext(10 * SECOND, 6, /*position*/onEachStep, condition) + .addNext(10 * SECOND, 30, /*position*/onEachStep, condition) + .addNext(10 * SECOND, 50, /*position*/onEachStep, condition) + .addNext(10 * SECOND, 70, /*position*/onEachStep, condition) + .addNext(10 * SECOND, 95, /*position*/onEachStep, condition) + .addNext(10 * SECOND, 50, /*position*/onEachStep, condition) + .addNext(10 * SECOND, 70, /*position*/onEachStep, condition) + .addNext(10 * SECOND, 4, /*position*/onEachStep, condition) + .addNext(10 * SECOND, 0, /*position*/onEachStep, condition) ; return result; } diff --git a/java_console/ui/src/com/rusefi/etb/TestSequenceStep.java b/java_console/ui/src/com/rusefi/etb/TestSequenceStep.java index e97dccd776..1794539e78 100644 --- a/java_console/ui/src/com/rusefi/etb/TestSequenceStep.java +++ b/java_console/ui/src/com/rusefi/etb/TestSequenceStep.java @@ -7,18 +7,23 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public abstract class TestSequenceStep { - protected final long duration; + /** + * First we execute {{@link #doJob()}} then we schedule next step for after 'nextStepDelay' time passes. + */ + protected final long nextStepDelay; + private final EtbTarget.Condition condition; private TestSequenceStep next; - public TestSequenceStep(long duration) { - this.duration = duration; + public TestSequenceStep(long nextStepDelay, EtbTarget.Condition condition) { + this.nextStepDelay = nextStepDelay; + this.condition = condition; } public void execute(ScheduledExecutorService executor) { doJob(); - if (next != null) { - FileLog.MAIN.logLine("Scheduling " + next + " with " + duration + "ms delay"); - executor.schedule(() -> next.execute(executor), duration, TimeUnit.MILLISECONDS); + if (next != null && condition.shouldContinue()) { + FileLog.MAIN.logLine("Scheduling " + next + " with " + nextStepDelay + "ms delay"); + executor.schedule(() -> next.execute(executor), nextStepDelay, TimeUnit.MILLISECONDS); } else { MessagesCentral.getInstance().postMessage(TestSequenceStep.class, "ETB test sequence done!"); } @@ -26,8 +31,8 @@ public abstract class TestSequenceStep { protected abstract void doJob(); - public TestSequenceStep addNext(long duration, double position, Runnable onEachStep) { - return addNext(new EtbTarget(duration, position, onEachStep)); + public TestSequenceStep addNext(long duration, double position, Runnable onEachStep, Condition condition) { + return addNext(new EtbTarget(duration, position, onEachStep, condition)); } public TestSequenceStep addNext(TestSequenceStep step) { @@ -38,4 +43,10 @@ public abstract class TestSequenceStep { public TestSequenceStep getNext() { return next; } + + public interface Condition { + boolean shouldContinue(); + + Condition YES = () -> true; + } } diff --git a/java_console/ui/src/com/rusefi/ui/etb/EtbMonteCarloSequence.java b/java_console/ui/src/com/rusefi/ui/etb/EtbMonteCarloSequence.java index ba906caf82..641e015419 100644 --- a/java_console/ui/src/com/rusefi/ui/etb/EtbMonteCarloSequence.java +++ b/java_console/ui/src/com/rusefi/ui/etb/EtbMonteCarloSequence.java @@ -22,10 +22,13 @@ import static com.rusefi.ui.etb.EtbTestSequence.*; */ public class EtbMonteCarloSequence { public static final int LIMIT = 300; + private static final double DEFAULT_POSITION = 7; private final JButton button = new JButton("ETB I feel lucky!"); private final static Random r = new Random(); private int counter; + private double bestResultSoFar = 75; + public EtbMonteCarloSequence() { button.addActionListener(e -> { counter = 0; @@ -33,6 +36,7 @@ public class EtbMonteCarloSequence { // 3000 data points at 10Hz should be 300 seconds worth of data StandardTestSequence.metric.start(/* buffer size: */3000, /*period, ms: */ 100); + // start first cycle. At the end of the run it would decide if it wants to start from beginning again executor.execute(this::runRandomCycle); }); } @@ -53,14 +57,32 @@ public class EtbMonteCarloSequence { CommandQueue.getInstance().write("set etb_i " + iFactor); CommandQueue.getInstance().write("set etb_d " + dFactor); - TestSequenceStep firstStep = new EtbTarget(10 * SECOND, 4, null); - TestSequenceStep last = StandardTestSequence.addSequence(firstStep, null); - last.addNext(new TestSequenceStep(5 * SECOND) { + TestSequenceStep firstStep = new EtbTarget(10 * SECOND, DEFAULT_POSITION, null, TestSequenceStep.Condition.YES); + TestSequenceStep.Condition condition = new TestSequenceStep.Condition() { + @Override + public boolean shouldContinue() { + double currentValue = StandardTestSequence.metric.getStandardDeviation(); + boolean shouldContinue = currentValue < bestResultSoFar; + if (!shouldContinue) { + MessagesCentral.getInstance().postMessage(EtbMonteCarloSequence.class, + "Two much error accumulated, aborting! " + currentValue + " > " + bestResultSoFar); + + } + return shouldContinue; + } + }; + TestSequenceStep last = StandardTestSequence.addSequence(firstStep, null, condition); + last.addNext(new TestSequenceStep(5 * SECOND, EtbTarget.Condition.YES) { @Override protected void doJob() { - double result = SensorCentral.getInstance().getValue(Sensor.ETB_CONTROL_QUALITY); + double cycleResult = SensorCentral.getInstance().getValue(Sensor.ETB_CONTROL_QUALITY); + if (cycleResult < bestResultSoFar) { + bestResultSoFar = cycleResult; + MessagesCentral.getInstance().postMessage(EtbMonteCarloSequence.class, + getSecondsSinceFileStart() + ":" + stats + ":new_record:" + bestResultSoFar); + } MessagesCentral.getInstance().postMessage(EtbMonteCarloSequence.class, - getSecondsSinceFileStart() + ":" + stats + ":result:" + result); + getSecondsSinceFileStart() + ":" + stats + ":result:" + cycleResult); if (counter == LIMIT) { MessagesCentral.getInstance().postMessage(EtbTestSequence.class, "ETB MC sequence done!"); return; diff --git a/java_console/ui/src/com/rusefi/ui/etb/EtbTestSequence.java b/java_console/ui/src/com/rusefi/ui/etb/EtbTestSequence.java index 86703d77c5..720b4e04ca 100644 --- a/java_console/ui/src/com/rusefi/ui/etb/EtbTestSequence.java +++ b/java_console/ui/src/com/rusefi/ui/etb/EtbTestSequence.java @@ -43,13 +43,13 @@ public class EtbTestSequence { AtomicInteger stepCounter = new AtomicInteger(); AtomicInteger totalSteps = new AtomicInteger(); - TestSequenceStep lastStep = new TestSequenceStep(SECOND) { + TestSequenceStep lastStep = new TestSequenceStep(SECOND, EtbTarget.Condition.YES) { @Override protected void doJob() { button.setEnabled(true); button.setText(BUTTON_TEXT); - double value = StandardTestSequence.metric.getStandardDeviation(); - result.setText(String.format("Final Result: %.3f", value)); + double finalValue = StandardTestSequence.metric.getStandardDeviation(); + result.setText(String.format("Final Result: %.3f", finalValue)); } }; @@ -68,8 +68,8 @@ public class EtbTestSequence { } }; - TestSequenceStep firstStep = new EtbTarget(10 * SECOND, 4, /*position*/onEachStep); - TestSequenceStep result = StandardTestSequence.addSequence(firstStep, onEachStep); + TestSequenceStep firstStep = new EtbTarget(10 * SECOND, 4, /*position*/onEachStep, TestSequenceStep.Condition.YES); + TestSequenceStep result = StandardTestSequence.addSequence(firstStep, onEachStep, TestSequenceStep.Condition.YES); result.addNext(lastStep); totalSteps.set(count(firstStep));