File size: 1,997 Bytes
96a5049
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#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;
}