ETB monte carlo keeps track of best result

This commit is contained in:
rusefi 2019-05-04 09:57:57 -04:00
parent fb5545b39f
commit d2e2f817db
6 changed files with 121 additions and 57 deletions

View File

@ -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 // ETB_BENCH_ENGINE
// set engine_type 58 // set engine_type 58
void setEtbTestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { void setEtbTestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
@ -266,7 +296,8 @@ void setEtbTestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
CONFIGB(etb1.controlPin1) = GPIOE_14; CONFIGB(etb1.controlPin1) = GPIOE_14;
#if EFI_ELECTRONIC_THROTTLE_BODY #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 // values are above 100% since we have feedforward part of the total summation
engineConfiguration->etb.minValue = -200; engineConfiguration->etb.minValue = -200;
engineConfiguration->etb.maxValue = 200; engineConfiguration->etb.maxValue = 200;

View File

@ -9,8 +9,8 @@ public class EtbTarget extends TestSequenceStep {
private final double position; private final double position;
private final Runnable onEachStep; private final Runnable onEachStep;
public EtbTarget(long duration, double position, Runnable onEachStep) { public EtbTarget(long duration, double position, Runnable onEachStep, Condition condition) {
super(duration); super(duration, condition);
this.position = position; this.position = position;
this.onEachStep = onEachStep; this.onEachStep = onEachStep;
} }
@ -24,7 +24,7 @@ public class EtbTarget extends TestSequenceStep {
@Override @Override
public String toString() { public String toString() {
return "EtbTarget{" + return "EtbTarget{" +
"duration=" + duration + "nextStepDelay=" + nextStepDelay +
", position=" + position + ", position=" + position +
'}'; '}';
} }

View File

@ -18,47 +18,47 @@ public class StandardTestSequence {
); );
} }
public static TestSequenceStep addSequence(TestSequenceStep first_step, Runnable onEachStep) { public static TestSequenceStep addSequence(TestSequenceStep first_step, Runnable onEachStep, TestSequenceStep.Condition condition) {
TestSequenceStep secondStep = new TestSequenceStep(SECOND) { TestSequenceStep secondStep = new TestSequenceStep(SECOND, EtbTarget.Condition.YES) {
@Override @Override
protected void doJob() { protected void doJob() {
metric.reset(); metric.reset();
} }
}; };
TestSequenceStep result = first_step.addNext(secondStep) TestSequenceStep result = first_step.addNext(secondStep)
.addNext(10 * SECOND, 4 /*position*/, onEachStep) .addNext(10 * SECOND, 4 /*position*/, onEachStep, condition)
.addNext(5 * SECOND, 6, /*position*/onEachStep) .addNext(5 * SECOND, 6, /*position*/onEachStep, condition)
.addNext(5 * SECOND, 8, /*position*/onEachStep) .addNext(5 * SECOND, 8, /*position*/onEachStep, condition)
.addNext(5 * SECOND, 6, /*position*/onEachStep) .addNext(5 * SECOND, 6, /*position*/onEachStep, condition)
.addNext(5 * SECOND, 4, /*position*/onEachStep) .addNext(5 * SECOND, 4, /*position*/onEachStep, condition)
.addNext(5 * SECOND, 2, /*position*/onEachStep) .addNext(5 * SECOND, 2, /*position*/onEachStep, condition)
.addNext(5 * SECOND, 0, /*position*/onEachStep) .addNext(5 * SECOND, 0, /*position*/onEachStep, condition)
.addNext(5 * SECOND, 10, /*position*/onEachStep) .addNext(5 * SECOND, 10, /*position*/onEachStep, condition)
.addNext(3 * SECOND, 0, /*position*/onEachStep) .addNext(3 * SECOND, 0, /*position*/onEachStep, condition)
.addNext(1 * SECOND, 6, /*position*/onEachStep) .addNext(1 * SECOND, 6, /*position*/onEachStep, condition)
.addNext(1 * SECOND, 8, /*position*/onEachStep) .addNext(1 * SECOND, 8, /*position*/onEachStep, condition)
.addNext(1 * SECOND, 6, /*position*/onEachStep) .addNext(1 * SECOND, 6, /*position*/onEachStep, condition)
.addNext(1 * SECOND, 4, /*position*/onEachStep) .addNext(1 * SECOND, 4, /*position*/onEachStep, condition)
.addNext(1 * SECOND, 2, /*position*/onEachStep) .addNext(1 * SECOND, 2, /*position*/onEachStep, condition)
.addNext(1 * SECOND, 0, /*position*/onEachStep) .addNext(1 * SECOND, 0, /*position*/onEachStep, condition)
.addNext(1 * SECOND, 10, /*position*/onEachStep) .addNext(1 * SECOND, 10, /*position*/onEachStep, condition)
.addNext(3 * SECOND, 7, /*position*/onEachStep) .addNext(3 * SECOND, 7, /*position*/onEachStep, condition)
.addNext(3 * SECOND, 6, /*position*/onEachStep) .addNext(3 * SECOND, 6, /*position*/onEachStep, condition)
.addNext(3 * SECOND, 5, /*position*/onEachStep) .addNext(3 * SECOND, 5, /*position*/onEachStep, condition)
.addNext(3 * SECOND, 4, /*position*/onEachStep) .addNext(3 * SECOND, 4, /*position*/onEachStep, condition)
.addNext(3 * SECOND, 3, /*position*/onEachStep) .addNext(3 * SECOND, 3, /*position*/onEachStep, condition)
.addNext(3 * SECOND, 2, /*position*/onEachStep) .addNext(3 * SECOND, 2, /*position*/onEachStep, condition)
.addNext(3 * SECOND, 1, /*position*/onEachStep) .addNext(3 * SECOND, 1, /*position*/onEachStep, condition)
.addNext(3 * SECOND, 0, /*position*/onEachStep) .addNext(3 * SECOND, 0, /*position*/onEachStep, condition)
.addNext(10 * SECOND, 6, /*position*/onEachStep) .addNext(10 * SECOND, 6, /*position*/onEachStep, condition)
.addNext(10 * SECOND, 30, /*position*/onEachStep) .addNext(10 * SECOND, 30, /*position*/onEachStep, condition)
.addNext(10 * SECOND, 50, /*position*/onEachStep) .addNext(10 * SECOND, 50, /*position*/onEachStep, condition)
.addNext(10 * SECOND, 70, /*position*/onEachStep) .addNext(10 * SECOND, 70, /*position*/onEachStep, condition)
.addNext(10 * SECOND, 95, /*position*/onEachStep) .addNext(10 * SECOND, 95, /*position*/onEachStep, condition)
.addNext(10 * SECOND, 50, /*position*/onEachStep) .addNext(10 * SECOND, 50, /*position*/onEachStep, condition)
.addNext(10 * SECOND, 70, /*position*/onEachStep) .addNext(10 * SECOND, 70, /*position*/onEachStep, condition)
.addNext(10 * SECOND, 4, /*position*/onEachStep) .addNext(10 * SECOND, 4, /*position*/onEachStep, condition)
.addNext(10 * SECOND, 0, /*position*/onEachStep) .addNext(10 * SECOND, 0, /*position*/onEachStep, condition)
; ;
return result; return result;
} }

