#include "ignition_learning_table.h" #include "SD.h" #include "maps.h" 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; }