diff --git a/firmware/controllers/algo/engine_configuration.cpp b/firmware/controllers/algo/engine_configuration.cpp index c8a7689d96..2af7df2c53 100644 --- a/firmware/controllers/algo/engine_configuration.cpp +++ b/firmware/controllers/algo/engine_configuration.cpp @@ -124,8 +124,8 @@ void setConstantDwell(floatms_t dwellMs DECLARE_ENGINE_PARAMETER_S) { void setMap(fuel_table_t table, float value) { for (int l = 0; l < FUEL_LOAD_COUNT; l++) { - for (int r = 0; r < FUEL_RPM_COUNT; r++) { - table[l][r] = value; + for (int rpmIndex = 0; rpmIndex < FUEL_RPM_COUNT; rpmIndex++) { + table[l][rpmIndex] = value; } } } @@ -906,17 +906,17 @@ void setFrankenso0_1_joystick(engine_configuration_s *engineConfiguration) { } void copyFuelTable(fuel_table_t const source, fuel_table_t destination) { - for (int k = 0; k < FUEL_LOAD_COUNT; k++) { - for (int r = 0; r < FUEL_RPM_COUNT; r++) { - destination[k][r] = source[k][r]; + for (int loadIndex = 0; loadIndex < FUEL_LOAD_COUNT; loadIndex++) { + for (int rpmIndex = 0; rpmIndex < FUEL_RPM_COUNT; rpmIndex++) { + destination[loadIndex][rpmIndex] = source[loadIndex][rpmIndex]; } } } void copyTimingTable(ignition_table_t const source, ignition_table_t destination) { for (int k = 0; k < IGN_LOAD_COUNT; k++) { - for (int r = 0; r < IGN_RPM_COUNT; r++) { - destination[k][r] = source[k][r]; + for (int rpmIndex = 0; rpmIndex < IGN_RPM_COUNT; rpmIndex++) { + destination[k][rpmIndex] = source[k][rpmIndex]; } } } diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index 2afd2c7a3b..ee97f437f3 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -259,8 +259,8 @@ static int findAngleIndex(float target DECLARE_ENGINE_PARAMETER_S) { } else if (eventAngle > target) { right = middle - 1; } else { - // Values are equal - return middle; // Key found + // Values are equal + return middle; // Key found } } return left - 1; @@ -268,6 +268,7 @@ static int findAngleIndex(float target DECLARE_ENGINE_PARAMETER_S) { } void findTriggerPosition(event_trigger_position_s *position, angle_t angleOffset DECLARE_ENGINE_PARAMETER_S) { + // convert engine cycle angle into trigger cycle angle angleOffset += tdcPosition(); fixAngle(angleOffset); diff --git a/firmware/controllers/trigger/trigger_structure.cpp b/firmware/controllers/trigger/trigger_structure.cpp index 5f8ff34356..dc48c24104 100644 --- a/firmware/controllers/trigger/trigger_structure.cpp +++ b/firmware/controllers/trigger/trigger_structure.cpp @@ -218,7 +218,7 @@ uint32_t TriggerShape::getLength() const { return operationMode == FOUR_STROKE_CAM_SENSOR ? getSize() : 2 * getSize(); } -float TriggerShape::getAngle(int index) const { +angle_t TriggerShape::getAngle(int index) const { // todo: why is this check here? looks like the code below could be used universally if (operationMode == FOUR_STROKE_CAM_SENSOR) { return getSwitchAngle(index); @@ -352,11 +352,11 @@ void TriggerShape::addEvent(angle_t angle, trigger_wheel_e const waveIndex, trig wave.waves[waveIndex].pinStates[index] = state; } -int TriggerShape::getCycleDuration() const { +angle_t TriggerShape::getCycleDuration() const { return (operationMode == FOUR_STROKE_CAM_SENSOR) ? 720 : 360; } -float TriggerShape::getSwitchAngle(int index) const { +angle_t TriggerShape::getSwitchAngle(int index) const { return getCycleDuration() * wave.getSwitchTime(index); } diff --git a/firmware/controllers/trigger/trigger_structure.h b/firmware/controllers/trigger/trigger_structure.h index 39111ce98b..f89ebdc992 100644 --- a/firmware/controllers/trigger/trigger_structure.h +++ b/firmware/controllers/trigger/trigger_structure.h @@ -168,9 +168,12 @@ private: /** * These angles are in trigger DESCRIPTION coordinates - i.e. the way you add events while declaring trigger shape */ - float getSwitchAngle(int index) const; + angle_t getSwitchAngle(int index) const; - float previousAngle; + /** + * This variable is used to confirm that events are added in the right order. + */ + angle_t previousAngle; /** * this is part of performance optimization */ @@ -180,9 +183,9 @@ private: * This private method should only be used to prepare the array of pre-calculated values * See eventAngles array */ - float getAngle(int phaseIndex) const; + angle_t getAngle(int phaseIndex) const; - int getCycleDuration() const; + angle_t getCycleDuration() const; void calculateTriggerSynchPoint(TriggerState *state DECLARE_ENGINE_PARAMETER_S); }; diff --git a/java_console/models/src/com/rusefi/BinarySearch.java b/java_console/models/src/com/rusefi/BinarySearch.java index 96318acfbd..e5a48abe8b 100644 --- a/java_console/models/src/com/rusefi/BinarySearch.java +++ b/java_console/models/src/com/rusefi/BinarySearch.java @@ -1,7 +1,7 @@ package com.rusefi; public class BinarySearch { - public static int binarySearch(double target, double[] angles) { + public static int binarySearch(double target, float[] angles) { System.out.println("Testing " + target); int left = 0; diff --git a/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java b/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java index c720959a10..da32874a01 100644 --- a/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java +++ b/java_console/models/src/com/rusefi/autotune/FuelAutoTune.java @@ -62,20 +62,30 @@ public class FuelAutoTune { } public static class Result { - private final double[][] kgbcRES; + private final float[][] kgbcRES; - public Result(double[][] kgbcRES) { + public Result(float[][] kgbcRES) { this.kgbcRES = kgbcRES; } - public double[][] getKgbcRES() { + public float[][] getKgbcRES() { return kgbcRES; } } + private static float[][] deepCopy(float[][] input) { + if (input == null) + return null; + float[][] result = new float[input.length][]; + for (int r = 0; r < input.length; r++) { + result[r] = input[r].clone(); + } + return result; + } + // void MainWindow::calckGBC(double STEP) - public static Result process(boolean smooth, Collection dataECU, double STEP, double targetAFR) { - double kgbcSQ[][] = new double[SIZE][SIZE]; + public static Result process(boolean smooth, Collection dataECU, double STEP, double targetAFR, float[][] kgbcINIT) { + float kgbcSQ[][] = new float[SIZE][SIZE]; double kgbcSQsum = 0; double kgbcSQsumLast; double minSQ; @@ -92,16 +102,9 @@ public class FuelAutoTune { for (stDataOnline data : dataECU) { bkGBC[data.PRESS_RT_32()][data.RPM_RT_32()]++; } - // todo: add a comment what is this? - double kgbcRES[][] = new double[Fields.FUEL_LOAD_COUNT][Fields.FUEL_RPM_COUNT]; - double kgbcINIT[][] = new double[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; - kgbcRES[engineLoadIndex][rpmIndex] = 1; - } - } + float result[][] = deepCopy(kgbcINIT); + // double addGbcTwatRES[] = new double[TEMP_CORR]; // double addGbcTwatINIT[] = new double[TEMP_CORR]; // @@ -152,12 +155,12 @@ public class FuelAutoTune { } kgbcSQsumLast = kgbcSQsum; - countDeviation(dataECU, kgbcSQ, kgbcRES, kgbcINIT, targetAFR); + countDeviation(dataECU, kgbcSQ, result, kgbcINIT, targetAFR); kgbcSQsum = sumArray(kgbcSQ); if (smooth) { - kgbcSQsum = smooth(kgbcSQsum, ksq, ke, kg, kgbcRES); + kgbcSQsum = smooth(kgbcSQsum, ksq, ke, kg, result); } //////////////////////////////////// if (kgbcSQsum >= kgbcSQsumLast) @@ -166,7 +169,7 @@ public class FuelAutoTune { /*if(bkGBC[r][c]) */ // log("Adjusting " + step); - kgbcRES[r][c] += step; + result[r][c] += step; if (kgbcSQsum < minSQ) minSQ = kgbcSQsum; @@ -189,7 +192,7 @@ public class FuelAutoTune { //updateTablekGBC(); //ui->statusBar->showMessage(QString::number(kgbcSQsum), 500); log("return " + minK); - return new Result(kgbcRES); + return new Result(result); } kgbcSQsumLastTotal = kgbcSQsum; //ui->statusBar->showMessage(QString::number(gbcSQsum)); @@ -198,7 +201,7 @@ public class FuelAutoTune { } } - private static void countDeviation(Collection dataECU, double[][] kgbcSQ, double[][] kgbcRES, double[][] kgbcINIT, double targetAFR) { + private static void countDeviation(Collection dataECU, float[][] kgbcSQ, float[][] kgbcRES, float[][] kgbcINIT, double targetAFR) { for (stDataOnline dataPoint : dataECU) { double corrInit = 1; // addGbcTwatINIT_190[dataPoint.twat + 40]; double corrRes = 1; //addGbcTwatRES_190[dataPoint.twat + 40]; @@ -216,7 +219,7 @@ public class FuelAutoTune { } } - private static double sumArray(double[][] kgbcSQ) { + private static double sumArray(float[][] kgbcSQ) { double kgbcSQsum = 0; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { @@ -226,7 +229,7 @@ public class FuelAutoTune { return kgbcSQsum; } - private static double smooth(double kgbcSQsum, double ksq, double ke, double kg, double[][] kgbcRES) { + private static double smooth(double kgbcSQsum, double ksq, double ke, double kg, float[][] kgbcRES) { double e; double g; kgbcSQsum = ksq * kgbcSQsum; 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 437edc14c4..c5bd043a6b 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,7 @@ package com.rusefi.autotune.test; import com.rusefi.autotune.FuelAutoTune; +import com.rusefi.config.Fields; import org.junit.Test; import java.util.ArrayList; @@ -18,7 +19,7 @@ public class FuelAutoTuneTest { dataPoints.add(FuelAutoTune.stDataOnline.valueOf(13, 1200, 80)); { - FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.1, 13); + FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.1, 13, createVeTable()); printNotDefault(r.getKgbcRES(), 1); } @@ -31,7 +32,7 @@ public class FuelAutoTuneTest { dataPoints.add(FuelAutoTune.stDataOnline.valueOf(16, 1500 + i, 90)); { - FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.01, 13); + FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.01, 13, createVeTable()); printNotDefault(r.getKgbcRES(), 1); } @@ -39,7 +40,7 @@ public class FuelAutoTuneTest { dataPoints.add(FuelAutoTune.stDataOnline.valueOf(15, 1500 + i, 90)); { - FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.01, 13); + FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.01, 13, createVeTable()); printNotDefault(r.getKgbcRES(), 1); } @@ -51,16 +52,27 @@ public class FuelAutoTuneTest { /** * this method prints all values which do not equal default value */ - private static void printNotDefault(double[][] array, double defaultValue) { + 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(double[] array, int index, double 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/test/BinarySearchTest.java b/java_console/models/src/com/rusefi/test/BinarySearchTest.java index 66cda281b2..e5ee3ebcb0 100644 --- a/java_console/models/src/com/rusefi/test/BinarySearchTest.java +++ b/java_console/models/src/com/rusefi/test/BinarySearchTest.java @@ -12,7 +12,7 @@ public class BinarySearchTest extends TestCase { public void testBinary() { - double[] angles = new double[] {0, 56, 126, 180, 236, 279, 306, 416, 486, 540, 596, 666}; + float[] angles = new float[] {0, 56, 126, 180, 236, 279, 306, 416, 486, 540, 596, 666}; Arrays.sort(angles); diff --git a/java_console/ui/src/com/rusefi/ui/FuelTunePane.java b/java_console/ui/src/com/rusefi/ui/FuelTunePane.java index b9e546c7d6..9a52ffcf62 100644 --- a/java_console/ui/src/com/rusefi/ui/FuelTunePane.java +++ b/java_console/ui/src/com/rusefi/ui/FuelTunePane.java @@ -23,15 +23,17 @@ import java.util.List; /** * (c) Andrey Belomutskiy 2013-2016 * 1/9/2016 + * * @see FuelAutoTune */ public class FuelTunePane { private final JPanel content = new JPanel(new BorderLayout()); private final List incomingDataPoints = new ArrayList<>(); - private final double veLoadBins[] = new double[Fields.FUEL_LOAD_COUNT]; - private final double veRpmBins[] = new double[Fields.FUEL_RPM_COUNT]; + private final float veLoadBins[] = new float[Fields.FUEL_LOAD_COUNT]; + private final float veRpmBins[] = new float[Fields.FUEL_RPM_COUNT]; private final Table3D veTable = new Table3D(); + private final Table3D changeMap = new Table3D(); public FuelTunePane() { final JLabel incomingBufferSize = new JLabel(); @@ -64,7 +66,7 @@ public class FuelTunePane { JPanel rightPanel = new JPanel(new GridLayout(2, 1)); - rightPanel.add(new JLabel("top")); + rightPanel.add(changeMap); rightPanel.add(new JLabel("bottom")); JPanel middlePanel = new JPanel(new GridLayout(1, 2)); @@ -72,25 +74,28 @@ public class FuelTunePane { middlePanel.add(rightPanel); content.add(middlePanel, BorderLayout.CENTER); + initTable(veTable); + initTable(changeMap); + } + private void initTable(Table3D table) { // todo: which one is which? - veTable.setSizeX(Fields.FUEL_LOAD_COUNT); - veTable.setSizeY(Fields.FUEL_RPM_COUNT); - veTable.getXAxis().setDataSize(Fields.FUEL_LOAD_COUNT); - veTable.getYAxis().setDataSize(Fields.FUEL_RPM_COUNT); + table.setSizeX(Fields.FUEL_LOAD_COUNT); + table.setSizeY(Fields.FUEL_RPM_COUNT); + table.getXAxis().setDataSize(Fields.FUEL_LOAD_COUNT); + table.getYAxis().setDataSize(Fields.FUEL_RPM_COUNT); - veTable.getXAxis().setAxisParent(veTable); - veTable.getYAxis().setAxisParent(veTable); - - veTable.setBorder(BorderFactory.createLineBorder(Color.red)); - veTable.addScale(new Scale()); - veTable.getXAxis().addScale(new Scale()); - veTable.getYAxis().addScale(new Scale()); + table.getXAxis().setAxisParent(table); + table.getYAxis().setAxisParent(table); + table.setBorder(BorderFactory.createLineBorder(Color.red)); + table.addScale(new Scale()); + table.getXAxis().addScale(new Scale()); + table.getYAxis().addScale(new Scale()); } private void doJob() { - double veTable[][] = new double[Fields.FUEL_LOAD_COUNT][Fields.FUEL_RPM_COUNT]; + float veTable[][] = new float[Fields.FUEL_LOAD_COUNT][Fields.FUEL_RPM_COUNT]; loadMap(veTable, Fields.VETABLE.getOffset()); List data = new ArrayList<>(); @@ -99,7 +104,22 @@ public class FuelTunePane { data.add(point.asDataOnline()); } - FuelAutoTune.process(false, data, 0.1, 14.7); + // todo: move this away from AWT thread + FuelAutoTune.Result a = FuelAutoTune.process(false, data, 0.1, 14.7, veTable); + + + changeMap.setStorageAddress(0); + changeMap.setStorageType(Settings.STORAGE_TYPE_FLOAT); + changeMap.populateTable(new byte[4 * 16 * 16], 0); + + for (int i = 0; i < 16; i++) { + for (int rpmIndex = 0; rpmIndex < 16; rpmIndex++) { + changeMap.get3dData()[i][rpmIndex].setBinValue(a.getKgbcRES()[i][rpmIndex]); + } + } + + changeMap.drawTable(); + } public void showContent() { @@ -136,13 +156,13 @@ public class FuelTunePane { // UiUtils.trueLayout(content.getParent()); } - private void loadMap(double[][] map, int offset) { - for (int engineLoadIndex = 0;engineLoadIndex < map.length; engineLoadIndex++) { + private void loadMap(float[][] map, int offset) { + for (int engineLoadIndex = 0; engineLoadIndex < map.length; engineLoadIndex++) { loadArray(map[engineLoadIndex], offset + engineLoadIndex * 4 * Fields.FUEL_RPM_COUNT); } } - private void loadArray(double[] array, int offset) { + private void loadArray(float[] array, int offset) { BinaryProtocol bp = BinaryProtocol.instance; if (bp == null) { FileLog.MAIN.logLine("bp not ready");