auto-sync

This commit is contained in:
rusEfi 2016-01-08 11:01:40 -05:00
parent a6f83d36de
commit 9a65bfe806
11 changed files with 134 additions and 90 deletions

View File

@ -209,6 +209,8 @@ void setDodgeNeon1995EngineConfiguration(DECLARE_ENGINE_PARAMETER_F) {
boardConfiguration->fuelPumpPin = GPIOC_13; // Frankenstein: low side - out #4
boardConfiguration->fuelPumpPinMode = OM_DEFAULT;
engineConfiguration->mapErrorDetectionTooHigh = 120;
// set_injection_pin_mode 0
boardConfiguration->injectionPinMode = OM_DEFAULT;

View File

@ -450,8 +450,8 @@ void setDefaultConfiguration(DECLARE_ENGINE_PARAMETER_F) {
engineConfiguration->tpsMin = convertVoltageTo10bitADC(1.250);
engineConfiguration->tpsMax = convertVoltageTo10bitADC(4.538);
engineConfiguration->tpsErrorLowValue = convertVoltageTo10bitADC(0.2);
engineConfiguration->tpsErrorHighValue = convertVoltageTo10bitADC(6);
engineConfiguration->tpsErrorDetectionTooLow = -10; // -10% open
engineConfiguration->tpsErrorDetectionTooHigh = 110; // 110% open
engineConfiguration->canNbcType = CAN_BUS_NBC_BMW;
engineConfiguration->canSleepPeriod = 50;
@ -619,8 +619,8 @@ void setDefaultConfiguration(DECLARE_ENGINE_PARAMETER_F) {
boardConfiguration->logicAnalyzerMode[0] = false;
boardConfiguration->logicAnalyzerMode[1] = false;
engineConfiguration->mapErrorLowValue = 5;
engineConfiguration->mapErrorHighValue = 250;
engineConfiguration->mapErrorDetectionTooLow = 5;
engineConfiguration->mapErrorDetectionTooHigh = 250;
boardConfiguration->idleThreadPeriod = 100;
boardConfiguration->consoleLoopPeriod = 200;

View File

@ -1,4 +1,4 @@
// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Sun Jan 03 09:10:53 EST 2016
// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Thu Jan 07 13:56:04 EST 2016
// begin
#include "rusefi_types.h"
typedef struct {
@ -775,14 +775,14 @@ typedef struct {
*/
int16_t tpsMax;
/**
* todo: finish implementation. These values are used for TPS disconnect detection
* TPS error detection, what TPS % value is unrealistically low
* offset 88
*/
int16_t tpsErrorLowValue;
int16_t tpsErrorDetectionTooLow;
/**
* offset 90
*/
int16_t tpsErrorHighValue;
int16_t tpsErrorDetectionTooHigh;
/**
* offset 92
*/
@ -1312,12 +1312,12 @@ typedef struct {
* kPa value which is too low to be true
* offset 1896
*/
float mapErrorLowValue;
float mapErrorDetectionTooLow;
/**
* kPa value which is too high to be true
* offset 1900
*/
float mapErrorHighValue;
float mapErrorDetectionTooHigh;
/**
* RPMs prior to step1rpm point where ignition advance is retarded
* offset 1904
@ -1612,4 +1612,4 @@ typedef struct {
} persistent_config_s;
// end
// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Sun Jan 03 09:10:53 EST 2016
// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Thu Jan 07 13:56:04 EST 2016

View File

@ -44,9 +44,9 @@
#define tpsMin_offset_hex 54
#define tpsMax_offset 86
#define tpsMax_offset_hex 56
#define tpsErrorLowValue_offset 88
#define tpsErrorLowValue_offset_hex 58
#define tpsErrorHighValue_offset 90
#define tpsErrorDetectionTooLow_offset 88
#define tpsErrorDetectionTooLow_offset_hex 58
#define tpsErrorDetectionTooHigh_offset 90
#define cranking_offset 92
#define cranking_baseFuel_offset 92
#define cranking_rpm_offset 96
@ -665,9 +665,9 @@
#define addedToWallCoef_offset 1864
#define addedToWallCoef_offset_hex 748
#define unused72_offset 1868
#define mapErrorLowValue_offset 1896
#define mapErrorLowValue_offset_hex 768
#define mapErrorHighValue_offset 1900
#define mapErrorDetectionTooLow_offset 1896
#define mapErrorDetectionTooLow_offset_hex 768
#define mapErrorDetectionTooHigh_offset 1900
#define step1RpmWindow_offset 1904
#define step1RpmWindow_offset_hex 770
#define idlePid_offset 1908

View File

@ -95,8 +95,8 @@ float decodePressure(float voltage, air_pressure_sensor_config_s * config) {
* @return unchanged mapKPa parameter
*/
float validateMap(float mapKPa DECLARE_ENGINE_PARAMETER_S) {
if (cisnan(mapKPa) || mapKPa < CONFIG(mapErrorLowValue) || mapKPa > CONFIG(mapErrorHighValue)) {
warning(OBD_PCM_Processor_Fault, "invalid MAP value: %f", mapKPa);
if (cisnan(mapKPa) || mapKPa < CONFIG(mapErrorDetectionTooLow) || mapKPa > CONFIG(mapErrorDetectionTooHigh)) {
warning(OBD_PCM_Processor_Fault, "unexpected MAP value: %f", mapKPa);
return 0;
}
return mapKPa;

View File

@ -152,8 +152,8 @@ bit directSelfStimulation;Should the trigger emulator push data right into trigg
int16_t tpsMin;todo: extract these two fields into a structure\ntodo: we need two sets of TPS parameters - modern ETBs have two sensors;"ADC", 1, 0, 0, 1023, 0
int16_t tpsMax;tpsMax value as 10 bit ADC value. Not Voltage!;"ADC", 1, 0, 0, 1023, 0
int16_t tpsErrorLowValue;todo: finish implementation. These values are used for TPS disconnect detection;"*C", 1, 0, -40, 200, 1
int16_t tpsErrorHighValue;;"*C", 1, 0, -40, 200, 1
int16_t tpsErrorDetectionTooLow;TPS error detection, what TPS % value is unrealistically low;"%", 1, 0, -40, 200, 0
int16_t tpsErrorDetectionTooHigh;;"%", 1, 0, -40, 200, 0
cranking_parameters_s cranking
float primingSquirtDurationMs;;"*C", 1, 0, -40, 200, 1
@ -586,8 +586,10 @@ baro_corr_table_t baroCorrTable;
float[7] unused71;TODO make suckedOffCoef an array by RPM;
float addedToWallCoef;;"%", 1, 0, 0.0, 300.0, 2
float[7] unused72;TODO make addedToWallCoef an array by RPM;
float mapErrorLowValue;kPa value which is too low to be true;"kPa", 1, 0, -100.0, 100.0, 2
float mapErrorHighValue;kPa value which is too high to be true;"kPa", 1, 0, -100.0, 800.0, 2
! todo: mapErrorDetectionIdleTooLow? 30kPa is usually lowest on idle
float mapErrorDetectionTooLow;kPa value which is too low to be true;"kPa", 1, 0, -100.0, 100.0, 2
float mapErrorDetectionTooHigh;kPa value which is too high to be true;"kPa", 1, 0, -100.0, 800.0, 2
int step1RpmWindow;RPMs prior to step1rpm point where ignition advance is retarded;"rpm", 1, 0, 0, 3000.0, 2
pid_s idlePid;
int idleDT;

View File

@ -17,8 +17,8 @@
*
* @section sec_main Brief overview
*
* rusEfi runs on crankshaft or camshaft ('trigger') position sensor events.
* Once per crankshaft revolution we evaluate the amount of needed fuel and
* rusEfi runs on crank shaft or cam shaft ('trigger') position sensor events.
* Once per crank shaft revolution we evaluate the amount of needed fuel and
* the spark timing. Once we have decided on the parameters for this revolution
* we schedule all the actions to be triggered by the closest trigger event.
*
@ -29,9 +29,9 @@
* @section sec_trigger Trigger Decoding
*
* Our primary trigger decoder is based on the idea of synchronizing the primary shaft signal and simply counting events on
* the secondary signal. A typical scenario would be when camshaft positions sensor is the primary signal and crankshaft is secondary,
* but sometimes there would be two signals generated by two camshaft sensors.
* Another scenario is when we only have crankshaft position sensor, this would make it the primary signal and there would be no secondary signal.
* the secondary signal. A typical scenario would be when cam shaft positions sensor is the primary signal and crankshaft is secondary,
* but sometimes there would be two signals generated by two cam shaft sensors.
* Another scenario is when we only have crank shaft position sensor, this would make it the primary signal and there would be no secondary signal.
*
* There is no software filtering so the signals are expected to be valid. TODO: in reality we are still catching engine stop noise as unrealisticly high RPM.
*
@ -50,8 +50,8 @@
*
* @section sec_scheduler Event Scheduler
*
* It is a general agreement to measure all angles in crankshaft angles. In a four stroke
* engine, a full cycle consists of two revolutions of the crankshaft, so all the angles are
* It is a general agreement to measure all angles in crank shaft angles. In a four stroke
* engine, a full cycle consists of two revolutions of the crank shaft, so all the angles are
* running between 0 and 720 degrees.
*
* Ignition timing is a great example of a process which highlights the need of a hybrid
@ -79,7 +79,7 @@
*
* Please note that due to TunerStudio protocol it's important to have the total structure size in synch between the firmware and TS .ini file -
* just to make sure that this is not forgotten the size of the structure is hard-coded as PAGE_0_SIZE constant. There is always some 'unused' fields added in advance so that
* one can add some fields without the pain of increasing the total config page size.
* one can add some fields without the pain of increasing the total configuration page size.
* <br>See flash_main.cpp
*
*

View File

@ -41,7 +41,7 @@ enable2ndByteCanID = false
; see PAGE_0_SIZE in C source code
; CONFIG_DEFINITION_START
; this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Sun Jan 03 09:10:53 EST 2016
; this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Thu Jan 07 13:56:04 EST 2016
pageSize = 16088
page = 1
@ -54,8 +54,8 @@ page = 1
directSelfStimulation = bits, U32, 80, [0:0], "false", "true"
tpsMin = scalar, S16, 84, "ADC", 1, 0, 0, 1023, 0
tpsMax = scalar, S16, 86, "ADC", 1, 0, 0, 1023, 0
tpsErrorLowValue = scalar, S16, 88, "*C", 1, 0, -40, 200, 1
tpsErrorHighValue = scalar, S16, 90, "*C", 1, 0, -40, 200, 1
tpsErrorDetectionTooLow = scalar, S16, 88, "%", 1, 0, -40, 200, 0
tpsErrorDetectionTooHigh = scalar, S16, 90, "%", 1, 0, -40, 200, 0
cranking_baseFuel = scalar, F32, 92, "ms", 1, 0, 0, 200, 1
cranking_rpm = scalar, S16, 96, "RPM", 1, 0, 0, 3000, 0
;skipping cranking_alignmentFill offset 98
@ -476,8 +476,8 @@ page = 1
unused71 = array, F32, 1836, [7],
addedToWallCoef = scalar, F32, 1864, "%", 1, 0, 0.0, 300.0, 2
unused72 = array, F32, 1868, [7],
mapErrorLowValue = scalar, F32, 1896, "kPa", 1, 0, -100.0, 100.0, 2
mapErrorHighValue = scalar, F32, 1900, "kPa", 1, 0, -100.0, 800.0, 2
mapErrorDetectionTooLow = scalar, F32, 1896, "kPa", 1, 0, -100.0, 100.0, 2
mapErrorDetectionTooHigh = scalar, F32, 1900, "kPa", 1, 0, -100.0, 800.0, 2
step1RpmWindow = scalar, S32, 1904, "rpm", 1, 0, 0, 3000.0, 2
idlePid_pFactor = scalar, F32, 1908, "value", 1, 0, 0, 1000, 2
idlePid_iFactor = scalar, F32, 1912, "value", 1, 0, 0, 1000, 2

View File

@ -70,8 +70,6 @@ public class FuelAutoTune {
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];
@ -113,17 +111,21 @@ public class FuelAutoTune {
}
}
int gMinRT = 20; // todo: what is this?
int gMinRT = 20; // minimal number of measurments in cell to be considered
int minK = 0; // 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; //****
continue;
//log("Processing " + r + "/c" + c);
minSQ = 1e+16;
kgbcSQsum = 1e+16;
step = STEP;
mink = 0;
double mink = 0;
while (true) {
////////////////////////////////////
//????????? ?????????? ? ????????
@ -133,58 +135,24 @@ public class FuelAutoTune {
}
}
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));
countDeviation(dataECU, kgbcSQ, kgbcRES, kgbcINIT, r, c);
if (isLogEnabled())
log(r + "/" + c + ": tmp=" + tmp);
kgbcSQsum = sumArray(kgbcSQ);
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;
kgbcSQsum = smooth(kgbcSQsum, ksq, ke, kg, kgbcRES);
}
////////////////////////////////////
if (kgbcSQsum >= kgbcSQsumLast)
step = -step;
//???? ?????? ?? ??????? ????? ???, ?? ? ?? ?????????? ??
/*if(bkGBC[r][c]) */
// log("Adjusting " + step);
kgbcRES[r][c] += step;
if (kgbcSQsum < minSQ) minSQ = kgbcSQsum;
if (kgbcSQsum < minSQ)
minSQ = kgbcSQsum;
if (Math.abs(minSQ - kgbcSQsumLast) < 1e-10)
mink++;
@ -197,7 +165,8 @@ public class FuelAutoTune {
}
}
}
if (kgbcSQsum < minSQtotal) minSQtotal = kgbcSQsum;
if (kgbcSQsum < minSQtotal)
minSQtotal = kgbcSQsum;
if (Math.abs(minSQtotal - kgbcSQsumLastTotal) < 1e-10)
minK++;
if (minK > 4) {
@ -213,6 +182,62 @@ public class FuelAutoTune {
}
}
private static void countDeviation(Collection<stDataOnline> dataECU, double[][] kgbcSQ, double[][] kgbcRES, double[][] kgbcINIT, int r, int c) {
for (stDataOnline dataPoint : dataECU) {
double targetAFR = 13.0; // 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 = targetAFR / 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=" + r + "/c=" + c + ": tmp=" + tmp);
kgbcSQ[dataPoint.PRESS_RT_32()][dataPoint.RPM_RT_32()] += tmp * tmp;
}
}
private static double sumArray(double[][] kgbcSQ) {
double kgbcSQsum = 0;
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
kgbcSQsum += kgbcSQ[i][j];
}
}
return kgbcSQsum;
}
private static double smooth(double kgbcSQsum, double ksq, double ke, double kg, double[][] kgbcRES) {
double e;
double g;
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;
return kgbcSQsum;
}
private static void log(String s) {
System.out.println(s);
}

