From 8e3d4490bdbb9c10322653e59a867e7c7702a53f Mon Sep 17 00:00:00 2001 From: rusEfi Date: Sat, 2 Mar 2019 15:40:55 -0500 Subject: [PATCH] #494 --- .../ClosedLoopControlQualityMetric.java | 14 +-- .../com/rusefi/ui/widgets/EtbResearch.java | 4 +- .../rusefi/ui/widgets/EtbTestSequence.java | 95 +++++++++++++------ 3 files changed, 72 insertions(+), 41 deletions(-) diff --git a/java_console/ui/src/com/rusefi/ui/widgets/ClosedLoopControlQualityMetric.java b/java_console/ui/src/com/rusefi/ui/widgets/ClosedLoopControlQualityMetric.java index 96fc6cf0c5..d2b8099892 100644 --- a/java_console/ui/src/com/rusefi/ui/widgets/ClosedLoopControlQualityMetric.java +++ b/java_console/ui/src/com/rusefi/ui/widgets/ClosedLoopControlQualityMetric.java @@ -20,7 +20,6 @@ import java.util.concurrent.TimeUnit; * @see SensorStats */ public class ClosedLoopControlQualityMetric { - private static final int BUFFER_SIZE = 100; private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); private final ValueSource target; @@ -31,7 +30,7 @@ public class ClosedLoopControlQualityMetric { * Buffer of recent error measurements * GuardedBy(this) */ - private DataBuffer errors = new CyclicBuffer(BUFFER_SIZE); + private DataBuffer errorsBuffer; /** * @param target what value are we trying to achieve @@ -43,23 +42,24 @@ public class ClosedLoopControlQualityMetric { this.destination = destination; } - public void start() { + public void start(int bufferSize, int periodMs) { + errorsBuffer = new CyclicBuffer(bufferSize); executor.scheduleAtFixedRate(() -> { rememberCurrentError(target.getValue() - result.getValue()); SensorCentral.getInstance().setValue(getStandardDeviation(), destination); - }, 0, 100, TimeUnit.MILLISECONDS); + }, 0, periodMs, TimeUnit.MILLISECONDS); } public synchronized void reset() { - errors.clear(); + errorsBuffer.clear(); } private synchronized double getStandardDeviation() { - return DataBuffer.getStandardDeviation(errors.getValues()); + return DataBuffer.getStandardDeviation(errorsBuffer.getValues()); } private synchronized void rememberCurrentError(double error) { - errors.add(error); + errorsBuffer.add(error); } } diff --git a/java_console/ui/src/com/rusefi/ui/widgets/EtbResearch.java b/java_console/ui/src/com/rusefi/ui/widgets/EtbResearch.java index c2f99e619f..440f798680 100644 --- a/java_console/ui/src/com/rusefi/ui/widgets/EtbResearch.java +++ b/java_console/ui/src/com/rusefi/ui/widgets/EtbResearch.java @@ -17,7 +17,7 @@ import java.util.concurrent.ScheduledExecutorService; */ public class EtbResearch { private static final int SECOND = 1000; - private static final long SLEEP = 3 * SECOND; + private static final long SLEEP = SECOND; // how much do we want to change duty cycle on each iteration? private static final double DUTY_CYCLE_STEP = 0.5; private final JButton button = new JButton("ETB Research"); @@ -45,13 +45,11 @@ public class EtbResearch { executor.execute(new Runnable() { @Override public void run() { - sleep(); double tpsPosition = SensorCentral.getInstance().getValue(Sensor.TPS); MessagesCentral.getInstance().postMessage(getClass(), "ETB duty " + currentValue + ": tps=" + tpsPosition); - if (tpsPosition >= 100) { currentValue -= DUTY_CYCLE_STEP; CommandQueue.getInstance().write("set_etb " + currentValue, goingDown); diff --git a/java_console/ui/src/com/rusefi/ui/widgets/EtbTestSequence.java b/java_console/ui/src/com/rusefi/ui/widgets/EtbTestSequence.java index 03a3c569ca..f1a6218e8a 100644 --- a/java_console/ui/src/com/rusefi/ui/widgets/EtbTestSequence.java +++ b/java_console/ui/src/com/rusefi/ui/widgets/EtbTestSequence.java @@ -1,8 +1,8 @@ package com.rusefi.ui.widgets; import com.rusefi.FileLog; -import com.rusefi.SensorSnifferCentral; import com.rusefi.TimeBasedBuffer; +import com.rusefi.core.MessagesCentral; import com.rusefi.core.Sensor; import com.rusefi.core.SensorCentral; import com.rusefi.io.CommandQueue; @@ -13,11 +13,13 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** - * https://github.com/rusefi/rusefi/issues/494 - *

