mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2026-09-11 19:55:14 +02:00
Add option to either store native data or averaged data (for chart smootihing) in history buffer
This commit is contained in:
@@ -107,7 +107,6 @@ void CalibrationData::readConfig(GwConfigHandler* config)
|
|||||||
LOG_DEBUG(GwLog::LOG, "Calibration data type added: %s, offset: %f, slope: %f, smoothing: %f", instance.c_str(),
|
LOG_DEBUG(GwLog::LOG, "Calibration data type added: %s, offset: %f, slope: %f, smoothing: %f", instance.c_str(),
|
||||||
calibrationMap[instance].offset, calibrationMap[instance].slope, calibrationMap[instance].smooth);
|
calibrationMap[instance].offset, calibrationMap[instance].slope, calibrationMap[instance].smooth);
|
||||||
}
|
}
|
||||||
// LOG_DEBUG(GwLog::LOG, "All calibration data read");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle calibrationMap and calibrate all boat data values
|
// Handle calibrationMap and calibrate all boat data values
|
||||||
@@ -208,15 +207,14 @@ bool CalibrationData::smoothInstance(GwApi::BoatValue* boatDataValue)
|
|||||||
calibrationMap[instance].value = dataValue; // store the smoothed value in the list
|
calibrationMap[instance].value = dataValue; // store the smoothed value in the list
|
||||||
calibrationMap[instance].isCalibrated = true;
|
calibrationMap[instance].isCalibrated = true;
|
||||||
|
|
||||||
// LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: smooth: %f, oldValue: %f, result: %f", instance.c_str(), smoothFactor, oldValue, calibrationMap[instance].value);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// --- End Class CalibrationData ---------------
|
// --- End Class CalibrationData ---------------
|
||||||
|
|
||||||
// --- Class HstryBuf ---------------
|
// --- Class HstryBuf ---------------
|
||||||
HstryBuf::HstryBuf(const String& name, int size, BoatValueList* boatValues, GwLog* log)
|
HstryBuf::HstryBuf(const String& name, const int size, BoatValueList* boatValues, const bool smooth, GwLog* log)
|
||||||
: logger(log)
|
: logger(log)
|
||||||
|
, smoothing(smooth)
|
||||||
, boatDataName(name)
|
, boatDataName(name)
|
||||||
{
|
{
|
||||||
hstryBuf.resize(size);
|
hstryBuf.resize(size);
|
||||||
@@ -232,23 +230,42 @@ void HstryBuf::init(const String& format, int updFreq, double mltplr, double min
|
|||||||
if (!boatValue->valid) {
|
if (!boatValue->valid) {
|
||||||
boatValue->value = std::numeric_limits<double>::max(); // mark current value invalid
|
boatValue->value = std::numeric_limits<double>::max(); // mark current value invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isTypeAngle = format == "formatCourse" || format == "formatWind" || format == "formatRot";
|
||||||
|
// initialize correct variant of buffer for averaging history data
|
||||||
|
if (smoothing) {
|
||||||
|
if (isTypeAngle) {
|
||||||
|
chrtAvgAngle.begin();
|
||||||
|
} else {
|
||||||
|
chrtAvg.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HstryBuf::add(double value)
|
void HstryBuf::add(const double value)
|
||||||
{
|
{
|
||||||
|
double bufVal = value;
|
||||||
|
|
||||||
if (value >= hstryMin && value <= hstryMax) {
|
if (value >= hstryMin && value <= hstryMax) {
|
||||||
hstryBuf.add(value);
|
|
||||||
|
if (smoothing) {
|
||||||
|
if (isTypeAngle) {
|
||||||
|
bufVal = chrtAvgAngle.reading(value);
|
||||||
|
} else {
|
||||||
|
bufVal = chrtAvg.reading(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hstryBuf.add(bufVal);
|
||||||
// LOG_DEBUG(GwLog::DEBUG, "HstryBuf::add: name: %s, value: %.3f, value buffer: %.3f", hstryBuf.getName(), value, hstryBuf.getLast());
|
// LOG_DEBUG(GwLog::DEBUG, "HstryBuf::add: name: %s, value: %.3f, value buffer: %.3f", hstryBuf.getName(), value, hstryBuf.getLast());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HstryBuf::handle(bool useSimuData, CommonData& common)
|
void HstryBuf::handle(const bool useSimuData, CommonData& common)
|
||||||
{
|
{
|
||||||
if ((millis() - bufUpdateTime) >= hstryBuf.getUpdFreq()) {
|
if ((millis() - bufUpdateTime) >= hstryBuf.getUpdFreq()) {
|
||||||
|
|
||||||
bufUpdateTime = millis();
|
bufUpdateTime = millis();
|
||||||
// LOG_DEBUG(GwLog::DEBUG, "HstryBuf::handle: name: %s, frequency: %d, format: %s, value: %.3f", hstryBuf.getName(), hstryBuf.getUpdFreq(),
|
|
||||||
// boatValue->getFormat().c_str(), boatValue->value);
|
|
||||||
|
|
||||||
if (boatValue->valid) {
|
if (boatValue->valid) {
|
||||||
add(boatValue->value);
|
add(boatValue->value);
|
||||||
@@ -262,20 +279,20 @@ void HstryBuf::handle(bool useSimuData, CommonData& common)
|
|||||||
double simSIValue = formatValue(tmpBVal.get(), common).value; // simulated value is generated at <formatValue>; here: retreive SI value
|
double simSIValue = formatValue(tmpBVal.get(), common).value; // simulated value is generated at <formatValue>; here: retreive SI value
|
||||||
add(simSIValue);
|
add(simSIValue);
|
||||||
} else {
|
} else {
|
||||||
// here we will add invalid (DBL_MAX) value; this will mark periods of missing data in buffer together with a timestamp
|
// TODO: add invalid (DBL_MAX) value; this will mark periods of missing data in buffer together with a timestamp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// --- End Class HstryBuf ---------------
|
// --- End Class HstryBuf ---------------
|
||||||
|
|
||||||
// --- Class HstryBuffers ---------------
|
// --- Class HstryBuffers ---------------
|
||||||
HstryBuffers::HstryBuffers(int size, BoatValueList* boatValues, GwLog* log)
|
HstryBuffers::HstryBuffers(const int size, BoatValueList* boatValues, GwLog* log)
|
||||||
: size(size)
|
: size(size)
|
||||||
, boatValueList(boatValues)
|
, boatValueList(boatValues)
|
||||||
, logger(log) { };
|
, logger(log) { };
|
||||||
|
|
||||||
// Create history buffer for boat data type
|
// Create history buffer for boat data type
|
||||||
void HstryBuffers::addBuffer(const String& name)
|
void HstryBuffers::addBuffer(const String& name, const bool smooth)
|
||||||
{
|
{
|
||||||
if (HstryBuffers::getBuffer(name) != nullptr) { // buffer for this data type already exists
|
if (HstryBuffers::getBuffer(name) != nullptr) { // buffer for this data type already exists
|
||||||
return;
|
return;
|
||||||
@@ -288,8 +305,9 @@ void HstryBuffers::addBuffer(const String& name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create buffer only; initialization with metadata can only be done later after boat data have been updated first time
|
// create buffer only; initialization with metadata can only be done later after boat data have been updated first time
|
||||||
hstryBuffers[name] = std::unique_ptr<HstryBuf>(new HstryBuf(name, size, boatValueList, logger));
|
hstryBuffers[name] = std::unique_ptr<HstryBuf>(new HstryBuf(name, size, boatValueList, smooth, logger));
|
||||||
LOG_DEBUG(GwLog::DEBUG, "HstryBuffers: new buffer added: name: %s", name);
|
|
||||||
|
LOG_DEBUG(GwLog::LOG, "HstryBuffers: new buffer added: name: %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle all registered history buffers
|
// Handle all registered history buffers
|
||||||
@@ -301,7 +319,7 @@ void HstryBuffers::handleHstryBufs(bool useSimuData, CommonData& common)
|
|||||||
if (!buf->hasMetaData()) { // meta data initialization for buffer has not been done before
|
if (!buf->hasMetaData()) { // meta data initialization for buffer has not been done before
|
||||||
|
|
||||||
String valueFormat = boatValueList->findValueOrCreate(buf->boatDataName)->getFormat().c_str();
|
String valueFormat = boatValueList->findValueOrCreate(buf->boatDataName)->getFormat().c_str();
|
||||||
LOG_DEBUG(GwLog::DEBUG, "HstryBuffers: value name: %s, format: %s", boatValueList->findValueOrCreate(buf->boatDataName)->getName().c_str(), valueFormat);
|
// LOG_DEBUG(GwLog::DEBUG, "HstryBuffers: value name: %s, format: %s", boatValueList->findValueOrCreate(buf->boatDataName)->getName().c_str(), valueFormat);
|
||||||
|
|
||||||
if (!valueFormat.isEmpty()) {
|
if (!valueFormat.isEmpty()) {
|
||||||
String lookupKey = buf->boatDataName;
|
String lookupKey = buf->boatDataName;
|
||||||
@@ -321,7 +339,7 @@ void HstryBuffers::handleHstryBufs(bool useSimuData, CommonData& common)
|
|||||||
|
|
||||||
hstryBuffers[buf->boatDataName]->init(valueFormat, hstryUpdFreq, mltplr, bufferMinVal, bufferMaxVal);
|
hstryBuffers[buf->boatDataName]->init(valueFormat, hstryUpdFreq, mltplr, bufferMinVal, bufferMaxVal);
|
||||||
buf->metaDataDefined = true;
|
buf->metaDataDefined = true;
|
||||||
LOG_DEBUG(GwLog::DEBUG, "HstryBuffers::handleBufs: metadata added: name: %s, format: %s, frequency: %d, multiplier: %f, min value: %.2f, max value: %.2f", buf->boatDataName, valueFormat, hstryUpdFreq,
|
LOG_DEBUG(GwLog::LOG, "HstryBuffers::handleBufs: metadata added: name: %s, format: %s, frequency: %d, multiplier: %f, min value: %.2f, max value: %.2f", buf->boatDataName, valueFormat, hstryUpdFreq,
|
||||||
mltplr, bufferMinVal, bufferMaxVal);
|
mltplr, bufferMinVal, bufferMaxVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,8 +451,6 @@ bool WindUtils::calcHDT(const double* hdmVal, const double* varVal, const double
|
|||||||
*hdtVal = DBL_MAX; // Cannot calculate HDT without valid HDM or HDM+VAR or COG
|
*hdtVal = DBL_MAX; // Cannot calculate HDT without valid HDM or HDM+VAR or COG
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// LOG_DEBUG(GwLog::DEBUG, "WindUtils:calcHDT: HDT: %.1f, HDM %.1f, VAR %.1f, COG %.1f, SOG %.1f", *hdtVal * RAD_TO_DEG, *hdmVal * RAD_TO_DEG, *varVal * RAD_TO_DEG,
|
|
||||||
// *cogVal * RAD_TO_DEG, *sogVal * 3.6 / 1.852);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -482,7 +498,6 @@ bool WindUtils::calcTrueWinds(const double* awaVal, const double* awsVal, const
|
|||||||
// 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;
|
||||||
}
|
}
|
||||||
// LOG_DEBUG(GwLog::DEBUG, "WindUtils:calcTrueWinds: HDT: %.1f, CTW %.1f, STW %.1f", *hdtVal * RAD_TO_DEG, ctw * RAD_TO_DEG, stw * 3.6 / 1.852);
|
|
||||||
|
|
||||||
calcTwdSA(awaVal, awsVal, awd, &ctw, &stw, hdtVal, &twa, &tws, &twd);
|
calcTwdSA(awaVal, awsVal, awd, &ctw, &stw, hdtVal, &twa, &tws, &twd);
|
||||||
*twaVal = twa;
|
*twaVal = twa;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "OBPRingBuffer.h"
|
#include "OBPRingBuffer.h"
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "obp60task.h"
|
#include "obp60task.h"
|
||||||
|
#include "movingAvg.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@@ -36,10 +37,14 @@ public:
|
|||||||
class HstryBuf {
|
class HstryBuf {
|
||||||
private:
|
private:
|
||||||
RingBuffer<uint16_t> hstryBuf; // Circular buffer to store history values
|
RingBuffer<uint16_t> hstryBuf; // Circular buffer to store history values
|
||||||
|
movingAvg<double> chrtAvg {6}; // Store average of the last 6 chart values if chart gradient shall be smoothed
|
||||||
|
movingAvgAngle<double> chrtAvgAngle {6}; // Store average of the last 6 chart values (angle data) if chart gradient shall be smoothed
|
||||||
String boatDataName;
|
String boatDataName;
|
||||||
double hstryMin;
|
double hstryMin;
|
||||||
double hstryMax;
|
double hstryMax;
|
||||||
bool metaDataDefined = false;
|
bool metaDataDefined = false;
|
||||||
|
bool smoothing = false;
|
||||||
|
bool isTypeAngle = false;
|
||||||
unsigned long bufUpdateTime;
|
unsigned long bufUpdateTime;
|
||||||
GwApi::BoatValue* boatValue;
|
GwApi::BoatValue* boatValue;
|
||||||
GwLog* logger;
|
GwLog* logger;
|
||||||
@@ -47,7 +52,7 @@ private:
|
|||||||
friend class HstryBuffers;
|
friend class HstryBuffers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HstryBuf(const String& name, int size, BoatValueList* boatValues, GwLog* log);
|
HstryBuf(const String& name, const int size, BoatValueList* boatValues, const bool smooth, GwLog* log);
|
||||||
bool hasMetaData() const { return metaDataDefined; };
|
bool hasMetaData() const { return metaDataDefined; };
|
||||||
void init(const String& format, int updFreq, double mltplr, double minVal, double maxVal);
|
void init(const String& format, int updFreq, double mltplr, double minVal, double maxVal);
|
||||||
void add(double value);
|
void add(double value);
|
||||||
@@ -101,7 +106,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
HstryBuffers(int size, BoatValueList* boatValues, GwLog* log);
|
HstryBuffers(int size, BoatValueList* boatValues, GwLog* log);
|
||||||
void addBuffer(const String& name);
|
void addBuffer(const String& name, const bool smooth);
|
||||||
void handleHstryBufs(bool useSimuData, CommonData& common);
|
void handleHstryBufs(bool useSimuData, CommonData& common);
|
||||||
RingBuffer<uint16_t>* getBuffer(const String& name);
|
RingBuffer<uint16_t>* getBuffer(const String& name);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user