only:dead

This commit is contained in:
Andrey 2023-06-17 20:54:56 -04:00
parent c925eedf65
commit 349f2fe51e
30 changed files with 0 additions and 1930 deletions

View File

@ -1,48 +0,0 @@
package com.rusefi;
import com.rusefi.models.MafValue;
import com.rusefi.models.RpmValue;
/**
* @author Andrey Belomutskiy
* 1/29/13
*/
public class ReportLine {
private final int time;
private final MafValue maf;
private final RpmValue rpm;
private final int wave;
public ReportLine(int time, MafValue maf, RpmValue rpm, int wave) {
this.time = time;
this.maf = maf;
this.rpm = rpm;
this.wave = wave;
}
public int getTime() {
return time;
}
public MafValue getMaf() {
return maf;
}
public RpmValue getRpm() {
return rpm;
}
public int getWave() {
return wave;
}
@Override
public String toString() {
return "ReportLine{" +
"time=" + time +
", maf=" + maf +
", rpm=" + rpm +
", wave=" + wave +
'}';
}
}

View File

@ -1,36 +0,0 @@
package com.rusefi.models;
import com.rusefi.config.Field;
/**
* @author Andrey Belomutskiy
* 7/14/2015
*/
public class Array1D {
private double[] values;
public Array1D(double[] values) {
this.values = values;
for (int i = 1; i < values.length; i++) {
double prev = values[i - 1];
double current = values[i];
if (prev >= current)
throw new IllegalStateException("Out of order at index " + i);
}
}
public static Array1D create(Field field, int offset, int size) {
double result[] = new double[size];
return new Array1D(result);
}
public int findIndex(double v) {
for (int i = 0; i < values.length; i++) {
if (v < values[i])
return i - 1;
}
return values.length;
}
}

View File

@ -1,19 +0,0 @@
package com.rusefi.models;
/**
* type-safe engine load value
*
* @author Andrey Belomutskiy
* 7/14/2015
*/
public class EngineLoad {
private final double value;
public EngineLoad(double value) {
this.value = value;
}
public double getValue() {
return value;
}
}

View File

@ -1,9 +0,0 @@
package com.rusefi.models;
/**
* @author Andrey Belomutskiy
* 1/29/13
*/
public interface Factory<K, V> {
V create(K key);
}

View File

@ -1,29 +0,0 @@
package com.rusefi.models;
/**
* @author Andrey Belomutskiy
* 1/29/13
*/
public class MafValue {
private final int value;
public MafValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static MafValue valueOf(String value) {
return new MafValue(Utils.parseIntWithReason(value, "MAF value"));
}
@Override
public String toString() {
return "Maf{" +
value +
'}';
}
}

View File

@ -1,31 +0,0 @@
package com.rusefi.models;
/**
* Date: 3/24/13
* Andrey Belomutskiy, (c) 2013-2020
*/
public class Range {
private final float min;
private final float max;
public Range(double min, double max) {
this((float) min, (float) max);
}
public Range(float min, float max) {
this.min = min;
this.max = max;
}
public float getMin() {
return min;
}
public float getMax() {
return max;
}
public float getWidth() {
return max - min;
}
}

View File

@ -1,30 +0,0 @@
package com.rusefi.models;
/**
* Type-safe immutable RPM value
*
* @author Andrey Belomutskiy
* 1/29/13
*/
public class RpmValue {
private final int value;
public RpmValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static RpmValue valueOf(String value) {
return new RpmValue(Integer.valueOf(value));
}
@Override
public String toString() {
return "Rpm{"
+ value +
'}';
}
}

View File

