From 351ef5d9fe88ca83b66bdae9af4e8acd757509c4 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Sun, 27 Jul 2025 20:51:11 +0200 Subject: [PATCH 1/2] fix true wind input check; fix TWS not calculated with SOG only or w/o COG --- lib/obp60task/OBPDataOperations.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/obp60task/OBPDataOperations.cpp b/lib/obp60task/OBPDataOperations.cpp index cc6ac2a..eca2fe9 100644 --- a/lib/obp60task/OBPDataOperations.cpp +++ b/lib/obp60task/OBPDataOperations.cpp @@ -94,7 +94,7 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal, } else if (*cogVal != DBL_MIN) { hdt = *cogVal; // Use COG as fallback if HDT and HDM are not available } else { - return false; // Cannot calculate without valid HDT or HDM + return false; // Cannot calculate without valid HDT or HDM+VAR or COG } } @@ -102,8 +102,7 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal, ctw = *cogVal; // Use COG as CTW if available // ctw = *cogVal + ((*cogVal - hdt) / 2); // Estimate CTW from COG } else { - ctw = hdt; // 2nd approximation for CTW; - return false; + ctw = hdt; // 2nd approximation for CTW; hdt must exist if we reach this part of the code } if (*stwVal != DBL_MIN) { @@ -115,11 +114,11 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal, return false; } - if ((*awaVal == DBL_MIN) || (*awsVal == DBL_MIN) || (*cogVal == DBL_MIN) || (*stwVal == DBL_MIN)) { - // Cannot calculate true wind without valid AWA, AWS, COG, or STW + if ((*awaVal == DBL_MIN) || (*awsVal == DBL_MIN)) { + // Cannot calculate true wind without valid AWA, AWS; other checks are done earlier return false; } else { - calcTwdSA(awaVal, awsVal, &ctw, stwVal, &hdt, &twd, &tws, &twa); + calcTwdSA(awaVal, awsVal, &ctw, &stw, &hdt, &twd, &tws, &twa); *twdVal = twd; *twsVal = tws; *twaVal = twa; From 05f8b3ec65f3473b35834c067709c5c43dfbcdb0 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Sun, 27 Jul 2025 20:54:35 +0200 Subject: [PATCH 2/2] fix TWS name not displayed; improve check for chart center adjustment; debug code changes --- lib/obp60task/PageWindPlot.cpp | 20 +++++--------------- lib/obp60task/obp60task.cpp | 13 ++++++------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/lib/obp60task/PageWindPlot.cpp b/lib/obp60task/PageWindPlot.cpp index cf6430c..5255320 100644 --- a/lib/obp60task/PageWindPlot.cpp +++ b/lib/obp60task/PageWindPlot.cpp @@ -206,7 +206,7 @@ public: // read boat data values; TWD only for validation test, TWS for display of current value for (int i = 0; i < numBoatData; i++) { bvalue = pageData.values[i]; - // BDataName[i] = xdrDelete(bvalue->getName()); + BDataName[i] = xdrDelete(bvalue->getName()); BDataName[i] = BDataName[i].substring(0, 6); // String length limit for value name calibrationData.calibrateInstance(bvalue, logger); // Check if boat data value is to be calibrated BDataValue[i] = bvalue->value; // Value as double in SI unit @@ -326,24 +326,13 @@ public: chrtVal = static_cast(pageData.boatHstry.twdHstry->get(bufStart + (i * dataIntv))); // show the latest wind values in buffer; keep 1st value constant in a rolling buffer if (chrtVal == INT16_MIN) { chrtPrevVal = INT16_MIN; - /* if (i == linesToShow - 1) { - numNoData++; - // If more than 4 invalid values in a row, reset chart - } else { - numNoData = 0; // Reset invalid value counter - } - if (numNoData > 4) { - // If more than 4 invalid values in a row, send message - getdisplay().setFont(&Ubuntu_Bold10pt8b); - getdisplay().fillRect(xCenter - 66, height / 2 - 20, 146, 24, commonData->bgcolor); // Clear area for TWS value - drawTextCenter(xCenter, height / 2 - 10, "No sensor data"); - } */ } else { chrtVal = static_cast((chrtVal / 1000.0 * radToDeg) + 0.5); // Convert to degrees and round x = ((chrtVal - wndLeft + 360) % 360) * chrtScl; y = yOffset + cHeight - i; // Position in chart area - if (i >= (numWndVals / dataIntv) - 10) +// if (i >= (numWndVals / dataIntv) - 10) + if (i >= (numWndVals / dataIntv) - 1) LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Chart: i: %d, chrtVal: %d, bufStart: %d, count: %d, linesToShow: %d", i, chrtVal, bufStart, count, (numWndVals / dataIntv)); if ((i == 0) || (chrtPrevVal == INT16_MIN)) { @@ -378,7 +367,8 @@ public: int minWndDir = pageData.boatHstry.twdHstry->getMin(numWndVals) / 1000.0 * radToDeg; int maxWndDir = pageData.boatHstry.twdHstry->getMax(numWndVals) / 1000.0 * radToDeg; LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: Minimum: %d, Maximum: %d, OldwndCenter: %d", minWndDir, maxWndDir, wndCenter); - if ((minWndDir + 540 >= wndCenter + 540) || (maxWndDir + 540 <= wndCenter + 540)) { +// if ((minWndDir + 540 >= wndCenter + 540) || (maxWndDir + 540 <= wndCenter + 540)) { + if (((minWndDir - wndCenter >= 0) && (minWndDir - wndCenter < 180)) || ((maxWndDir - wndCenter <= 0) && (maxWndDir - wndCenter >=180))) { // Check if all wind value are left or right of center value -> optimize chart range midWndDir = pageData.boatHstry.twdHstry->getMid(numWndVals) / 1000.0 * radToDeg; if (midWndDir != INT16_MIN) { diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 11b986d..3ee638b 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -404,10 +404,9 @@ bool addTrueWind(GwApi* api, BoatValueList* boatValues) { hdtVal = hdtBVal->valid ? hdtBVal->value : DBL_MIN; hdmVal = hdmBVal->valid ? hdmBVal->value : DBL_MIN; varVal = varBVal->valid ? varBVal->value : DBL_MIN; - api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: AWA: %.1f, AWS: %.1f, COG: %.1f, STW: %.1f, HDT: %.1f, HDM: %.1f, VAR: %.1f", awaBVal->value * RAD_TO_DEG, awsBVal->value * 3.6 / 1.852, - cogBVal->value * RAD_TO_DEG, stwBVal->value * 3.6 / 1.852, hdtBVal->value * RAD_TO_DEG, hdmBVal->value * RAD_TO_DEG, varBVal->value * RAD_TO_DEG); + api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: AWA %.1f, AWS %.1f, COG %.1f, STW %.1f, SOG %.1f, HDT %.1f, HDM %.1f, VAR %.1f", awaBVal->value * RAD_TO_DEG, awsBVal->value * 3.6 / 1.852, + cogBVal->value * RAD_TO_DEG, stwBVal->value * 3.6 / 1.852, sogBVal->value * 3.6 / 1.852, hdtBVal->value * RAD_TO_DEG, hdmBVal->value * RAD_TO_DEG, varBVal->value * RAD_TO_DEG); -// isCalculated = WindUtils::calcTrueWind(&awaVal, &awsVal, &cogVal, &stwVal, &sogVal, &hdtVal, &hdmVal, &varVal, &twdBVal->value, &twsBVal->value, &twaBVal->value); isCalculated = WindUtils::calcTrueWind(&awaVal, &awsVal, &cogVal, &stwVal, &sogVal, &hdtVal, &hdmVal, &varVal, &twd, &tws, &twa); if (isCalculated) { // Replace values only, if successfully calculated and not already available @@ -424,8 +423,8 @@ bool addTrueWind(GwApi* api, BoatValueList* boatValues) { twaBVal->valid = true; } } - api->getLogger()->logDebug(GwLog::DEBUG,"obp60task calcTrueWind: TWD_Valid? %d, TWD=%.1f, TWS=%.1f, TWA=%.1f, isCalculated? %d", twdBVal->valid, twdBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852, - twaBVal->value * RAD_TO_DEG, isCalculated); + api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: TWD_Valid %d, isCalculated %d, TWD %.1f, TWA %.1f, TWS %.1f", twdBVal->valid, isCalculated, twdBVal->value * RAD_TO_DEG, + twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852); return isCalculated; } @@ -464,8 +463,8 @@ void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryB GwApi::BoatValue *twsBVal = boatValues->findValueOrCreate(hstryBufList.twsHstry->getName()); GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA"); - api->getLogger()->logDebug(GwLog::DEBUG,"obp60task handleHstryBuf: twdBVal: %f, twsBVal: %f, twaBVal: %f, TWD_isValid? %d", twdBVal->value * RAD_TO_DEG, - twsBVal->value * 3.6 / 1.852, twaBVal->value * RAD_TO_DEG, twdBVal->valid); + api->getLogger()->logDebug(GwLog::DEBUG,"obp60task handleHstryBuf: twdBVal: %.1f, twaBVal: %.1f, twsBVal: %.1f, TWD_isValid? %d", twdBVal->value * RAD_TO_DEG, + twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852, twdBVal->valid); calBVal = new GwApi::BoatValue("TWD"); // temporary solution for calibration of history buffer values calBVal->setFormat(twdBVal->getFormat()); if (twdBVal->valid) {