bigcode-starcoder2-15b / learning_manager.cpp
Dikhan1's picture
Upload 24 files
96a5049 verified
raw
history blame
7.74 kB
#include "learning_manager.h"
#include <ArduinoJson.h>
LearningManager::LearningManager() :
isLearningEnabled(false),
isFuelLearningEnabled(true),
isIgnitionLearningEnabled(true),
learningStartTime(0),
minLearningTime(300000), // 5 минут
minEngineTemp(60), // 60°C
maxEngineTemp(100), // 100°C
minThrottlePosition(5), // 5%
maxThrottlePosition(95), // 95%
totalLearningPoints(0),
knockEvents(0),
richMixtureEvents(0),
leanMixtureEvents(0)
{
}
void LearningManager::begin() {
fuelTable.begin();
ignitionTable.begin();
// Загружаем сохраненные данные
load();
// Устанавливаем параметры обучения
fuelTable.setLearningRate(0.01);
fuelTable.setCorrectionLimits(0.8, 1.2);
ignitionTable.setLearningRate(0.05);
ignitionTable.setCorrectionLimits(-5.0, 5.0);
ignitionTable.setKnockParameters(0.8, 2.0);
learningStartTime = millis();
}
bool LearningManager::checkLearningConditions(float engineTemp, float throttlePosition) {
// Проверка времени работы двигателя
if (millis() - learningStartTime < minLearningTime) {
return false;
}
// Проверка температуры двигателя
if (engineTemp < minEngineTemp || engineTemp > maxEngineTemp) {
return false;
}
// Проверка положения дросселя
if (throttlePosition < minThrottlePosition || throttlePosition > maxThrottlePosition) {
return false;
}
return true;
}
void LearningManager::update(float load, float rpm, float lambda, float knockLevel,
float engineTemp, float throttlePosition) {
if (!isLearningEnabled || !checkLearningConditions(engineTemp, throttlePosition)) {
return;
}
// Обучение топливной карты
if (isFuelLearningEnabled) {
float lambdaError = lambda - 1.0; // Отклонение от стехиометрии
if (abs(lambdaError) > 0.02) { // Порог ошибки 2%
fuelTable.learn(load, rpm, lambdaError);
if (lambdaError > 0) {
richMixtureEvents++;
} else {
leanMixtureEvents++;
}
}
}
// Обучение карты УОЗ
if (isIgnitionLearningEnabled) {
ignitionTable.learn(load, rpm, knockLevel);
if (knockLevel > 0.8) { // Порог детонации
knockEvents++;
}
}
totalLearningPoints++;
}
float LearningManager::getFuelCorrection(float load, float rpm) {
return fuelTable.getCorrection(load, rpm);
}
float LearningManager::getIgnitionCorrection(float load, float rpm) {
return ignitionTable.getCorrection(load, rpm);
}
void LearningManager::setLearningParameters(float minTemp, float maxTemp,
float minThrottle, float maxThrottle) {
minEngineTemp = minTemp;
maxEngineTemp = maxTemp;
minThrottlePosition = minThrottle;
maxThrottlePosition = maxThrottle;
}
void LearningManager::setLearningRates(float fuelRate, float ignitionRate) {
fuelTable.setLearningRate(fuelRate);
ignitionTable.setLearningRate(ignitionRate);
}
bool LearningManager::save() {
bool fuelSaved = fuelTable.save();
bool ignitionSaved = ignitionTable.save();
// Сохраняем статистику
Preferences prefs;
prefs.begin("learning", false);
prefs.putUInt("total_points", totalLearningPoints);
prefs.putUInt("knock_events", knockEvents);
prefs.putUInt("rich_events", richMixtureEvents);
prefs.putUInt("lean_events", leanMixtureEvents);
prefs.end();
return fuelSaved && ignitionSaved;
}
bool LearningManager::load() {
bool fuelLoaded = fuelTable.load();
bool ignitionLoaded = ignitionTable.load();
// Загружаем статистику
Preferences prefs;
prefs.begin("learning", true);
totalLearningPoints = prefs.getUInt("total_points", 0);
knockEvents = prefs.getUInt("knock_events", 0);
richMixtureEvents = prefs.getUInt("rich_events", 0);
leanMixtureEvents = prefs.getUInt("lean_events", 0);
prefs.end();
return fuelLoaded && ignitionLoaded;
}
void LearningManager::reset() {
fuelTable.reset();
ignitionTable.reset();
totalLearningPoints = 0;
knockEvents = 0;
richMixtureEvents = 0;
leanMixtureEvents = 0;
save();
}
void LearningManager::enable() {
isLearningEnabled = true;
learningStartTime = millis();
}
void LearningManager::disable() {
isLearningEnabled = false;
}
uint32_t LearningManager::getTotalLearningPoints() const {
return totalLearningPoints;
}
uint32_t LearningManager::getKnockEvents() const {
return knockEvents;
}
uint32_t LearningManager::getRichMixtureEvents() const {
return richMixtureEvents;
}
uint32_t LearningManager::getLeanMixtureEvents() const {
return leanMixtureEvents;
}
float LearningManager::getLearningProgress() const {
// Максимальное количество точек обучения (16x16 ячеек, минимум 10 точек на ячейку)
const uint32_t maxPoints = 16 * 16 * 10;
return (float)totalLearningPoints / maxPoints * 100.0f;
}
String LearningManager::exportToJson() {
DynamicJsonDocument doc(8192);
// Основные параметры
doc["enabled"] = isLearningEnabled;
doc["fuel_enabled"] = isFuelLearningEnabled;
doc["ignition_enabled"] = isIgnitionLearningEnabled;
// Статистика
JsonObject stats = doc.createNestedObject("statistics");
stats["total_points"] = totalLearningPoints;
stats["knock_events"] = knockEvents;
stats["rich_events"] = richMixtureEvents;
stats["lean_events"] = leanMixtureEvents;
stats["progress"] = getLearningProgress();
// Топливная карта
JsonArray fuelMap = doc.createNestedArray("fuel_map");
for (int i = 0; i < 16; i++) {
JsonArray row = fuelMap.createNestedArray();
for (int j = 0; j < 16; j++) {
row.add(fuelTable.getCellValue(i, j));
}
}
// Карта УОЗ
JsonArray ignitionMap = doc.createNestedArray("ignition_map");
for (int i = 0; i < 16; i++) {
JsonArray row = ignitionMap.createNestedArray();
for (int j = 0; j < 16; j++) {
row.add(ignitionTable.getCellValue(i, j));
}
}
String output;
serializeJson(doc, output);
return output;
}
bool LearningManager::importFromJson(const String& json) {
DynamicJsonDocument doc(8192);
DeserializationError error = deserializeJson(doc, json);
if (error) {
return false;
}
// Временно отключаем обучение
bool wasEnabled = isLearningEnabled;
disable();
// Сбрасываем текущие данные
reset();
// Загружаем новые данные
if (doc.containsKey("enabled")) {
isLearningEnabled = doc["enabled"];
}
if (doc.containsKey("statistics")) {
JsonObject stats = doc["statistics"];
totalLearningPoints = stats["total_points"] | 0;
knockEvents = stats["knock_events"] | 0;
richMixtureEvents = stats["rich_events"] | 0;
leanMixtureEvents = stats["lean_events"] | 0;
}
// Восстанавливаем состояние обучения
if (wasEnabled) {
enable();
}
// Сохраняем изменения
return save();
}