From b8e64ff64c6aa24760c5f1429efb7c46da7f24b0 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Sat, 17 Jan 2026 12:25:57 +0100 Subject: [PATCH 1/3] Update data calibration: calibration in main loop on boat data values: - modified code to calibrate affected boat data each second in main obp60task loop; - removed individual calibration call in all pages - moved code from BoatDataCalibration to OBPDataOperations - added DBS and HDT to list of supported data calibration types - changed output format for wind angles from [-180..180] to [0..360], because negative value are not displayed properly on pages --- lib/obp60task/BoatDataCalibration.cpp | 190 --------------------- lib/obp60task/BoatDataCalibration.h | 34 ---- lib/obp60task/OBPDataOperations.cpp | 229 +++++++++++++++++++++++++- lib/obp60task/OBPDataOperations.h | 29 +++- lib/obp60task/PageFourValues.cpp | 5 - lib/obp60task/PageFourValues2.cpp | 5 - lib/obp60task/PageOneValue.cpp | 2 - lib/obp60task/PageRudderPosition.cpp | 2 - lib/obp60task/PageSixValues.cpp | 2 - lib/obp60task/PageThreeValues.cpp | 4 - lib/obp60task/PageTwoValues.cpp | 2 - lib/obp60task/PageWind.cpp | 3 - lib/obp60task/PageWindRose.cpp | 7 - lib/obp60task/PageWindRoseFlex.cpp | 7 - lib/obp60task/config.json | 30 ++-- lib/obp60task/config_obp40.json | 30 ++-- lib/obp60task/obp60task.cpp | 28 ++-- 17 files changed, 300 insertions(+), 309 deletions(-) delete mode 100644 lib/obp60task/BoatDataCalibration.cpp delete mode 100644 lib/obp60task/BoatDataCalibration.h diff --git a/lib/obp60task/BoatDataCalibration.cpp b/lib/obp60task/BoatDataCalibration.cpp deleted file mode 100644 index 9543926..0000000 --- a/lib/obp60task/BoatDataCalibration.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3 - -#include "BoatDataCalibration.h" -#include -#include -#include - -CalibrationDataList calibrationData; -std::unordered_map CalibrationDataList::calibMap; // list of calibration data instances - -void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) -// Initial load of calibration data into internal list -// This method is called once at init phase of to read the configuration values -{ - std::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] - String distanceFormat = config->getString(config->distanceFormat); // [m|km|nm] - String speedFormat = config->getString(config->speedFormat); // [m/s|km/h|kn] - String windspeedFormat = config->getString(config->windspeedFormat); // [m/s|km/h|kn|bft] - String tempFormat = config->getString(config->tempFormat); // [K|C|F] - - // Read calibration settings for data instances - for (int i = 0; i < MAX_CALIBRATION_DATA; i++) { - calInstance = "calInstance" + String(i + 1); - calOffset = "calOffset" + String(i + 1); - calSlope = "calSlope" + String(i + 1); - calSmooth = "calSmooth" + String(i + 1); - - instance = std::string(config->getString(calInstance, "---").c_str()); - if (instance == "---") { - LOG_DEBUG(GwLog::LOG, "no calibration data for instance no. %d", i + 1); - continue; - } - calibMap[instance] = { 0.0f, 1.0f, 1.0f, 0.0f, false }; - offset = (config->getString(calOffset, "")).toFloat(); - slope = (config->getString(calSlope, "")).toFloat(); - smooth = (config->getString(calSmooth, "")).toInt(); // user input is int; further math is done with double - - // Convert calibration values to internal standard formats - if (instance == "AWS" || instance == "TWS") { - if (windspeedFormat == "m/s") { - // No conversion needed - } else if (windspeedFormat == "km/h") { - offset /= 3.6; // Convert km/h to m/s - } else if (windspeedFormat == "kn") { - offset /= 1.94384; // Convert kn to m/s - } else if (windspeedFormat == "bft") { - offset *= 2 + (offset / 2); // Convert Bft to m/s (approx) -> to be improved - } - - } else if (instance == "AWA" || instance == "COG" || instance == "TWA" || instance == "TWD" || instance == "HDM" || instance == "PRPOS" || instance == "RPOS") { - offset *= M_PI / 180; // Convert deg to rad - - } else if (instance == "DBT") { - if (lengthFormat == "m") { - // No conversion needed - } else if (lengthFormat == "ft") { - offset /= 3.28084; // Convert ft to m - } - - } else if (instance == "SOG" || instance == "STW") { - if (speedFormat == "m/s") { - // No conversion needed - } else if (speedFormat == "km/h") { - offset /= 3.6; // Convert km/h to m/s - } else if (speedFormat == "kn") { - offset /= 1.94384; // Convert kn to m/s - } - - } else if (instance == "WTemp") { - if (tempFormat == "K" || tempFormat == "C") { - // No conversion needed - } else if (tempFormat == "F") { - offset *= 9.0 / 5.0; // Convert °F to K - slope *= 9.0 / 5.0; // Convert °F to K - } - } - - // transform smoothing factor from {0.01..10} to {0.3..0.95} and invert for exponential smoothing formula - if (smooth <= 0) { - smooth = 0; - } else { - if (smooth > 10) { - smooth = 10; - } - smooth = 0.3 + ((smooth - 0.01) * (0.95 - 0.3) / (10 - 0.01)); - } - smooth = 1 - smooth; - - calibMap[instance].offset = offset; - calibMap[instance].slope = slope; - calibMap[instance].smooth = smooth; - calibMap[instance].isCalibrated = false; - LOG_DEBUG(GwLog::LOG, "calibration data: %s, offset: %f, slope: %f, smoothing: %f", instance.c_str(), - calibMap[instance].offset, calibMap[instance].slope, calibMap[instance].smooth); - } - LOG_DEBUG(GwLog::LOG, "all calibration data read"); -} - -void CalibrationDataList::calibrateInstance(GwApi::BoatValue* boatDataValue, GwLog* logger) -// Method to calibrate the boat data value -{ - std::string instance = boatDataValue->getName().c_str(); - double offset = 0; - double slope = 1.0; - double dataValue = 0; - std::string format = ""; - - if (calibMap.find(instance) == calibMap.end()) { - LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s not in calibration list", instance.c_str()); - return; - } else if (!boatDataValue->valid) { // no valid boat data value, so we don't want to apply calibration data - calibMap[instance].isCalibrated = false; - return; - } else { - offset = calibMap[instance].offset; - slope = calibMap[instance].slope; - dataValue = boatDataValue->value; - format = boatDataValue->getFormat().c_str(); - LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: value: %f, format: %s", instance.c_str(), dataValue, format.c_str()); - - if (format == "formatWind") { // instance is of type angle - dataValue = (dataValue * slope) + offset; - dataValue = fmod(dataValue, 2 * M_PI); - if (dataValue > (M_PI)) { - dataValue -= (2 * M_PI); - } else if (dataValue < (M_PI * -1)) { - dataValue += (2 * M_PI); - } - } else if (format == "formatCourse") { // instance is of type direction - dataValue = (dataValue * slope) + offset; - dataValue = fmod(dataValue, 2 * M_PI); - if (dataValue < 0) { - dataValue += (2 * M_PI); - } - } else if (format == "kelvinToC") { // instance is of type temperature - dataValue = ((dataValue - 273.15) * slope) + offset + 273.15; - } else { - - dataValue = (dataValue * slope) + offset; - } - - calibMap[instance].isCalibrated = true; - boatDataValue->value = dataValue; - - calibrationData.smoothInstance(boatDataValue, logger); // smooth the boat data value - calibMap[instance].value = boatDataValue->value; // store the calibrated + smoothed value in the list - - LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: Offset: %f, Slope: %f, Result: %f", instance.c_str(), offset, slope, calibMap[instance].value); - } -} - -void CalibrationDataList::smoothInstance(GwApi::BoatValue* boatDataValue, GwLog* logger) -// Method to smoothen the boat data value -{ - static std::unordered_map lastValue; // array for last values of smoothed boat data values - - std::string instance = boatDataValue->getName().c_str(); - double oldValue = 0; - double dataValue = boatDataValue->value; - double smoothFactor = 0; - - if (!boatDataValue->valid) { // no valid boat data value, so we don't want to smoothen value - return; - } else if (calibMap.find(instance) == calibMap.end()) { - LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: smooth factor for %s not found in calibration list", instance.c_str()); - return; - } else { - smoothFactor = calibMap[instance].smooth; - - if (lastValue.find(instance) != lastValue.end()) { - oldValue = lastValue[instance]; - dataValue = oldValue + (smoothFactor * (dataValue - oldValue)); // exponential smoothing algorithm - } - lastValue[instance] = dataValue; // store the new value for next cycle; first time, store only the current value and return - boatDataValue->value = dataValue; // set the smoothed value to the boat data value - } -} - -#endif \ No newline at end of file diff --git a/lib/obp60task/BoatDataCalibration.h b/lib/obp60task/BoatDataCalibration.h deleted file mode 100644 index d906fa9..0000000 --- a/lib/obp60task/BoatDataCalibration.h +++ /dev/null @@ -1,34 +0,0 @@ -// Functions lib for data instance calibration - -#ifndef _BOATDATACALIBRATION_H -#define _BOATDATACALIBRATION_H - -// #include "Pagedata.h" -#include "GwApi.h" -#include -#include - -#define MAX_CALIBRATION_DATA 3 // maximum number of calibration data instances - -typedef struct { - double offset; // calibration offset - double slope; // calibration slope - double smooth; // smoothing factor - double value; // calibrated data value - bool isCalibrated; // is data instance value calibrated? -} TypeCalibData; - -class CalibrationDataList { -public: - static std::unordered_map calibMap; // list of calibration data instances - - void readConfig(GwConfigHandler* config, GwLog* logger); - void calibrateInstance(GwApi::BoatValue* boatDataValue, GwLog* logger); - void smoothInstance(GwApi::BoatValue* boatDataValue, GwLog* logger); - -private: -}; - -extern CalibrationDataList calibrationData; // this list holds all calibration data - -#endif \ No newline at end of file diff --git a/lib/obp60task/OBPDataOperations.cpp b/lib/obp60task/OBPDataOperations.cpp index aae0040..1adb7f4 100644 --- a/lib/obp60task/OBPDataOperations.cpp +++ b/lib/obp60task/OBPDataOperations.cpp @@ -1,5 +1,221 @@ #include "OBPDataOperations.h" -#include "BoatDataCalibration.h" // Functions lib for data instance calibration +//#include "BoatDataCalibration.h" // Functions lib for data instance calibration + +// --- Class CalibrationData --------------- +CalibrationData::CalibrationData(GwLog* log) +{ + logger = log; +} + +void CalibrationData::readConfig(GwConfigHandler* config) +// Initial load of calibration data into internal list +// This method is called once at init phase of to read the configuration values +{ + std::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] + String distanceFormat = config->getString(config->distanceFormat); // [m|km|nm] + String speedFormat = config->getString(config->speedFormat); // [m/s|km/h|kn] + String windspeedFormat = config->getString(config->windspeedFormat); // [m/s|km/h|kn|bft] + String tempFormat = config->getString(config->tempFormat); // [K|C|F] + + // Read calibration settings for data instances + for (int i = 0; i < MAX_CALIBRATION_DATA; i++) { + calInstance = "calInstance" + String(i + 1); + calOffset = "calOffset" + String(i + 1); + calSlope = "calSlope" + String(i + 1); + calSmooth = "calSmooth" + String(i + 1); + + instance = std::string(config->getString(calInstance, "---").c_str()); + if (instance == "---") { + LOG_DEBUG(GwLog::LOG, "No calibration data for instance no. %d", i + 1); + continue; + } + + calibrationMap[instance] = { 0.0f, 1.0f, 1.0f, 0.0f, false }; + offset = (config->getString(calOffset, "")).toDouble(); + slope = (config->getString(calSlope, "")).toDouble(); + smooth = (config->getString(calSmooth, "")).toInt(); // user input is int; further math is done with double + + if (slope == 0.0) { + slope = 1.0; // eliminate adjustment if user selected "0" -> that would set the calibrated value to "0" + } + + // Convert calibration values from user input format to internal standard SI format + if (instance == "AWS" || instance == "TWS") { + if (windspeedFormat == "m/s") { + // No conversion needed + } else if (windspeedFormat == "km/h") { + offset /= 3.6; // Convert km/h to m/s + } else if (windspeedFormat == "kn") { + offset /= 1.94384; // Convert kn to m/s + } else if (windspeedFormat == "bft") { + offset *= 2 + (offset / 2); // Convert Bft to m/s (approx) -> to be improved + } + + } else if (instance == "AWA" || instance == "COG" || instance == "HDM" || instance == "HDT" || instance == "PRPOS" || instance == "RPOS" || instance == "TWA" || instance == "TWD") { + offset *= DEG_TO_RAD; // Convert deg to rad + + } else if (instance == "DBS" || instance == "DBT") { + if (lengthFormat == "m") { + // No conversion needed + } else if (lengthFormat == "ft") { + offset /= 3.28084; // Convert ft to m + } + + } else if (instance == "SOG" || instance == "STW") { + if (speedFormat == "m/s") { + // No conversion needed + } else if (speedFormat == "km/h") { + offset /= 3.6; // Convert km/h to m/s + } else if (speedFormat == "kn") { + offset /= 1.94384; // Convert kn to m/s + } + + } else if (instance == "WTemp") { + if (tempFormat == "K" || tempFormat == "C") { + // No conversion needed + } else if (tempFormat == "F") { + offset *= 9.0 / 5.0; // Convert °F to K + slope *= 9.0 / 5.0; // Convert °F to K + } + } + + // transform smoothing factor from [0.01..10] to [0.3..0.95] and invert for exponential smoothing formula + if (smooth <= 0) { + smooth = 0; + } else { + if (smooth > 10) { + smooth = 10; + } + smooth = 0.3 + ((smooth - 0.01) * (0.95 - 0.3) / (10 - 0.01)); + } + smooth = 1 - smooth; + + calibrationMap[instance].offset = offset; + calibrationMap[instance].slope = slope; + calibrationMap[instance].smooth = smooth; + calibrationMap[instance].isCalibrated = false; + LOG_DEBUG(GwLog::LOG, "Calibration data type added: %s, offset: %f, slope: %f, smoothing: %f", instance.c_str(), + calibrationMap[instance].offset, calibrationMap[instance].slope, calibrationMap[instance].smooth); + } + // LOG_DEBUG(GwLog::LOG, "All calibration data read"); +} + +// Handle calibrationMap and calibrate all boat data values +void CalibrationData::handleCalibration(BoatValueList* boatValueList) +{ + GwApi::BoatValue* bValue; + + for (const auto& cMap : calibrationMap) { + std::string instance = cMap.first.c_str(); + bValue = boatValueList->findValueOrCreate(String(instance.c_str())); + + calibrateInstance(bValue); + smoothInstance(bValue); + } +} + +// Calibrate single boat data value +// Return calibrated boat value or DBL_MAX, if no calibration was performed +bool CalibrationData::calibrateInstance(GwApi::BoatValue* boatDataValue) +{ + std::string instance = boatDataValue->getName().c_str(); + double offset = 0; + double slope = 1.0; + double dataValue = 0; + std::string format = ""; + + // we test this earlier, but for safety reason ... + if (calibrationMap.find(instance) == calibrationMap.end()) { + LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s not in calibration list", instance.c_str()); + return false; + } + + calibrationMap[instance].isCalibrated = false; // reset calibration flag until properly calibrated + + if (!boatDataValue->valid) { // no valid boat data value, so we don't want to apply calibration data + return false; + } + + offset = calibrationMap[instance].offset; + slope = calibrationMap[instance].slope; + dataValue = boatDataValue->value; + format = boatDataValue->getFormat().c_str(); + LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: value: %f, format: %s", instance.c_str(), dataValue, format.c_str()); + + if (format == "formatWind") { // instance is of type angle + dataValue = (dataValue * slope) + offset; + // dataValue = WindUtils::toPI(dataValue); + dataValue = WindUtils::to2PI(dataValue); // we should call for format of [-180..180], but pages cannot handle negative values yet + + } else if (format == "formatCourse") { // instance is of type direction + dataValue = (dataValue * slope) + offset; + dataValue = WindUtils::to2PI(dataValue); + + } else if (format == "kelvinToC") { // instance is of type temperature + dataValue = ((dataValue - 273.15) * slope) + offset + 273.15; + + } else { + dataValue = (dataValue * slope) + offset; + } + + + boatDataValue->value = dataValue; // update boat data value with calibrated value + calibrationMap[instance].value = dataValue; // store the calibrated value in the list + calibrationMap[instance].isCalibrated = true; + + LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: Offset: %f, Slope: %f, Result: %f", instance.c_str(), offset, slope, calibrationMap[instance].value); + return true; +} + +// Smooth single boat data value +// Return smoothed boat value or DBL_MAX, if no smoothing was performed +bool CalibrationData::smoothInstance(GwApi::BoatValue* boatDataValue) +{ + std::string instance = boatDataValue->getName().c_str(); + double oldValue = 0; + double dataValue = boatDataValue->value; + double smoothFactor = 0; + + // we test this earlier, but for safety reason ... + if (calibrationMap.find(instance) == calibrationMap.end()) { + LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s not in calibration list", instance.c_str()); + return false; + } + + calibrationMap[instance].isCalibrated = false; // reset calibration flag until properly calibrated + + if (!boatDataValue->valid) { // no valid boat data value, so we don't need to do anything + return false; + } + + smoothFactor = calibrationMap[instance].smooth; + + if (lastValue.find(instance) != lastValue.end()) { + oldValue = lastValue[instance]; + dataValue = oldValue + (smoothFactor * (dataValue - oldValue)); // exponential smoothing algorithm + } + lastValue[instance] = dataValue; // store the new value for next cycle; first time, store only the current value and return + + boatDataValue->value = dataValue; // update boat data value with smoothed value + calibrationMap[instance].value = dataValue; // store the smoothed value in the list + calibrationMap[instance].isCalibrated = true; + + LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: smooth: %f, oldValue: %f, result: %f", instance.c_str(), smoothFactor, oldValue, calibrationMap[instance].value); + + return true; +} +// --- End Class CalibrationData --------------- // --- Class HstryBuf --------------- HstryBuf::HstryBuf(const String& name, int size, BoatValueList* boatValues, GwLog* log) @@ -43,12 +259,15 @@ void HstryBuf::handle(bool useSimuData, CommonData& common) if (boatValue->valid) { // Calibrate boat value before adding it to history buffer - calibrationData.calibrateInstance(tmpBVal.get(), logger); - add(tmpBVal->value); + //calibrationData.calibrateInstance(tmpBVal.get(), logger); + //add(tmpBVal->value); + add(boatValue->value); } else if (useSimuData) { // add simulated value to history buffer - double simValue = formatValue(tmpBVal.get(), common).value; // simulated value is generated at - add(simValue); + double simSIValue = formatValue(tmpBVal.get(), common).value; // simulated value is generated at ; here: retreive SI value + add(simSIValue); + } else { + // here we will add invalid (DBL_MAX) value; this will mark periods of missing data in buffer together with a timestamp } } // --- End Class HstryBuf --------------- diff --git a/lib/obp60task/OBPDataOperations.h b/lib/obp60task/OBPDataOperations.h index 0fb8647..e42e293 100644 --- a/lib/obp60task/OBPDataOperations.h +++ b/lib/obp60task/OBPDataOperations.h @@ -1,9 +1,36 @@ -// Function lib for history buffer handling, true wind calculation, and other operations on boat data +// Function lib for boat data calibration, history buffer handling, true wind calculation, and other operations on boat data #pragma once #include "OBPRingBuffer.h" #include "Pagedata.h" #include "obp60task.h" #include +#include + +// Calibration of boat data values, when user setting available +// supported boat data types are: AWA, AWS, COG, DBS, DBT, HDM, HDT, PRPOS, RPOS, SOG, STW, TWA, TWS, TWD, WTemp +class CalibrationData { +private: + typedef struct { + double offset; // calibration offset + double slope; // calibration slope + double smooth; // smoothing factor + double value; // calibrated data value (for future use) + bool isCalibrated; // is data instance value calibrated? (for future use) + } tCalibrationData; + + std::unordered_map calibrationMap; // list of calibration data instances + std::unordered_map lastValue; // array for last smoothed values of boat data values + GwLog* logger; + + static constexpr int8_t MAX_CALIBRATION_DATA = 3; // maximum number of calibration data instances + +public: + CalibrationData(GwLog* log); + void readConfig(GwConfigHandler* config); + void handleCalibration(BoatValueList* boatValues); // Handle calibrationMap and calibrate all boat data values + bool calibrateInstance(GwApi::BoatValue* boatDataValue); // Calibrate single boat data value + bool smoothInstance(GwApi::BoatValue* boatDataValue); // Smooth single boat data value +}; class HstryBuf { private: diff --git a/lib/obp60task/PageFourValues.cpp b/lib/obp60task/PageFourValues.cpp index b7526c0..cb9de68 100644 --- a/lib/obp60task/PageFourValues.cpp +++ b/lib/obp60task/PageFourValues.cpp @@ -2,7 +2,6 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -#include "BoatDataCalibration.h" class PageFourValues : public Page { @@ -46,7 +45,6 @@ class PageFourValues : public Page GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue) String name1 = xdrDelete(bvalue1->getName()); // Value name name1 = name1.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -56,7 +54,6 @@ class PageFourValues : public Page GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list String name2 = xdrDelete(bvalue2->getName()); // Value name name2 = name2.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -66,7 +63,6 @@ class PageFourValues : public Page GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list String name3 = xdrDelete(bvalue3->getName()); // Value name name3 = name3.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -76,7 +72,6 @@ class PageFourValues : public Page GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list String name4 = xdrDelete(bvalue4->getName()); // Value name name4 = name4.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated double value4 = bvalue4->value; // Value as double in SI unit bool valid4 = bvalue4->valid; // Valid information String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places diff --git a/lib/obp60task/PageFourValues2.cpp b/lib/obp60task/PageFourValues2.cpp index e608409..730e14b 100644 --- a/lib/obp60task/PageFourValues2.cpp +++ b/lib/obp60task/PageFourValues2.cpp @@ -2,7 +2,6 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -#include "BoatDataCalibration.h" class PageFourValues2 : public Page { @@ -46,7 +45,6 @@ class PageFourValues2 : public Page GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue) String name1 = xdrDelete(bvalue1->getName()); // Value name name1 = name1.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -56,7 +54,6 @@ class PageFourValues2 : public Page GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue) String name2 = xdrDelete(bvalue2->getName()); // Value name name2 = name2.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -66,7 +63,6 @@ class PageFourValues2 : public Page GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue) String name3 = xdrDelete(bvalue3->getName()); // Value name name3 = name3.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -76,7 +72,6 @@ class PageFourValues2 : public Page GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue) String name4 = xdrDelete(bvalue4->getName()); // Value name name4 = name4.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated double value4 = bvalue4->value; // Value as double in SI unit bool valid4 = bvalue4->valid; // Valid information String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places diff --git a/lib/obp60task/PageOneValue.cpp b/lib/obp60task/PageOneValue.cpp index 6349f29..a5c0f9c 100644 --- a/lib/obp60task/PageOneValue.cpp +++ b/lib/obp60task/PageOneValue.cpp @@ -2,7 +2,6 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -#include "BoatDataCalibration.h" #include "OBPDataOperations.h" #include "OBPcharts.h" @@ -88,7 +87,6 @@ private: String name1 = xdrDelete(bValue1->getName()); // Value name name1 = name1.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bValue1, logger); // Check if boat data value is to be calibrated double value1 = bValue1->value; // Value as double in SI unit bool valid1 = bValue1->valid; // Valid information String sValue1 = formatValue(bValue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places diff --git a/lib/obp60task/PageRudderPosition.cpp b/lib/obp60task/PageRudderPosition.cpp index 22b5f91..6a8695f 100644 --- a/lib/obp60task/PageRudderPosition.cpp +++ b/lib/obp60task/PageRudderPosition.cpp @@ -2,7 +2,6 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -#include "BoatDataCalibration.h" class PageRudderPosition : public Page { @@ -41,7 +40,6 @@ public: GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list String name1 = bvalue1->getName().c_str(); // Value name name1 = name1.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated value1 = bvalue1->value; // Raw value without unit convertion bool valid1 = bvalue1->valid; // Valid information String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places diff --git a/lib/obp60task/PageSixValues.cpp b/lib/obp60task/PageSixValues.cpp index af735f2..b75f307 100644 --- a/lib/obp60task/PageSixValues.cpp +++ b/lib/obp60task/PageSixValues.cpp @@ -2,7 +2,6 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -#include "BoatDataCalibration.h" const int SixValues_x1 = 5; const int SixValues_DeltaX = 200; @@ -57,7 +56,6 @@ class PageSixValues : public Page bvalue = pageData.values[i]; DataName[i] = xdrDelete(bvalue->getName()); DataName[i] = DataName[i].substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue, logger); // Check if boat data value is to be calibrated DataValue[i] = bvalue->value; // Value as double in SI unit DataValid[i] = bvalue->valid; DataText[i] = formatValue(bvalue, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places diff --git a/lib/obp60task/PageThreeValues.cpp b/lib/obp60task/PageThreeValues.cpp index 996e2bc..7c5324f 100644 --- a/lib/obp60task/PageThreeValues.cpp +++ b/lib/obp60task/PageThreeValues.cpp @@ -2,7 +2,6 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -#include "BoatDataCalibration.h" class PageThreeValues : public Page { @@ -44,7 +43,6 @@ class PageThreeValues : public Page GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue) String name1 = xdrDelete(bvalue1->getName()); // Value name name1 = name1.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -54,7 +52,6 @@ class PageThreeValues : public Page GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list String name2 = xdrDelete(bvalue2->getName()); // Value name name2 = name2.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -64,7 +61,6 @@ class PageThreeValues : public Page GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list String name3 = xdrDelete(bvalue3->getName()); // Value name name3 = name3.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places diff --git a/lib/obp60task/PageTwoValues.cpp b/lib/obp60task/PageTwoValues.cpp index d4c0d98..323cbcb 100644 --- a/lib/obp60task/PageTwoValues.cpp +++ b/lib/obp60task/PageTwoValues.cpp @@ -2,7 +2,6 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -#include "BoatDataCalibration.h" #include "OBPDataOperations.h" #include "OBPcharts.h" @@ -69,7 +68,6 @@ private: int yOffset = YOFFSET * i; String name = xdrDelete(bValue[i]->getName()); // Value name name = name.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bValue[i], logger); // Check if boat data value is to be calibrated double value = bValue[i]->value; // Value as double in SI unit bool valid = bValue[i]->valid; // Valid information String sValue = formatValue(bValue[i], *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places diff --git a/lib/obp60task/PageWind.cpp b/lib/obp60task/PageWind.cpp index 226b430..242a365 100644 --- a/lib/obp60task/PageWind.cpp +++ b/lib/obp60task/PageWind.cpp @@ -3,7 +3,6 @@ #include "Pagedata.h" #include "OBP60Extensions.h" #include "N2kMessages.h" -#include "BoatDataCalibration.h" #define front_width 120 #define front_height 162 @@ -324,7 +323,6 @@ public: } String name1 = bvalue1->getName().c_str(); // Value name name1 = name1.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated double value1 = bvalue1->value; // Value as double in SI unit // bool valid1 = bvalue1->valid; // Valid information String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -338,7 +336,6 @@ public: } String name2 = bvalue2->getName().c_str(); // Value name name2 = name2.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated double value2 = bvalue2->value; // Value as double in SI unit // bool valid2 = bvalue2->valid; // Valid information if (simulation) { diff --git a/lib/obp60task/PageWindRose.cpp b/lib/obp60task/PageWindRose.cpp index c4ab0e0..427e64b 100644 --- a/lib/obp60task/PageWindRose.cpp +++ b/lib/obp60task/PageWindRose.cpp @@ -2,7 +2,6 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -#include "BoatDataCalibration.h" class PageWindRose : public Page { @@ -52,7 +51,6 @@ public: GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue) String name1 = xdrDelete(bvalue1->getName()); // Value name name1 = name1.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information value1 = formatValue(bvalue1, *commonData).value;// Format only nesaccery for simulation data for pointer @@ -67,7 +65,6 @@ public: GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list String name2 = xdrDelete(bvalue2->getName()); // Value name name2 = name2.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -81,7 +78,6 @@ public: GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list String name3 = xdrDelete(bvalue3->getName()); // Value name name3 = name3.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -95,7 +91,6 @@ public: GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list String name4 = xdrDelete(bvalue4->getName()); // Value name name4 = name4.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated double value4 = bvalue4->value; // Value as double in SI unit bool valid4 = bvalue4->valid; // Valid information String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -109,7 +104,6 @@ public: GwApi::BoatValue *bvalue5 = pageData.values[4]; // Fifth element in list String name5 = xdrDelete(bvalue5->getName()); // Value name name5 = name5.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue5, logger); // Check if boat data value is to be calibrated double value5 = bvalue5->value; // Value as double in SI unit bool valid5 = bvalue5->valid; // Valid information String svalue5 = formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -123,7 +117,6 @@ public: GwApi::BoatValue *bvalue6 = pageData.values[5]; // Sixth element in list String name6 = xdrDelete(bvalue6->getName()); // Value name name6 = name6.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue6, logger); // Check if boat data value is to be calibrated double value6 = bvalue6->value; // Value as double in SI unit bool valid6 = bvalue6->valid; // Valid information String svalue6 = formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places diff --git a/lib/obp60task/PageWindRoseFlex.cpp b/lib/obp60task/PageWindRoseFlex.cpp index 26efa28..d3526e0 100644 --- a/lib/obp60task/PageWindRoseFlex.cpp +++ b/lib/obp60task/PageWindRoseFlex.cpp @@ -2,7 +2,6 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -#include "BoatDataCalibration.h" class PageWindRoseFlex : public Page { @@ -79,7 +78,6 @@ public: } String name1 = bvalue1->getName().c_str(); // Value name name1 = name1.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -97,7 +95,6 @@ public: } String name2 = bvalue2->getName().c_str(); // Value name name2 = name2.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information if (simulation) { @@ -122,7 +119,6 @@ public: else{ name3font=Ubuntu_Bold12pt8b; } - calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -142,7 +138,6 @@ public: else{ name4font=Ubuntu_Bold12pt8b; } - calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated double value4 = bvalue4->value; // Value as double in SI unit bool valid4 = bvalue4->valid; // Valid information String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -162,7 +157,6 @@ public: else{ name5font=Ubuntu_Bold12pt8b; } - calibrationData.calibrateInstance(bvalue5, logger); // Check if boat data value is to be calibrated double value5 = bvalue5->value; // Value as double in SI unit bool valid5 = bvalue5->valid; // Valid information String svalue5 = formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places @@ -182,7 +176,6 @@ public: else{ name6font=Ubuntu_Bold8pt8b; } - calibrationData.calibrateInstance(bvalue6, logger); // Check if boat data value is to be calibrated double value6 = bvalue6->value; // Value as double in SI unit bool valid6 = bvalue6->valid; // Valid information String svalue6 = formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index 3c7d3fe..0616a39 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -708,8 +708,10 @@ "AWA", "AWS", "COG", + "DBS", "DBT", "HDM", + "HDT", "PRPOS", "RPOS", "SOG", @@ -735,7 +737,7 @@ "obp60":"true" }, "condition": [ - { "calInstance1": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance1": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -743,13 +745,13 @@ "label": "Data Instance 1 Calibration Slope", "type": "number", "default": "1.00", - "description": "Slope for data instance 1", + "description": "Slope for data instance 1; Default: 1(!)", "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" }, "condition": [ - { "calInstance1": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance1": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -766,7 +768,7 @@ "obp60":"true" }, "condition": [ - { "calInstance1": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance1": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -780,8 +782,10 @@ "AWA", "AWS", "COG", + "DBS", "DBT", "HDM", + "HDT", "PRPOS", "RPOS", "SOG", @@ -807,7 +811,7 @@ "obp60":"true" }, "condition": [ - { "calInstance2": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance2": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -815,13 +819,13 @@ "label": "Data Instance 2 Calibration Slope", "type": "number", "default": "1.00", - "description": "Slope for data instance 2", + "description": "Slope for data instance 2; Default: 1(!)", "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" }, "condition": [ - { "calInstance2": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance2": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -838,7 +842,7 @@ "obp60":"true" }, "condition": [ - { "calInstance2": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance2": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -852,8 +856,10 @@ "AWA", "AWS", "COG", + "DBS", "DBT", "HDM", + "HDT", "PRPOS", "RPOS", "SOG", @@ -879,7 +885,7 @@ "obp60":"true" }, "condition": [ - { "calInstance3": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance3": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -887,13 +893,13 @@ "label": "Data Instance 3 Calibration Slope", "type": "number", "default": "1.00", - "description": "Slope for data instance 3", + "description": "Slope for data instance 3; Default: 1(!)", "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" }, "condition": [ - { "calInstance3": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance3": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -910,7 +916,7 @@ "obp60":"true" }, "condition": [ - { "calInstance3": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance3": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { diff --git a/lib/obp60task/config_obp40.json b/lib/obp60task/config_obp40.json index c8553c0..bb0478a 100644 --- a/lib/obp60task/config_obp40.json +++ b/lib/obp60task/config_obp40.json @@ -719,8 +719,10 @@ "AWA", "AWS", "COG", + "DBS", "DBT", "HDM", + "HDT", "PRPOS", "RPOS", "SOG", @@ -746,7 +748,7 @@ "obp40":"true" }, "condition": [ - { "calInstance1": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance1": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -754,13 +756,13 @@ "label": "Data Instance 1 Calibration Slope", "type": "number", "default": "1.00", - "description": "Slope for data instance 1", + "description": "Slope for data instance 1, Default: 1(!)", "category": "OBP40 Calibrations", "capabilities": { "obp40":"true" }, "condition": [ - { "calInstance1": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance1": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -777,7 +779,7 @@ "obp40":"true" }, "condition": [ - { "calInstance1": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance1": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -791,8 +793,10 @@ "AWA", "AWS", "COG", + "DBS", "DBT", "HDM", + "HDT", "PRPOS", "RPOS", "SOG", @@ -818,7 +822,7 @@ "obp40":"true" }, "condition": [ - { "calInstance2": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance2": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -826,13 +830,13 @@ "label": "Data Instance 2 Calibration Slope", "type": "number", "default": "1.00", - "description": "Slope for data instance 2", + "description": "Slope for data instance 2; Default: 1(!)", "category": "OBP40 Calibrations", "capabilities": { "obp40":"true" }, "condition": [ - { "calInstance2": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance2": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -849,7 +853,7 @@ "obp40":"true" }, "condition": [ - { "calInstance2": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance2": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -863,8 +867,10 @@ "AWA", "AWS", "COG", + "DBS", "DBT", "HDM", + "HDT", "PRPOS", "RPOS", "SOG", @@ -890,7 +896,7 @@ "obp40":"true" }, "condition": [ - { "calInstance3": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance3": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -898,13 +904,13 @@ "label": "Data Instance 3 Calibration Slope", "type": "number", "default": "1.00", - "description": "Slope for data instance 3", + "description": "Slope for data instance 3, Default: 1(!)", "category": "OBP40 Calibrations", "capabilities": { "obp40":"true" }, "condition": [ - { "calInstance3": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance3": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { @@ -921,7 +927,7 @@ "obp40":"true" }, "condition": [ - { "calInstance3": ["AWA", "AWS", "COG", "DBT", "HDM", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + { "calInstance3": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, { diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 1058ae0..5ac6575 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -12,7 +12,6 @@ #include // GxEPD2 lib for b/w E-Ink displays #include "OBP60Extensions.h" // Functions lib for extension board #include "OBP60Keypad.h" // Functions for keypad -#include "BoatDataCalibration.h" // Functions lib for data instance calibration #include "OBPDataOperations.h" // Functions lib for data operations such as true wind calculation #ifdef BOARD_OBP40S3 @@ -147,7 +146,6 @@ void keyboardTask(void *param){ vTaskDelete(NULL); } -// Scorgan: moved class declaration to header file to make class available to other functions // --- Class BoatValueList -------------- bool BoatValueList::addValueToList(GwApi::BoatValue *v){ for (int i=0;igetString(xxx); - //add all necessary data to common data + CalibrationData calibrationDataList(logger); // all boat data types which are supposed to be calibrated //fill the page data from config numPages=config->getInt(config->visiblePages,1); @@ -480,26 +477,25 @@ void OBP60Task(GwApi *api){ pages[i].parameters.values.push_back(value); } - // Read the specified boat data type of relevant pages and create a history buffer for each type + // Read the specified boat data types of relevant pages and create a history buffer for each type if (pages[i].parameters.pageName == "OneValue" || pages[i].parameters.pageName == "TwoValues" || pages[i].parameters.pageName == "WindPlot") { for (auto pVal : pages[i].parameters.values) { - hstryBufList.addBuffer(pVal->getName()); + hstryBufferList.addBuffer(pVal->getName()); } } // Add list of history buffers to page parameters - pages[i].parameters.hstryBuffers = &hstryBufList; + pages[i].parameters.hstryBuffers = &hstryBufferList; } // add out of band system page (always available) Page *syspage = allPages.pages[0]->creator(commonData); - // Check user settings for true wind calculation + // Read user settings from config file bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false); bool useSimuData = api->getConfig()->getBool(api->getConfig()->useSimuData, false); - - // Read all calibration data settings from config - calibrationData.readConfig(config, logger); + // Read user calibration data settings from config file + calibrationDataList.readConfig(config); // Display screenshot handler for HTTP request // http://192.168.15.1/api/user/OBP60Task/screenshot @@ -814,10 +810,10 @@ void OBP60Task(GwApi *api){ api->getStatus(commonData.status); if (calcTrueWnds) { - trueWind.addWinds(); + trueWind.addWinds(); // calculate true wind data from apparent wind values } - // Handle history buffers for certain boat data for windplot page and other usage - hstryBufList.handleHstryBufs(useSimuData, commonData); + calibrationDataList.handleCalibration(&boatValues); // Process calibration for all boat data in + hstryBufferList.handleHstryBufs(useSimuData, commonData); // Handle history buffers for certain boat data for windplot page and other usage // Clear display // getdisplay().fillRect(0, 0, getdisplay().width(), getdisplay().height(), commonData.bgcolor); From cc1d07fac049483aa40b7a52ab5e2f9dff335cd6 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Sat, 17 Jan 2026 13:07:48 +0100 Subject: [PATCH 2/3] True Wind Calculation: change wind angle range to [0..360] temporarily for proper display on pages --- lib/obp60task/OBPDataOperations.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/obp60task/OBPDataOperations.cpp b/lib/obp60task/OBPDataOperations.cpp index 1adb7f4..562b1f6 100644 --- a/lib/obp60task/OBPDataOperations.cpp +++ b/lib/obp60task/OBPDataOperations.cpp @@ -156,7 +156,7 @@ bool CalibrationData::calibrateInstance(GwApi::BoatValue* boatDataValue) if (format == "formatWind") { // instance is of type angle dataValue = (dataValue * slope) + offset; // dataValue = WindUtils::toPI(dataValue); - dataValue = WindUtils::to2PI(dataValue); // we should call for format of [-180..180], but pages cannot handle negative values yet + dataValue = WindUtils::to2PI(dataValue); // we should call for format of [-180..180], but pages cannot display negative values properly yet } else if (format == "formatCourse") { // instance is of type direction dataValue = (dataValue * slope) + offset; @@ -518,7 +518,8 @@ bool WindUtils::addWinds() twsBVal->valid = true; } if (!twaBVal->valid) { - twaBVal->value = twa; + //twaBVal->value = twa; + twaBVal->value = to2PI(twa); // convert to [0..360], because pages cannot display negative values properly yet twaBVal->valid = true; } if (!awdBVal->valid) { From cb2b85d50599a74af06c2d80745b068af1e91481 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Sat, 17 Jan 2026 13:45:41 +0100 Subject: [PATCH 3/3] Data Calibration: Extend no. of calibration instances from 3 to 4 --- lib/obp60task/OBPDataOperations.h | 2 +- lib/obp60task/config.json | 74 +++++++++++++++++++++++++++++++ lib/obp60task/config_obp40.json | 74 +++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) diff --git a/lib/obp60task/OBPDataOperations.h b/lib/obp60task/OBPDataOperations.h index e42e293..9c5b783 100644 --- a/lib/obp60task/OBPDataOperations.h +++ b/lib/obp60task/OBPDataOperations.h @@ -22,7 +22,7 @@ private: std::unordered_map lastValue; // array for last smoothed values of boat data values GwLog* logger; - static constexpr int8_t MAX_CALIBRATION_DATA = 3; // maximum number of calibration data instances + static constexpr int8_t MAX_CALIBRATION_DATA = 4; // maximum number of calibration data instances public: CalibrationData(GwLog* log); diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index 0616a39..e897c7f 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -919,6 +919,80 @@ { "calInstance3": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, + { + "name": "calInstance4", + "label": "Calibration Data Instance 4", + "type": "list", + "default": "---", + "description": "Data instance for calibration", + "list": [ + "---", + "AWA", + "AWS", + "COG", + "DBS", + "DBT", + "HDM", + "HDT", + "PRPOS", + "RPOS", + "SOG", + "STW", + "TWA", + "TWS", + "TWD", + "WTemp" + ], + "category": "OBP60 Calibrations", + "capabilities": { + "obp60":"true" + } + }, + { + "name": "calOffset4", + "label": "Data Instance 4 Calibration Offset", + "type": "number", + "default": "0.00", + "description": "Offset for data instance 4", + "category": "OBP60 Calibrations", + "capabilities": { + "obp60":"true" + }, + "condition": [ + { "calInstance4": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + ] + }, + { + "name": "calSlope4", + "label": "Data Instance 4 Calibration Slope", + "type": "number", + "default": "1.00", + "description": "Slope for data instance 3; Default: 1(!)", + "category": "OBP60 Calibrations", + "capabilities": { + "obp60":"true" + }, + "condition": [ + { "calInstance4": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + ] + }, + { + "name": "calSmooth4", + "label": "Data Instance 4 Smoothing", + "type": "number", + "default": "0", + "check": "checkMinMax", + "min": 0, + "max": 10, + "description": "Smoothing factor [0..10]; 0 = no smoothing", + "category": "OBP60 Calibrations", + "capabilities": { + "obp60":"true" + }, + "condition": [ + { "calInstance4": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + ] + }, { "name": "mapsource", "label": "Map Source", diff --git a/lib/obp60task/config_obp40.json b/lib/obp60task/config_obp40.json index bb0478a..1fbc987 100644 --- a/lib/obp60task/config_obp40.json +++ b/lib/obp60task/config_obp40.json @@ -930,6 +930,80 @@ { "calInstance3": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } ] }, + { + "name": "calInstance4", + "label": "Calibration Data Instance 4", + "type": "list", + "default": "---", + "description": "Data instance for calibration", + "list": [ + "---", + "AWA", + "AWS", + "COG", + "DBS", + "DBT", + "HDM", + "HDT", + "PRPOS", + "RPOS", + "SOG", + "STW", + "TWA", + "TWS", + "TWD", + "WTemp" + ], + "category": "OBP40 Calibrations", + "capabilities": { + "obp40": "true" + } + }, + { + "name": "calOffset4", + "label": "Data Instance 4 Calibration Offset", + "type": "number", + "default": "0.00", + "description": "Offset for data instance 4", + "category": "OBP40 Calibrations", + "capabilities": { + "obp40":"true" + }, + "condition": [ + { "calInstance4": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + ] + }, + { + "name": "calSlope4", + "label": "Data Instance 4 Calibration Slope", + "type": "number", + "default": "1.00", + "description": "Slope for data instance 4, Default: 1(!)", + "category": "OBP40 Calibrations", + "capabilities": { + "obp40":"true" + }, + "condition": [ + { "calInstance4": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + ] + }, + { + "name": "calSmooth4", + "label": "Data Instance 4 Smoothing", + "type": "number", + "default": "0", + "check": "checkMinMax", + "min": 0, + "max": 10, + "description": "Smoothing factor [0..10]; 0 = no smoothing", + "category": "OBP40 Calibrations", + "capabilities": { + "obp40":"true" + }, + "condition": [ + { "calInstance4": ["AWA", "AWS", "COG", "DBS", "DBT", "HDM", "HDT", "PRPOS", "RPOS", "SOG", "STW", "TWA", "TWS", "TWD", "WTemp" ] } + ] + }, { "name": "mapsource", "label": "Map Source",