add simulation data for TWD, TWS history data

This commit is contained in:
Ulrich Meine 2025-08-16 16:49:17 +02:00
parent 398b8e0d02
commit 8faead0a1a
4 changed files with 123 additions and 126 deletions

View File

@ -86,7 +86,7 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
double minSogVal = 0.1; // SOG below this value (m/s) is assumed to be data noise from GPS sensor double minSogVal = 0.1; // SOG below this value (m/s) is assumed to be data noise from GPS sensor
static const double DBL_MIN = std::numeric_limits<double>::lowest(); static const double DBL_MIN = std::numeric_limits<double>::lowest();
Serial.println("\ncalcTrueWind: HDT: " + String(*hdtVal) + ", HDM: " + String(*hdmVal) + ", VAR: " + String(*varVal) + ", SOG: " + String(*sogVal) + ", COG: " + String(*cogVal)); // Serial.println("\ncalcTrueWind: HDT: " + String(*hdtVal) + ", HDM: " + String(*hdmVal) + ", VAR: " + String(*varVal) + ", SOG: " + String(*sogVal) + ", COG: " + String(*cogVal));
if (*hdtVal != DBL_MIN) { if (*hdtVal != DBL_MIN) {
hdt = *hdtVal; // Use HDT if available hdt = *hdtVal; // Use HDT if available
} else { } else {
@ -100,7 +100,7 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
} }
} }
if (*cogVal != DBL_MIN && *sogVal >= minSogVal ) { // if SOG is data noise, we don't trust COG if (*cogVal != DBL_MIN && *sogVal >= minSogVal) { // if SOG is data noise, we don't trust COG
ctw = *cogVal; // Use COG for CTW if available ctw = *cogVal; // Use COG for CTW if available
} else { } else {
@ -115,7 +115,7 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
// If STW and SOG are not available, we cannot calculate true wind // If STW and SOG are not available, we cannot calculate true wind
return false; return false;
} }
Serial.println("\ncalcTrueWind: HDT: " + String(hdt) + ", CTW: " + String(ctw) + ", STW: " + String(stw)); // Serial.println("\ncalcTrueWind: HDT: " + String(hdt) + ", CTW: " + String(ctw) + ", STW: " + String(stw));
if ((*awaVal == DBL_MIN) || (*awsVal == DBL_MIN)) { if ((*awaVal == DBL_MIN) || (*awsVal == DBL_MIN)) {
// Cannot calculate true wind without valid AWA, AWS; other checks are done earlier // Cannot calculate true wind without valid AWA, AWS; other checks are done earlier
@ -128,30 +128,4 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
return true; return true;
} }
} }
void HstryBuf::fillWndBufSimData(tBoatHstryData& hstryBufs)
// Fill most part of TWD and TWS history buffer with simulated data
{
double value = 20.0;
int16_t value2 = 0;
for (int i = 0; i < 900; i++) {
value += random(-20, 20);
value = WindUtils::to360(value);
value2 = static_cast<int16_t>(value * DEG_TO_RAD * 1000);
hstryBufs.twdHstry->add(value2);
}
}
/* void HstryBuf::simWndDir(double &wndDir)
{
wndDir += random(-20, 20);
wndDir = WindUtils::to360(wndDir);
int16_t z = static_cast<int16_t>(DegToRad(wndDir) * 1000.0);
pageData.boatHstry.twdHstry->add(z); // Fill the buffer with some test data
simTws += random(-200, 150) / 10.0; // TWS value in knots
simTws = constrain(simTws, 0.0f, 50.0f); // Ensure TWS is between 0 and 50 knots
twsValue = simTws;
}*/

View File