@ -1,46 +1,10 @@
package com.rusefi.models;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* @author Andrey Belomutskiy
* 1/29/13
*/
public class Utils {
// i do not want to deal with overflow so no MAX_VALUE for me
private static final int LARGE_VALUE = 10000000;
/**
* finds a key in the map which is closest to the specified element
*/
public static int findClosest(TreeMap<Integer, ?> map, int value) {
SortedMap<Integer, ?> head = map.headMap(value, true);
SortedMap<Integer, ?> tail = map.tailMap(value, true);
if (head.isEmpty() && tail.isEmpty())
throw new IllegalStateException("Empty map? " + value);
int fromHead = head.isEmpty() ? LARGE_VALUE : head.lastKey();
int fromTail = tail.isEmpty() ? LARGE_VALUE : tail.firstKey();
int headDiff = Math.abs(value - fromHead);
int tailDiff = Math.abs(value - fromTail);
return headDiff < tailDiff ? fromHead : fromTail;
}
/**
* gets an element from the map. if no such element - new one is created using the factory
*/
public static <K, V> V getOrCreate(Map<K, V> map, K key, Factory<K, V> factory) {
V result = map.get(key);
if (result != null)
return result;
result = factory.create(key);
map.put(key, result);
return result;
}
public static int parseIntWithReason(String number, String reason) {
try {
return Integer.parseInt(number);

View File

@ -1,12 +0,0 @@
package com.rusefi.trigger;
/**
* Andrey Belomutskiy, (c) 2013-2020
* 1/18/2015
*/
public class MiataNA implements TriggerShape {
@Override
public int getTotalToothCount() {
return 6;
}
}

View File

@ -1,11 +0,0 @@
package com.rusefi.trigger;
/**
* http://rusefi.com/wiki/index.php?title=Manual:Software:Trigger
*
* Andrey Belomutskiy, (c) 2013-2020
* 1/18/2015
*/
public interface TriggerShape {
int getTotalToothCount();
}

View File

@ -1,9 +0,0 @@
package com.rusefi.trigger;
/**
* Andrey Belomutskiy, (c) 2013-2020
* 1/18/2015
*/
public class TriggerShapeHolder {
public static TriggerShape CURRENT = new MiataNA();
}

View File

@ -1,32 +0,0 @@
package com.rusefi.models.test;
import com.rusefi.models.Array1D;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Andrey Belomutskiy
* 7/14/2015
*/
public class Array1DTest {
@Test
public void testArrayValidation() {
try {
new Array1D(new double[] {3, 1});
} catch (Throwable e) {
// expected behaviour
}
new Array1D(new double[1]);
}
@Test
public void testFindIndex() {
Array1D array = new Array1D(new double[] {1 , 2, 3, 4});
assertEquals(-1, array.findIndex(0));
assertEquals(0, array.findIndex(1));
assertEquals(0, array.findIndex(1.5));
assertEquals(4, array.findIndex(15));
}
}

View File

@ -1,29 +0,0 @@
package com.rusefi.models.test;
import org.junit.Test;
import java.util.TreeMap;
import static com.rusefi.models.Utils.findClosest;
import static junit.framework.Assert.assertEquals;
/**
* @author Andrey Belomutskiy
* 1/29/13
*/
public class UtilTest {
@Test
public void testClosest() {
TreeMap<Integer, Object> map = new TreeMap<>();
map.put(0, "0");
map.put(1, "1");
map.put(10, "10");
map.put(11, "11");
assertEquals(0, findClosest(map, -1));
assertEquals(0, findClosest(map, 0));
assertEquals(1, findClosest(map, 1));
assertEquals(1, findClosest(map, 3));
assertEquals(10, findClosest(map, 10));
}
}

View File

@ -1,324 +0,0 @@
package com.rusefi;
import com.rusefi.core.MessagesCentral;
import com.rusefi.core.Sensor;
import com.rusefi.core.SensorCentral;
import com.rusefi.file.TableGenerator;
import com.rusefi.models.Point3D;
import com.rusefi.models.Range;
import com.rusefi.models.XYData;
//import com.rusefi.ui.ChartHelper;
import com.rusefi.ui.RpmModel;
//import com.rusefi.ui.widgets.PotCommand;
import com.rusefi.ui.widgets.RpmCommand;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
* Date: 3/24/13
* Andrey Belomutskiy, (c) 2013-2020
*/
/*
public class EcuStimulator {
private static final String DELIMITER = ",";
private static final long SLEEP_TIME = 300;
private static final double EPS = 0.001;
public boolean isDisplayingFuel = true;
private static final int MEASURES = 7;
// private static final String C_FILE_NAME = "advance_map.c";
// private static final String C_PREFIX = "ad_";
private static final String C_PREFIX = "fuel_";
public static Range RPM_RANGE = new Range(0, StimulationInputs.DEFAULT_RPM_MAX); // x-coord
private StimulationInputs inputs = new StimulationInputs(this);
//
private XYData data = new XYData();
private DefaultSurfaceModel model = ChartHelper.createDefaultSurfaceModel(data, RPM_RANGE, new Range(1, 5));
private final JPanel content = new JPanel(new BorderLayout());
private static EcuStimulator instance = new EcuStimulator();
private final JLabel statusLabel = new JLabel();
private EcuStimulator() {
JPanel panel = ChartHelper.create3DControl(data, model, isDisplayingFuel ? "Fuel Table" : "Timing");
content.add(statusLabel, BorderLayout.NORTH);
content.add(panel, BorderLayout.CENTER);
content.add(inputs.getContent(), BorderLayout.SOUTH);
}
public static EcuStimulator getInstance() {
return instance;
}
public JPanel getPanel() {
return content;
}
public void buildTable() {
data.clear();
// setPotVoltage(2.2, Sensor.MAF);
// if (1 == 1)
// return;
String csvFileName = "table_" + inputs.getRpmStep() + "_" + inputs.getEngineLoadStep() + FileLog.getDate() + ".csv";
FileLog.MAIN.logLine("Wring to " + csvFileName);
final BufferedWriter csv;
try {
csv = new BufferedWriter(new FileWriter(csvFileName));
} catch (IOException e) {
throw new IllegalStateException(e);
}
ResultListener listener = new ResultListener() {
@Override
public void onResult(int rpm, double engineLoad, double advance, double dwell) {
data.addPoint(new Point3D(rpm, engineLoad, isDisplayingFuel ? (float) dwell : (float) advance));
model.plot().execute();
String msg = putValue("rpm", rpm) +
putValue("engine_load", engineLoad) +
putValue("advance", advance) +
putValue("dwell", dwell);
MessagesCentral.getInstance().postMessage(EcuStimulator.class, msg);
try {
csv.write(msg + "\r\n");
csv.flush();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
};
ChartHelper.setYRange(new Range(inputs.getEngineLoadMin(), inputs.getEngineLoadMax()), model);
//buildTable(listener, DWELL_SENSOR);
try {
csv.close();
} catch (IOException e) {
throw new IllegalStateException(e);
}
TableGenerator.writeAsC(data, C_PREFIX, "map" + FileLog.getDate() + ".c");
}
private void buildTable(ResultListener listener, Sensor dwellSensor) {
for (double rpm = inputs.getRpmFrom(); rpm <= inputs.getRpmTo() + EPS; rpm += inputs.getRpmStep()) {
for (double engineLoad = inputs.getEngineLoadMin(); engineLoad <= inputs.getEngineLoadMax() + EPS; engineLoad += inputs.getEngineLoadStep()) {
for (int clt = inputs.getCltFrom(); clt <= inputs.getCltTo(); clt += 100) {
testPoint((int) rpm, engineLoad, clt, listener, dwellSensor);
}
}
}
}
private void testPoint(int rpm, double engineLoad, int clt, ResultListener resultListener, Sensor dwellSensor) {
//setPotVoltage(maf, Sensor.MAF);
setPotVoltage(engineLoad, null);
setRpm(rpm);
/**
* Let's give the firmware some time to react
*/
/*
sleepRuntime(SLEEP_TIME);
statusLabel.setText("RPM " + rpm + ", el " + engineLoad + ", CLT " + clt);
/**
* We are making a number of measurements and then we take the middle one
*/
/*
MultipleMeasurements r = waitForMultipleResults(dwellSensor, null);
List<Double> dwells = r.getDwells();
List<Double> advances = r.getAdvances();
// sorting measurements, taking middle value
Collections.sort(dwells);
Collections.sort(advances);
double dwellDiff = Math.abs(dwells.get(0) - dwells.get(MEASURES - 1));
if (dwellDiff > 1)
System.out.println("dwells " + dwells);
double dwell = dwells.get(MEASURES / 2);
double advance = advances.get(MEASURES / 2);
// if (dwell > 40)
// throw new IllegalStateException("Unexpected value, how come? " + dwell);
log("Stimulator result: " + rpm + "@" + engineLoad + ": " + dwell + ", adv=" + advance);
// double dwell = Launcher.getAdcModel().getValue(Sensor.DWELL0);
// double advance = Launcher.getAdcModel().getValue(Sensor.ADVANCE);
resultListener.onResult(rpm, engineLoad, (float) advance, dwell);
}
private static void sleepRuntime(long sleepTime) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
private static double getValue(Sensor sensor) {
return SensorCentral.getInstance().getValue(sensor);
}
private static void setRpm(int rpm) {
int actual;
int attempt = 0;
do {
RpmCommand.requestRpmChange(rpm, null);
sleepRuntime(50);
actual = RpmModel.getInstance().getValue();
} while (attempt++ < 10 && Math.abs(rpm - actual) >= 100);
log("Result: " + actual + " while setting " + rpm);
}
public static void setPotVoltage(double targetVoltage, Sensor sensor) {
if (sensor != null)
log("Current targetVoltage: " + getValue(sensor) + ", setting " + targetVoltage);
int attempt = 0;
double vRef = getVRef();
int resistance = PotCommand.getPotResistance(targetVoltage, vRef);
if (resistance <= 0) {
log("Invalid resistance " + resistance + ". Invalid targetVoltage " + targetVoltage + "?");
return;
}
if (sensor == null) {
PotCommand.requestPotChange(1, resistance);
sleepRuntime(1000);
} else {
double actual;
do {
PotCommand.requestPotChange(1, resistance);
sleepRuntime(50);
actual = getValue(sensor);
log("Got: " + actual + " on attempt=" + attempt + " while setting " + targetVoltage + " for " + sensor);
} while (attempt++ < 10 && Math.abs(targetVoltage - actual) > 0.2);
log("Result: " + actual + " while setting " + targetVoltage);
}
}
private static double getVRef() {
// todo: make this adjustable via the UI
//double vRef = SensorCentral.getConfig().getValue(Sensor.VREF) * PotCommand.VOLTAGE_CORRECTION;
return 4.7;
}
private static void log(String message) {
MessagesCentral.getInstance().postMessage(EcuStimulator.class, message);
FileLog.MAIN.logLine(message);
}
private static String putValue(String msg, double value) {
return msg + DELIMITER + value + DELIMITER;
}
private static String putValue(String msg, int value) {
return msg + DELIMITER + value + DELIMITER;
}
public JButton createButton() {
final JButton button = new JButton("stimulate stock ECU");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new Thread(new Runnable() {
@Override
public void run() {
try {
buildTable();
} catch (Throwable e) {
e.printStackTrace();
System.exit(-20);
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
button.setText("Done");
}
});
}
}, "Ecu Stimulator").start();
}
});
return button;
}
public StimulationInputs getInputs() {
return inputs;
}
interface ResultListener {
void onResult(int rpm, double engineLoad, double advance, double dwell);
}
public MultipleMeasurements waitForMultipleResults(final Sensor dwellSensor, final Sensor advanceSensor) {
final MultipleMeasurements result = new MultipleMeasurements();
final CountDownLatch latch = new CountDownLatch(MEASURES);
/*
EngineTimeListener listener = new EngineTimeListener() {
@Override
public void onTime(double time) {
if (latch.getCount() == 0)
return;
double dwell = getValue(dwellSensor);
double advance = getValue(advanceSensor);
advance = Sensor.processAdvance(advance);
result.dwells.add(dwell);
result.advances.add(advance);
latch.countDown();
}
};
LinkManager.engineState.timeListeners.add(listener);
try {
latch.await();
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
LinkManager.engineState.timeListeners.remove(listener);
*/
/*
return result;
}
private static class MultipleMeasurements {
private List<Double> dwells = new ArrayList<>(MEASURES);
private List<Double> advances = new ArrayList<>(MEASURES);
public List<Double> getDwells() {
return dwells;
}
public List<Double> getAdvances() {
return advances;
}
}
}
*/

View File

@ -1,155 +0,0 @@
package com.rusefi;
import com.rusefi.models.Factory;
import com.rusefi.models.MafValue;
import com.rusefi.models.RpmValue;
import com.rusefi.models.Utils;
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Date: 1/29/13
* Andrey Belomutskiy, (c) 2013-2020
*/
public class ReportReader {
private static final Pattern LINE_PATTERN = Pattern.compile("\\D*(\\d*);a0;(\\d*);a1;-1;rpm;(\\d*);wave;(\\d*).*");
private static final int INVALID_RPM_DIFF = 200;
public static void main(String[] args) {
//List<ReportLine> lines = read("unfiltered.txt");
readMap("200ohm.txt");
}
public static TreeMap<Integer, TreeMap<Integer, ReportLine>> readMap(String filename) {
if (!new File(filename).exists()) {
FileLog.MAIN.logLine("Error: not found " + filename);
return new TreeMap<>();
}
List<ReportLine> lines = read(filename);
FileLog.MAIN.logLine("Got " + lines.size() + " lines");
lines = filter(Collections.unmodifiableList(lines));
findMinMax(lines);
return asMap(lines);
}
private static TreeMap<Integer, TreeMap<Integer, ReportLine>> asMap(List<ReportLine> lines) {
/**
* map of maps by RPM. inner map is by MAF
*/
TreeMap<Integer, TreeMap<Integer, ReportLine>> rpm2mapByMaf = new TreeMap<>();
for (ReportLine cur : lines) {
int rpmKey = cur.getRpm().getValue();
// round to 100
rpmKey -= (rpmKey % 100);
TreeMap<Integer, ReportLine> maf2line = Utils.getOrCreate(rpm2mapByMaf, rpmKey, new Factory<Integer, TreeMap<Integer, ReportLine>>() {
public TreeMap<Integer, ReportLine> create(Integer key) {
return new TreeMap<>();
}
});
maf2line.put(cur.getMaf().getValue(), cur);
}
return rpm2mapByMaf;
}
private static void findMinMax(List<ReportLine> lines) {
int minMaf = 100000;
int maxMaf = 0;
int minRpm = 100000;
int maxRpm = 0;
for (ReportLine cur : lines) {
minMaf = Math.min(minMaf, cur.getMaf().getValue());
maxMaf = Math.max(maxMaf, cur.getMaf().getValue());
minRpm = Math.min(minRpm, cur.getRpm().getValue());
maxRpm = Math.max(maxRpm, cur.getRpm().getValue());
}
FileLog.MAIN.logLine("MAF range from " + minMaf + " to " + maxMaf);
FileLog.MAIN.logLine("RPM range from " + minRpm + " to " + maxRpm);
}
private static List<ReportLine> filter(List<ReportLine> lines) {
List<ReportLine> result = new ArrayList<>();
int maxValidDiff = 0;
int originalCount = lines.size();
int removedCount = 0;
result.add(lines.get(0));
for (int i = 1; i < lines.size(); i++) {
ReportLine prev = result.get(result.size() - 1);
ReportLine cur = lines.get(i);
int rpmDiff = cur.getRpm().getValue() - prev.getRpm().getValue();
int timeDiff = cur.getTime() - prev.getTime();
if (Math.abs(rpmDiff) > INVALID_RPM_DIFF) {
FileLog.MAIN.logLine("Invalid diff: " + cur);
removedCount++;
continue;
}
result.add(cur);
// maximum valid diff
maxValidDiff = Math.max(maxValidDiff, Math.abs(rpmDiff));
// System.out.println("current rpm: " + cur + ", rpm diff=" + rpmDiff + " td=" + timeDiff);
// System.out.println("value," + cur.getRpm().getValue() + "," + cur.getMaf().getValue() + "," + cur.getWave());
}
double percent = 100.0 * removedCount / originalCount;
FileLog.MAIN.logLine(removedCount + " out of " + originalCount + " record(s) removed. " + percent + "%");
FileLog.MAIN.logLine("Max valid diff: " + maxValidDiff);
return result;
}
private static List<ReportLine> read(String filename) {
List<ReportLine> result = new LinkedList<>();
try {
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line;
while ((line = reader.readLine()) != null) {
//process each line in some way
ReportLine rl = handleOneLine(line);
if (rl != null)
result.add(rl);
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
return result;
}
private static int prevMaf = -1;
private static int prevRpm = -1;
private static int prevWave = -1;
private static ReportLine handleOneLine(String line) {
// System.out.println(line);
Matcher m = LINE_PATTERN.matcher(line);
if (m.matches()) {
int time = Integer.parseInt(m.group(1));
MafValue maf = MafValue.valueOf(m.group(2));
RpmValue rpm = RpmValue.valueOf(m.group(3));
int wave = Integer.parseInt(m.group(4));
if (prevMaf == maf.getValue() && prevRpm == rpm.getValue() && prevWave == wave) {
// System.out.println("All the same...");
return null;
}
//System.out.println(time + " m=" + maf + " r=" + rpm + " w=" + wave);
prevMaf = maf.getValue();
prevRpm = rpm.getValue();
prevWave = wave;
return new ReportLine(time, maf, rpm, wave);
}
return null;
}
}

View File

@ -1,97 +0,0 @@
package com.rusefi.etb;
import com.rusefi.CyclicBuffer;
import com.rusefi.DataBuffer;
import com.rusefi.NamedThreadFactory;
import com.rusefi.core.Sensor;
import com.rusefi.core.SensorCentral;
import com.rusefi.core.SensorStats;
import com.rusefi.core.ValueSource;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
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
* Andrey Belomutskiy, (c) 2013-2020
*
* @see SensorStats
*/
public class ClosedLoopControlQualityMetric {
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory(ClosedLoopControlQualityMetric.class.getSimpleName()));
private final int delayDepth;
private final ValueSource target;
private final ValueSource result;
private final Sensor destination;
private boolean isStarted;
/**
* Buffer of recent error measurements
* GuardedBy(this)
*/
private DataBuffer errorsBuffer;
private CyclicBuffer targetBuffer;
/**
* @param delayDepth
* @param target what value are we trying to achieve
* @param result what value do we actually have
*/
public ClosedLoopControlQualityMetric(ValueSource target, ValueSource result, Sensor destination, int delayDepth) {
this.target = target;
this.result = result;
this.destination = destination;
this.delayDepth = delayDepth;
}
public void start(int bufferSize, int periodMs) {
if (isStarted)
return;
isStarted = true;
create(bufferSize);
executor.scheduleAtFixedRate(() -> {
add();
SensorCentral.getInstance().setValue(getStandardDeviation(), destination);
}, 0, periodMs, TimeUnit.MILLISECONDS);
}
public void add() {
double targetValue = target.getValue();
double resultValue = result.getValue();
double error = Math.abs(targetValue - resultValue);
int pointer = targetBuffer.getPointer();
for (int i = 0; i < Math.min(delayDepth - 1, targetBuffer.getSize()); i++) {
double thisError = Math.abs(targetBuffer.get(pointer - i) - resultValue);
error = Math.min(error, thisError);
}
rememberCurrentError(error, targetValue);
}
public void create(int bufferSize) {
errorsBuffer = new CyclicBuffer(bufferSize);
targetBuffer = new CyclicBuffer(delayDepth);
}
public synchronized void reset() {
errorsBuffer.clear();
}
public synchronized double getStandardDeviation() {
return DataBuffer.getStandardDeviation(errorsBuffer.getValues());
}
private synchronized void rememberCurrentError(double error, double targetValue) {
Objects.requireNonNull(errorsBuffer, "errorsBuffer");
errorsBuffer.add(error);
targetBuffer.add(targetValue);
}
}

View File

@ -1,33 +0,0 @@
package com.rusefi.etb.test;
import com.rusefi.core.Sensor;
import com.rusefi.etb.ClosedLoopControlQualityMetric;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.Assert.assertEquals;
public class ClosedLoopControlQualityMetricTest {
private static final double EPS = 0;
@Test
public void testPastDepth() {
AtomicInteger targetValue = new AtomicInteger();
AtomicInteger resultValue = new AtomicInteger();
ClosedLoopControlQualityMetric m = new ClosedLoopControlQualityMetric(
targetValue::doubleValue,
resultValue::doubleValue,
Sensor.ETB_CONTROL_QUALITY, 3);
m.create(1000);
m.add();
assertEquals(0, m.getStandardDeviation(), EPS);
targetValue.set(10);
// result same 0
m.add();
assertEquals(0, m.getStandardDeviation(), EPS);
}
}

View File

@ -1,59 +0,0 @@
package com.rusefi.file;
import com.rusefi.FileLog;
import com.rusefi.models.XYData;
/**
* 7/18/13
* Andrey Belomutskiy, (c) 2013-2020
*/
public class BaseMap {
public static void main(String[] args) {
loadData("a.csv", "maf", "af");
}
public static XYData loadData(String filename, final String key, final String value) {
FileLog.MAIN.logLine("Loading from " + filename);
FileLog.MAIN.logLine("Loading " + key + ">" + value);
final XYData data = new XYData();
/*
EngineState.EngineStateListener listener = new EngineState.EngineStateListenerImpl() {
Map<String, String> values = new HashMap<String, String>();
@Override
public void onKeyValue(String key, String value) {
values.put(key, value);
}
@Override
public void afterLine(String fullLine) {
if (values.containsKey("rpm") && values.containsKey(key)) {
process(values);
}
values.clear();
}
private void process(Map<String, String> values) {
int rpm = (int) Double.parseDouble(values.get("rpm"));
double k = Double.parseDouble(values.get(key));
String valueString = values.get(value);
if (valueString == null)
throw new NullPointerException("No value for: " + value);
float v = Float.parseFloat(valueString);
data.addPoint(new Point3D(rpm, k, v));
}
};
EngineState engineState = new EngineState(listener);
engineState.registerStringValueAction(EngineReport.ENGINE_CHART, new EngineState.ValueCallback<String>() {
@Override
public void onUpdate(String value) {
}
});
FileUtils.readFile2(filename, engineState);
//return AverageData.average(data, 8);
*/
return data;
}
}

View File

@ -1,89 +0,0 @@
package com.rusefi.file;
import com.rusefi.models.XYData;
import com.rusefi.models.XYDataReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Andrey Belomutskiy
* 3/27/13
*/
public class TableGenerator {
public static void main(String[] args) throws IOException {
XYData data = XYDataReader.readFile("in.csv");
writeAsC(data, "ad_", "advance_map.c");
}
public static void writeAsC(XYData data, String prefix, String fileName) {
try {
doWrite(data, prefix, fileName);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
private static void doWrite(XYData data, String prefix, String fileName) throws IOException {
List<Double> rpms = new ArrayList<>(data.getXSet());
BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
out.write("#include \"thermistors.h\"\n\n\n");
// writeArray(rpms, out, prefix + "rpm");
List<Double> engineLoadValues = new ArrayList<>(data.getYAxis(rpms.get(0)).getYs());
// writeArray(yArray, out, prefix + "maf");
out.write("static float " + prefix + "table[" + rpms.size() + "][" + engineLoadValues.size() + "] = {\n");
boolean isFirstEngineLoad = true;
int indexX = 0;
for (double engineLoad : engineLoadValues) {
if (!isFirstEngineLoad)
out.write(",\n");
isFirstEngineLoad = false;
out.write("{");
int indexY = 0;
for (double rpm : data.getXSet()) {
if (indexY == 0)
out.write("/*" + indexX + " engineLoad=" + engineLoadValues.get(indexX) + "*/");
if (indexY > 0)
out.write(", ");
out.write("/*" + indexY + " " + rpms.get(indexY) + "*/" + data.getValue(rpm, engineLoad));
indexY++;
}
out.write("}");
indexX++;
}
out.write("\n};\n");
out.close();
}
private static void writeArray(List<Double> rpms, BufferedWriter out, String title) throws IOException {
out.write("#define " + title.toUpperCase() + "_COUNT " + rpms.size() + "\n");
outputDoubles(rpms, out, title);
}
private static void outputDoubles(List<Double> values, BufferedWriter out, String title) throws IOException {
out.write("static float " + title + "_table[] = {");
for (int i = 0; i < values.size(); i++) {
if (i > 0)
out.write(", ");
out.write("/*" + i + "*/ " + values.get(i));
}
out.write("};\n\n");
}
}

View File

@ -1,78 +0,0 @@
package com.rusefi.logic;
/**
* Andrey Belomutskiy, (c) 2013-2020
* 12/24/2015
*/
public class IgnitionMapBuilder {
public enum ChamberStyle {
OPEN_CHAMBER(33),
CLOSED_CHAMBER(28),
SWIRL_TUMBLE(22);
private final int advance;
ChamberStyle(int advance) {
this.advance = advance;
}
}
public static double getTopAdvanceForBore(ChamberStyle style, int octane, double compression, double bore) {
int octaneCorrection;
if ( octane <= 90) {
octaneCorrection = -2;
} else if (octane < 94) {
octaneCorrection = -1;
} else {
octaneCorrection = 0;
}
int compressionCorrection;
if (compression <= 9) {
compressionCorrection = 2;
} else if (compression <= 10) {
compressionCorrection = 1;
} else if (compression <= 11) {
compressionCorrection = 0;
} else {
// compression ratio above 11
compressionCorrection = -2;
}
double result = style.advance + octaneCorrection + compressionCorrection + getBoreCorrection(bore);
return round10(result);
}
public static double interpolate(double x1, double y1, double x2, double y2, double x) {
double a = ((y1 - y2) / (x1 - x2));
double b = y1 - a * x1;
return a * x + b;
}
public static double getAdvanceForRpm(int rpm, double advanceMax) {
if (rpm >= 3000)
return advanceMax;
if (rpm < 600)
return 10;
return interpolate(600, 10, 3000, advanceMax, rpm);
}
public static double getInitialAdvance(int rpm, double map, double advanceMax) {
double advance = getAdvanceForRpm(rpm, advanceMax);
if (rpm > 3000)
return round10(advance + 0.1 * (100 - map));
return round10(advance + 0.1 * (100 - map) * rpm / 3000);
}
public static double round10(double result) {
return ((int)(result * 10)) / 10.0;
}
public static double getBoreCorrection(double bore) {
return (bore - 4 * 25.4) / 25.4 * 6;
}
}

View File

@ -1,50 +0,0 @@
package com.rusefi.logic.test;
import com.rusefi.logic.IgnitionMapBuilder;
import org.junit.Test;
import static com.rusefi.logic.IgnitionMapBuilder.*;
import static com.rusefi.logic.IgnitionMapBuilder.ChamberStyle.*;
import static junit.framework.Assert.assertEquals;
/**
* Andrey Belomutskiy, (c) 2013-2020
* 12/24/2015
*/
public class IgnitionMapBuilderTest {
private static final double EPS = 0.001;
@Test
public void testIgnitionMapBuilder() {
assertEquals(1.1, round10(1.1));
assertEquals(1.1, round10(1.123));
assertEquals(0.0, getBoreCorrection(4 * 25.4));
assertEquals(6.0, getBoreCorrection(5 * 25.4), EPS);
assertEquals(35.0, getTopAdvanceForBore(OPEN_CHAMBER, 98, 8, 101.6));
assertEquals(33.0, getTopAdvanceForBore(OPEN_CHAMBER, 98, 11, 101.6));
assertEquals(22.0, getTopAdvanceForBore(SWIRL_TUMBLE, 89, 9, 101.6));
assertEquals(32.2, getTopAdvanceForBore(SWIRL_TUMBLE, 89, 9, 145));
assertEquals(10.0, interpolate(0, 10, 10, 20, 0));
assertEquals(20.0, interpolate(0, 10, 10, 20, 10));
assertEquals(10.0, getAdvanceForRpm(0, 36));
assertEquals(10.0, getAdvanceForRpm(600, 36));
assertEquals(36.0, getAdvanceForRpm(6500, 36));
assertEquals(16.5, getAdvanceForRpm(1200, 36));
assertEquals(29.5, getAdvanceForRpm(2400, 36));
assertEquals(36.0, getInitialAdvance(6000, 100, 36));
assertEquals(10.0, getInitialAdvance(600, 100, 36));
assertEquals(44.0, getInitialAdvance(6000, 20, 36));
assertEquals(34.3, getInitialAdvance(2400, 40, 36));
assertEquals(42.0, getInitialAdvance(4400, 40, 36));
assertEquals(11.6, getInitialAdvance(600, 20, 36));
}
}

View File

@ -1,65 +0,0 @@
package com.rusefi.models;
import com.rusefi.FileLog;
import java.util.Set;
/**
* 7/18/13
* Andrey Belomutskiy, (c) 2013-2020
*/
public class AverageData {
public static XYData average(XYData data, int divider) {
double minX = data.getMinXValue();
double xWidth = data.getMaxXValue() - minX;
FileLog.MAIN.logLine("From x" + minX + " w=" + xWidth);
XYData result = new XYData();
for (int i = 0; i < divider; i++) {
double fromX_ = minX + (xWidth * i) / divider;
double toX_ = minX + (xWidth * (i + 1)) / divider;
FileLog.MAIN.logLine("from " + fromX_ + " to " + toX_);
// double fromX = data.findXfromSet(fromX_);
// double toX = data.findXfromSet(toX_);
// System.out.println("from internal " + fromX + " to internal " + toX);
average(data, result, fromX_, toX_, divider);
}
return result;
}
private static void average(XYData data, XYData result, double fromX, double toX, int divider) {
double minY = data.getMinYValue();
double yWidth = data.getMaxYValue() - minY;
for (int i = 0; i < divider; i++) {
double fromY_ = minY + (yWidth * i) / divider;
double toY_ = minY + (yWidth * (i + 1)) / divider;
Set<Double> xRange = data.getXSet().tailSet(fromX).headSet(toX);
int counter = 0;
double acc = 0;
for (Double x : xRange) {
YAxisData yData = data.getYAxis(x);
Set<Double> yRange = yData.getYs().tailSet(fromY_).headSet(toY_);
for (double y : yRange) {
counter++;
acc += yData.getValue(y);
}
}
if (counter == 0)
result.addPoint(new Point3D(fromX, fromY_, Float.NaN));
else
result.addPoint(new Point3D(fromX, fromY_, (float) (acc / counter)));
}
}
}

View File

@ -1,156 +0,0 @@
package com.rusefi.models;
import com.rusefi.FileLog;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import java.util.NavigableSet;
import java.util.TreeMap;
/**
* Date: 3/24/13
* Andrey Belomutskiy, (c) 2013-2020
*
* @see com.rusefi.file.TableGenerator
*/
public class XYData {
@NotNull
private final TreeMap<Double, YAxisData> yDatas = new TreeMap<Double, YAxisData>();
private double maxXValue;
private double minXValue;
private double maxYValue;
private double minYValue;
String date = FileLog.getDate();
public XYData() {
clear();
}
public float getValue(double x, double y) {
YAxisData yAxis = findYAxis(x);
if (yAxis == null)
return Float.NaN; // empty map?
return yAxis.findZ(y);
}
public double getMaxXValue() {
return maxXValue;
}
public double getMinXValue() {
return minXValue;
}
public double getMaxYValue() {
return maxYValue;
}
public double getMinYValue() {
return minYValue;
}
public void addPoint(int rpm, double key, float value) {
addPoint(new Point3D(rpm, key, value));
}
public void addPoint(Point3D xyz) {
YAxisData yAxis = getYdata(xyz);
yAxis.addValue(xyz.getY(), xyz.getZ());
}
public void setPoint(Point3D xyz) {
YAxisData yAxis = getYdata(xyz);
yAxis.setValue(xyz.getY(), xyz.getZ());
}
private YAxisData getYdata(Point3D xyz) {
minYValue = Math.min(minYValue, xyz.getY());
maxYValue = Math.max(maxYValue, xyz.getY());
return getYAxis(xyz.getX());
}
@NotNull
public NavigableSet<Double> getXSet() {
return yDatas.navigableKeySet();
}
@NotNull
public YAxisData getYAxis(double x) {
YAxisData result = yDatas.get(x);
if (result == null) {
result = new YAxisData(x);
maxXValue = Math.max(maxXValue, x);
minXValue = Math.min(minXValue, x);
yDatas.put(x, result);
}
return result;
}
@Nullable
public YAxisData findYAxis(double x) {
double xfromSet = findXfromSet(x);
if (Double.isNaN(xfromSet))
return null;
return yDatas.get(xfromSet);
}
public double findXfromSet(double x) {
Map.Entry<Double, YAxisData> floorEntry = yDatas.floorEntry(x);
if (floorEntry != null)
return floorEntry.getKey();
Map.Entry<Double, YAxisData> ceilingEntry = yDatas.ceilingEntry(x);
if (ceilingEntry == null)
return Double.NaN;
return ceilingEntry.getKey();
}
public void clear() {
maxXValue = Double.MIN_VALUE;
minXValue = Double.MAX_VALUE;
maxYValue = Double.MIN_VALUE;
minYValue = Double.MAX_VALUE;
yDatas.clear();
}
@Override
public String toString() {
return "XYData{" +
"yDatas.size()=" + yDatas.size() +
'}';
}
public void saveToFile(String filename) {
try {
String name = date + filename;
FileLog.MAIN.logLine("Writing data to " + name);
Writer w = new FileWriter(name);
for (YAxisData yAxisData : yDatas.values())
yAxisData.write(w);
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void fill(Range rpmRange, Range keyRange, int count, float value) {
clear();
for (int i = 0; i < count; i++)
for (int j = 0; j < count; j++) {
float rpm = rpmRange.getMin() + (rpmRange.getWidth() * i / count);
float key = keyRange.getMin() + (keyRange.getWidth() * j / count);
addPoint(new Point3D(rpm, key, value));
}
}
}

View File

@ -1,37 +0,0 @@
package com.rusefi.models;
import com.rusefi.FileLog;
import java.io.*;
/**
* 6/30/13
* Andrey Belomutskiy, (c) 2013-2020
*/
public class XYDataReader {
public static XYData readFile(String fileName) {
if (!new File(fileName).exists())
throw new IllegalArgumentException("No file: " + fileName);
try {
return doReadFile(fileName);
} catch (FileNotFoundException e) {
throw new IllegalStateException(e);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
private static XYData doReadFile(String fileName) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line;
XYData data = new XYData();
while ((line = reader.readLine()) != null) {
//process each line in some way
Point3D xyz = Point3D.parseLine(line);
data.addPoint(xyz);
}
FileLog.MAIN.logLine("x range: " + data.getMinXValue() + " to " + data.getMaxXValue());
FileLog.MAIN.logLine("y range: " + data.getMinYValue() + " to " + data.getMaxYValue());
return data;
}
}

View File

@ -1,109 +0,0 @@
package com.rusefi.models;
import com.rusefi.FileLog;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import java.util.NavigableSet;
import java.util.TreeMap;
/**
* Y>Z mapping for the same X
* <p/>
* Date: 3/24/13
* Andrey Belomutskiy, (c) 2013-2020
*/
public class YAxisData {
private final TreeMap<Double, ValuesHolder> values = new TreeMap<Double, ValuesHolder>();
private double maxYValue = Double.MIN_VALUE;
private double minYValue = Double.MAX_VALUE;
private final double x;
public YAxisData(double x) {
this.x = x;
}
public double getX() {
return x;
}
public NavigableSet<Double> getYs() {
return values.navigableKeySet();
}
public float findZ(double y) {
Map.Entry<Double, ValuesHolder> entry = values.floorEntry(y);
if (entry != null)
return entry.getValue().get();
return values.ceilingEntry(y).getValue().get();
}
public void setValue(double y, float value) {
ValuesHolder holder = getHolder(y);
holder.set(value);
}
public void addValue(double y, float value) {
ValuesHolder holder = getHolder(y);
holder.add(value);
float newAvg = holder.get();
if (newAvg != value && !Float.isNaN(newAvg)) {
FileLog.MAIN.logLine("new " + value + " avg " + newAvg + " for x=" + x + "/y=" + y);
}
}
private ValuesHolder getHolder(double y) {
minYValue = Math.min(minYValue, y);
maxYValue = Math.max(maxYValue, y);
ValuesHolder holder = values.get(y);
if (holder == null)
values.put(y, holder = new ValuesHolder());
return holder;
}
public double getValue(double y) {
return values.get(y).get();
}
@Override
public String toString() {
return "YAxisData{" +
"size=" + values.size() +
", maxYValue=" + maxYValue +
", minYValue=" + minYValue +
", x=" + x +
'}';
}
public void write(Writer w) throws IOException {
for (Map.Entry<Double, ValuesHolder> e : values.entrySet())
w.write("rpm," + x + ",key," + e.getKey() + ",value," + e.getValue().get() + "\r\n");
}
private static class ValuesHolder {
private float total;
private int count;
private ValuesHolder() {
}
public float get() {
return total / count;
}
public void add(float value) {
total += value;
count++;
}
public void set(float value) {
total = value;
count = 1;
}
}
}

View File

@ -1,66 +0,0 @@
package com.rusefi.ui;
//import com.rusefi.EcuStimulator;
import com.rusefi.core.MessagesCentral;
import com.rusefi.models.Point3D;
import com.rusefi.models.Range;
import com.rusefi.models.XYData;
//import net.ericaro.surfaceplotter.DefaultSurfaceModel;
import javax.swing.*;
import java.awt.*;
/**
* 7/22/13
* Andrey Belomutskiy, (c) 2013-2020
*/
/*
public class Live3DReport {
public static final Range KEY_RANGE = new Range(1.5f, 4.0f);
private final XYData primary = new XYData();
private final XYData secondary = null;//new XYData();
private final JPanel control;
private static final String KEY = "map_adjusted: ";
public Live3DReport() {
final DefaultSurfaceModel model = ChartHelper.createDefaultSurfaceModel(primary, EcuStimulator.RPM_RANGE, KEY_RANGE, secondary);
// primary.fill(EcuStimulator.RPM_RANGE, KEY_RANGE, 16, 1);
control = ChartHelper.create3DControl(primary, model, "Live Data");
// addPoint("1000 3 0.9", model);
// addPoint("1000 320 90", model);
// addPoint("1000 340 90", model);
MessagesCentral.getInstance().addListener(new MessagesCentral.MessageListener() {
@Override
public void onMessage(Class clazz, String message) {
if (!message.startsWith(KEY))
return;
message = message.substring(KEY.length());
addPoint(message, model);
}
});
}
private void addPoint(String message, DefaultSurfaceModel model) {
String[] v = message.split(" ");
if (v.length != 3)
return;
int rpm = Integer.parseInt(v[0]);
float key = Integer.parseInt(v[1]) / 100.0f;
float value = Integer.parseInt(v[2]) / 100.0f;
primary.setPoint(new Point3D(rpm, key, value));
primary.saveToFile("_mult.csv");
model.plot().execute();
}
public Component getControl() {
return control;
}
}
*/

View File

@ -1,27 +0,0 @@
package com.rusefi.ui;
import com.rusefi.file.BaseMap;
import com.rusefi.models.XYData;
import com.rusefi.core.ui.FrameHelper;
import javax.swing.*;
/**
* 7/18/13
* Andrey Belomutskiy, (c) 2013-2020
*/
/*
public class ShowMap {
public static void main(String[] args) {
// XYData data = BaseMap.loadData("a.csv", "maf", "af");
// XYData data2 = BaseMap.loadData("a.csv", "maf", "table_fuel");
XYData data = BaseMap.loadData("200.csv", "maf", "dwell");
XYData data2 = null;
JPanel jsp = ChartHelper.create3DControl(data, ChartHelper.createDefaultSurfaceModel(data, data2), "MAF<>Fuel Map");
new FrameHelper().showFrame(jsp);
}
}
*/

View File

@ -1,159 +0,0 @@
package com.rusefi.ui;
import com.rusefi.AverageAnglePanel;
import com.rusefi.core.Sensor;
import com.rusefi.core.SensorCentral;
import com.rusefi.OutputChannel;
import com.rusefi.io.CommandQueue;
import com.rusefi.io.InvocationConfirmationListener;
import com.rusefi.trigger.TriggerShapeHolder;
import com.rusefi.ui.util.UiUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Date;
import java.util.concurrent.atomic.AtomicReference;
/**
* 1/17/2015
*/
public class Wizard {
private final JPanel panel = new JPanel(new BorderLayout());
private final JPanel content = new JPanel();
private final JButton button = new JButton("Trigger Wizard");
interface WizardStep {
Component getContent();
}
abstract static class WizardStepImpl implements WizardStep {
protected WizardStep nextStep;
public WizardStepImpl() {
}
public WizardStepImpl setNext(WizardStepImpl nextStep) {
this.nextStep = nextStep;
return nextStep;
}
}
class SendCommand extends WizardStepImpl {
private final String command;
SendCommand(String command) {
this.command = command;
}
@Override
public Component getContent() {
CommandQueue instance = null;
instance.write(command, CommandQueue.DEFAULT_TIMEOUT, new InvocationConfirmationListener() {
@Override
public void onCommandConfirmation() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
applyStep(nextStep);
}
});
}
});
return new JLabel("Sending " + command);
}
}
private final WizardStepImpl TRIGGER_WIZARD_HELLO = new WizardStepImpl() {
@Override
public Component getContent() {
JButton button = new JButton("Hello, let's test trigger. Click this to process");
button.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
applyStep(nextStep);
}
});
return button;
}
};
{
TRIGGER_WIZARD_HELLO.setNext(new SendCommand("disable injection"))
.setNext(new SendCommand("disable ignition"))
.setNext(new SendCommand("chartsize " + (10 * TriggerShapeHolder.CURRENT.getTotalToothCount() * 2)))
.setNext(new SendCommand("subscribe " + OutputChannel.WaveChartCurrentSize.getProtocolId()))
.setNext(new SendCommand("subscribe " + OutputChannel.RunningTriggerError.getProtocolId()))
.setNext(new SendCommand("subscribe " + OutputChannel.RunningOrderingTriggerError.getProtocolId()))
.setNext(new SendCommand("set_analog_chart_freq " + 1))
.setNext(new WaitForZeroRpm())
;
}
public Component createPane() {
panel.add(button, BorderLayout.NORTH);
panel.add(content, BorderLayout.CENTER);
panel.add(new AverageAnglePanel(null).getPanel(), BorderLayout.SOUTH);
button.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
button.setEnabled(false);
applyStep(Wizard.this.TRIGGER_WIZARD_HELLO);
}
});
return panel;
}
private void applyStep(WizardStep step) {
System.out.println(new Date() + " apply " + step);
Component newContent = getContent(step);
content.removeAll();
content.add(newContent);
UiUtils.trueLayout(content);
}
private Component getContent(WizardStep step) {
Component newContent;
if (step == null) {
newContent = new JLabel("Wizard is done!");
button.setEnabled(true);
} else {
newContent = step.getContent();
}
return newContent;
}
private class WaitForZeroRpm extends WizardStepImpl {
private int counter;
@Override
public Component getContent() {
double rpm = SensorCentral.getInstance().getValue(Sensor.RPMValue);
if (rpm == 0) {
return Wizard.this.getContent(nextStep);
}
scheduleRepaint(1000, this);
return new JLabel("Current RPM: " + rpm + ", please stop the engine. Waiting " + counter++);
}
}
private void scheduleRepaint(int timeoutMs, final WizardStep step) {
final AtomicReference<Timer> tHolder = new AtomicReference<>();
Timer t = new Timer(timeoutMs, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tHolder.get().stop();
applyStep(step);
}
});
tHolder.set(t);
t.start();
}
}

