This commit is contained in:
rusEfi 2019-03-02 17:07:33 -05:00
parent 4829124644
commit a41404ac40
4 changed files with 130 additions and 25 deletions

View File

@ -2,6 +2,7 @@ package com.rusefi;
import com.rusefi.ui.MessagesView;
import com.rusefi.ui.util.UiUtils;
import com.rusefi.ui.widgets.EtbMonteCarloSequence;
import com.rusefi.ui.widgets.EtbResearch;
import com.rusefi.ui.widgets.EtbTestSequence;
import org.jetbrains.annotations.NotNull;
@ -25,6 +26,7 @@ public class BenchTestPane {
content.add(createIdleTest());
content.add(createDizzyTest());
content.add(UiUtils.wrap(new EtbTestSequence().getButton()));
content.add(UiUtils.wrap(new EtbMonteCarloSequence().getButton()));
content.add(UiUtils.wrap(new EtbResearch().getButton()));
content.add(new MessagesView().messagesScroll);
}

View File

@ -14,6 +14,8 @@ import java.util.concurrent.TimeUnit;
/**
* https://github.com/rusefi/rusefi/issues/494
* <p>
* https://en.wikipedia.org/wiki/Standard_deviation of error posted to specified sensor
* <p>
* 11/16/2017
* (c) Andrey Belomutskiy
*
@ -25,6 +27,7 @@ public class ClosedLoopControlQualityMetric {
private final ValueSource target;
private final ValueSource result;
private final Sensor destination;
private boolean isStarted;
/**
* Buffer of recent error measurements
@ -43,6 +46,10 @@ public class ClosedLoopControlQualityMetric {
}
public void start(int bufferSize, int periodMs) {
if (isStarted)
return;
isStarted = true;
errorsBuffer = new CyclicBuffer(bufferSize);
executor.scheduleAtFixedRate(() -> {
rememberCurrentError(target.getValue() - result.getValue());

View File

@ -0,0 +1,73 @@
package com.rusefi.ui.widgets;
import com.rusefi.core.MessagesCentral;
import com.rusefi.core.Sensor;
import com.rusefi.core.SensorCentral;
import com.rusefi.io.CommandQueue;
import javax.swing.*;
import java.util.Random;
import static com.rusefi.Timeouts.SECOND;
import static com.rusefi.ui.widgets.EtbTestSequence.*;
/**
* 3/2/2019
* (c) Andrey Belomutskiy
*/
public class EtbMonteCarloSequence {
public static final int LIMIT = 100;
private final JButton button = new JButton("ETB I feel lucky!");
private final static Random r = new Random();
private int counter;
public EtbMonteCarloSequence() {
button.addActionListener(e -> {
counter = 0;
// 3000 data points at 10Hz should be 300 seconds worth of data
metric.start(/* buffer size: */3000, /*period, ms: */ 100);
executor.execute(this::runRandomCycle);
});
}
private void runRandomCycle() {
final int offset = r.nextInt(100);
final double pFactor = 1 + (r.nextInt(300) / 100.0);
final double iFactor = r.nextInt(30) / 100.0;
final double dFactor = r.nextInt(30) / 100.0;
String stats = "mcstats:offset:" + offset +
":pFactor:" + pFactor +
":iFactor:" + iFactor +
":dFactor:" + dFactor;
MessagesCentral.getInstance().postMessage(EtbMonteCarloSequence.class, stats);
CommandQueue.getInstance().write("set etb_o " + offset);
CommandQueue.getInstance().write("set etb_p " + pFactor);
CommandQueue.getInstance().write("set etb_i " + iFactor);
CommandQueue.getInstance().write("set etb_d " + dFactor);
SequenceStep firstStep = new EtbTarget(10 * SECOND, 4 /*position*/);
SequenceStep last = addSequence(firstStep);
last.addNext(new SequenceStep(5 * SECOND) {
@Override
protected void doJob() {
double result = SensorCentral.getInstance().getValue(Sensor.ETB_CONTROL_QUALITY);
MessagesCentral.getInstance().postMessage(EtbMonteCarloSequence.class, stats + ":result:" + result);
if (counter == LIMIT) {
MessagesCentral.getInstance().postMessage(EtbTestSequence.class, "ETB MC sequence done!");
return;
}
counter++;
MessagesCentral.getInstance().postMessage(EtbTestSequence.class, "Starting " + counter + " of " + LIMIT);
runRandomCycle();
}
});
firstStep.execute(executor);
}
public JButton getButton() {
return button;
}
}

View File