@ -12,7 +12,7 @@ typedef struct {
class HstryBuf { class HstryBuf {
public: public:
void fillWndBufSimData(tBoatHstryData& hstryBufs); // Fill most part of the TWD and TWS history buffer with simulated data
}; };
class WindUtils { class WindUtils {

View File

@ -6,15 +6,42 @@
#include "Pagedata.h" #include "Pagedata.h"
#include <vector> #include <vector>
static const double radToDeg = 180.0 / M_PI; // Conversion factor from radians to degrees static const double radToDeg = 180.0 / PI; // Conversion factor from radians to degrees
// Get maximum difference of last <amount> of TWD ringbuffer values to center chart
int getCntr(const RingBuffer<int16_t>& windDirHstry, size_t amount)
{
int minVal = windDirHstry.getMinVal();
size_t count = windDirHstry.getCurrentSize();
if (windDirHstry.isEmpty() || amount <= 0) {
return minVal;
}
if (amount > count)
amount = count;
int16_t midWndDir, minWndDir, maxWndDir = 0;
int wndCenter = 0;
midWndDir = windDirHstry.getMid(amount);
if (midWndDir != INT16_MIN) {
midWndDir = midWndDir / 1000.0 * radToDeg;
wndCenter = int((midWndDir + (midWndDir >= 0 ? 5 : -5)) / 10) * 10; // Set new center value; round to nearest 10 degree value
minWndDir = windDirHstry.getMin(amount) / 1000.0 * radToDeg;
maxWndDir = windDirHstry.getMax(amount) / 1000.0 * radToDeg;
if ((maxWndDir - minWndDir) > 180 && !(minWndDir > maxWndDir)) { // if wind range is > 180 and no 0° crossover, adjust wndCenter to smaller wind range end
wndCenter = WindUtils::to360(wndCenter + 180);
}
}
return wndCenter;
}
// Get maximum difference of last <amount> of TWD ringbuffer values to center chart // Get maximum difference of last <amount> of TWD ringbuffer values to center chart
int getRng(const RingBuffer<int16_t>& windDirHstry, int center, size_t amount) int getRng(const RingBuffer<int16_t>& windDirHstry, int center, size_t amount)
{ {
int minVal = windDirHstry.getMinVal(); int minVal = windDirHstry.getMinVal();
size_t count = windDirHstry.getCurrentSize(); size_t count = windDirHstry.getCurrentSize();
// size_t capacity = windDirHstry.getCapacity();
// size_t last = windDirHstry.getLastIdx();
if (windDirHstry.isEmpty() || amount <= 0) { if (windDirHstry.isEmpty() || amount <= 0) {
return minVal; return minVal;
@ -118,7 +145,7 @@ public:
GwConfigHandler* config = commonData->config; GwConfigHandler* config = commonData->config;
GwLog* logger = commonData->logger; GwLog* logger = commonData->logger;
// float twsValue; // TWS value in chart area float twsValue; // TWS value in chart area
static String twdName, twdUnit; // TWD name and unit static String twdName, twdUnit; // TWD name and unit
static int updFreq; // Update frequency for TWD static int updFreq; // Update frequency for TWD
static int16_t twdLowest, twdHighest; // TWD range static int16_t twdLowest, twdHighest; // TWD range
@ -137,8 +164,8 @@ public:
static bool isInitialized = false; // Flag to indicate that page is initialized static bool isInitialized = false; // Flag to indicate that page is initialized
static bool wndDataValid = false; // Flag to indicate if wind data is valid static bool wndDataValid = false; // Flag to indicate if wind data is valid
static int numNoData; // Counter for multiple invalid data values in a row static int numNoData; // Counter for multiple invalid data values in a row
static bool simulation = false; // static bool useSimuData = false;
static bool holdValues = false; // static bool holdValues = false;
static int width; // Screen width static int width; // Screen width
static int height; // Screen height static int height; // Screen height
@ -163,8 +190,8 @@ public:
int diffRng; // Difference between mid and current wind value int diffRng; // Difference between mid and current wind value
static const int dfltRng = 60; // Default range for chart static const int dfltRng = 60; // Default range for chart
int midWndDir; // New value for wndCenter after chart start / shift int midWndDir; // New value for wndCenter after chart start / shift
static int simTwd; // Simulation value for TWD // static int simTwd; // Simulation value for TWD
static float simTws; // Simulation value for TWS // static float simTws; // Simulation value for TWS
int x, y; // x and y coordinates for drawing int x, y; // x and y coordinates for drawing
static int prevX, prevY; // Last x and y coordinates for drawing static int prevX, prevY; // Last x and y coordinates for drawing
@ -175,8 +202,8 @@ public:
LOG_DEBUG(GwLog::LOG, "Display page WindPlot"); LOG_DEBUG(GwLog::LOG, "Display page WindPlot");
// Get config data // Get config data
simulation = config->getBool(config->useSimuData); bool useSimuData = config->getBool(config->useSimuData);
holdValues = config->getBool(config->holdvalues); // holdValues = config->getBool(config->holdvalues);
String flashLED = config->getString(config->flashLED); String flashLED = config->getString(config->flashLED);
String backlightMode = config->getString(config->backlight); String backlightMode = config->getString(config->backlight);
@ -187,9 +214,9 @@ public:
cHeight = height - yOffset - 22; cHeight = height - yOffset - 22;
bufSize = pageData.boatHstry.twdHstry->getCapacity(); bufSize = pageData.boatHstry.twdHstry->getCapacity();
numNoData = 0; numNoData = 0;
simTwd = pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg; // simTwd = pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg;
simTws = 0; // simTws = 0;
// twsValue = 0; twsValue = 0;
bufStart = 0; bufStart = 0;
oldDataIntv = 0; oldDataIntv = 0;
numAddedBufVals, currIdx, lastIdx = 0; numAddedBufVals, currIdx, lastIdx = 0;
@ -246,15 +273,9 @@ public:
// Set wndCenter from 1st real buffer value // Set wndCenter from 1st real buffer value
if (wndCenter == INT_MIN || (wndCenter == 0 && count == 1)) { if (wndCenter == INT_MIN || (wndCenter == 0 && count == 1)) {
midWndDir = pageData.boatHstry.twdHstry->getMid(numWndVals); wndCenter = getCntr(*pageData.boatHstry.twdHstry, numWndVals);
if (midWndDir != INT16_MIN) { LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range Init: count: %d, TWD: %.0f, wndCenter: %d, diffRng: %d, chrtRng: %d, Min: %.0f, Max: %.0f", count, pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg,
midWndDir = midWndDir / 1000.0 * radToDeg; wndCenter, diffRng, chrtRng, pageData.boatHstry.twdHstry->getMin(numWndVals) / 1000.0 * radToDeg, pageData.boatHstry.twdHstry->getMax(numWndVals) / 1000.0 * radToDeg);
wndCenter = int((midWndDir + (midWndDir >= 0 ? 5 : -5)) / 10) * 10; // Set new center value; round to nearest 10 degree value
} else {
wndCenter = 0;
}
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range Init: count: %d, TWD: %.0f, wndCenter: %d, diffRng: %d, chrtRng: %d", count, pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg,
wndCenter, diffRng, chrtRng);
} else { } else {
// check and adjust range between left, center, and right chart limit // check and adjust range between left, center, and right chart limit
diffRng = getRng(*pageData.boatHstry.twdHstry, wndCenter, numWndVals); diffRng = getRng(*pageData.boatHstry.twdHstry, wndCenter, numWndVals);
@ -263,8 +284,8 @@ public:
chrtRng = int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10; // Round up to next 10 degree value chrtRng = int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10; // Round up to next 10 degree value
} else if (diffRng + 10 < chrtRng) { // Reduce chart range for higher resolution if possible } else if (diffRng + 10 < chrtRng) { // Reduce chart range for higher resolution if possible
chrtRng = max(dfltRng, int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10); chrtRng = max(dfltRng, int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10);
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range adjust: wndCenter: %d, diffRng: %d, chrtRng: %d, Min: %.0f, Max: %.0f", wndCenter, diffRng, chrtRng, pageData.boatHstry.twdHstry->getMin(numWndVals) / 1000.0 * radToDeg, pageData.boatHstry.twdHstry->getMax(numWndVals) / 1000.0 * radToDeg);
} }
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range adjust: wndCenter: %d, diffRng: %d, chrtRng: %d", wndCenter, diffRng, chrtRng);
} }
chrtScl = float(width) / float(chrtRng) / 2.0; // Chart scale: pixels per degree chrtScl = float(width) / float(chrtRng) / 2.0; // Chart scale: pixels per degree
wndLeft = wndCenter - chrtRng; wndLeft = wndCenter - chrtRng;
@ -308,8 +329,8 @@ public:
if (pageData.boatHstry.twdHstry->getMax() == pageData.boatHstry.twdHstry->getMinVal()) { if (pageData.boatHstry.twdHstry->getMax() == pageData.boatHstry.twdHstry->getMinVal()) {
// only <INT16_MIN> values in buffer -> no valid wind data available // only <INT16_MIN> values in buffer -> no valid wind data available
wndDataValid = false; wndDataValid = false;
} else if (!BDataValid[0]) { } else if (!BDataValid[0] && !useSimuData) {
// currently no valid TWD data available // currently no valid TWD data available and no simulation mode
numNoData++; numNoData++;
wndDataValid = true; wndDataValid = true;
if (numNoData > 3) { if (numNoData > 3) {
@ -332,7 +353,7 @@ public:
x = ((chrtVal - wndLeft + 360) % 360) * chrtScl; x = ((chrtVal - wndLeft + 360) % 360) * chrtScl;
y = yOffset + cHeight - i; // Position in chart area y = yOffset + cHeight - i; // Position in chart area
if (i >= (numWndVals / dataIntv) - 1) // log chart data for 1 or more lines if (i >= (numWndVals / dataIntv) - 1) // log chart data of 1 line (adjust for test purposes)
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Chart: i: %d, chrtVal: %d, bufStart: %d, count: %d, linesToShow: %d", i, chrtVal, bufStart, count, (numWndVals / dataIntv)); 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)) { if ((i == 0) || (chrtPrevVal == INT16_MIN)) {
@ -368,21 +389,59 @@ public:
int maxWndDir = pageData.boatHstry.twdHstry->getMax(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); LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: Minimum: %d, Maximum: %d, OldwndCenter: %d", minWndDir, maxWndDir, wndCenter);
// if (((minWndDir - wndCenter >= 0) && (minWndDir - wndCenter < 180)) || ((maxWndDir - wndCenter <= 0) && (maxWndDir - wndCenter >=180))) { // if (((minWndDir - wndCenter >= 0) && (minWndDir - wndCenter < 180)) || ((maxWndDir - wndCenter <= 0) && (maxWndDir - wndCenter >=180))) {
if ((wndRight > wndCenter && (minWndDir >= wndCenter && minWndDir <= wndRight)) || if ((wndRight > wndCenter && (minWndDir >= wndCenter && minWndDir <= wndRight)) || (wndRight <= wndCenter && (minWndDir >= wndCenter || minWndDir <= wndRight)) || (wndLeft < wndCenter && (maxWndDir <= wndCenter && maxWndDir >= wndLeft)) || (wndLeft >= wndCenter && (maxWndDir <= wndCenter || maxWndDir >= wndLeft))) {
(wndRight <= wndCenter && (minWndDir >= wndCenter || minWndDir <= wndRight)) || // Check if all wind value are left or right of center value -> optimize chart center
(wndLeft < wndCenter && (maxWndDir <= wndCenter && maxWndDir >= wndLeft)) || wndCenter = getCntr(*pageData.boatHstry.twdHstry, numWndVals);
(wndLeft >= wndCenter && (maxWndDir <= wndCenter || maxWndDir >= wndLeft))) {
// 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) {
wndCenter = int((midWndDir + (midWndDir >= 0 ? 5 : -5)) / 10) * 10; // Set new center value; round to nearest 10 degree value
}
} }
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: cHeight: %d, bufStart: %d, numWndVals: %d, wndCenter: %d", cHeight, bufStart, numWndVals, wndCenter); LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: cHeight: %d, bufStart: %d, numWndVals: %d, wndCenter: %d", cHeight, bufStart, numWndVals, wndCenter);
break; break;
} }
} }
// Print TWS value
if (showTWS) {
int currentZone;
static int lastZone = 0;
static bool flipTws = false;
int xPosTws;
static const int yPosTws = yOffset + 40;
xPosTws = flipTws ? 20 : width - 145;
currentZone = (y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146) ? 1 : 0; // Define current zone for TWS value
if (currentZone != lastZone) {
// Only flip when x moves to a different zone
if ((y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146)) {
flipTws = !flipTws;
xPosTws = flipTws ? 20 : width - 145;
}
}
lastZone = currentZone;
twsValue = pageData.boatHstry.twsHstry->getLast();
getdisplay().fillRect(xPosTws - 4, yPosTws - 38, 142, 44, commonData->bgcolor); // Clear area for TWS value
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
getdisplay().setCursor(xPosTws, yPosTws);
if (twsValue == pageData.boatHstry.twsHstry->getMinVal()) {
getdisplay().print("--.-");
} else {
twsValue = twsValue / 10.0 * 1.94384; // TWS value in knots
if (twsValue < 10.0) {
getdisplay().printf("!%3.1f", twsValue); // Value, round to 1 decimal
} else {
getdisplay().printf("%4.1f", twsValue); // Value, round to 1 decimal
}
}
getdisplay().setFont(&Ubuntu_Bold12pt8b);
getdisplay().setCursor(xPosTws + 82, yPosTws - 14);
// getdisplay().print("TWS"); // Name
getdisplay().print(BDataName[1]); // Name
getdisplay().setFont(&Ubuntu_Bold8pt8b);
// getdisplay().setCursor(xPosTws + 78, yPosTws + 1);
getdisplay().setCursor(xPosTws + 82, yPosTws + 1);
// getdisplay().printf(" kn"); // Unit
getdisplay().print(BDataUnit[1]); // Unit
}
} else { } else {
// No valid data available // No valid data available
LOG_DEBUG(GwLog::LOG, "PageWindPlot: No valid data available"); LOG_DEBUG(GwLog::LOG, "PageWindPlot: No valid data available");
@ -391,51 +450,6 @@ public:
drawTextCenter(xCenter, height / 2 - 10, "No data"); drawTextCenter(xCenter, height / 2 - 10, "No data");
} }
// Print TWS value
if (showTWS) {
int currentZone;
static int lastZone = 0;
static bool flipTws = false;
int xPosTws;
static const int yPosTws = yOffset + 40;
// twsValue = pageData.boatHstry.twsHstry->getLast() / 10.0 * 1.94384; // TWS value in knots
xPosTws = flipTws ? 20 : width - 138;
currentZone = (y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146) ? 1 : 0; // Define current zone for TWS value
if (currentZone != lastZone) {
// Only flip when x moves to a different zone
if ((y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146)) {
flipTws = !flipTws;
xPosTws = flipTws ? 20 : width - 145;
}
}
lastZone = currentZone;
getdisplay().fillRect(xPosTws - 4, yPosTws - 38, 142, 44, commonData->bgcolor); // Clear area for TWS value
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
getdisplay().setCursor(xPosTws, yPosTws);
if (!BDataValid[1]) {
getdisplay().print("--.-");
} else {
double dbl = BDataValue[1] * 3.6 / 1.852;
if (dbl < 10.0) {
getdisplay().printf("!%3.1f", dbl); // Value, round to 1 decimal
} else {
getdisplay().printf("%4.1f", dbl); // Value, round to 1 decimal
}
}
getdisplay().setFont(&Ubuntu_Bold12pt8b);
getdisplay().setCursor(xPosTws + 82, yPosTws - 14);
// getdisplay().print("TWS"); // Name
getdisplay().print(BDataName[1]); // Name
getdisplay().setFont(&Ubuntu_Bold8pt8b);
// getdisplay().setCursor(xPosTws + 78, yPosTws + 1);
getdisplay().setCursor(xPosTws + 82, yPosTws + 1);
// getdisplay().printf(" kn"); // Unit
getdisplay().print(BDataUnit[1]); // Unit
}
// chart Y axis labels; print at last to overwrite potential chart lines in label area // chart Y axis labels; print at last to overwrite potential chart lines in label area
int yPos; int yPos;
int chrtLbl; int chrtLbl;