View File

@ -7,18 +7,23 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public abstract class TestSequenceStep { 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; private TestSequenceStep next;
public TestSequenceStep(long duration) { public TestSequenceStep(long nextStepDelay, EtbTarget.Condition condition) {
this.duration = duration; this.nextStepDelay = nextStepDelay;
this.condition = condition;
} }
public void execute(ScheduledExecutorService executor) { public void execute(ScheduledExecutorService executor) {
doJob(); doJob();
if (next != null) { if (next != null && condition.shouldContinue()) {
FileLog.MAIN.logLine("Scheduling " + next + " with " + duration + "ms delay"); FileLog.MAIN.logLine("Scheduling " + next + " with " + nextStepDelay + "ms delay");
executor.schedule(() -> next.execute(executor), duration, TimeUnit.MILLISECONDS); executor.schedule(() -> next.execute(executor), nextStepDelay, TimeUnit.MILLISECONDS);
} else { } else {
MessagesCentral.getInstance().postMessage(TestSequenceStep.class, "ETB test sequence done!"); MessagesCentral.getInstance().postMessage(TestSequenceStep.class, "ETB test sequence done!");
} }
@ -26,8 +31,8 @@ public abstract class TestSequenceStep {
protected abstract void doJob(); protected abstract void doJob();
public TestSequenceStep addNext(long duration, double position, Runnable onEachStep) { public TestSequenceStep addNext(long duration, double position, Runnable onEachStep, Condition condition) {
return addNext(new EtbTarget(duration, position, onEachStep)); return addNext(new EtbTarget(duration, position, onEachStep, condition));
} }
public TestSequenceStep addNext(TestSequenceStep step) { public TestSequenceStep addNext(TestSequenceStep step) {
@ -38,4 +43,10 @@ public abstract class TestSequenceStep {
public TestSequenceStep getNext() { public TestSequenceStep getNext() {
return next; return next;
} }
public interface Condition {
boolean shouldContinue();
Condition YES = () -> true;
}
} }

View File

@ -22,10 +22,13 @@ import static com.rusefi.ui.etb.EtbTestSequence.*;
*/ */
public class EtbMonteCarloSequence { public class EtbMonteCarloSequence {
public static final int LIMIT = 300; 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 JButton button = new JButton("ETB I feel lucky!");
private final static Random r = new Random(); private final static Random r = new Random();
private int counter; private int counter;
private double bestResultSoFar = 75;
public EtbMonteCarloSequence() { public EtbMonteCarloSequence() {
button.addActionListener(e -> { button.addActionListener(e -> {
counter = 0; counter = 0;
@ -33,6 +36,7 @@ public class EtbMonteCarloSequence {
// 3000 data points at 10Hz should be 300 seconds worth of data // 3000 data points at 10Hz should be 300 seconds worth of data
StandardTestSequence.metric.start(/* buffer size: */3000, /*period, ms: */ 100); 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); executor.execute(this::runRandomCycle);
}); });
} }
@ -53,14 +57,32 @@ public class EtbMonteCarloSequence {
CommandQueue.getInstance().write("set etb_i " + iFactor); CommandQueue.getInstance().write("set etb_i " + iFactor);
CommandQueue.getInstance().write("set etb_d " + dFactor); CommandQueue.getInstance().write("set etb_d " + dFactor);
TestSequenceStep firstStep = new EtbTarget(10 * SECOND, 4, null); TestSequenceStep firstStep = new EtbTarget(10 * SECOND, DEFAULT_POSITION, null, TestSequenceStep.Condition.YES);
TestSequenceStep last = StandardTestSequence.addSequence(firstStep, null); TestSequenceStep.Condition condition = new TestSequenceStep.Condition() {
last.addNext(new TestSequenceStep(5 * SECOND) { @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 @Override
protected void doJob() { 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, MessagesCentral.getInstance().postMessage(EtbMonteCarloSequence.class,
getSecondsSinceFileStart() + ":" + stats + ":result:" + result); getSecondsSinceFileStart() + ":" + stats + ":new_record:" + bestResultSoFar);
}
MessagesCentral.getInstance().postMessage(EtbMonteCarloSequence.class,
getSecondsSinceFileStart() + ":" + stats + ":result:" + cycleResult);
if (counter == LIMIT) { if (counter == LIMIT) {
MessagesCentral.getInstance().postMessage(EtbTestSequence.class, "ETB MC sequence done!"); MessagesCentral.getInstance().postMessage(EtbTestSequence.class, "ETB MC sequence done!");
return; return;

View File

@ -43,13 +43,13 @@ public class EtbTestSequence {
AtomicInteger stepCounter = new AtomicInteger(); AtomicInteger stepCounter = new AtomicInteger();
AtomicInteger totalSteps = new AtomicInteger(); AtomicInteger totalSteps = new AtomicInteger();
TestSequenceStep lastStep = new TestSequenceStep(SECOND) { TestSequenceStep lastStep = new TestSequenceStep(SECOND, EtbTarget.Condition.YES) {
@Override @Override
protected void doJob() { protected void doJob() {
button.setEnabled(true); button.setEnabled(true);
button.setText(BUTTON_TEXT); button.setText(BUTTON_TEXT);
double value = StandardTestSequence.metric.getStandardDeviation(); double finalValue = StandardTestSequence.metric.getStandardDeviation();
result.setText(String.format("Final Result: %.3f", value)); 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 firstStep = new EtbTarget(10 * SECOND, 4, /*position*/onEachStep, TestSequenceStep.Condition.YES);
TestSequenceStep result = StandardTestSequence.addSequence(firstStep, onEachStep); TestSequenceStep result = StandardTestSequence.addSequence(firstStep, onEachStep, TestSequenceStep.Condition.YES);
result.addNext(lastStep); result.addNext(lastStep);
totalSteps.set(count(firstStep)); totalSteps.set(count(firstStep));