@ -6,6 +6,7 @@ import com.rusefi.core.MessagesCentral;
import com.rusefi.core.Sensor;
import com.rusefi.core.SensorCentral;
import com.rusefi.io.CommandQueue;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.concurrent.Executors;
@ -26,14 +27,18 @@ import java.util.concurrent.TimeUnit;
* @see TimeBasedBuffer
*/
public class EtbTestSequence {
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
private boolean isStarted;
protected static final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
protected final ClosedLoopControlQualityMetric metric = new ClosedLoopControlQualityMetric(
protected final static ClosedLoopControlQualityMetric metric = createMetric();
@NotNull
protected static ClosedLoopControlQualityMetric createMetric() {
return new ClosedLoopControlQualityMetric(
SensorCentral.getInstance().getValueSource(Sensor.PPS),
SensorCentral.getInstance().getValueSource(Sensor.TPS),
Sensor.ETB_CONTROL_QUALITY
);
}
private final static long SECOND = 1000;
@ -42,7 +47,11 @@ public class EtbTestSequence {
private SequenceStep FIRST_STEP = new EtbTarget(10 * SECOND, 4 /*position*/);
{
FIRST_STEP.add(new SequenceStep(SECOND) {
addSequence(FIRST_STEP);
}
protected static SequenceStep addSequence(SequenceStep first_step) {
return first_step.addNext(new SequenceStep(SECOND) {
@Override
protected void doJob() {
metric.reset();
@ -56,24 +65,38 @@ public class EtbTestSequence {
.addNext(5 * SECOND, 2 /*position*/)
.addNext(5 * SECOND, 0 /*position*/)
.addNext(5 * SECOND, 10 /*position*/)
.addNext(10 * SECOND, 6 /*position*/)
.addNext(10 * SECOND, 30 /*position*/)
.addNext(10 * SECOND, 50 /*position*/)
.addNext(10 * SECOND, 70 /*position*/)
.addNext(10 * SECOND, 100 /*position*/)
.addNext(10 * SECOND, 50 /*position*/)
.addNext(10 * SECOND, 70 /*position*/)
.addNext(10 * SECOND, 4 /*position*/)
.addNext(10 * SECOND, 0 /*position*/)
.addNext(3 * SECOND, 0 /*position*/)
.addNext(1 * SECOND, 6 /*position*/)
.addNext(1 * SECOND, 8 /*position*/)
.addNext(1 * SECOND, 6 /*position*/)
.addNext(1 * SECOND, 4 /*position*/)
.addNext(1 * SECOND, 2 /*position*/)
.addNext(1 * SECOND, 0 /*position*/)
.addNext(1 * SECOND, 10 /*position*/)
.addNext(3 * SECOND, 7 /*position*/)
.addNext(3 * SECOND, 6 /*position*/)
.addNext(3 * SECOND, 5 /*position*/)
.addNext(3 * SECOND, 4 /*position*/)
.addNext(3 * SECOND, 3 /*position*/)
.addNext(3 * SECOND, 2 /*position*/)
.addNext(3 * SECOND, 1 /*position*/)
.addNext(3 * SECOND, 0 /*position*/)
// .addNext(10 * SECOND, 6 /*position*/)
// .addNext(10 * SECOND, 30 /*position*/)
// .addNext(10 * SECOND, 50 /*position*/)
// .addNext(10 * SECOND, 70 /*position*/)
// .addNext(10 * SECOND, 100 /*position*/)
// .addNext(10 * SECOND, 50 /*position*/)
// .addNext(10 * SECOND, 70 /*position*/)
// .addNext(10 * SECOND, 4 /*position*/)
// .addNext(10 * SECOND, 0 /*position*/)
;
}
public EtbTestSequence() {
button.addActionListener(e -> {
if (!isStarted) {
metric.start(/* buffer size: */1000, /*period, ms: */ 100);
isStarted = true;
}
// 3000 data points at 10Hz should be 300 seconds worth of data
metric.start(/* buffer size: */3000, /*period, ms: */ 100);
FIRST_STEP.execute(executor);
});
}
@ -93,7 +116,7 @@ public class EtbTestSequence {
public void execute(ScheduledExecutorService executor) {
doJob();
if (next != null) {
FileLog.MAIN.logLine("Scheduling " + next);
FileLog.MAIN.logLine("Scheduling " + next + " with " + duration + "ms delay");
executor.schedule(() -> next.execute(executor), duration, TimeUnit.MILLISECONDS);
} else {
MessagesCentral.getInstance().postMessage(EtbTestSequence.class, "ETB test sequence done!");
@ -103,10 +126,10 @@ public class EtbTestSequence {
protected abstract void doJob();
public SequenceStep addNext(long duration, double position) {
return add(new EtbTarget(duration, position));
return addNext(new EtbTarget(duration, position));
}
private SequenceStep add(SequenceStep step) {
public SequenceStep addNext(SequenceStep step) {
next = step;
return next;
}