This commit is contained in:
rusEfi 2019-03-02 15:40:55 -05:00
parent 66af49df63
commit 8e3d4490bd
3 changed files with 72 additions and 41 deletions

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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
* <p>
* 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.
* <p>
* Error standard deviation is posted to {@link Sensor#ETB_CONTROL_QUALITY}
* <p>
* https://github.com/rusefi/rusefi/issues/494
* <p>
* 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