From 214c10ff9317ee759880c44080b9f270df9c286c Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Wed, 21 May 2025 21:47:21 +0200 Subject: [PATCH 1/7] removed static definition of methods --- lib/obp60task/BoatDataCalibration.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/obp60task/BoatDataCalibration.h b/lib/obp60task/BoatDataCalibration.h index 43a4623..934484c 100644 --- a/lib/obp60task/BoatDataCalibration.h +++ b/lib/obp60task/BoatDataCalibration.h @@ -21,9 +21,9 @@ class CalibrationDataList { public: CalibData list[maxCalibrationData]; // list of calibration data instances - static void readConfig(GwConfigHandler* config, GwLog* logger); - static int getInstanceListNo(String instance); - static void calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger); + void readConfig(GwConfigHandler* config, GwLog* logger); + int getInstanceListNo(String instance); + void calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger); void smoothInstance(String instance, double &dataValue, GwLog* logger); private: From bf59cfbae82314ed46a50fdca989cad00841c4b9 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Thu, 22 May 2025 21:48:32 +0200 Subject: [PATCH 2/7] tiny code adjustments --- lib/obp60task/BoatDataCalibration.cpp | 29 ++++++++++++--------------- lib/obp60task/config.json | 6 +++--- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/lib/obp60task/BoatDataCalibration.cpp b/lib/obp60task/BoatDataCalibration.cpp index cb2c853..3fc4447 100644 --- a/lib/obp60task/BoatDataCalibration.cpp +++ b/lib/obp60task/BoatDataCalibration.cpp @@ -9,13 +9,21 @@ CalibrationDataList calibrationData; 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 +// This method is called once at init phase of to read the configuration values { String instance; double offset; double slope; double smooth; + // Approximate mid-range values in m/s for Beaufort scale 0–12 + // hier geht's weiter mit den Bft-Werten: was muss ich bei welcher Windstärke addieren bzw. wie ist der Multiplikator? +/* static const std::array, 12> mps = {{ + {0.2, 1.3}, {1.5, 1.8}, {3.3, 2.1}, {5.4, 2.5}, + {7.9, 2.8}, {10.7, 3.1}, {13.8, 3.3}, {17.1, 3.6}, + {20.7, 3.7}, {24.4, 4.0}, {28.4, 4.2}, {32.6, 4.2} + }}; */ + String calInstance = ""; String calOffset = ""; String calSlope = ""; @@ -43,7 +51,7 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) } offset = (config->getString(calOffset, "")).toFloat(); slope = (config->getString(calSlope, "")).toFloat(); - smooth = (config->getString(calSmooth, "")).toInt(); + 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") { @@ -54,7 +62,7 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) } else if (windspeedFormat == "kn") { offset /= 1.94384; // Convert kn to m/s } else if (windspeedFormat == "bft") { - offset *= 0.5; // Convert Bft to m/s (approx) -> to be improved + offset *= 2 + (offset / 2); // Convert Bft to m/s (approx) -> to be improved } } else if (instance == "AWA" || instance == "TWA" || instance == "TWD" || instance == "HDM" || instance == "PRPOS" || instance == "RPOS") { @@ -92,7 +100,6 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) if (smooth > 10) { smooth = 10; } - // calibrationData.list[i].smooth = 1 - (smooth / 10.0); // smooth factor is between 0 and 1 smooth = 0.3 + ((smooth - 0.01) * (0.95 - 0.3) / (10 - 0.01)); } smooth = 1 - smooth; @@ -120,17 +127,6 @@ int CalibrationDataList::getInstanceListNo(String instance) return -1; // instance not found } -/* void CalibrationDataList::updateBoatDataValidity(String instance) -{ - for (int i = 0; i < maxCalibrationData; i++) { - if (calibrationData.list[i].instance == instance) { - // test for boat data value validity - to be implemented - calibrationData.list[i].isValid = true; - return; - } - } -} */ - void CalibrationDataList::calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger) // Method to calibrate the boat data value { @@ -147,6 +143,7 @@ void CalibrationDataList::calibrateInstance(String instance, GwApi::BoatValue* b slope = calibrationData.list[listNo].slope; if (!boatDataValue->valid) { // no valid boat data value, so we don't want to apply calibration data + calibrationData.list[listNo].isCalibrated = false; return; } else { dataValue = boatDataValue->value; @@ -161,7 +158,7 @@ void CalibrationDataList::calibrateInstance(String instance, GwApi::BoatValue* b dataValue += (2 * M_PI); } } else if (boatDataValue->getFormat() == "formatCourse") { // instance is of type direction - dataValue = (dataValue * slope) + offset; + dataValue = (dataValue * slope) + offset; dataValue = fmod(dataValue, 2 * M_PI); if (dataValue < 0) { dataValue += (2 * M_PI); diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index c1801af..0a2e981 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -741,7 +741,7 @@ "check": "checkMinMax", "min": 0, "max": 10, - "description": "Smoothing factor for data instance 1", + "description": "Smoothing factor [0..10]; 0 = no smoothing", "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" @@ -802,7 +802,7 @@ "check": "checkMinMax", "min": 0, "max": 10, - "description": "Smoothing factor for data instance 2", + "description": "Smoothing factor [0..10]; 0 = no smoothing", "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" @@ -863,7 +863,7 @@ "check": "checkMinMax", "min": 0, "max": 10, - "description": "Smoothing factor for data instance 3", + "description": "Smoothing factor [0..10]; 0 = no smoothing", "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" From f9cf73ae04bc09ceb4e4c48c76aa805a711b43a1 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Thu, 22 May 2025 22:45:20 +0200 Subject: [PATCH 3/7] adjust code position of calibration method call, where not applied yet --- lib/obp60task/PageFourValues.cpp | 8 ++++---- lib/obp60task/PageFourValues2.cpp | 8 ++++---- lib/obp60task/PageSixValues.cpp | 2 +- lib/obp60task/PageThreeValues.cpp | 6 +++--- lib/obp60task/PageTwoValues.cpp | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/obp60task/PageFourValues.cpp b/lib/obp60task/PageFourValues.cpp index 5343de6..9e76988 100644 --- a/lib/obp60task/PageFourValues.cpp +++ b/lib/obp60task/PageFourValues.cpp @@ -46,9 +46,9 @@ 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(name1, 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 - calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value @@ -56,9 +56,9 @@ class PageFourValues : 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(name2, 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 - calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value @@ -66,9 +66,9 @@ class PageFourValues : 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(name3, 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 - calibrationData.calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value @@ -76,9 +76,9 @@ class PageFourValues : 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(name4, 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 - calibrationData.calibrateInstance(name4, bvalue4, logger); // Check if boat data value is to be calibrated String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value diff --git a/lib/obp60task/PageFourValues2.cpp b/lib/obp60task/PageFourValues2.cpp index 24b3fce..9f94e08 100644 --- a/lib/obp60task/PageFourValues2.cpp +++ b/lib/obp60task/PageFourValues2.cpp @@ -46,9 +46,9 @@ 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(name1, 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 - calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value @@ -56,9 +56,9 @@ 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(name2, 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 - calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value @@ -66,9 +66,9 @@ 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(name3, 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 - calibrationData.calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value @@ -76,9 +76,9 @@ 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(name4, 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 - calibrationData.calibrateInstance(name4, bvalue4, logger); // Check if boat data value is to be calibrated String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value diff --git a/lib/obp60task/PageSixValues.cpp b/lib/obp60task/PageSixValues.cpp index b3bdeee..bf55d98 100644 --- a/lib/obp60task/PageSixValues.cpp +++ b/lib/obp60task/PageSixValues.cpp @@ -61,8 +61,8 @@ 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 - DataValue[i] = bvalue->value; // Value as double in SI unit calibrationData.calibrateInstance(DataName[i], 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 DataUnits[i] = formatValue(bvalue, *commonData).unit; diff --git a/lib/obp60task/PageThreeValues.cpp b/lib/obp60task/PageThreeValues.cpp index a90d636..c918ce4 100644 --- a/lib/obp60task/PageThreeValues.cpp +++ b/lib/obp60task/PageThreeValues.cpp @@ -44,9 +44,9 @@ 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(name1, 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 - calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value @@ -54,9 +54,9 @@ class PageThreeValues : 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(name2, 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 - calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value @@ -64,9 +64,9 @@ class PageThreeValues : 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(name3, 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 - calibrationData.calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value diff --git a/lib/obp60task/PageTwoValues.cpp b/lib/obp60task/PageTwoValues.cpp index 68dcfa9..c4e510c 100644 --- a/lib/obp60task/PageTwoValues.cpp +++ b/lib/obp60task/PageTwoValues.cpp @@ -42,9 +42,9 @@ class PageTwoValues : 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(name1, 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 - calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value @@ -52,9 +52,9 @@ class PageTwoValues : 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(name2, 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 - calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value From 4e6d52d197d2fdcbd5c0bfbc1149e09cf5d642de Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Thu, 22 May 2025 23:28:33 +0200 Subject: [PATCH 4/7] added "condition" to calibration settings in config.json --- lib/obp60task/config.json | 126 +++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 9 deletions(-) diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index 0a2e981..7c9fadb 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -720,7 +720,19 @@ "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" - } + }, + "condition": [ + { "calInstance1": "AWA" }, + { "calInstance1": "AWS" }, + { "calInstance1": "DBT" }, + { "calInstance1": "HDM" }, + { "calInstance1": "PRPOS" }, + { "calInstance1": "RPOS" }, + { "calInstance1": "STW" }, + { "calInstance1": "TWA" }, + { "calInstance1": "TWS" }, + { "calInstance1": "TWD" }, + { "calInstance1": "WTemp" } ] }, { "name": "calSlope1", @@ -731,7 +743,19 @@ "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" - } + }, + "condition": [ + { "calInstance1": "AWA" }, + { "calInstance1": "AWS" }, + { "calInstance1": "DBT" }, + { "calInstance1": "HDM" }, + { "calInstance1": "PRPOS" }, + { "calInstance1": "RPOS" }, + { "calInstance1": "STW" }, + { "calInstance1": "TWA" }, + { "calInstance1": "TWS" }, + { "calInstance1": "TWD" }, + { "calInstance1": "WTemp" } ] }, { "name": "calSmooth1", @@ -745,7 +769,19 @@ "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" - } + }, + "condition": [ + { "calInstance1": "AWA" }, + { "calInstance1": "AWS" }, + { "calInstance1": "DBT" }, + { "calInstance1": "HDM" }, + { "calInstance1": "PRPOS" }, + { "calInstance1": "RPOS" }, + { "calInstance1": "STW" }, + { "calInstance1": "TWA" }, + { "calInstance1": "TWS" }, + { "calInstance1": "TWD" }, + { "calInstance1": "WTemp" } ] }, { "name": "calInstance2", @@ -781,7 +817,19 @@ "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" - } + }, + "condition": [ + { "calInstance2": "AWA" }, + { "calInstance2": "AWS" }, + { "calInstance2": "DBT" }, + { "calInstance2": "HDM" }, + { "calInstance2": "PRPOS" }, + { "calInstance2": "RPOS" }, + { "calInstance2": "STW" }, + { "calInstance2": "TWA" }, + { "calInstance2": "TWS" }, + { "calInstance2": "TWD" }, + { "calInstance2": "WTemp" } ] }, { "name": "calSlope2", @@ -792,7 +840,19 @@ "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" - } + }, + "condition": [ + { "calInstance2": "AWA" }, + { "calInstance2": "AWS" }, + { "calInstance2": "DBT" }, + { "calInstance2": "HDM" }, + { "calInstance2": "PRPOS" }, + { "calInstance2": "RPOS" }, + { "calInstance2": "STW" }, + { "calInstance2": "TWA" }, + { "calInstance2": "TWS" }, + { "calInstance2": "TWD" }, + { "calInstance2": "WTemp" } ] }, { "name": "calSmooth2", @@ -806,7 +866,19 @@ "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" - } + }, + "condition": [ + { "calInstance2": "AWA" }, + { "calInstance2": "AWS" }, + { "calInstance2": "DBT" }, + { "calInstance2": "HDM" }, + { "calInstance2": "PRPOS" }, + { "calInstance2": "RPOS" }, + { "calInstance2": "STW" }, + { "calInstance2": "TWA" }, + { "calInstance2": "TWS" }, + { "calInstance2": "TWD" }, + { "calInstance2": "WTemp" } ] }, { "name": "calInstance3", @@ -842,7 +914,19 @@ "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" - } + }, + "condition": [ + { "calInstance3": "AWA" }, + { "calInstance3": "AWS" }, + { "calInstance3": "DBT" }, + { "calInstance3": "HDM" }, + { "calInstance3": "PRPOS" }, + { "calInstance3": "RPOS" }, + { "calInstance3": "STW" }, + { "calInstance3": "TWA" }, + { "calInstance3": "TWS" }, + { "calInstance3": "TWD" }, + { "calInstance3": "WTemp" } ] }, { "name": "calSlope3", @@ -853,7 +937,19 @@ "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" - } + }, + "condition": [ + { "calInstance3": "AWA" }, + { "calInstance3": "AWS" }, + { "calInstance3": "DBT" }, + { "calInstance3": "HDM" }, + { "calInstance3": "PRPOS" }, + { "calInstance3": "RPOS" }, + { "calInstance3": "STW" }, + { "calInstance3": "TWA" }, + { "calInstance3": "TWS" }, + { "calInstance3": "TWD" }, + { "calInstance3": "WTemp" } ] }, { "name": "calSmooth3", @@ -867,7 +963,19 @@ "category": "OBP60 Calibrations", "capabilities": { "obp60":"true" - } + }, + "condition": [ + { "calInstance3": "AWA" }, + { "calInstance3": "AWS" }, + { "calInstance3": "DBT" }, + { "calInstance3": "HDM" }, + { "calInstance3": "PRPOS" }, + { "calInstance3": "RPOS" }, + { "calInstance3": "STW" }, + { "calInstance3": "TWA" }, + { "calInstance3": "TWS" }, + { "calInstance3": "TWD" }, + { "calInstance3": "WTemp" } ] }, { "name": "display", From 0c4fce0e25f03fd0b6d12451e2c5b0c0101def15 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Sat, 24 May 2025 00:40:10 +0200 Subject: [PATCH 5/7] No smoothing when boatDataValue is invalid --- lib/obp60task/BoatDataCalibration.cpp | 42 +++++++++++++++++---------- lib/obp60task/BoatDataCalibration.h | 3 +- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/lib/obp60task/BoatDataCalibration.cpp b/lib/obp60task/BoatDataCalibration.cpp index 3fc4447..cf8d432 100644 --- a/lib/obp60task/BoatDataCalibration.cpp +++ b/lib/obp60task/BoatDataCalibration.cpp @@ -18,11 +18,11 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) // Approximate mid-range values in m/s for Beaufort scale 0–12 // hier geht's weiter mit den Bft-Werten: was muss ich bei welcher Windstärke addieren bzw. wie ist der Multiplikator? -/* static const std::array, 12> mps = {{ - {0.2, 1.3}, {1.5, 1.8}, {3.3, 2.1}, {5.4, 2.5}, - {7.9, 2.8}, {10.7, 3.1}, {13.8, 3.3}, {17.1, 3.6}, - {20.7, 3.7}, {24.4, 4.0}, {28.4, 4.2}, {32.6, 4.2} - }}; */ + /* static const std::array, 12> mps = {{ + {0.2, 1.3}, {1.5, 1.8}, {3.3, 2.1}, {5.4, 2.5}, + {7.9, 2.8}, {10.7, 3.1}, {13.8, 3.3}, {17.1, 3.6}, + {20.7, 3.7}, {24.4, 4.0}, {28.4, 4.2}, {32.6, 4.2} + }}; */ String calInstance = ""; String calOffset = ""; @@ -158,7 +158,7 @@ void CalibrationDataList::calibrateInstance(String instance, GwApi::BoatValue* b dataValue += (2 * M_PI); } } else if (boatDataValue->getFormat() == "formatCourse") { // instance is of type direction - dataValue = (dataValue * slope) + offset; + dataValue = (dataValue * slope) + offset; dataValue = fmod(dataValue, 2 * M_PI); if (dataValue < 0) { dataValue += (2 * M_PI); @@ -169,32 +169,42 @@ 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; + + calibrationData.smoothInstance(instance, boatDataValue, logger); // smooth the boat data value + calibrationData.list[listNo].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, boatDataValue->value); } } } -void CalibrationDataList::smoothInstance(String instance, double& dataValue, GwLog* logger) +void CalibrationDataList::smoothInstance(String instance, GwApi::BoatValue* boatDataValue, 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; + double dataValue = boatDataValue->value; - if (lastValue.find(instance.c_str()) != lastValue.end()) { - oldValue = lastValue[instance.c_str()]; + if (!boatDataValue->valid) { // no valid boat data value, so we don't want to smoothen value + return; + } else { - dataValue = oldValue + (smoothFactor * (dataValue - oldValue)); // exponential smoothing algorithm + 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 + boatDataValue->value = dataValue; // set the smoothed value to the boat data value + + LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: Smoothing factor: %f, Smoothed value: %f", instance.c_str(), smoothFactor, dataValue); } - lastValue[instance.c_str()] = dataValue; // store the new value for next cycle; first time, store only the current value and return - - LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: Smoothing factor: %f, Smoothed value: %f", instance.c_str(), smoothFactor, dataValue); } #endif \ No newline at end of file diff --git a/lib/obp60task/BoatDataCalibration.h b/lib/obp60task/BoatDataCalibration.h index 934484c..b28d371 100644 --- a/lib/obp60task/BoatDataCalibration.h +++ b/lib/obp60task/BoatDataCalibration.h @@ -24,7 +24,8 @@ public: void readConfig(GwConfigHandler* config, GwLog* logger); int getInstanceListNo(String instance); void calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger); - void smoothInstance(String instance, double &dataValue, GwLog* logger); +// void smoothInstance(String instance, double &dataValue, GwLog* logger); + void smoothInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger); private: }; From 02712263d3bc74c36b26ae8a42d78b6986fc40a6 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Sun, 25 May 2025 13:53:50 +0200 Subject: [PATCH 6/7] Changed array for calibration data into a hash map; reduced unnecessary method parameters --- lib/obp60task/BoatDataCalibration.cpp | 137 +++++++++++++++----------- lib/obp60task/BoatDataCalibration.h | 21 ++-- lib/obp60task/PageFourValues.cpp | 8 +- lib/obp60task/PageFourValues2.cpp | 8 +- lib/obp60task/PageOneValue.cpp | 2 +- lib/obp60task/PageRudderPosition.cpp | 2 +- lib/obp60task/PageSixValues.cpp | 2 +- lib/obp60task/PageThreeValues.cpp | 6 +- lib/obp60task/PageTwoValues.cpp | 4 +- lib/obp60task/PageWind.cpp | 4 +- lib/obp60task/PageWindRose.cpp | 12 +-- lib/obp60task/PageWindRoseFlex.cpp | 12 +-- 12 files changed, 119 insertions(+), 99 deletions(-) diff --git a/lib/obp60task/BoatDataCalibration.cpp b/lib/obp60task/BoatDataCalibration.cpp index cf8d432..a9c5b5c 100644 --- a/lib/obp60task/BoatDataCalibration.cpp +++ b/lib/obp60task/BoatDataCalibration.cpp @@ -6,12 +6,13 @@ #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 { - String instance; + std::string instance; double offset; double slope; double smooth; @@ -37,18 +38,18 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) String tempFormat = config->getString(config->tempFormat); // [K|C|F] // Read calibration settings for data instances - for (int i = 0; i < maxCalibrationData; i++) { + 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); - calibrationData.list[i] = { "---", 0.0f, 1.0f, 1, 0.0f, false }; - instance = config->getString(calInstance, "---"); + 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 @@ -104,21 +105,37 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) } smooth = 1 - smooth; - calibrationData.list[i].instance = instance; - calibrationData.list[i].offset = offset; - calibrationData.list[i].slope = slope; - calibrationData.list[i].smooth = smooth; - calibrationData.list[i].isCalibrated = false; - 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); + calibMap[instance].offset = offset; + calibMap[instance].slope = slope; + calibMap[instance].smooth = smooth; + calibMap[instance].isCalibrated = false; + LOG_DEBUG(GwLog::LOG, "stored 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"); } -int CalibrationDataList::getInstanceListNo(String instance) +/* +int CalibrationDataList::getInstanceListNo(std::string instance) // Method to get the index of the requested instance in the list { // Check if instance is in the list + auto it = calibrationData.list.begin(); + std::advance(it, 1); // Move iterator to the second element + if (it != calibrationData.list.end()) { + std::string secondKey = it->first; // Get the key of the second value pair + LOG_DEBUG(GwLog::DEBUG, "Second key in calibration data list: %s", secondKey.c_str()); + } else { + LOG_DEBUG(GwLog::DEBUG, "Calibration data list has less than two elements."); + } + + // Iterate through the map and retrieve keys + for (const auto& pair : list) { + std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl; + } + + + for (int i = 0; i < maxCalibrationData; i++) { if (calibrationData.list[i].instance == instance) { return i; @@ -126,81 +143,83 @@ int CalibrationDataList::getInstanceListNo(String instance) } return -1; // instance not found } +*/ -void CalibrationDataList::calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger) +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 = ""; - int listNo = getInstanceListNo(instance); - if (listNo < 0) { + if (calibMap.find(instance) == calibMap.end()) { LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s not found in calibration data 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 = calibrationData.list[listNo].offset; - slope = calibrationData.list[listNo].slope; + 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 (!boatDataValue->valid) { // no valid boat data value, so we don't want to apply calibration data - calibrationData.list[listNo].isCalibrated = false; - return; - } else { - dataValue = boatDataValue->value; - LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: value: %f, format: %s", boatDataValue->getName().c_str(), boatDataValue->value, boatDataValue->getFormat().c_str()); - - if (boatDataValue->getFormat() == "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 (boatDataValue->getFormat() == "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 (boatDataValue->getFormat() == "kelvinToC") { // instance is of type temperature - dataValue = ((dataValue - 273.15) * slope) + offset + 273.15; - } else { - dataValue = (dataValue * slope) + offset; + 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); } - - calibrationData.list[listNo].isCalibrated = true; - boatDataValue->value = dataValue; - - calibrationData.smoothInstance(instance, boatDataValue, logger); // smooth the boat data value - calibrationData.list[listNo].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, boatDataValue->value); + } 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(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger) +void CalibrationDataList::smoothInstance(GwApi::BoatValue* boatDataValue, GwLog* logger) // Method to smoothen the boat data value { - // array for last values of smoothed boat data values - static std::unordered_map lastValue; + 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 data list", instance.c_str()); + return; } else { + smoothFactor = calibMap[instance].smooth; - double smoothFactor = calibrationData.list[getInstanceListNo(instance)].smooth; - - if (lastValue.find(instance.c_str()) != lastValue.end()) { - oldValue = lastValue[instance.c_str()]; - + if (lastValue.find(instance) != lastValue.end()) { + oldValue = lastValue[instance]; 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 + 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 LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: Smoothing factor: %f, Smoothed value: %f", instance.c_str(), smoothFactor, dataValue); diff --git a/lib/obp60task/BoatDataCalibration.h b/lib/obp60task/BoatDataCalibration.h index b28d371..b0624d4 100644 --- a/lib/obp60task/BoatDataCalibration.h +++ b/lib/obp60task/BoatDataCalibration.h @@ -4,28 +4,29 @@ #define _BOATDATACALIBRATION_H #include "Pagedata.h" -#include "WString.h" +#include +#include + +#define MAX_CALIBRATION_DATA 3 // maximum number of calibration data instances typedef struct { - String instance; // data type/instance to be calibrated +// 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; - -const int maxCalibrationData = 3; // maximum number of calibration data instances +} TypeCalibData; class CalibrationDataList { public: - CalibData list[maxCalibrationData]; // list of calibration data instances +// CalibData list[maxCalibrationData]; // list of calibration data instances + static std::unordered_map calibMap; // list of calibration data instances void readConfig(GwConfigHandler* config, GwLog* logger); - int getInstanceListNo(String instance); - void calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger); -// void smoothInstance(String instance, double &dataValue, GwLog* logger); - void smoothInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger); +// int getInstanceListNo(std::string instance); + void calibrateInstance(GwApi::BoatValue* boatDataValue, GwLog* logger); + void smoothInstance(GwApi::BoatValue* boatDataValue, GwLog* logger); private: }; diff --git a/lib/obp60task/PageFourValues.cpp b/lib/obp60task/PageFourValues.cpp index 9e76988..964ae0d 100644 --- a/lib/obp60task/PageFourValues.cpp +++ b/lib/obp60task/PageFourValues.cpp @@ -46,7 +46,7 @@ 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(name1, bvalue1, logger); // Check if boat data value is to be calibrated + 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 +56,7 @@ class PageFourValues : 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(name2, bvalue2, logger); // Check if boat data value is to be calibrated + 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 +66,7 @@ class PageFourValues : 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(name3, bvalue3, logger); // Check if boat data value is to be calibrated + 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 +76,7 @@ class PageFourValues : 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(name4, bvalue4, logger); // Check if boat data value is to be calibrated + 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 9f94e08..dbaba22 100644 --- a/lib/obp60task/PageFourValues2.cpp +++ b/lib/obp60task/PageFourValues2.cpp @@ -46,7 +46,7 @@ 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(name1, bvalue1, logger); // Check if boat data value is to be calibrated + 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 +56,7 @@ 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(name2, bvalue2, logger); // Check if boat data value is to be calibrated + 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 +66,7 @@ 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(name3, bvalue3, logger); // Check if boat data value is to be calibrated + 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 +76,7 @@ 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(name4, bvalue4, logger); // Check if boat data value is to be calibrated + 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 eac6cf2..e955719 100644 --- a/lib/obp60task/PageOneValue.cpp +++ b/lib/obp60task/PageOneValue.cpp @@ -40,7 +40,7 @@ class PageOneValue : 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(name1, bvalue1, logger); // Check if boat data value is to be calibrated + 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 290a9a6..be8fca5 100644 --- a/lib/obp60task/PageRudderPosition.cpp +++ b/lib/obp60task/PageRudderPosition.cpp @@ -41,7 +41,7 @@ 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(name1, bvalue1, logger); // Check if boat data value is to be calibrated + 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 bf55d98..04ad3ba 100644 --- a/lib/obp60task/PageSixValues.cpp +++ b/lib/obp60task/PageSixValues.cpp @@ -61,7 +61,7 @@ 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(DataName[i], bvalue, logger); // Check if boat data value is to be calibrated + 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 c918ce4..b51229b 100644 --- a/lib/obp60task/PageThreeValues.cpp +++ b/lib/obp60task/PageThreeValues.cpp @@ -44,7 +44,7 @@ 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(name1, bvalue1, logger); // Check if boat data value is to be calibrated + 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 +54,7 @@ class PageThreeValues : 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(name2, bvalue2, logger); // Check if boat data value is to be calibrated + 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 +64,7 @@ class PageThreeValues : 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(name3, bvalue3, logger); // Check if boat data value is to be calibrated + 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 c4e510c..5334af8 100644 --- a/lib/obp60task/PageTwoValues.cpp +++ b/lib/obp60task/PageTwoValues.cpp @@ -42,7 +42,7 @@ class PageTwoValues : 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(name1, bvalue1, logger); // Check if boat data value is to be calibrated + 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 @@ -52,7 +52,7 @@ class PageTwoValues : 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(name2, bvalue2, logger); // Check if boat data value is to be calibrated + 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 diff --git a/lib/obp60task/PageWind.cpp b/lib/obp60task/PageWind.cpp index 272478b..c40d61c 100644 --- a/lib/obp60task/PageWind.cpp +++ b/lib/obp60task/PageWind.cpp @@ -324,7 +324,7 @@ public: } String name1 = bvalue1->getName().c_str(); // Value name name1 = name1.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated + 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 +338,7 @@ public: } String name2 = bvalue2->getName().c_str(); // Value name name2 = name2.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated + 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 dba50d1..268d555 100644 --- a/lib/obp60task/PageWindRose.cpp +++ b/lib/obp60task/PageWindRose.cpp @@ -52,7 +52,7 @@ 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(name1, bvalue1, logger); // Check if boat data value is to be calibrated + 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 +67,7 @@ public: GwApi::BoatValue *bvalue2 = pageData.values[1]; // First 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(name2, bvalue2, logger); // Check if boat data value is to be calibrated + 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 +81,7 @@ public: 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(name3, bvalue3, logger); // Check if boat data value is to be calibrated + 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 +95,7 @@ public: 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(name4, bvalue4, logger); // Check if boat data value is to be calibrated + 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 +109,7 @@ public: GwApi::BoatValue *bvalue5 = pageData.values[4]; // Second element in list (only one value by PageOneValue) String name5 = xdrDelete(bvalue5->getName()); // Value name name5 = name5.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(name5, bvalue5, logger); // Check if boat data value is to be calibrated + 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 +123,7 @@ public: GwApi::BoatValue *bvalue6 = pageData.values[5]; // Second element in list (only one value by PageOneValue) String name6 = xdrDelete(bvalue6->getName()); // Value name name6 = name6.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(name6, bvalue6, logger); // Check if boat data value is to be calibrated + 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 b946342..f107d9e 100644 --- a/lib/obp60task/PageWindRoseFlex.cpp +++ b/lib/obp60task/PageWindRoseFlex.cpp @@ -52,7 +52,7 @@ 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(name1, bvalue1, logger); // Check if boat data value is to be calibrated + 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 +67,7 @@ public: GwApi::BoatValue *bvalue2 = pageData.values[1]; // First 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(name2, bvalue2, logger); // Check if boat data value is to be calibrated + 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 +81,7 @@ public: 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(name3, bvalue3, logger); // Check if boat data value is to be calibrated + 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 +95,7 @@ public: 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(name4, bvalue4, logger); // Check if boat data value is to be calibrated + 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 +109,7 @@ public: GwApi::BoatValue *bvalue5 = pageData.values[4]; // Second element in list (only one value by PageOneValue) String name5 = xdrDelete(bvalue5->getName()); // Value name name5 = name5.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(name5, bvalue5, logger); // Check if boat data value is to be calibrated + 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 +123,7 @@ public: GwApi::BoatValue *bvalue6 = pageData.values[5]; // Second element in list (only one value by PageOneValue) String name6 = xdrDelete(bvalue6->getName()); // Value name name6 = name6.substring(0, 6); // String length limit for value name - calibrationData.calibrateInstance(name6, bvalue6, logger); // Check if boat data value is to be calibrated + 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 From d6e3c7ad4816f9db259cc874d1ea42088c6909bb Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Sun, 25 May 2025 17:42:50 +0200 Subject: [PATCH 7/7] Calibration for data types COG, SOG added --- lib/obp60task/BoatDataCalibration.cpp | 43 ++------------------------- lib/obp60task/BoatDataCalibration.h | 3 -- lib/obp60task/config.json | 24 +++++++++++++++ 3 files changed, 27 insertions(+), 43 deletions(-) diff --git a/lib/obp60task/BoatDataCalibration.cpp b/lib/obp60task/BoatDataCalibration.cpp index a9c5b5c..dcfd8ba 100644 --- a/lib/obp60task/BoatDataCalibration.cpp +++ b/lib/obp60task/BoatDataCalibration.cpp @@ -17,14 +17,6 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) double slope; double smooth; - // Approximate mid-range values in m/s for Beaufort scale 0–12 - // hier geht's weiter mit den Bft-Werten: was muss ich bei welcher Windstärke addieren bzw. wie ist der Multiplikator? - /* static const std::array, 12> mps = {{ - {0.2, 1.3}, {1.5, 1.8}, {3.3, 2.1}, {5.4, 2.5}, - {7.9, 2.8}, {10.7, 3.1}, {13.8, 3.3}, {17.1, 3.6}, - {20.7, 3.7}, {24.4, 4.0}, {28.4, 4.2}, {32.6, 4.2} - }}; */ - String calInstance = ""; String calOffset = ""; String calSlope = ""; @@ -66,7 +58,7 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) offset *= 2 + (offset / 2); // 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 == "COG" || instance == "TWA" || instance == "TWD" || instance == "HDM" || instance == "PRPOS" || instance == "RPOS") { offset *= M_PI / 180; // Convert deg to rad } else if (instance == "DBT") { @@ -76,7 +68,7 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) offset /= 3.28084; // Convert ft to m } - } else if (instance == "STW") { + } else if (instance == "SOG" || instance == "STW") { if (speedFormat == "m/s") { // No conversion needed } else if (speedFormat == "km/h") { @@ -115,36 +107,6 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger) LOG_DEBUG(GwLog::LOG, "all calibration data read"); } -/* -int CalibrationDataList::getInstanceListNo(std::string instance) -// Method to get the index of the requested instance in the list -{ - // Check if instance is in the list - auto it = calibrationData.list.begin(); - std::advance(it, 1); // Move iterator to the second element - if (it != calibrationData.list.end()) { - std::string secondKey = it->first; // Get the key of the second value pair - LOG_DEBUG(GwLog::DEBUG, "Second key in calibration data list: %s", secondKey.c_str()); - } else { - LOG_DEBUG(GwLog::DEBUG, "Calibration data list has less than two elements."); - } - - // Iterate through the map and retrieve keys - for (const auto& pair : list) { - std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl; - } - - - - for (int i = 0; i < maxCalibrationData; i++) { - if (calibrationData.list[i].instance == instance) { - return i; - } - } - return -1; // instance not found -} -*/ - void CalibrationDataList::calibrateInstance(GwApi::BoatValue* boatDataValue, GwLog* logger) // Method to calibrate the boat data value { @@ -184,6 +146,7 @@ void CalibrationDataList::calibrateInstance(GwApi::BoatValue* boatDataValue, GwL } else if (format == "kelvinToC") { // instance is of type temperature dataValue = ((dataValue - 273.15) * slope) + offset + 273.15; } else { + dataValue = (dataValue * slope) + offset; } diff --git a/lib/obp60task/BoatDataCalibration.h b/lib/obp60task/BoatDataCalibration.h index b0624d4..5a0606b 100644 --- a/lib/obp60task/BoatDataCalibration.h +++ b/lib/obp60task/BoatDataCalibration.h @@ -10,7 +10,6 @@ #define MAX_CALIBRATION_DATA 3 // maximum number of calibration data instances typedef struct { -// String instance; // data type/instance to be calibrated double offset; // calibration offset double slope; // calibration slope double smooth; // smoothing factor @@ -20,11 +19,9 @@ typedef struct { class CalibrationDataList { public: -// CalibData list[maxCalibrationData]; // list of calibration data instances static std::unordered_map calibMap; // list of calibration data instances void readConfig(GwConfigHandler* config, GwLog* logger); -// int getInstanceListNo(std::string instance); void calibrateInstance(GwApi::BoatValue* boatDataValue, GwLog* logger); void smoothInstance(GwApi::BoatValue* boatDataValue, GwLog* logger); diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index 7c9fadb..23df2f9 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -696,10 +696,12 @@ "---", "AWA", "AWS", + "COG", "DBT", "HDM", "PRPOS", "RPOS", + "SOG", "STW", "TWA", "TWS", @@ -724,10 +726,12 @@ "condition": [ { "calInstance1": "AWA" }, { "calInstance1": "AWS" }, + { "calInstance2": "COG" }, { "calInstance1": "DBT" }, { "calInstance1": "HDM" }, { "calInstance1": "PRPOS" }, { "calInstance1": "RPOS" }, + { "calInstance1": "SOG" }, { "calInstance1": "STW" }, { "calInstance1": "TWA" }, { "calInstance1": "TWS" }, @@ -747,10 +751,12 @@ "condition": [ { "calInstance1": "AWA" }, { "calInstance1": "AWS" }, + { "calInstance2": "COG" }, { "calInstance1": "DBT" }, { "calInstance1": "HDM" }, { "calInstance1": "PRPOS" }, { "calInstance1": "RPOS" }, + { "calInstance1": "SOG" }, { "calInstance1": "STW" }, { "calInstance1": "TWA" }, { "calInstance1": "TWS" }, @@ -773,10 +779,12 @@ "condition": [ { "calInstance1": "AWA" }, { "calInstance1": "AWS" }, + { "calInstance2": "COG" }, { "calInstance1": "DBT" }, { "calInstance1": "HDM" }, { "calInstance1": "PRPOS" }, { "calInstance1": "RPOS" }, + { "calInstance1": "SOG" }, { "calInstance1": "STW" }, { "calInstance1": "TWA" }, { "calInstance1": "TWS" }, @@ -793,10 +801,12 @@ "---", "AWA", "AWS", + "COG", "DBT", "HDM", "PRPOS", "RPOS", + "SOG", "STW", "TWA", "TWS", @@ -821,10 +831,12 @@ "condition": [ { "calInstance2": "AWA" }, { "calInstance2": "AWS" }, + { "calInstance2": "COG" }, { "calInstance2": "DBT" }, { "calInstance2": "HDM" }, { "calInstance2": "PRPOS" }, { "calInstance2": "RPOS" }, + { "calInstance2": "SOG" }, { "calInstance2": "STW" }, { "calInstance2": "TWA" }, { "calInstance2": "TWS" }, @@ -844,10 +856,12 @@ "condition": [ { "calInstance2": "AWA" }, { "calInstance2": "AWS" }, + { "calInstance2": "COG" }, { "calInstance2": "DBT" }, { "calInstance2": "HDM" }, { "calInstance2": "PRPOS" }, { "calInstance2": "RPOS" }, + { "calInstance2": "SOG" }, { "calInstance2": "STW" }, { "calInstance2": "TWA" }, { "calInstance2": "TWS" }, @@ -870,10 +884,12 @@ "condition": [ { "calInstance2": "AWA" }, { "calInstance2": "AWS" }, + { "calInstance2": "COG" }, { "calInstance2": "DBT" }, { "calInstance2": "HDM" }, { "calInstance2": "PRPOS" }, { "calInstance2": "RPOS" }, + { "calInstance2": "SOG" }, { "calInstance2": "STW" }, { "calInstance2": "TWA" }, { "calInstance2": "TWS" }, @@ -890,10 +906,12 @@ "---", "AWA", "AWS", + "COG", "DBT", "HDM", "PRPOS", "RPOS", + "SOG", "STW", "TWA", "TWS", @@ -918,10 +936,12 @@ "condition": [ { "calInstance3": "AWA" }, { "calInstance3": "AWS" }, + { "calInstance3": "COG" }, { "calInstance3": "DBT" }, { "calInstance3": "HDM" }, { "calInstance3": "PRPOS" }, { "calInstance3": "RPOS" }, + { "calInstance3": "SOG" }, { "calInstance3": "STW" }, { "calInstance3": "TWA" }, { "calInstance3": "TWS" }, @@ -941,10 +961,12 @@ "condition": [ { "calInstance3": "AWA" }, { "calInstance3": "AWS" }, + { "calInstance3": "COG" }, { "calInstance3": "DBT" }, { "calInstance3": "HDM" }, { "calInstance3": "PRPOS" }, { "calInstance3": "RPOS" }, + { "calInstance3": "SOG" }, { "calInstance3": "STW" }, { "calInstance3": "TWA" }, { "calInstance3": "TWS" }, @@ -967,10 +989,12 @@ "condition": [ { "calInstance3": "AWA" }, { "calInstance3": "AWS" }, + { "calInstance3": "COG" }, { "calInstance3": "DBT" }, { "calInstance3": "HDM" }, { "calInstance3": "PRPOS" }, { "calInstance3": "RPOS" }, + { "calInstance3": "SOG" }, { "calInstance3": "STW" }, { "calInstance3": "TWA" }, { "calInstance3": "TWS" },