From c17f8238a4f9daf468a7c3519a06e6efe79ee95f Mon Sep 17 00:00:00 2001 From: Ulrich Meine <145987006+Scorgan01@users.noreply.github.com> Date: Fri, 19 Jun 2026 00:00:08 +0200 Subject: [PATCH] Implement MaxTWS for OBP true wind calculation --- lib/obp60task/OBPDataOperations.cpp | 20 ++++++++++++++++---- lib/obp60task/OBPDataOperations.h | 12 +++++++----- lib/obp60task/obp60task.cpp | 5 +++++ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/lib/obp60task/OBPDataOperations.cpp b/lib/obp60task/OBPDataOperations.cpp index 3099536..1d84a70 100644 --- a/lib/obp60task/OBPDataOperations.cpp +++ b/lib/obp60task/OBPDataOperations.cpp @@ -238,7 +238,7 @@ void HstryBuf::add(double value) { if (value >= hstryMin && value <= hstryMax) { hstryBuf.add(value); - LOG_DEBUG(GwLog::DEBUG, "HstryBuf::add: name: %s, value: %.3f", hstryBuf.getName(), value); + // LOG_DEBUG(GwLog::DEBUG, "HstryBuf::add: name: %s, value: %.3f, value buffer: %.3f", hstryBuf.getName(), value, hstryBuf.getLast()); } } @@ -492,10 +492,24 @@ bool WindUtils::calcTrueWinds(const double* awaVal, const double* awsVal, const return true; } +// Set max wind speed +void WindUtils::setMaxWs(GwApi::BoatValue* wsMaxValue, const double* wsVal) +{ + static double maxWs = 0.0; // maintain own maxTWS value in obp user task; core gateway would reset MaxTWS obp boat value if true wind data is not available + + if (*wsVal != DBL_MAX && *wsVal > maxWs) { + maxWs = *wsVal; + } + + if ( maxWs > 0.0 && maxWs >= wsMaxValue->value) { + wsMaxValue->value = maxWs; // overwrite core gateway value each second again with own user task value if that value is larger + wsMaxValue->valid = true; + } +}; + // Calculate true wind data and add to obp60task boat data list bool WindUtils::handleWinds(bool calcWinds) { - double twd, tws, twa, awd; bool twCalculated = false; double awaVal = awaBVal->valid ? awaBVal->value : DBL_MAX; @@ -508,8 +522,6 @@ bool WindUtils::handleWinds(bool calcWinds) double varVal = varBVal->valid ? varBVal->value : DBL_MAX; double twaVal = twaBVal->valid ? twaBVal->value : DBL_MAX; double twsVal = twsBVal->valid ? twsBVal->value : DBL_MAX; - // LOG_DEBUG(GwLog::DEBUG, "WindUtils:handleWinds: AWA %.1f, AWS %.1f, AWD %.1f, COG %.1f, STW %.1f, SOG %.2f, HDT %.1f, HDM %.1f, VAR %.1f", awaVal * RAD_TO_DEG, awsVal * 3.6 / 1.852, - // awd * RAD_TO_DEG, cogVal * RAD_TO_DEG, stwVal * 3.6 / 1.852, sogVal * 3.6 / 1.852, hdtVal * RAD_TO_DEG, hdmVal * RAD_TO_DEG, varVal * RAD_TO_DEG); if (calcHDT(&hdmVal, &varVal, &cogVal, &sogVal, &hdtVal)) { hdtBVal->value = hdtVal; diff --git a/lib/obp60task/OBPDataOperations.h b/lib/obp60task/OBPDataOperations.h index 7e48297..2722ae0 100644 --- a/lib/obp60task/OBPDataOperations.h +++ b/lib/obp60task/OBPDataOperations.h @@ -68,7 +68,6 @@ private: // [10000: 0 - 6.5535 | 1000: 0 - 65.535 | 100: 0 - 655.35 | 10: 0 - 6553.5 | 1: 0 - 65535 | 0.1: 0 - 655350] double bufferMinVal; // minimum valid data value double bufferMaxVal; // maximum valid data value - //String format; // format of data type }; std::map bufferParams = { @@ -91,14 +90,13 @@ private: { "WTemp", { 1000, 100, 263.0, 403.0 } }, // water temp [-10..130] °C { "formatXdr:C:K", { 1000, 100, 223.0, 473.15 } }, // temperature [-50..200] deg celsius { "formatXdr:P:B", { 1000, 1000, 0, 65.0 } }, // pressure [0..65] bar - { "formatXdr:P:P", { 60000, 0.1, 0, 650000 } }, // pressure [0..6500] hPa + { "formatXdr:P:P", { 5000, 0.1, 0, 650000 } }, // pressure [0..6500] hPa { "formatXdr:H:P", { 1000, 100, 0, 100 } }, // humidity [0..100] percent { "formatXdr:I:A", { 1000, 100, 0, 650.0 } }, // current [0..650] amperes { "formatXdr:U:V", { 1000, 1000, 0, 65.0 } }, // voltage [0..65] volts - { "formatXdr:T:R", { 1000, 1, 0, 65000 } }, // tachometer [0..65000] rpm + { "formatXdr:T:R", { 1000, 1, 0, 30000 } }, // tachometer [0..30000] rpm { "formatXdr:V:L", { 10000, 100, 0, 650 } }, // volume [0..650] litres { "formatXdr:V:M", { 10000, 10000, 0, 6.50 } }, // volume [0..6.5] m^3 - { "formatXdr:G:M", { 3000, 0.1, 0, 650000 } } // generic -> (pressure) [0..6500] hPa }; public: @@ -110,9 +108,10 @@ public: class WindUtils { private: - GwApi::BoatValue *twaBVal, *twsBVal, *twdBVal; + GwApi::BoatValue *twaBVal, *twsBVal, *twdBVal, *maxtwsBVal; GwApi::BoatValue *awaBVal, *awsBVal, *awdBVal; GwApi::BoatValue *cogBVal, *stwBVal, *sogBVal, *hdtBVal, *hdmBVal, *varBVal; + double twd, tws, twa, awd; static constexpr double DBL_MAX = std::numeric_limits::max(); GwLog* logger; @@ -122,6 +121,7 @@ public: { twaBVal = boatValues->findValueOrCreate("TWA"); twsBVal = boatValues->findValueOrCreate("TWS"); + maxtwsBVal = boatValues->findValueOrCreate("MaxTws"); twdBVal = boatValues->findValueOrCreate("TWD"); awaBVal = boatValues->findValueOrCreate("AWA"); awsBVal = boatValues->findValueOrCreate("AWS"); @@ -150,5 +150,7 @@ public: bool calcTrueWinds(const double* awaVal, const double* awsVal, const double* awd, const double* cogVal, const double* stwVal, const double* sogVal, const double* hdtVal, double* twdVal, double* twsVal, double* twaVal); + void setMaxWs(GwApi::BoatValue *wsMaxValue, const double * wsVal); + void setMaxWs() { setMaxWs(maxtwsBVal, &tws); }; bool handleWinds(bool calcWinds); }; \ No newline at end of file diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 1079277..a8de252 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -265,6 +265,8 @@ void registerAllPages(PageList &list){ list.add(®isterPageDigitalOut); extern PageDescription registerPageAutopilot; list.add(®isterPageAutopilot); +// extern PageDescription registerPageWeather; +// list.add(®isterPageWeather); } // Undervoltage detection for shutdown display @@ -846,9 +848,12 @@ void OBP60Task(GwApi *api){ api->getBoatDataValues(boatValues.numValues,boatValues.allBoatValues); api->getStatus(commonData.status); + // ulong startHndl = millis(); trueWind.handleWinds(calcTrueWnds); // calculate true wind data from apparent wind values + trueWind.setMaxWs(); // maintain MaxTWS value in any case; invalid TWS value is considered automatically calibrationDataList.handleCalibration(&boatValues); // Process calibration for all boat data in hstryBufferList.handleHstryBufs(useSimuData, commonData); // Handle history buffers for certain boat data for charts and other usage + // LOG_DEBUG(GwLog::DEBUG, "obp60task: data handling: %d ms", millis() - startHndl); // Clear display // getdisplay().fillRect(0, 0, getdisplay().width(), getdisplay().height(), commonData.bgcolor);