Spaces:
Running
Running
IgnitionLearningTable::IgnitionLearningTable() { | |
reset(); | |
} | |
void IgnitionLearningTable::reset() { | |
for (int i = 0; i < 16; i++) { | |
for (int j = 0; j < 16; j++) { | |
corrections[i][j] = 0.0; | |
cellHits[i][j] = 0; | |
} | |
} | |
} | |
bool IgnitionLearningTable::save() { | |
File file = SD.open("/ignition_learning.bin", FILE_WRITE); | |
if (!file) return false; | |
file.write((uint8_t*)corrections, sizeof(corrections)); | |
file.write((uint8_t*)cellHits, sizeof(cellHits)); | |
file.close(); | |
return true; | |
} | |
bool IgnitionLearningTable::load() { | |
File file = SD.open("/ignition_learning.bin", FILE_READ); | |
if (!file) return false; | |
file.read((uint8_t*)corrections, sizeof(corrections)); | |
file.read((uint8_t*)cellHits, sizeof(cellHits)); | |
file.close(); | |
return true; | |
} | |
float IgnitionLearningTable::getCorrection(float load, float rpm) { | |
int loadIdx = constrain(mapf(load, 0, 100, 0, 15), 0, 15); | |
int rpmIdx = constrain(mapf(rpm, 0, 7000, 0, 15), 0, 15); | |
return corrections[loadIdx][rpmIdx]; | |
} | |
void IgnitionLearningTable::learn(float load, float rpm, float knockLevel) { | |
int loadIdx = constrain(mapf(load, 0, 100, 0, 15), 0, 15); | |
int rpmIdx = constrain(mapf(rpm, 0, 7000, 0, 15), 0, 15); | |
if (knockLevel > 0.5) { // Если есть детонация | |
float currentCorr = corrections[loadIdx][rpmIdx]; | |
float learningRate = 0.5f / (1.0f + cellHits[loadIdx][rpmIdx]); | |
corrections[loadIdx][rpmIdx] = currentCorr - learningRate; // Уменьшаем УОЗ | |
} | |
cellHits[loadIdx][rpmIdx]++; | |
} | |
float IgnitionLearningTable::getProgress() const { | |
int totalCells = 16 * 16; | |
int learnedCells = 0; | |
for (int i = 0; i < 16; i++) { | |
for (int j = 0; j < 16; j++) { | |
if (cellHits[i][j] > 0) learnedCells++; | |
} | |
} | |
return (float)learnedCells / totalCells; | |
} | |