From cfb75e1e7c0d4153e7fcf9837bd786281b7425d0 Mon Sep 17 00:00:00 2001 From: rusEfi Date: Tue, 5 Jan 2016 13:02:07 -0500 Subject: [PATCH] auto-sync --- .../src/com/rusefi/autotune/FuelAutoTune.java | 211 ++++++++++++++++++ .../autotune/test/FuelAutoTuneTest.java | 51 +++++ 2 files changed, 262 insertions(+) create mode 100644 java_console/models/src/com/rusefi/autotune/test/FuelAutoTuneTest.java diff --git a/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java b/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java index 4aa20b6209..2337435cc2 100644 --- a/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java +++ b/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java @@ -1,9 +1,220 @@ package com.rusefi.autotune; +import java.util.Collection; + /** * 1/5/2016 * (c) Andrey Belomutskiy 2013-2015 */ public class FuelAutoTune { + private static final int SIZE = 16; + + private static boolean isLogEnabled() { + return true; + } + +// private static final int TEMP_CORR = 39; + + + public static class stDataOnline { + public final double AFR; + private final int rpm; + private final double engineLoad; + + public stDataOnline(double AFR, int rpm, double engineLoad) { + this.AFR = AFR; + this.rpm = rpm; + this.engineLoad = engineLoad; + } + + int getRpmIndex() { + return (int) (rpm / 7000.0 * SIZE); + } + + private int getEngineLoadIndex() { + return (int) (engineLoad / 120.0 * SIZE); + } + + public int PRESS_RT_32() { + return getEngineLoadIndex(); + } + + public int RPM_RT_32() { + return getRpmIndex(); + } + } + + public static class Result { + + private final double[][] kgbcRES; + + public Result(double[][] kgbcRES) { + this.kgbcRES = kgbcRES; + } + + public double[][] getKgbcRES() { + return kgbcRES; + } + } + + // void MainWindow::calckGBC(double STEP) + public static Result process(boolean smooth, Collection dataECU, double STEP) { + double kgbcSQ[][] = new double[SIZE][SIZE]; + double kgbcSQsum = 0; + double kgbcSQsumLast = 0; + double minSQ, e, g; + double step; + double minSQtotal = 1e+15; + double kgbcSQsumLastTotal = 1e+16; + double ksq = 1000; //???? ??????????????????? ?????????? + double ke = 100; //???? ?????????? + double kg = 100; //???? ????? + + int minK = 0; // todo: what is this? + int mink = 0; // todo: what is this? + + // let's could how many data points we have for each cell + int bkGBC[][] = new int[SIZE][SIZE]; + for (stDataOnline data : dataECU) { + bkGBC[data.PRESS_RT_32()][data.RPM_RT_32()]++; + } + // todo: add a comment what is this? + double kgbcRES[][] = new double[SIZE][SIZE]; + double kgbcINIT[][] = new double[SIZE][SIZE]; + + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + kgbcINIT[i][j] = 1; + kgbcRES[i][j] = 1; + } + } +// double addGbcTwatRES[] = new double[TEMP_CORR]; +// double addGbcTwatINIT[] = new double[TEMP_CORR]; +// +// double addGbcTwatINIT_190[] = new double[191]; +// double addGbcTwatRES_190[] = new double[191]; +// double mulGbcTwatRES[] = new double[TEMP_CORR]; +// double mulGbcTwatINIT[] = new double[TEMP_CORR]; +// double mulGbcTwatINIT_190[] = new double[191]; +// double mulGbcTwatRES_190[] = new double[191]; + +// for (int i = 0; i < 39; i++) { +// addGbcTwatINIT[i] = 1; +// addGbcTwatRES[i] = 1; +// } + + double ktgbcRES[][] = new double[SIZE][SIZE]; + double ktgbcINIT[][] = new double[SIZE][SIZE]; + + for (int i = 0; i < SIZE; i++) { //trt + for (int j = 0; j < SIZE; j++) { //rpm + ktgbcINIT[i][j] = 1; + ktgbcRES[i][j] = 1; + } + } + + int gMinRT = 20; // todo: what is this? + + while (true) { + for (int r = 0; r < SIZE; r++) { + for (int c = 0; c < SIZE; c++) { + if (bkGBC[r][c] < gMinRT) + continue; //**** + minSQ = 1e+16; + kgbcSQsum = 1e+16; + step = STEP; + mink = 0; + while (true) { + //////////////////////////////////// + //????????? ?????????? ? ???????? + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + kgbcSQ[i][j] = 0; + } + } + kgbcSQsumLast = kgbcSQsum; + for (stDataOnline dataPoint : dataECU) { + // double targetAFR = 14.7; // todo: target AFR? is this target AFR or not? + double corrInit = 1; // addGbcTwatINIT_190[dataPoint.twat + 40]; + double corrRes = 1; //addGbcTwatRES_190[dataPoint.twat + 40]; + double tpsCorrInit = 1; //ktgbcINIT[dataPoint.THR_RT_16][dataPoint.RPM_RT_32()]; + double tpsCorrRes = 1; //ktgbcRES[dataPoint.THR_RT_16][dataPoint.RPM_RT_32()]; + + double ALF = dataPoint.AFR / 14.7; + double tmp = (dataPoint.AFR / 14.7 - ALF * (kgbcRES[dataPoint.PRESS_RT_32()][dataPoint.RPM_RT_32()] * tpsCorrRes * corrRes) / + (kgbcINIT[dataPoint.PRESS_RT_32()][dataPoint.RPM_RT_32()] * tpsCorrInit * corrInit)); + + if (isLogEnabled()) + log(r + "/" + c + ": tmp=" + tmp); + + kgbcSQ[dataPoint.PRESS_RT_32()][dataPoint.RPM_RT_32()] += tmp * tmp; + } + kgbcSQsum = 0; + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + kgbcSQsum += kgbcSQ[i][j]; + } + } + if (smooth) { + kgbcSQsum = ksq * kgbcSQsum; + e = 0; + // todo: add a comment while 'SIZE - 1' here? + for (int i = 0; i < SIZE - 1; i++) { + for (int j = 0; j < SIZE; j++) { + double tmp = kgbcRES[i][j] - kgbcRES[i + 1][j]; + e += tmp * tmp; + tmp = kgbcRES[j][i] - kgbcRES[j][i + 1]; + e += tmp * tmp; + } + } + g = 0; + for (int i = 0; i < SIZE - 2; i++) { + for (int j = 0; j < SIZE; j++) { + double tmp = kgbcRES[i][j] - 2 * kgbcRES[i + 1][j] + kgbcRES[i + 2][j]; + g += tmp * tmp; + tmp = kgbcRES[j][i] - 2 * kgbcRES[j][i + 1] + kgbcRES[j][i + 2]; + g += tmp * tmp; + } + } + kgbcSQsum += ke * e + kg * g; + } + //////////////////////////////////// + if (kgbcSQsum >= kgbcSQsumLast) + step = -step; + //???? ?????? ?? ??????? ????? ???, ?? ? ?? ?????????? ?? + /*if(bkGBC[r][c]) */ + kgbcRES[r][c] += step; + if (kgbcSQsum < minSQ) minSQ = kgbcSQsum; + + if (Math.abs(minSQ - kgbcSQsumLast) < 1e-10) + mink++; + if (mink > 4) { +// updateTablekGBC(); +// ui -> statusBar -> showMessage(QString::number (kgbcSQsum), 500); + log("break " + c + "/" + r); + break; + } + } + } + } + if (kgbcSQsum < minSQtotal) minSQtotal = kgbcSQsum; + if (Math.abs(minSQtotal - kgbcSQsumLastTotal) < 1e-10) + minK++; + if (minK > 4) { + //updateTablekGBC(); + //ui->statusBar->showMessage(QString::number(kgbcSQsum), 500); + log("return " + minK); + return new Result(kgbcRES); + } + kgbcSQsumLastTotal = kgbcSQsum; + //ui->statusBar->showMessage(QString::number(gbcSQsum)); + //updateTableGBC(); + + } + } + + private static void log(String s) { + System.out.println(s); + } } diff --git a/java_console/models/src/com/rusefi/autotune/test/FuelAutoTuneTest.java b/java_console/models/src/com/rusefi/autotune/test/FuelAutoTuneTest.java new file mode 100644 index 0000000000..21d050f733 --- /dev/null +++ b/java_console/models/src/com/rusefi/autotune/test/FuelAutoTuneTest.java @@ -0,0 +1,51 @@ +package com.rusefi.autotune.test; + +import com.rusefi.autotune.FuelAutoTune; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +/** + * 1/5/2016 + * (c) Andrey Belomutskiy 2013-2015 + */ +public class FuelAutoTuneTest { + + @Test + public void testAutoTune() { + List dataPoints = new ArrayList<>(); + dataPoints.add(new FuelAutoTune.stDataOnline(13, 1200, 80)); + + { + FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.1); + printNotDefault(r.getKgbcRES(), 1); + } + + dataPoints.add(new FuelAutoTune.stDataOnline(13, 1200, 80)); + dataPoints.add(new FuelAutoTune.stDataOnline(14, 1300, 60)); + dataPoints.add(new FuelAutoTune.stDataOnline(15, 1400, 70)); + dataPoints.add(new FuelAutoTune.stDataOnline(16, 1500, 90)); + + { + FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.1); + printNotDefault(r.getKgbcRES(), 1); + } + } + + /** + * this method prints all values which do not equal default value + */ + private static void printNotDefault(double[][] array, double defaultValue) { + for (int i = 0; i < array.length; i++) { + printNotDefault(array[i], i, defaultValue); + } + } + + private static void printNotDefault(double[] array, int index, double defaultValue) { + for (int i = 0; i < array.length; i++) { + if (array[i] != defaultValue) + System.out.println(index + " " + i + ": " + array[i]); + } + } +}