* Here we initiate a sequence of commands which would change target electronic throttle position so that we can * see how far the result would be how soon. *

+ * Error standard deviation is posted to {@link Sensor#ETB_CONTROL_QUALITY} + *

+ * https://github.com/rusefi/rusefi/issues/494 + *

* 11/16/2017 * (c) Andrey Belomutskiy * @@ -27,7 +29,7 @@ public class EtbTestSequence { private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); private boolean isStarted; - private ClosedLoopControlQualityMetric metric = new ClosedLoopControlQualityMetric( + protected final ClosedLoopControlQualityMetric metric = new ClosedLoopControlQualityMetric( SensorCentral.getInstance().getValueSource(Sensor.PPS), SensorCentral.getInstance().getValueSource(Sensor.TPS), Sensor.ETB_CONTROL_QUALITY @@ -37,25 +39,39 @@ public class EtbTestSequence { private final JButton button = new JButton("ETB Test"); - private static EtbTarget FIRST_STEP = new EtbTarget(SECOND, 0); + private SequenceStep FIRST_STEP = new EtbTarget(10 * SECOND, 4 /*position*/); - static { - FIRST_STEP - .addNext(5 * SECOND, 10) - .addNext(10 * SECOND, 30) - .addNext(10 * SECOND, 50) - .addNext(10 * SECOND, 70) - .addNext(10 * SECOND, 100) - .addNext(10 * SECOND, 50) - .addNext(10 * SECOND, 70) - .addNext(10 * SECOND, 0) + { + FIRST_STEP.add(new SequenceStep(SECOND) { + @Override + protected void doJob() { + metric.reset(); + } + }) + .addNext(10 * SECOND, 4 /*position*/) + .addNext(5 * SECOND, 6 /*position*/) + .addNext(5 * SECOND, 8 /*position*/) + .addNext(5 * SECOND, 6 /*position*/) + .addNext(5 * SECOND, 4 /*position*/) + .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*/) ; } public EtbTestSequence() { button.addActionListener(e -> { if (!isStarted) { - metric.start(); + metric.start(/* buffer size: */1000, /*period, ms: */ 100); isStarted = true; } FIRST_STEP.execute(executor); @@ -66,32 +82,49 @@ public class EtbTestSequence { return button; } - static class EtbTarget { + static abstract class SequenceStep { final long duration; + SequenceStep next; + + public SequenceStep(long duration) { + this.duration = duration; + } + + public void execute(ScheduledExecutorService executor) { + doJob(); + if (next != null) { + FileLog.MAIN.logLine("Scheduling " + next); + executor.schedule(() -> next.execute(executor), duration, TimeUnit.MILLISECONDS); + } else { + MessagesCentral.getInstance().postMessage(EtbTestSequence.class, "ETB test sequence done!"); + } + } + + protected abstract void doJob(); + + public SequenceStep addNext(long duration, double position) { + return add(new EtbTarget(duration, position)); + } + + private SequenceStep add(SequenceStep step) { + next = step; + return next; + } + } + + static class EtbTarget extends SequenceStep { /** * 0-100 percent open */ final double position; - EtbTarget next; - public EtbTarget(long duration, double position) { - this.duration = duration; + super(duration); this.position = position; } - public EtbTarget addNext(long duration, double position) { - next = new EtbTarget(duration, position); - return next; - } - - public void execute(ScheduledExecutorService executor) { + protected void doJob() { CommandQueue.getInstance().write("set mock_pedal_position " + position); - if (next != null) { - FileLog.MAIN.logLine("Scheduling " + next); - executor.schedule(() -> next.execute(executor), - duration, TimeUnit.MILLISECONDS); - } } @Override