mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2026-01-26 08:13:05 +01:00
General history buffers working; fine tuning required
This commit is contained in:
@@ -1,38 +1,34 @@
|
|||||||
#include "OBPDataOperations.h"
|
#include "OBPDataOperations.h"
|
||||||
#include "BoatDataCalibration.h" // Functions lib for data instance calibration
|
#include "BoatDataCalibration.h" // Functions lib for data instance calibration
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
// --- Class HstryBuf ---------------
|
// --- Class HstryBuf ---------------
|
||||||
|
HstryBuf::HstryBuf(const String& name, int size, BoatValueList* boatValues, GwLog* log)
|
||||||
HstryBuf::HstryBuf(const String& name, int size, GwLog* log, BoatValueList* boatValues)
|
|
||||||
: logger(log), boatDataName(name) {
|
: logger(log), boatDataName(name) {
|
||||||
hstry.resize(size);
|
hstryBuf.resize(size);
|
||||||
boatValue = boatValues->findValueOrCreate(name);
|
boatValue = boatValues->findValueOrCreate(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HstryBuf::init(const String& format, int updFreq, int mltplr, double minVal, double maxVal) {
|
void HstryBuf::init(const String& format, int updFreq, int mltplr, double minVal, double maxVal) {
|
||||||
hstry.setMetaData(boatDataName, format, updFreq, mltplr, minVal, maxVal);
|
hstryBuf.setMetaData(boatDataName, format, updFreq, mltplr, minVal, maxVal);
|
||||||
hstryMin = minVal;
|
hstryMin = minVal;
|
||||||
hstryMax = maxVal;
|
hstryMax = maxVal;
|
||||||
if (!boatValue->valid) {
|
if (!boatValue->valid) {
|
||||||
boatValue->setFormat(format);
|
boatValue->setFormat(format);
|
||||||
boatValue->value = std::numeric_limits<double>::max();
|
boatValue->value = std::numeric_limits<double>::max(); // mark current value invalid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HstryBuf::add(double value) {
|
void HstryBuf::add(double value) {
|
||||||
if (value >= hstryMin && value <= hstryMax) {
|
if (value >= hstryMin && value <= hstryMax) {
|
||||||
hstry.add(value);
|
hstryBuf.add(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HstryBuf::handle(bool useSimuData) {
|
void HstryBuf::handle(bool useSimuData) {
|
||||||
GwApi::BoatValue *calBVal;
|
GwApi::BoatValue *calBVal;
|
||||||
|
|
||||||
if (boatValue->valid) {
|
if (boatValue->valid) { // add calibrated boat value to history buffer
|
||||||
calBVal = new GwApi::BoatValue(boatDataName.c_str());
|
calBVal = new GwApi::BoatValue(boatDataName.c_str());
|
||||||
calBVal->setFormat(boatValue->getFormat());
|
calBVal->setFormat(boatValue->getFormat());
|
||||||
calBVal->value = boatValue->value;
|
calBVal->value = boatValue->value;
|
||||||
@@ -41,8 +37,8 @@ void HstryBuf::handle(bool useSimuData) {
|
|||||||
add(calBVal->value);
|
add(calBVal->value);
|
||||||
delete calBVal;
|
delete calBVal;
|
||||||
calBVal = nullptr;
|
calBVal = nullptr;
|
||||||
} else if (useSimuData) {
|
} else if (useSimuData) { // add simulated value to history buffer
|
||||||
double simValue = hstry.getLast();
|
double simValue = hstryBuf.getLast();
|
||||||
if (boatDataName == "TWD" || boatDataName == "AWD") {
|
if (boatDataName == "TWD" || boatDataName == "AWD") {
|
||||||
simValue += static_cast<double>(random(-349, 349) / 1000.0);
|
simValue += static_cast<double>(random(-349, 349) / 1000.0);
|
||||||
simValue = WindUtils::to2PI(simValue);
|
simValue = WindUtils::to2PI(simValue);
|
||||||
@@ -53,48 +49,53 @@ void HstryBuf::handle(bool useSimuData) {
|
|||||||
add(simValue);
|
add(simValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// --- End Class HstryBuf ---------------
|
||||||
|
|
||||||
// --- Class HstryManager ---------------
|
// --- Class HstryBuffers ---------------
|
||||||
HstryManager::HstryManager(int size, GwLog* log, BoatValueList* boatValues) {
|
HstryBuffers::HstryBuffers(int size, BoatValueList* boatValues, GwLog* log)
|
||||||
// Create history buffers for each boat data type
|
: size(size), boatValueList(boatValues), logger(log) {
|
||||||
hstryBufs["TWD"] = std::unique_ptr<HstryBuf>(new HstryBuf("TWD", size, log, boatValues));
|
|
||||||
hstryBufs["TWS"] = std::unique_ptr<HstryBuf>(new HstryBuf("TWS", size, log, boatValues));
|
|
||||||
hstryBufs["AWD"] = std::unique_ptr<HstryBuf>(new HstryBuf("AWD", size, log, boatValues));
|
|
||||||
hstryBufs["AWS"] = std::unique_ptr<HstryBuf>(new HstryBuf("AWS", size, log, boatValues));
|
|
||||||
|
|
||||||
// Initialize metadata for each buffer
|
|
||||||
int hstryUpdFreq = 1000; // Update frequency for history buffers in ms
|
|
||||||
int mltplr = 1000; // Multiplier which transforms original <double> value into buffer type format
|
|
||||||
double hstryMinVal = 0; // Minimum value for these history buffers
|
|
||||||
double courseMax = 2 * M_PI;
|
|
||||||
double speedMax = 65;
|
|
||||||
|
|
||||||
mltplr = 10000; // Store 4 decimals for course data
|
|
||||||
hstryBufs["TWD"]->init("formatCourse", hstryUpdFreq, mltplr, hstryMinVal, courseMax);
|
|
||||||
hstryBufs["AWD"]->init("formatCourse", hstryUpdFreq, mltplr, hstryMinVal, courseMax);
|
|
||||||
|
|
||||||
mltplr = 1000; // Store 3 decimals for windspeed data
|
|
||||||
hstryBufs["TWS"]->init("formatKnots", hstryUpdFreq, mltplr, hstryMinVal, speedMax);
|
|
||||||
hstryBufs["AWS"]->init("formatKnots", hstryUpdFreq, mltplr, hstryMinVal, speedMax);
|
|
||||||
|
|
||||||
// collect boat values for true wind calculation
|
// collect boat values for true wind calculation
|
||||||
awaBVal = boatValues->findValueOrCreate("AWA");
|
// should have been already all created at true wind object initialization
|
||||||
hdtBVal = boatValues->findValueOrCreate("HDT");
|
// potentially to be moved to history buffer handling
|
||||||
hdmBVal = boatValues->findValueOrCreate("HDM");
|
awaBVal = boatValueList->findValueOrCreate("AWA");
|
||||||
varBVal = boatValues->findValueOrCreate("VAR");
|
hdtBVal = boatValueList->findValueOrCreate("HDT");
|
||||||
cogBVal = boatValues->findValueOrCreate("COG");
|
hdmBVal = boatValueList->findValueOrCreate("HDM");
|
||||||
sogBVal = boatValues->findValueOrCreate("SOG");
|
varBVal = boatValueList->findValueOrCreate("VAR");
|
||||||
awdBVal = boatValues->findValueOrCreate("AWD");
|
cogBVal = boatValueList->findValueOrCreate("COG");
|
||||||
|
sogBVal = boatValueList->findValueOrCreate("SOG");
|
||||||
|
awdBVal = boatValueList->findValueOrCreate("AWD");
|
||||||
|
}
|
||||||
|
|
||||||
|
void HstryBuffers::addBuffer(const String& name) {
|
||||||
|
// Create history buffer for boat data type
|
||||||
|
|
||||||
|
if (HstryBuffers::getBuffer(name) != nullptr) { // buffer for this data type already exists
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hstryBuffers[name] = std::unique_ptr<HstryBuf>(new HstryBuf(name, size, boatValueList, logger));
|
||||||
|
|
||||||
|
// Initialize metadata for buffer
|
||||||
|
// String valueFormat = boatValueList->findValueOrCreate(name)->getFormat().c_str(); // Unfortunately, format is not yet available during system initialization
|
||||||
|
String valueFormat = bufferParams[name].format; // Data format of boat data type
|
||||||
|
int hstryUpdFreq = bufferParams[name].hstryUpdFreq; // Update frequency for history buffers in ms
|
||||||
|
int mltplr = bufferParams[name].mltplr; // default multiplier which transforms original <double> value into buffer type format
|
||||||
|
double bufferMinVal = bufferParams[name].bufferMinVal; // Min value for this history buffer
|
||||||
|
double bufferMaxVal = bufferParams[name].bufferMaxVal; // Max value for this history buffer
|
||||||
|
|
||||||
|
hstryBuffers[name]->init(valueFormat, hstryUpdFreq, mltplr, bufferMinVal, bufferMaxVal);
|
||||||
|
LOG_DEBUG(GwLog::DEBUG,"HstryBuffers-new buffer added: name: %s, format: %s, multiplier: %d, min value: %.2f, max value: %.2f", name, valueFormat, mltplr, bufferMinVal, bufferMaxVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle history buffers for TWD, TWS, AWD, AWS
|
// Handle history buffers for TWD, TWS, AWD, AWS
|
||||||
void HstryManager::handleHstryBufs(bool useSimuData) {
|
void HstryBuffers::handleHstryBufs(bool useSimuData) {
|
||||||
|
|
||||||
static double hdt = 20; //initial value only relevant if we use simulation data
|
static double hdt = 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
|
||||||
|
|
||||||
// Handle all registered history buffers
|
// Handle all registered history buffers
|
||||||
for (auto& pair : hstryBufs) {
|
for (auto& pair : hstryBuffers) {
|
||||||
auto& buf = pair.second;
|
auto& buf = pair.second;
|
||||||
buf->handle(useSimuData);
|
buf->handle(useSimuData);
|
||||||
}
|
}
|
||||||
@@ -118,8 +119,8 @@ void HstryManager::handleHstryBufs(bool useSimuData) {
|
|||||||
awdBVal->value = calBVal->value;
|
awdBVal->value = calBVal->value;
|
||||||
awdBVal->valid = true;
|
awdBVal->valid = true;
|
||||||
// Find the AWD buffer and add the value.
|
// Find the AWD buffer and add the value.
|
||||||
auto it = hstryBufs.find("AWD");
|
auto it = hstryBuffers.find("AWD");
|
||||||
if (it != hstryBufs.end()) {
|
if (it != hstryBuffers.end()) {
|
||||||
it->second->add(calBVal->value);
|
it->second->add(calBVal->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,14 +131,14 @@ void HstryManager::handleHstryBufs(bool useSimuData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RingBuffer<uint16_t>* HstryManager::getBuffer(const String& name) {
|
RingBuffer<uint16_t>* HstryBuffers::getBuffer(const String& name) {
|
||||||
auto it = hstryBufs.find(name);
|
auto it = hstryBuffers.find(name);
|
||||||
if (it != hstryBufs.end()) {
|
if (it != hstryBuffers.end()) {
|
||||||
return &it->second->hstry;
|
return &it->second->hstryBuf;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// --- Class HstryBuf ---------------
|
// --- End Class HstryBuffers ---------------
|
||||||
|
|
||||||
// --- Class WindUtils --------------
|
// --- Class WindUtils --------------
|
||||||
double WindUtils::to2PI(double a)
|
double WindUtils::to2PI(double a)
|
||||||
@@ -277,23 +278,24 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate true wind data and add to obp60task boat data list
|
// Calculate true wind data and add to obp60task boat data list
|
||||||
bool WindUtils::addTrueWind(GwApi* api, BoatValueList* boatValues, GwLog* log) {
|
//bool WindUtils::addTrueWind(GwApi* api, GwLog* log) {
|
||||||
|
bool WindUtils::addTrueWind() {
|
||||||
|
|
||||||
GwLog* logger = log;
|
// GwLog* logger = log;
|
||||||
|
|
||||||
double awaVal, awsVal, cogVal, stwVal, sogVal, hdtVal, hdmVal, varVal;
|
// double awaVal, awsVal, cogVal, stwVal, sogVal, hdtVal, hdmVal, varVal;
|
||||||
double twd, tws, twa;
|
double twd, tws, twa;
|
||||||
bool isCalculated = false;
|
bool isCalculated = false;
|
||||||
|
|
||||||
awaVal = awaBVal->valid ? awaBVal->value : DBL_MAX;
|
double awaVal = awaBVal->valid ? awaBVal->value : DBL_MAX;
|
||||||
awsVal = awsBVal->valid ? awsBVal->value : DBL_MAX;
|
double awsVal = awsBVal->valid ? awsBVal->value : DBL_MAX;
|
||||||
cogVal = cogBVal->valid ? cogBVal->value : DBL_MAX;
|
double cogVal = cogBVal->valid ? cogBVal->value : DBL_MAX;
|
||||||
stwVal = stwBVal->valid ? stwBVal->value : DBL_MAX;
|
double stwVal = stwBVal->valid ? stwBVal->value : DBL_MAX;
|
||||||
sogVal = sogBVal->valid ? sogBVal->value : DBL_MAX;
|
double sogVal = sogBVal->valid ? sogBVal->value : DBL_MAX;
|
||||||
hdtVal = hdtBVal->valid ? hdtBVal->value : DBL_MAX;
|
double hdtVal = hdtBVal->valid ? hdtBVal->value : DBL_MAX;
|
||||||
hdmVal = hdmBVal->valid ? hdmBVal->value : DBL_MAX;
|
double hdmVal = hdmBVal->valid ? hdmBVal->value : DBL_MAX;
|
||||||
varVal = varBVal->valid ? varBVal->value : DBL_MAX;
|
double varVal = varBVal->valid ? varBVal->value : DBL_MAX;
|
||||||
LOG_DEBUG(GwLog::DEBUG,"obp60task addTrueWind: AWA %.1f, AWS %.1f, COG %.1f, STW %.1f, SOG %.2f, HDT %.1f, HDM %.1f, VAR %.1f", awaBVal->value * RAD_TO_DEG, awsBVal->value * 3.6 / 1.852,
|
LOG_DEBUG(GwLog::DEBUG,"WindUtils:addTrueWind: AWA %.1f, AWS %.1f, COG %.1f, STW %.1f, SOG %.2f, 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);
|
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 = calcTrueWind(&awaVal, &awsVal, &cogVal, &stwVal, &sogVal, &hdtVal, &hdmVal, &varVal, &twd, &tws, &twa);
|
isCalculated = calcTrueWind(&awaVal, &awsVal, &cogVal, &stwVal, &sogVal, &hdtVal, &hdmVal, &varVal, &twd, &tws, &twa);
|
||||||
@@ -312,9 +314,9 @@ bool WindUtils::addTrueWind(GwApi* api, BoatValueList* boatValues, GwLog* log) {
|
|||||||
twaBVal->valid = true;
|
twaBVal->valid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG(GwLog::DEBUG,"obp60task addTrueWind: isCalculated %d, TWD %.1f, TWA %.1f, TWS %.1f", isCalculated, twdBVal->value * RAD_TO_DEG,
|
LOG_DEBUG(GwLog::DEBUG,"WindUtils: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;
|
||||||
}
|
}
|
||||||
// --- Class WindUtils --------------
|
// --- End Class WindUtils --------------
|
||||||
|
|||||||
@@ -2,36 +2,66 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "OBPRingBuffer.h"
|
#include "OBPRingBuffer.h"
|
||||||
#include "obp60task.h"
|
#include "obp60task.h"
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <limits>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
class HstryBuf {
|
class HstryBuf {
|
||||||
private:
|
private:
|
||||||
GwLog *logger;
|
RingBuffer<uint16_t> hstryBuf; // Circular buffer to store history values
|
||||||
RingBuffer<uint16_t> hstry; // Circular buffer to store history values
|
|
||||||
String boatDataName;
|
String boatDataName;
|
||||||
double hstryMin;
|
double hstryMin;
|
||||||
double hstryMax;
|
double hstryMax;
|
||||||
GwApi::BoatValue *boatValue;
|
GwApi::BoatValue *boatValue;
|
||||||
|
GwLog *logger;
|
||||||
|
|
||||||
friend class HstryManager;
|
friend class HstryBuffers;
|
||||||
void handleHistory(bool useSimuData);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HstryBuf(const String& name, int size, GwLog* log, BoatValueList* boatValues);
|
HstryBuf(const String& name, int size, BoatValueList* boatValues, GwLog* log);
|
||||||
void init(const String& format, int updFreq, int mltplr, double minVal, double maxVal);
|
void init(const String& format, int updFreq, int mltplr, double minVal, double maxVal);
|
||||||
void add(double value);
|
void add(double value);
|
||||||
void handle(bool useSimuData);
|
void handle(bool useSimuData);
|
||||||
};
|
};
|
||||||
|
|
||||||
class HstryManager {
|
class HstryBuffers {
|
||||||
private:
|
private:
|
||||||
std::map<String, std::unique_ptr<HstryBuf>> hstryBufs;
|
std::map<String, std::unique_ptr<HstryBuf>> hstryBuffers;
|
||||||
// boat values for true wind calculation
|
int size; // size of all history buffers
|
||||||
GwApi::BoatValue *awaBVal, *hdtBVal, *hdmBVal, *varBVal, *cogBVal, *sogBVal, *awdBVal;
|
BoatValueList* boatValueList;
|
||||||
|
GwLog* logger;
|
||||||
|
GwApi::BoatValue *awaBVal, *hdtBVal, *hdmBVal, *varBVal, *cogBVal, *sogBVal, *awdBVal; // boat values for true wind calculation
|
||||||
|
|
||||||
|
struct HistoryParams {
|
||||||
|
int hstryUpdFreq;
|
||||||
|
int mltplr;
|
||||||
|
double bufferMinVal;
|
||||||
|
double bufferMaxVal;
|
||||||
|
String format;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define buffer parameters for each boat data type
|
||||||
|
std::map<String, HistoryParams> bufferParams = {
|
||||||
|
{"AWA", {1000, 10000, -M_PI, M_PI, "formatWind"}},
|
||||||
|
{"AWD", {1000, 10000, 0.0, M_TWOPI, "formatCourse"}},
|
||||||
|
{"AWS", {1000, 1000, 0.0, 65.0, "formatKnots"}},
|
||||||
|
{"DBS", {1000, 100, 0.0, 650, "formatDepth"}},
|
||||||
|
{"DBT", {1000, 100, 0.0, 650, "formatDepth"}},
|
||||||
|
{"DPT", {1000, 100, 0.0, 650, "formatDepth"}},
|
||||||
|
{"HDT", {1000, 10000, 0.0, M_TWOPI, "formatCourse"}},
|
||||||
|
{"HDM", {1000, 10000, 0.0, M_TWOPI, "formatCourse"}},
|
||||||
|
{"TWA", {1000, 10000, -M_PI, M_PI, "formatWind"}},
|
||||||
|
{"TWD", {1000, 10000, 0.0, M_TWOPI, "formatCourse"}},
|
||||||
|
{"TWS", {1000, 1000, 0.0, 65.0, "formatKnots"}},
|
||||||
|
{"SOG", {1000, 1000, 0.0, 65.0, "formatKnots"}},
|
||||||
|
{"STW", {1000, 1000, 0.0, 65.0, "formatKnots"}},
|
||||||
|
{"WTemp", {1000, 100, 0.0, 650.0, "kelvinToC"}}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HstryManager(int size, GwLog* log, BoatValueList* boatValues);
|
HstryBuffers(int size, BoatValueList* boatValues, GwLog* log);
|
||||||
|
void addBuffer(const String& name);
|
||||||
void handleHstryBufs(bool useSimuData);
|
void handleHstryBufs(bool useSimuData);
|
||||||
RingBuffer<uint16_t>* getBuffer(const String& name);
|
RingBuffer<uint16_t>* getBuffer(const String& name);
|
||||||
};
|
};
|
||||||
@@ -41,9 +71,11 @@ private:
|
|||||||
GwApi::BoatValue *twdBVal, *twsBVal, *twaBVal;
|
GwApi::BoatValue *twdBVal, *twsBVal, *twaBVal;
|
||||||
GwApi::BoatValue *awaBVal, *awsBVal, *cogBVal, *stwBVal, *sogBVal, *hdtBVal, *hdmBVal, *varBVal;
|
GwApi::BoatValue *awaBVal, *awsBVal, *cogBVal, *stwBVal, *sogBVal, *hdtBVal, *hdmBVal, *varBVal;
|
||||||
static constexpr double DBL_MAX = std::numeric_limits<double>::max();
|
static constexpr double DBL_MAX = std::numeric_limits<double>::max();
|
||||||
|
GwLog* logger;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WindUtils(BoatValueList* boatValues){
|
WindUtils(BoatValueList* boatValues, GwLog* log)
|
||||||
|
: logger(log) {
|
||||||
twdBVal = boatValues->findValueOrCreate("TWD");
|
twdBVal = boatValues->findValueOrCreate("TWD");
|
||||||
twsBVal = boatValues->findValueOrCreate("TWS");
|
twsBVal = boatValues->findValueOrCreate("TWS");
|
||||||
twaBVal = boatValues->findValueOrCreate("TWA");
|
twaBVal = boatValues->findValueOrCreate("TWA");
|
||||||
@@ -73,5 +105,6 @@ public:
|
|||||||
bool calcTrueWind(const double* awaVal, const double* awsVal,
|
bool calcTrueWind(const double* awaVal, const double* awsVal,
|
||||||
const double* cogVal, const double* stwVal, const double* sogVal, const double* hdtVal,
|
const double* cogVal, const double* stwVal, const double* sogVal, const double* hdtVal,
|
||||||
const double* hdmVal, const double* varVal, double* twdVal, double* twsVal, double* twaVal);
|
const double* hdmVal, const double* varVal, double* twdVal, double* twsVal, double* twaVal);
|
||||||
bool addTrueWind(GwApi* api, BoatValueList* boatValues, GwLog *log);
|
// bool addTrueWind(GwApi* api, BoatValueList* boatValues, GwLog *log);
|
||||||
|
bool addTrueWind();
|
||||||
};
|
};
|
||||||
@@ -125,8 +125,10 @@ public:
|
|||||||
|
|
||||||
static RingBuffer<uint16_t>* wdHstry; // Wind direction data buffer
|
static RingBuffer<uint16_t>* wdHstry; // Wind direction data buffer
|
||||||
static RingBuffer<uint16_t>* wsHstry; // Wind speed data buffer
|
static RingBuffer<uint16_t>* wsHstry; // Wind speed data buffer
|
||||||
static String wdName, wdFormat; // Wind direction name and format
|
static RingBuffer<uint16_t>* twdHstry; // Wind direction data buffer for TWD
|
||||||
static String wsName, wsFormat; // Wind speed name and format
|
static RingBuffer<uint16_t>* twsHstry; // Wind speed data buffer for TWS
|
||||||
|
static RingBuffer<uint16_t>* awdHstry; // Wind direction data buffer for AWD
|
||||||
|
static RingBuffer<uint16_t>* awsHstry; // Wind speed data buffer for AWS
|
||||||
|
|
||||||
// Separate chart objects for true wind and apparent wind
|
// Separate chart objects for true wind and apparent wind
|
||||||
static std::unique_ptr<Chart<uint16_t>> twdFlChart, awdFlChart; // chart object for wind direction chart, full size
|
static std::unique_ptr<Chart<uint16_t>> twdFlChart, awdFlChart; // chart object for wind direction chart, full size
|
||||||
@@ -139,8 +141,8 @@ public:
|
|||||||
static Chart<uint16_t>* wdHfChart;
|
static Chart<uint16_t>* wdHfChart;
|
||||||
static Chart<uint16_t>* wsHfChart;
|
static Chart<uint16_t>* wsHfChart;
|
||||||
|
|
||||||
static GwApi::BoatValue* wdBVal = new GwApi::BoatValue("TWD"); // temp BoatValue for wind direction unit identification; required by OBP60Formater
|
static GwApi::BoatValue* wdBVal; // BoatValue for wind direction
|
||||||
static GwApi::BoatValue* wsBVal = new GwApi::BoatValue("TWS"); // temp BoatValue for wind speed unit identification; required by OBP60Formater */
|
static GwApi::BoatValue* wsBVal; // BoatValue for wind speed
|
||||||
double dfltRngWd = 60.0 * DEG_TO_RAD; // default range for course chart from min to max value in RAD
|
double dfltRngWd = 60.0 * DEG_TO_RAD; // default range for course chart from min to max value in RAD
|
||||||
double dfltRngWs = 7.5; // default range for wind speed chart from min to max value in m/s
|
double dfltRngWs = 7.5; // default range for wind speed chart from min to max value in m/s
|
||||||
|
|
||||||
@@ -163,24 +165,20 @@ public:
|
|||||||
|
|
||||||
if (showTruW != oldShowTruW) {
|
if (showTruW != oldShowTruW) {
|
||||||
if (!twdFlChart) { // Create true wind charts if they don't exist
|
if (!twdFlChart) { // Create true wind charts if they don't exist
|
||||||
|
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot: Creating true wind charts");
|
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot: Creating true wind charts");
|
||||||
auto* twdHstry = pageData.hstryManager->getBuffer("TWD");
|
twdHstry = pageData.hstryBuffers->getBuffer("TWD");
|
||||||
auto* twsHstry = pageData.hstryManager->getBuffer("TWS");
|
twsHstry = pageData.hstryBuffers->getBuffer("TWS");
|
||||||
|
|
||||||
twdFlChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*twdHstry, 'V', 0, dfltRngWd, *commonData, useSimuData));
|
twdFlChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*twdHstry, 'V', 0, dfltRngWd, *commonData, useSimuData));
|
||||||
twsFlChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*twsHstry, 'H', 0, dfltRngWs, *commonData, useSimuData));
|
twsFlChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*twsHstry, 'H', 0, dfltRngWs, *commonData, useSimuData));
|
||||||
twdHfChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*twdHstry, 'V', 1, dfltRngWd, *commonData, useSimuData));
|
twdHfChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*twdHstry, 'V', 1, dfltRngWd, *commonData, useSimuData));
|
||||||
twsHfChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*twsHstry, 'V', 2, dfltRngWs, *commonData, useSimuData));
|
twsHfChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*twsHstry, 'V', 2, dfltRngWs, *commonData, useSimuData));
|
||||||
// twdHfChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*twdHstry, 'H', 1, dfltRngWd, *commonData, useSimuData));
|
|
||||||
// twsHfChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*twsHstry, 'H', 2, dfltRngWs, *commonData, useSimuData));
|
|
||||||
// LOG_DEBUG(GwLog::DEBUG, "PageWindPlot: twdHstry: %p, twsHstry: %p", (void*)twdHstry, (void*)twsHstry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!awdFlChart) { // Create apparent wind charts if they don't exist
|
if (!awdFlChart) { // Create apparent wind charts if they don't exist
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot: Creating apparent wind charts");
|
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot: Creating apparent wind charts");
|
||||||
auto* awdHstry = pageData.hstryManager->getBuffer("AWD");
|
awdHstry = pageData.hstryBuffers->getBuffer("AWD");
|
||||||
auto* awsHstry = pageData.hstryManager->getBuffer("AWS");
|
awsHstry = pageData.hstryBuffers->getBuffer("AWS");
|
||||||
|
|
||||||
awdFlChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*awdHstry, 'V', 0, dfltRngWd, *commonData, useSimuData));
|
awdFlChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*awdHstry, 'V', 0, dfltRngWd, *commonData, useSimuData));
|
||||||
awsFlChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*awsHstry, 'H', 0, dfltRngWs, *commonData, useSimuData));
|
awsFlChart = std::unique_ptr<Chart<uint16_t>>(new Chart<uint16_t>(*awsHstry, 'H', 0, dfltRngWs, *commonData, useSimuData));
|
||||||
@@ -190,24 +188,25 @@ public:
|
|||||||
|
|
||||||
// Switch active charts based on showTruW
|
// Switch active charts based on showTruW
|
||||||
if (showTruW) {
|
if (showTruW) {
|
||||||
wdHstry = pageData.hstryManager->getBuffer("TWD");
|
wdHstry = twdHstry;
|
||||||
wsHstry = pageData.hstryManager->getBuffer("TWS");
|
wsHstry = twsHstry;
|
||||||
wdFlChart = twdFlChart.get();
|
wdFlChart = twdFlChart.get();
|
||||||
wsFlChart = twsFlChart.get();
|
wsFlChart = twsFlChart.get();
|
||||||
wdHfChart = twdHfChart.get();
|
wdHfChart = twdHfChart.get();
|
||||||
wsHfChart = twsHfChart.get();
|
wsHfChart = twsHfChart.get();
|
||||||
|
wdBVal = bvalue[0];
|
||||||
|
wsBVal = bvalue[1];
|
||||||
} else {
|
} else {
|
||||||
wdHstry = pageData.hstryManager->getBuffer("AWD");
|
wdHstry = awdHstry;
|
||||||
wsHstry = pageData.hstryManager->getBuffer("AWS");
|
wsHstry = awsHstry;
|
||||||
wdFlChart = awdFlChart.get();
|
wdFlChart = awdFlChart.get();
|
||||||
wsFlChart = awsFlChart.get();
|
wsFlChart = awsFlChart.get();
|
||||||
wdHfChart = awdHfChart.get();
|
wdHfChart = awdHfChart.get();
|
||||||
wsHfChart = awsHfChart.get();
|
wsHfChart = awsHfChart.get();
|
||||||
|
wdBVal = bvalue[2];
|
||||||
|
wsBVal = bvalue[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
wdHstry->getMetaData(wdName, wdFormat);
|
|
||||||
wsHstry->getMetaData(wsName, wsFormat);
|
|
||||||
|
|
||||||
oldShowTruW = showTruW;
|
oldShowTruW = showTruW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,27 +218,17 @@ public:
|
|||||||
getdisplay().setTextColor(commonData->fgcolor);
|
getdisplay().setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
if (chrtMode == 'D') {
|
if (chrtMode == 'D') {
|
||||||
wdBVal->value = wdHstry->getLast();
|
wdFlChart->showChrt(dataIntv, *wdBVal);
|
||||||
wdBVal->valid = wdBVal->value != wdHstry->getMaxVal();
|
|
||||||
wdFlChart->showChrt(dataIntv, *bvalue[0]);
|
|
||||||
|
|
||||||
} else if (chrtMode == 'S') {
|
} else if (chrtMode == 'S') {
|
||||||
wsBVal->value = wsHstry->getLast();
|
wsFlChart->showChrt(dataIntv, *wsBVal);
|
||||||
wsBVal->valid = wsBVal->value != wsHstry->getMaxVal();
|
|
||||||
wsFlChart->showChrt(dataIntv, *bvalue[1]);
|
|
||||||
|
|
||||||
} else if (chrtMode == 'B') {
|
} else if (chrtMode == 'B') {
|
||||||
wdBVal->value = wdHstry->getLast();
|
wdHfChart->showChrt(dataIntv, *wdBVal);
|
||||||
wdBVal->valid = wdBVal->value != wdHstry->getMaxVal();
|
wsHfChart->showChrt(dataIntv, *wsBVal);
|
||||||
wsBVal->value = wsHstry->getLast();
|
|
||||||
wsBVal->valid = wsBVal->value != wsHstry->getMaxVal();
|
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot showChrt: wsBVal.name: %s, format: %s, wsBVal.value: %.1f, valid: %d, address: %p", wsBVal->getName(), wsBVal->getFormat(), wsBVal->value,
|
|
||||||
wsBVal->valid, wsBVal);
|
|
||||||
wdHfChart->showChrt(dataIntv, *bvalue[0]);
|
|
||||||
wsHfChart->showChrt(dataIntv, *bvalue[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG(GwLog::LOG, "PageWindPlot: page time %ldms", millis() - pageTime);
|
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot: page time %ldms", millis() - pageTime);
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ typedef struct{
|
|||||||
uint8_t pageNumber; // page number in sequence of visible pages
|
uint8_t pageNumber; // page number in sequence of visible pages
|
||||||
//the values will always contain the user defined values first
|
//the values will always contain the user defined values first
|
||||||
ValueList values;
|
ValueList values;
|
||||||
HstryManager* hstryManager;
|
HstryBuffers* hstryBuffers; // list of all boat history buffers
|
||||||
} PageData;
|
} PageData;
|
||||||
|
|
||||||
// Sensor data structure (only for extended sensors, not for NMEA bus sensors)
|
// Sensor data structure (only for extended sensors, not for NMEA bus sensors)
|
||||||
|
|||||||
@@ -433,8 +433,8 @@ void OBP60Task(GwApi *api){
|
|||||||
int lastPage=pageNumber;
|
int lastPage=pageNumber;
|
||||||
|
|
||||||
BoatValueList boatValues; //all the boat values for the api query
|
BoatValueList boatValues; //all the boat values for the api query
|
||||||
HstryManager hstryManager(1920, logger, &boatValues); // Create and manage history buffers
|
HstryBuffers hstryBufList(1920, &boatValues, logger); // Create empty list of boat data history buffers
|
||||||
WindUtils trueWind(&boatValues); // Create helper object for true wind calculation
|
WindUtils trueWind(&boatValues, logger); // Create helper object for true wind calculation
|
||||||
//commonData.distanceformat=config->getString(xxx);
|
//commonData.distanceformat=config->getString(xxx);
|
||||||
//add all necessary data to common data
|
//add all necessary data to common data
|
||||||
|
|
||||||
@@ -477,9 +477,18 @@ void OBP60Task(GwApi *api){
|
|||||||
LOG_DEBUG(GwLog::DEBUG,"added fixed value %s to page %d",value->getName().c_str(),i);
|
LOG_DEBUG(GwLog::DEBUG,"added fixed value %s to page %d",value->getName().c_str(),i);
|
||||||
pages[i].parameters.values.push_back(value);
|
pages[i].parameters.values.push_back(value);
|
||||||
}
|
}
|
||||||
// Add history manager to page parameters
|
|
||||||
pages[i].parameters.hstryManager = &hstryManager;
|
// Read the specified boat data type of relevant pages and create a history buffer for each type
|
||||||
|
if (pages[i].parameters.pageName == "OneValue" || pages[i].parameters.pageName == "TwoValues" || pages[i].parameters.pageName == "WindPlot") {
|
||||||
|
for (auto pVal : pages[i].parameters.values) {
|
||||||
|
hstryBufList.addBuffer(pVal->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add list of history buffers to page parameters
|
||||||
|
pages[i].parameters.hstryBuffers = &hstryBufList;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add out of band system page (always available)
|
// add out of band system page (always available)
|
||||||
Page *syspage = allPages.pages[0]->creator(commonData);
|
Page *syspage = allPages.pages[0]->creator(commonData);
|
||||||
|
|
||||||
@@ -487,7 +496,6 @@ void OBP60Task(GwApi *api){
|
|||||||
bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false);
|
bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false);
|
||||||
bool useSimuData = api->getConfig()->getBool(api->getConfig()->useSimuData, false);
|
bool useSimuData = api->getConfig()->getBool(api->getConfig()->useSimuData, false);
|
||||||
|
|
||||||
// Initialize history buffer for certain boat data
|
|
||||||
// Read all calibration data settings from config
|
// Read all calibration data settings from config
|
||||||
calibrationData.readConfig(config, logger);
|
calibrationData.readConfig(config, logger);
|
||||||
|
|
||||||
@@ -804,10 +812,10 @@ void OBP60Task(GwApi *api){
|
|||||||
api->getStatus(commonData.status);
|
api->getStatus(commonData.status);
|
||||||
|
|
||||||
if (calcTrueWnds) {
|
if (calcTrueWnds) {
|
||||||
trueWind.addTrueWind(api, &boatValues, logger);
|
trueWind.addTrueWind();
|
||||||
}
|
}
|
||||||
// Handle history buffers for certain boat data for windplot page and other usage
|
// Handle history buffers for certain boat data for windplot page and other usage
|
||||||
hstryManager.handleHstryBufs(useSimuData);
|
hstryBufList.handleHstryBufs(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);
|
||||||
|
|||||||
Reference in New Issue
Block a user