View File

@ -376,7 +376,6 @@ void underVoltageDetection(GwApi *api, CommonData &common){
} }
} }
//bool addTrueWind(GwApi* api, BoatValueList* boatValues, double *twd, double *tws, double *twa) {
bool addTrueWind(GwApi* api, BoatValueList* boatValues) { bool addTrueWind(GwApi* api, BoatValueList* boatValues) {
// Calculate true wind data and add to obp60task boat data list // Calculate true wind data and add to obp60task boat data list
@ -423,7 +422,7 @@ bool addTrueWind(GwApi* api, BoatValueList* boatValues) {
twaBVal->valid = true; twaBVal->valid = true;
} }
} }
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: TWD_isValid %d, isCalculated %d, TWD %.1f, TWA %.1f, TWS %.1f", twdBVal->valid, isCalculated, twdBVal->value * RAD_TO_DEG, api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: isCalculated %d, TWD %.1f, TWA %.1f, TWS %.1f", isCalculated, twdBVal->value * RAD_TO_DEG,
twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852); twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852);
return isCalculated; return isCalculated;
@ -447,7 +446,7 @@ void initHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryBuf
GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA"); GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA");
} }
void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryBufList) { void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryBufList, bool useSimuData) {
// Handle history buffers for TWD, TWS // Handle history buffers for TWD, TWS
GwLog *logger = api->getLogger(); GwLog *logger = api->getLogger();
@ -456,18 +455,18 @@ void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryB
int16_t twdHstryMax = hstryBufList.twdHstry->getMaxVal(); int16_t twdHstryMax = hstryBufList.twdHstry->getMaxVal();
int16_t twsHstryMin = hstryBufList.twsHstry->getMinVal(); int16_t twsHstryMin = hstryBufList.twsHstry->getMinVal();
int16_t twsHstryMax = hstryBufList.twsHstry->getMaxVal(); int16_t twsHstryMax = hstryBufList.twsHstry->getMaxVal();
int16_t twdBuf, twsBuf; static int16_t twdBuf, twsBuf = 20; //initial value only relevant if we use simulation data
GwApi::BoatValue *calBVal; // temp variable just for data calibration -> we don't want to calibrate the original data here GwApi::BoatValue *calBVal; // temp variable just for data calibration -> we don't want to calibrate the original data here
GwApi::BoatValue *twdBVal = boatValues->findValueOrCreate(hstryBufList.twdHstry->getName()); GwApi::BoatValue *twdBVal = boatValues->findValueOrCreate(hstryBufList.twdHstry->getName());
GwApi::BoatValue *twsBVal = boatValues->findValueOrCreate(hstryBufList.twsHstry->getName()); GwApi::BoatValue *twsBVal = boatValues->findValueOrCreate(hstryBufList.twsHstry->getName());
GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA"); GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA");
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task handleHstryBuf: TWD_isValid? %d, twdBVal: %.1f, twaBVal: %.1f, twsBVal: %.1f", twdBVal->valid, twdBVal->value * RAD_TO_DEG, api->getLogger()->logDebug(GwLog::DEBUG,"obp60task handleHstryBuf: TWD_isValid? %d, twdBVal: %.1f, twaBVal: %.1f, twsBVal: %.1f", twdBVal->valid, twdBVal->value * RAD_TO_DEG,
twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852); twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852);
calBVal = new GwApi::BoatValue("TWD"); // temporary solution for calibration of history buffer values
calBVal->setFormat(twdBVal->getFormat());
if (twdBVal->valid) { if (twdBVal->valid) {
calBVal = new GwApi::BoatValue("TWD"); // temporary solution for calibration of history buffer values
calBVal->setFormat(twdBVal->getFormat());
calBVal->value = twdBVal->value; calBVal->value = twdBVal->value;
calBVal->valid = twdBVal->valid; calBVal->valid = twdBVal->valid;
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
@ -475,13 +474,18 @@ void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryB
if (twdBuf >= twdHstryMin && twdBuf <= twdHstryMax) { if (twdBuf >= twdHstryMin && twdBuf <= twdHstryMax) {
hstryBufList.twdHstry->add(twdBuf); hstryBufList.twdHstry->add(twdBuf);
} }
delete calBVal;
calBVal = nullptr;
} else if (useSimuData) {
twdBuf += random(-20, 20);
twdBuf = WindUtils::to360(twdBuf);
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task Simu: twdBVal: %d", twdBuf);
hstryBufList.twdHstry->add(static_cast<int16_t>(DegToRad(twdBuf) * 1000.0));
} }
delete calBVal;
calBVal = nullptr;
calBVal = new GwApi::BoatValue("TWS"); // temporary solution for calibration of history buffer values
calBVal->setFormat(twsBVal->getFormat());
if (twsBVal->valid) { if (twsBVal->valid) {
calBVal = new GwApi::BoatValue("TWS"); // temporary solution for calibration of history buffer values
calBVal->setFormat(twsBVal->getFormat());
calBVal->value = twsBVal->value; calBVal->value = twsBVal->value;
calBVal->valid = twsBVal->valid; calBVal->valid = twsBVal->valid;
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
@ -489,9 +493,14 @@ void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryB
if (twsBuf >= twsHstryMin && twsBuf <= twsHstryMax) { if (twsBuf >= twsHstryMin && twsBuf <= twsHstryMax) {
hstryBufList.twsHstry->add(twsBuf); hstryBufList.twsHstry->add(twsBuf);
} }
delete calBVal;
calBVal = nullptr;
} else if (useSimuData) {
twsBuf += random(-50, 50); // TWS value in m/s; expands to 1 decimal
twsBuf = constrain(twsBuf, 0, 250); // Limit TWS to [0..25] m/s
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task Simu: twsBVal: %d", twsBuf);
hstryBufList.twsHstry->add(twsBuf);
} }
delete calBVal;
calBVal = nullptr;
} }
// OBP60 Task // OBP60 Task
@ -663,7 +672,7 @@ void OBP60Task(GwApi *api){
// Check user setting for true wind calculation // Check user setting for true wind calculation
bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false); bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false);
// bool simulation = api->getConfig()->getBool(api->getConfig()->useSimuData, false); bool useSimuData = api->getConfig()->getBool(api->getConfig()->useSimuData, false);
// Initialize history buffer for certain boat data // Initialize history buffer for certain boat data
initHstryBuf(api, &boatValues, hstryBufList); initHstryBuf(api, &boatValues, hstryBufList);
@ -974,7 +983,7 @@ void OBP60Task(GwApi *api){
addTrueWind(api, &boatValues); addTrueWind(api, &boatValues);
} }
// Handle history buffers for TWD, TWS for wind plot page and other usage // Handle history buffers for TWD, TWS for wind plot page and other usage
handleHstryBuf(api, &boatValues, hstryBufList); handleHstryBuf(api, &boatValues, hstryBufList, useSimuData);
// Clear display // Clear display
// getdisplay().fillRect(0, 0, getdisplay().width(), getdisplay().height(), commonData.bgcolor); // getdisplay().fillRect(0, 0, getdisplay().width(), getdisplay().height(), commonData.bgcolor);