From 10951d7f1342d9267a34dc64eb5c8257f7ebdc55 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Sat, 17 May 2025 10:58:31 +0200 Subject: [PATCH] Basis working --- lib/obp60task/BoatDataCalibration.cpp | 49 ++++++++++++++++++----- lib/obp60task/BoatDataCalibration.h | 2 + lib/obp60task/config.json | 56 +++++++++++++++++++++++---- 3 files changed, 91 insertions(+), 16 deletions(-) diff --git a/lib/obp60task/BoatDataCalibration.cpp b/lib/obp60task/BoatDataCalibration.cpp index 33d4121..80c3aa7 100644 --- a/lib/obp60task/BoatDataCalibration.cpp +++ b/lib/obp60task/BoatDataCalibration.cpp @@ -3,6 +3,7 @@ #include "BoatDataCalibration.h" #include #include +#include CalibrationDataList calibrationData; @@ -13,10 +14,12 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) String instance; double offset; double slope; + double smooth; String calInstance = ""; String calOffset = ""; String calSlope = ""; + String calSmooth = ""; // Load user format configuration values String lengthFormat = config->getString(config->lengthFormat); // [m|ft] @@ -27,18 +30,20 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) // Read calibration settings for data instances for (int i = 0; i < maxCalibrationData; i++) { - calInstance = "calInstance" + String(i+1); - calOffset = "calOffset" + String(i+1); - calSlope = "calSlope" + String(i+1); - calibrationData.list[i] = { "---", 0.0f, 1.0f, 0.0f, false }; + calInstance = "calInstance" + String(i + 1); + calOffset = "calOffset" + String(i + 1); + calSlope = "calSlope" + String(i + 1); + calSmooth = "calSmooth" + String(i + 1); + calibrationData.list[i] = { "---", 0.0f, 1.0f, 1, 0.0f, false }; instance = config->getString(calInstance, "---"); if (instance == "---") { - LOG_DEBUG(GwLog::LOG, "no calibration data for instance no. %d", i+1); + LOG_DEBUG(GwLog::LOG, "no calibration data for instance no. %d", i + 1); continue; } offset = (config->getString(calOffset, "")).toFloat(); slope = (config->getString(calSlope, "")).toFloat(); + smooth = (config->getString(calSmooth, "")).toInt(); // Convert calibration values to internal standard formats if (instance == "AWS" || instance == "TWS") { @@ -52,8 +57,7 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) offset *= 0.5; // Convert Bft to m/s (approx) -> to be improved } - } else if (instance == "AWA" || instance == "TWA" ||instance == "TWD" || instance == "HDM" || - instance == "PRPOS" || instance == "RPOS") { + } else if (instance == "AWA" || instance == "TWA" || instance == "TWD" || instance == "HDM" || instance == "PRPOS" || instance == "RPOS") { offset *= M_PI / 180; // Convert deg to rad } else if (instance == "DBT") { @@ -62,7 +66,7 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) } else if (lengthFormat == "ft") { offset /= 3.28084; // Convert ft to m } - + } else if (instance == "STW") { if (speedFormat == "m/s") { // No conversion needed @@ -80,11 +84,18 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) slope *= 9.0 / 5.0; // Convert °F to K } } + if (smooth < 0) { + smooth = 0; + } else if (smooth > 9) { + smooth = 9; + } calibrationData.list[i].instance = instance; calibrationData.list[i].offset = offset; calibrationData.list[i].slope = slope; + calibrationData.list[i].smooth = 1 - (smooth / 10.0); // smooth factor is between 0 and 1 calibrationData.list[i].isCalibrated = false; - LOG_DEBUG(GwLog::LOG, "stored calibration data: %s, offset: %f, slope: %f", calibrationData.list[i].instance.c_str(), calibrationData.list[i].offset, calibrationData.list[i].slope); + LOG_DEBUG(GwLog::LOG, "stored calibration data: %s, offset: %f, slope: %f, smoothing: %f", calibrationData.list[i].instance.c_str(), + calibrationData.list[i].offset, calibrationData.list[i].slope, calibrationData.list[i].smooth); } LOG_DEBUG(GwLog::LOG, "all calibration data read"); } @@ -153,6 +164,7 @@ void CalibrationDataList::calibrateInstance(String instance, GwApi::BoatValue* b dataValue = (dataValue * slope) + offset; } + calibrationData.smoothInstance(instance, dataValue, logger); // smooth the boat data value calibrationData.list[listNo].value = dataValue; calibrationData.list[listNo].isCalibrated = true; boatDataValue->value = dataValue; @@ -161,4 +173,23 @@ void CalibrationDataList::calibrateInstance(String instance, GwApi::BoatValue* b } } +void CalibrationDataList::smoothInstance(String instance, double &dataValue, GwLog* logger) +// Method to smoothen the boat data value +{ + // array for last values of smoothed boat data values + static std::unordered_map lastValue; + + double oldValue = 0; + double smoothFactor = calibrationData.list[getInstanceListNo(instance)].smooth; + + if (lastValue.find(instance.c_str()) != lastValue.end()) { + oldValue = lastValue[instance.c_str()]; + + dataValue = oldValue + (smoothFactor * (dataValue - oldValue)); // exponential smoothing algorithm + } + lastValue[instance.c_str()] = dataValue; // store the new value for next cycle; first time, store only the current value and return + + LOG_DEBUG(GwLog::LOG, "BoatDataCalibration: %s: Smoothed value: %f", instance.c_str(), dataValue); +} + #endif \ No newline at end of file diff --git a/lib/obp60task/BoatDataCalibration.h b/lib/obp60task/BoatDataCalibration.h index 32fa7e9..43a4623 100644 --- a/lib/obp60task/BoatDataCalibration.h +++ b/lib/obp60task/BoatDataCalibration.h @@ -10,6 +10,7 @@ typedef struct { String instance; // data type/instance to be calibrated double offset; // calibration offset double slope; // calibration slope + double smooth; // smoothing factor double value; // calibrated data value bool isCalibrated; // is data instance value calibrated? } CalibData; @@ -23,6 +24,7 @@ public: static void readConfig(GwConfigHandler* config, GwLog* logger); static int getInstanceListNo(String instance); static void calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger); + void smoothInstance(String instance, double &dataValue, GwLog* logger); private: }; diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index b5db57d..ebce2df 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -713,7 +713,7 @@ }, { "name": "calOffset1", - "label": "Calibration Data Instance 1 Offset", + "label": "Data Instance 1 Calibration Offset", "type": "number", "default": "0.00", "description": "Offset for data instance 1", @@ -724,7 +724,7 @@ }, { "name": "calSlope1", - "label": "Calibration Data Instance 1 Slope", + "label": "Data Instance 1 Calibration Slope", "type": "number", "default": "1.00", "description": "Slope for data instance 1", @@ -733,6 +733,20 @@ "obp60":"true" } }, + { + "name": "calSmooth1", + "label": "Data Instance 1 Smoothing", + "type": "number", + "default": "0", + "check": "checkMinMax", + "min": 0, + "max": 9, + "description": "Smoothing factor for data instance 1", + "category": "OBP60 Calibrations", + "capabilities": { + "obp60":"true" + } + }, { "name": "calInstance2", "label": "Calibration Data Instance 2", @@ -760,7 +774,7 @@ }, { "name": "calOffset2", - "label": "Calibration Data Instance 2 Offset", + "label": "Data Instance 2 Calibration Offset", "type": "number", "default": "0.00", "description": "Offset for data instance 2", @@ -771,7 +785,7 @@ }, { "name": "calSlope2", - "label": "Calibration Data Instance 2 Slope", + "label": "Data Instance 2 Calibration Slope", "type": "number", "default": "1.00", "description": "Slope for data instance 2", @@ -780,6 +794,20 @@ "obp60":"true" } }, + { + "name": "calSmooth2", + "label": "Data Instance 2 Smoothing", + "type": "number", + "default": "0", + "check": "checkMinMax", + "min": 0, + "max": 9, + "description": "Smoothing factor for data instance 2", + "category": "OBP60 Calibrations", + "capabilities": { + "obp60":"true" + } + }, { "name": "calInstance3", "label": "Calibration Data Instance 3", @@ -807,7 +835,7 @@ }, { "name": "calOffset3", - "label": "Calibration Data Instance 3 Offset", + "label": "Data Instance 3 Calibration Offset", "type": "number", "default": "0.00", "description": "Offset for data instance 3", @@ -818,7 +846,7 @@ }, { "name": "calSlope3", - "label": "Calibration Data Instance 3 Slope", + "label": "Data Instance 3 Calibration Slope", "type": "number", "default": "1.00", "description": "Slope for data instance 3", @@ -827,7 +855,21 @@ "obp60":"true" } }, -{ + { + "name": "calSmooth3", + "label": "Data Instance 3 Smoothing", + "type": "number", + "default": "0", + "check": "checkMinMax", + "min": 0, + "max": 9, + "description": "Smoothing factor for data instance 3", + "category": "OBP60 Calibrations", + "capabilities": { + "obp60":"true" + } + }, + { "name": "display", "label": "Display Mode", "type": "list",