View File

@ -27,10 +27,25 @@ public class FuelAutoTuneTest {
dataPoints.add(new FuelAutoTune.stDataOnline(15, 1400, 70));
dataPoints.add(new FuelAutoTune.stDataOnline(16, 1500, 90));
for (int i = 0; i < 2000; i++)
dataPoints.add(new FuelAutoTune.stDataOnline(16, 1500 + i, 90));
{
FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.1);
FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.01);
printNotDefault(r.getKgbcRES(), 1);
}
for (int i = 0; i < 2000; i++)
dataPoints.add(new FuelAutoTune.stDataOnline(15, 1500 + i, 90));
{
FuelAutoTune.Result r = FuelAutoTune.process(false, dataPoints, 0.01);
printNotDefault(r.getKgbcRES(), 1);
}
// todo: validate results
}
/**
@ -45,7 +60,7 @@ public class FuelAutoTuneTest {
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]);
System.out.println("Found value: " + index + " " + i + ": " + array[i]);
}
}
}

View File

@ -1,6 +1,6 @@
package com.rusefi.config;
// this file was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Sun Jan 03 09:10:53 EST 2016
// this file was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Thu Jan 07 13:56:04 EST 2016
public class Fields {
public static final Field ENGINETYPE = new Field("ENGINETYPE", 0, FieldType.INT);
public static final Field UNUSEDOFFSET4 = new Field("UNUSEDOFFSET4", 4, FieldType.INT);
@ -9,8 +9,8 @@ public class Fields {
public static final Field DIRECTSELFSTIMULATION = new Field("DIRECTSELFSTIMULATION", 80, FieldType.BIT, 0);
public static final Field TPSMIN = new Field("TPSMIN", 84, FieldType.INT);
public static final Field TPSMAX = new Field("TPSMAX", 86, FieldType.INT);
public static final Field TPSERRORLOWVALUE = new Field("TPSERRORLOWVALUE", 88, FieldType.INT);
public static final Field TPSERRORHIGHVALUE = new Field("TPSERRORHIGHVALUE", 90, FieldType.INT);
public static final Field TPSERRORDETECTIONTOOLOW = new Field("TPSERRORDETECTIONTOOLOW", 88, FieldType.INT);
public static final Field TPSERRORDETECTIONTOOHIGH = new Field("TPSERRORDETECTIONTOOHIGH", 90, FieldType.INT);
public static final Field CRANKING_BASEFUEL = new Field("CRANKING_BASEFUEL", 92, FieldType.FLOAT);
public static final Field CRANKING_RPM = new Field("CRANKING_RPM", 96, FieldType.INT);
public static final Field PRIMINGSQUIRTDURATIONMS = new Field("PRIMINGSQUIRTDURATIONMS", 100, FieldType.FLOAT);
@ -423,8 +423,8 @@ public class Fields {
public static final Field TACHPULSETRIGGERINDEX = new Field("TACHPULSETRIGGERINDEX", 1828, FieldType.INT);
public static final Field SUCKEDOFFCOEF = new Field("SUCKEDOFFCOEF", 1832, FieldType.FLOAT);
public static final Field ADDEDTOWALLCOEF = new Field("ADDEDTOWALLCOEF", 1864, FieldType.FLOAT);
public static final Field MAPERRORLOWVALUE = new Field("MAPERRORLOWVALUE", 1896, FieldType.FLOAT);
public static final Field MAPERRORHIGHVALUE = new Field("MAPERRORHIGHVALUE", 1900, FieldType.FLOAT);
public static final Field MAPERRORDETECTIONTOOLOW = new Field("MAPERRORDETECTIONTOOLOW", 1896, FieldType.FLOAT);
public static final Field MAPERRORDETECTIONTOOHIGH = new Field("MAPERRORDETECTIONTOOHIGH", 1900, FieldType.FLOAT);
public static final Field STEP1RPMWINDOW = new Field("STEP1RPMWINDOW", 1904, FieldType.INT);
public static final Field IDLEPID_PFACTOR = new Field("IDLEPID_PFACTOR", 1908, FieldType.FLOAT);
public static final Field IDLEPID_IFACTOR = new Field("IDLEPID_IFACTOR", 1912, FieldType.FLOAT);