View File

@ -1,75 +0,0 @@
package com.rusefi.models.test;
import java.util.ArrayList;
import java.util.Random;
public class SoftLimiterSandbox {
private Random r = new Random();
public static void main(String[] args) {
new SoftLimiterSandbox().testSoftLimit();
}
public void testSoftLimit() {
double targetMissRatio = 0.3;
int windowSize = 50;
State state = new State(windowSize);
System.out.println("Target miss ratio: " + targetMissRatio);
System.out.println("Window length: " + windowSize);
System.out.println("eventIndex,state,currentWindowDeepRatio");
for (int i = 0; i < 250 * windowSize; i++) {
state.add(targetMissRatio);
System.out.println(i + "," + state.getLatest() + "," + state.getCurrentRatio());
}
}
class State {
private final int windowSize;
ArrayList<Boolean> states = new ArrayList<>();
public State(int windowSize) {
this.windowSize = windowSize;
states.add(false);
}
boolean getLatest() {
return states.get(states.size() - 1);
}
double getCurrentRatio() {
int from = Math.max(0, states.size() - windowSize);
int count = 0;
for (int i = from; i < states.size(); i++) {
if (states.get(i))
count++;
}
return count * 1.0 / windowSize;
}
public void add(double targetMissRatio) {
if (!getLatest()) {
// never skip two in a row
states.add(true);
} else {
double currentRatio = getCurrentRatio();
//double thisEventProbability =
/**
* Due to "never miss two events in a row" requirement we want more or less double the target in comparison
* if current ratio is above target we want to lower probability for next event to fire
*/
boolean newState = r.nextDouble() > 2 * targetMissRatio;
states.add(newState);
}
}
}
}

View File

@ -1,20 +0,0 @@
package com.rusefi.models.test;
import com.rusefi.models.XYData;
/**
* 7/24/13
* Andrey Belomutskiy, (c) 2013-2020
*/
public class XYDataSandbox {
public static void main(String[] args) {
XYData d = new XYData();
d.addPoint(600, 3, 11);
d.addPoint(600, 3.1, 11);
d.addPoint(1600, 3.1, 11);
d.saveToFile("_mult.dat");
}
}