diff --git a/java_console/models/src/com/rusefi/autotune/FuelAutoLogic.java b/java_console/models/src/com/rusefi/autotune/FuelAutoLogic.java index d00eb7a6fb..2f8511af04 100644 --- a/java_console/models/src/com/rusefi/autotune/FuelAutoLogic.java +++ b/java_console/models/src/com/rusefi/autotune/FuelAutoLogic.java @@ -8,5 +8,5 @@ import java.util.Collection; */ public interface FuelAutoLogic { // void MainWindow::calckGBC(double STEP) - FuelAutoTune.Result process(boolean smooth, Collection dataECU, double STEP, double targetAFR, float[][] kgbcINIT); + Result process(boolean smooth, Collection dataECU, double STEP, double targetAFR, float[][] kgbcINIT); } diff --git a/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java b/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java index 4bb98b147c..ef93f47f8e 100644 --- a/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java +++ b/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java @@ -14,7 +14,7 @@ public enum FuelAutoTune implements FuelAutoLogic { // todo: eliminate this // Fields.FUEL_RPM_COUNT // Fields.FUEL_LOAD_COUNT - private static final int SIZE = 16; + public static final int SIZE = 16; private static boolean isLogEnabled() { return true; @@ -23,70 +23,6 @@ public enum FuelAutoTune implements FuelAutoLogic { // private static final int TEMP_CORR = 39; - public static class stDataOnline { - public final double AFR; - private final int rpm; - private final double engineLoad; - int rpmIndex; - int engineLoadIndex; - - public stDataOnline(double AFR, int rpmIndex, int engineLoadIndex, int rpm, double engineLoad) { - this.rpm = rpm; - this.engineLoad = engineLoad; - if (rpmIndex < 0 || rpmIndex >= Fields.FUEL_RPM_COUNT) - throw new IllegalStateException("rpmIndex " + rpmIndex); - if (engineLoadIndex < 0 || engineLoadIndex >= Fields.FUEL_LOAD_COUNT) - throw new IllegalStateException("engineLoadIndex " + engineLoadIndex); - this.AFR = AFR; - this.rpmIndex = rpmIndex; - this.engineLoadIndex = engineLoadIndex; - } - - public static stDataOnline valueOf(double AFR, int rpm, double engineLoad) { - int rpmIndex = (int) (rpm / 7000.0 * SIZE); - if (rpmIndex < 0 || rpmIndex >= Fields.FUEL_RPM_COUNT) - return null; - int engineLoadIndex = (int) (engineLoad / 120.0 * SIZE); - return new stDataOnline(AFR, rpmIndex, engineLoadIndex, rpm, engineLoad); - } - - int getRpmIndex() { - return rpmIndex; - } - - private int getEngineLoadIndex() { - return (int) engineLoadIndex; - } - - public int PRESS_RT_32() { - return getEngineLoadIndex(); - } - - public int RPM_RT_32() { - return getRpmIndex(); - } - - public int getRpm() { - return rpm; - } - - public double getEngineLoad() { - return engineLoad; - } - } - - public static class Result { - private final float[][] kgbcRES; - - public Result(float[][] kgbcRES) { - this.kgbcRES = kgbcRES; - } - - public float[][] getKgbcRES() { - return kgbcRES; - } - } - // void MainWindow::calckGBC(double STEP) @Override public Result process(boolean smooth, Collection dataECU, double STEP, double targetAFR, float[][] kgbcINIT) { diff --git a/java_console/models/src/com/rusefi/autotune/FuelAutoTune2.java b/java_console/models/src/com/rusefi/autotune/FuelAutoTune2.java index c0b7b60261..5c6bcf72a9 100644 --- a/java_console/models/src/com/rusefi/autotune/FuelAutoTune2.java +++ b/java_console/models/src/com/rusefi/autotune/FuelAutoTune2.java @@ -1,17 +1,48 @@ package com.rusefi.autotune; +import com.rusefi.config.Fields; + import java.util.Collection; /** * (c) Andrey Belomutskiy 2013-2016 - 2/18/2016. + * 2/18/2016. */ public enum FuelAutoTune2 implements FuelAutoLogic { INSTANCE; + private static final int SIZE = 16; + @Override - public FuelAutoTune.Result process(boolean smooth, Collection dataECU, double STEP, double targetAFR, float[][] kgbcINIT) { - return null; + public Result process(boolean smooth, Collection dataECU, double GRAD, double targetAFR, float[][] VEcur) { + float result[][] = new float[SIZE][SIZE]; + + // proverka na statichnost' rezhimnoy tochki + boolean fl_static = true; + for (stDataOnline dataPoint : dataECU) { + // TODO + // proverka idet po trem poslednim dannym v dataECU + // proverka po rpmIndex + + // proverka po engineLoadIndex + + // esli tochka ne statichna to fl_static = false + } + if (!fl_static) + return null; + // end + stDataOnline s = dataECU.iterator().next(); + double delta = (s.AFR - targetAFR) / targetAFR; // privedennoe otklonenie po toplivu + + + for (int r = 0; r < SIZE; r++) { //rpmIndex + for (int e = 0; e < SIZE; e++) { //engineLoadIndex + result[r][e] = (float) (VEcur[r][e] + VEcur[r][e] * delta * GRAD / Math.min(Math.max(Math.abs(s.getEngineLoadIndex() - e), Math.abs(s.getRpmIndex() - r)), 1)); + } + } + + + return new Result(result); } -} +} \ No newline at end of file diff --git a/java_console/models/src/com/rusefi/autotune/Result.java b/java_console/models/src/com/rusefi/autotune/Result.java new file mode 100644 index 0000000000..d582af044d --- /dev/null +++ b/java_console/models/src/com/rusefi/autotune/Result.java @@ -0,0 +1,17 @@ +package com.rusefi.autotune; + +/** + * (c) Andrey Belomutskiy 2013-2016 + * 2/23/2016. + */ +public class Result { + private final float[][] kgbcRES; + + public Result(float[][] kgbcRES) { + this.kgbcRES = kgbcRES; + } + + public float[][] getKgbcRES() { + return kgbcRES; + } +} diff --git a/java_console/models/src/com/rusefi/autotune/stDataOnline.java b/java_console/models/src/com/rusefi/autotune/stDataOnline.java new file mode 100644 index 0000000000..782fb85fd1 --- /dev/null +++ b/java_console/models/src/com/rusefi/autotune/stDataOnline.java @@ -0,0 +1,59 @@ +package com.rusefi.autotune; + +import com.rusefi.config.Fields; + +/** + * (c) Andrey Belomutskiy 2013-2016 + * 2/23/2016. + */ +public class stDataOnline { + public final double AFR; + private final int rpm; + private final double engineLoad; + int rpmIndex; + int engineLoadIndex; + + public stDataOnline(double AFR, int rpmIndex, int engineLoadIndex, int rpm, double engineLoad) { + this.rpm = rpm; + this.engineLoad = engineLoad; + if (rpmIndex < 0 || rpmIndex >= Fields.FUEL_RPM_COUNT) + throw new IllegalStateException("rpmIndex " + rpmIndex); + if (engineLoadIndex < 0 || engineLoadIndex >= Fields.FUEL_LOAD_COUNT) + throw new IllegalStateException("engineLoadIndex " + engineLoadIndex); + this.AFR = AFR; + this.rpmIndex = rpmIndex; + this.engineLoadIndex = engineLoadIndex; + } + + public static stDataOnline valueOf(double AFR, int rpm, double engineLoad) { + int rpmIndex = (int) (rpm / 7000.0 * FuelAutoTune.SIZE); + if (rpmIndex < 0 || rpmIndex >= Fields.FUEL_RPM_COUNT) + return null; + int engineLoadIndex = (int) (engineLoad / 120.0 * FuelAutoTune.SIZE); + return new stDataOnline(AFR, rpmIndex, engineLoadIndex, rpm, engineLoad); + } + + int getRpmIndex() { + return rpmIndex; + } + + public int getEngineLoadIndex() { + return (int) engineLoadIndex; + } + + public int PRESS_RT_32() { + return getEngineLoadIndex(); + } + + public int RPM_RT_32() { + return getRpmIndex(); + } + + public int getRpm() { + return rpm; + } + + public double getEngineLoad() { + return engineLoad; + } +} diff --git a/java_console/models/src/com/rusefi/autotune/test/FuelAutoTune2Test.java b/java_console/models/src/com/rusefi/autotune/test/FuelAutoTune2Test.java new file mode 100644 index 0000000000..d112c3425d --- /dev/null +++ b/java_console/models/src/com/rusefi/autotune/test/FuelAutoTune2Test.java @@ -0,0 +1,79 @@ +package com.rusefi.autotune.test; + +import com.rusefi.autotune.FuelAutoTune2; +import com.rusefi.autotune.Result; +import com.rusefi.autotune.stDataOnline; +import com.rusefi.config.Fields; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +/** + * 2/23/2016 + * (c) Andrey Belomutskiy 2013-2016 + */ +public class FuelAutoTune2Test { + + @Test + public void testAutoTune() { + List dataPoints = new ArrayList<>(); + dataPoints.add(stDataOnline.valueOf(13, 1200, 80)); + + { + Result r = FuelAutoTune2.INSTANCE.process(false, dataPoints, 0.1, 13, createVeTable()); + printNotDefault(r.getKgbcRES(), 1); + } + + dataPoints.add(stDataOnline.valueOf(13, 1200, 80)); + dataPoints.add(stDataOnline.valueOf(14, 1300, 60)); + dataPoints.add(stDataOnline.valueOf(15, 1400, 70)); + dataPoints.add(stDataOnline.valueOf(16, 1500, 90)); + + for (int i = 0; i < 2000; i++) + dataPoints.add(stDataOnline.valueOf(16, 1500 + i, 90)); + + { + Result r = FuelAutoTune2.INSTANCE.process(false, dataPoints, 0.01, 13, createVeTable()); + printNotDefault(r.getKgbcRES(), 1); + } + + for (int i = 0; i < 2000; i++) + dataPoints.add(stDataOnline.valueOf(15, 1500 + i, 90)); + + { + Result r = FuelAutoTune2.INSTANCE.process(false, dataPoints, 0.01, 13, createVeTable()); + printNotDefault(r.getKgbcRES(), 1); + } + + + // todo: validate results + + } + + /** + * this method prints all values which do not equal default value + */ + private static void printNotDefault(float[][] array, double defaultValue) { + for (int i = 0; i < array.length; i++) { + printNotDefault(array[i], i, defaultValue); + } + } + + private static void printNotDefault(float[] array, int index, double defaultValue) { + for (int i = 0; i < array.length; i++) { + if (array[i] != defaultValue) + System.out.println("Found value: " + index + " " + i + ": " + array[i]); + } + } + + private static float[][] createVeTable() { + float kgbcINIT[][] = new float[Fields.FUEL_LOAD_COUNT][Fields.FUEL_RPM_COUNT]; + for (int engineLoadIndex = 0; engineLoadIndex < Fields.FUEL_LOAD_COUNT; engineLoadIndex++) { + for (int rpmIndex = 0; rpmIndex < Fields.FUEL_RPM_COUNT; rpmIndex++) { + kgbcINIT[engineLoadIndex][rpmIndex] = 1; + } + } + return kgbcINIT; + } +} diff --git a/java_console/models/src/com/rusefi/autotune/test/FuelAutoTuneTest.java b/java_console/models/src/com/rusefi/autotune/test/FuelAutoTuneTest.java index dfd2cd0f54..4a06b9f2fc 100644 --- a/java_console/models/src/com/rusefi/autotune/test/FuelAutoTuneTest.java +++ b/java_console/models/src/com/rusefi/autotune/test/FuelAutoTuneTest.java @@ -1,6 +1,8 @@ package com.rusefi.autotune.test; import com.rusefi.autotune.FuelAutoTune; +import com.rusefi.autotune.Result; +import com.rusefi.autotune.stDataOnline; import com.rusefi.config.Fields; import org.junit.Test; @@ -15,32 +17,32 @@ public class FuelAutoTuneTest { @Test public void testAutoTune() { - List dataPoints = new ArrayList<>(); - dataPoints.add(FuelAutoTune.stDataOnline.valueOf(13, 1200, 80)); + List dataPoints = new ArrayList<>(); + dataPoints.add(stDataOnline.valueOf(13, 1200, 80)); { - FuelAutoTune.Result r = FuelAutoTune.INSTANCE.process(false, dataPoints, 0.1, 13, createVeTable()); + Result r = FuelAutoTune.INSTANCE.process(false, dataPoints, 0.1, 13, createVeTable()); printNotDefault(r.getKgbcRES(), 1); } - dataPoints.add(FuelAutoTune.stDataOnline.valueOf(13, 1200, 80)); - dataPoints.add(FuelAutoTune.stDataOnline.valueOf(14, 1300, 60)); - dataPoints.add(FuelAutoTune.stDataOnline.valueOf(15, 1400, 70)); - dataPoints.add(FuelAutoTune.stDataOnline.valueOf(16, 1500, 90)); + dataPoints.add(stDataOnline.valueOf(13, 1200, 80)); + dataPoints.add(stDataOnline.valueOf(14, 1300, 60)); + dataPoints.add(stDataOnline.valueOf(15, 1400, 70)); + dataPoints.add(stDataOnline.valueOf(16, 1500, 90)); for (int i = 0; i < 2000; i++) - dataPoints.add(FuelAutoTune.stDataOnline.valueOf(16, 1500 + i, 90)); + dataPoints.add(stDataOnline.valueOf(16, 1500 + i, 90)); { - FuelAutoTune.Result r = FuelAutoTune.INSTANCE.process(false, dataPoints, 0.01, 13, createVeTable()); + Result r = FuelAutoTune.INSTANCE.process(false, dataPoints, 0.01, 13, createVeTable()); printNotDefault(r.getKgbcRES(), 1); } for (int i = 0; i < 2000; i++) - dataPoints.add(FuelAutoTune.stDataOnline.valueOf(15, 1500 + i, 90)); + dataPoints.add(stDataOnline.valueOf(15, 1500 + i, 90)); { - FuelAutoTune.Result r = FuelAutoTune.INSTANCE.process(false, dataPoints, 0.01, 13, createVeTable()); + Result r = FuelAutoTune.INSTANCE.process(false, dataPoints, 0.01, 13, createVeTable()); printNotDefault(r.getKgbcRES(), 1); } diff --git a/java_console/ui/src/com/rusefi/ui/FuelTunePane.java b/java_console/ui/src/com/rusefi/ui/FuelTunePane.java index 98f4250d07..7315af7447 100644 --- a/java_console/ui/src/com/rusefi/ui/FuelTunePane.java +++ b/java_console/ui/src/com/rusefi/ui/FuelTunePane.java @@ -10,6 +10,8 @@ import com.rusefi.ConfigurationImage; import com.rusefi.FileLog; import com.rusefi.UploadChanges; import com.rusefi.autotune.FuelAutoTune; +import com.rusefi.autotune.Result; +import com.rusefi.autotune.stDataOnline; import com.rusefi.binaryprotocol.BinaryProtocol; import com.rusefi.config.Fields; import com.rusefi.core.Sensor; @@ -26,7 +28,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; -import java.util.concurrent.RunnableFuture; /** * (c) Andrey Belomutskiy 2013-2016 @@ -190,7 +191,7 @@ public class FuelTunePane { loadMap(veTable, Fields.VETABLE.getOffset()); logMap("source", veTable); - List data = new ArrayList<>(); + List data = new ArrayList<>(); synchronized (incomingDataPoints) { for (FuelDataPoint point : incomingDataPoints) data.add(point.asDataOnline()); @@ -199,7 +200,7 @@ public class FuelTunePane { writeDataPoints(data); // todo: move this away from AWT thread - FuelAutoTune.Result a = FuelAutoTune.INSTANCE.process(false, data, 0.1, 14.7, veTable); + Result a = FuelAutoTune.INSTANCE.process(false, data, 0.1, 14.7, veTable); float[][] result = a.getKgbcRES(); logMap("result", result); @@ -209,14 +210,14 @@ public class FuelTunePane { upload.setEnabled(true); } - private void writeDataPoints(List data) { + private void writeDataPoints(List data) { DataOutputStream dos = getTuneLogStream(); if (dos == null) return; try { dos.writeBytes("Running with " + data.size() + " points\r\n"); dos.writeBytes("AFR\tRPM\tload\r\n"); - for (FuelAutoTune.stDataOnline point : data) + for (stDataOnline point : data) dos.writeBytes(point.AFR +"\t" + point.getRpm() + "\t" + point.getEngineLoad() + "\r\n"); } catch (IOException e) { @@ -357,8 +358,8 @@ public class FuelTunePane { engineLoadIndex = Math.max(0, BinarySearch.binarySearch(engineLoad, veLoadBins)); } - public FuelAutoTune.stDataOnline asDataOnline() { - return new FuelAutoTune.stDataOnline(afr, rpmIndex, engineLoadIndex, rpm, engineLoad); + public stDataOnline asDataOnline() { + return new stDataOnline(afr, rpmIndex, engineLoadIndex, rpm, engineLoad); } } }