Add late initialization for chart objects

This commit is contained in:
Ulrich Meine
2026-07-01 02:16:40 +02:00
parent a2822451c1
commit 3dd7f4751a
3 changed files with 67 additions and 52 deletions
+39 -33
View File
@@ -3,17 +3,6 @@
#include "OBPDataOperations.h" #include "OBPDataOperations.h"
#include "OBPRingBuffer.h" #include "OBPRingBuffer.h"
// Default ranges for various boat data types: 1st value default range, 2nd value step for range adjustment
// should be multiple of 4 for full integer chart labels w/o decimals
std::map<String, ChartProps> Chart::dfltChrtDta = {
{ "formatWind", { 60.0 * DEG_TO_RAD, 10.0 * DEG_TO_RAD } }, // default wind range 60 degrees
{ "formatCourse", { 60.0 * DEG_TO_RAD, 10.0 * DEG_TO_RAD } }, // default course range 60 degrees
{ "formatKnots", { 2.572, 2.572 } }, // default speed range in m/s
{ "formatDepth", { 10.0, 5.0 } }, // default depth range in m
{ "kelvinToC", { 20.0, 5.0 } }, // default temp range in °C/K
{ "formatXdr:P:P", { 4000.0, 1000.0 } } // default pressure range in Pascal (hPa * 100); XDR <B> (bar) format is represented in gateway in the same way
};
// --- Class Chart --------------- // --- Class Chart ---------------
// Chart - object holding the actual chart, incl. data buffer and format definition // Chart - object holding the actual chart, incl. data buffer and format definition
@@ -21,9 +10,8 @@ std::map<String, ChartProps> Chart::dfltChrtDta = {
// <dfltRng> default range of chart, e.g. 30 = [0..30] // <dfltRng> default range of chart, e.g. 30 = [0..30]
// <common> common program data; required for logger and color data // <common> common program data; required for logger and color data
// <useSimuData> flag to indicate if simulation data is active // <useSimuData> flag to indicate if simulation data is active
Chart::Chart(RingBuffer<uint16_t>& dataBuf, double dfltRng, CommonData& common, bool useSimuData) Chart::Chart(RingBuffer<uint16_t>& dataBuf, CommonData& common, bool useSimuData)
: dataBuf(dataBuf) : dataBuf(dataBuf)
, dfltRng(dfltRng)
, commonData(&common) , commonData(&common)
, useSimuData(useSimuData) , useSimuData(useSimuData)
{ {
@@ -40,17 +28,31 @@ Chart::Chart(RingBuffer<uint16_t>& dataBuf, double dfltRng, CommonData& common,
dHeight = getdisplay().height(); dHeight = getdisplay().height();
#endif #endif
smoothCharts = commonData->config->getBool(commonData->config->smoothCharts);
if (smoothCharts) {
chrtAvg.begin();
}
init();
};
Chart::~Chart()
{
}
bool Chart::init()
{
chrtMin = 0.0;
chrtMax = 0.0;
chrtMid = 0.0;
chrtRng = 0.0;
dataBuf.getMetaData(dbName, dbFormat); dataBuf.getMetaData(dbName, dbFormat);
dbMIN_VAL = dataBuf.getMinVal(); dbMIN_VAL = dataBuf.getMinVal();
dbMAX_VAL = dataBuf.getMaxVal(); dbMAX_VAL = dataBuf.getMaxVal();
bufSize = dataBuf.getCapacity(); bufSize = dataBuf.getCapacity();
LOG_DEBUG(GwLog::DEBUG, "Chart Init: dbMIN_VAL: %.2f, dbMAX_VAL: %.2fd, bufSize: %d", dbMIN_VAL, dbMAX_VAL, bufSize); LOG_DEBUG(GwLog::DEBUG, "Chart Init: dbMIN_VAL: %.2f, dbMAX_VAL: %.2fd, bufSize: %d", dbMIN_VAL, dbMAX_VAL, bufSize);
smoothCharts = common.config->getBool(common.config->smoothCharts);
if (smoothCharts) {
chrtAvg.begin();
}
// Initialize chart data format; shorter version of standard format indicator // Initialize chart data format; shorter version of standard format indicator
if (dbFormat == "formatCourse" || dbFormat == "formatWind") { if (dbFormat == "formatCourse" || dbFormat == "formatWind") {
chrtDataFmt = WIND; // Chart is showing data of course / wind <degree> format chrtDataFmt = WIND; // Chart is showing data of course / wind <degree> format
@@ -97,14 +99,18 @@ Chart::Chart(RingBuffer<uint16_t>& dataBuf, double dfltRng, CommonData& common,
chrtMax = chrtMin + dfltRng; chrtMax = chrtMin + dfltRng;
chrtMid = (chrtMin + chrtMax) / 2; chrtMid = (chrtMin + chrtMax) / 2;
chrtRng = dfltRng; chrtRng = dfltRng;
recalcRngMid = true; // initialize <chrtMid> and chart borders on first screen call recalcRngMid = true; // initialize <chrtMid> and chart borders on first chart display call
LOG_DEBUG(GwLog::DEBUG, "Chart Init: dWidth: %d, dHeight: %d, timAxis: %d, valAxis: %d, cRoot {x,y}: %d, %d, dbname: %s, rngStep: %.4f, chrtDataFmt: %d", if (dbFormat.isEmpty()) {
dWidth, dHeight, timAxis, valAxis, cRoot.x, cRoot.y, dbName, rngStep, chrtDataFmt); // data buffer may not exist yet, because boat data object is not available yet
}; initValid = false; // chart object will get invalid data during initialization
} else {
initValid = true;
}
LOG_DEBUG(GwLog::DEBUG, "Chart Init: dWidth: %d, dHeight: %d, timAxis: %d, valAxis: %d, cRoot {x,y}: %d, %d, dbname: %s, rngStep: %.4f, chrtDataFmt: %d, initValid: %d",
dWidth, dHeight, timAxis, valAxis, cRoot.x, cRoot.y, dbName, rngStep, chrtDataFmt, initValid);
Chart::~Chart() return isValid();
{
} }
// Perform all actions to draw chart // Perform all actions to draw chart
@@ -325,8 +331,15 @@ void Chart::calcChrtBorders(double& rngMin, double& rngMid, double& rngMax, doub
double currMinVal = dataBuf.getMin(numBufVals); double currMinVal = dataBuf.getMin(numBufVals);
double currMaxVal = dataBuf.getMax(numBufVals); double currMaxVal = dataBuf.getMax(numBufVals);
if (currMinVal == dbMAX_VAL || currMaxVal == dbMAX_VAL) { if (currMinVal == dbMAX_VAL || currMaxVal == dbMAX_VAL) { // no valid data
// return; // no valid data auto chkIsNaN = [](double& val) { if (std::isnan(val)) val = 0.0; }; // define inline function
// range values can be undefined if boat data type has not been created at time of chart printing (e.g. XDR data types)
// we set them to "0.0" then
chkIsNaN(rngMin);
chkIsNaN(rngMid);
chkIsNaN(rngMax);
chkIsNaN(rng);
return;
} }
// check if current chart border have to be adjusted // check if current chart border have to be adjusted
@@ -350,13 +363,6 @@ void Chart::calcChrtBorders(double& rngMin, double& rngMid, double& rngMax, doub
rngMid = (rngMin + rngMax) / 2.0; rngMid = (rngMin + rngMax) / 2.0;
rng = rngMax - rngMin; rng = rngMax - rngMin;
// range values can be undefined if boat data type has not been created at time of chart printing (e.g. XDR data types)
auto chkIsNaN = [](double& val) { if (std::isnan(val)) val = 0.0; };
chkIsNaN(rngMin);
chkIsNaN(rngMid);
chkIsNaN(rngMax);
chkIsNaN(rng);
LOG_DEBUG(GwLog::DEBUG, "calcChrtRange-end: currMinVal: %.1f, currMaxVal: %.1f, rngMin: %.1f, rngMid: %.1f, rngMax: %.1f, rng: %.1f, rngStep: %.1f, zeroValue: %.1f, dbMIN_VAL: %.1f", LOG_DEBUG(GwLog::DEBUG, "calcChrtRange-end: currMinVal: %.1f, currMaxVal: %.1f, rngMin: %.1f, rngMid: %.1f, rngMax: %.1f, rng: %.1f, rngStep: %.1f, zeroValue: %.1f, dbMIN_VAL: %.1f",
currMinVal, currMaxVal, rngMin, rngMid, rngMax, rng, rngStep, zeroValue, dbMIN_VAL); currMinVal, currMaxVal, rngMin, rngMid, rngMax, rng, rngStep, zeroValue, dbMIN_VAL);
} }
+18 -8
View File
@@ -20,8 +20,7 @@ class GwLog;
class Chart { class Chart {
public: public:
/* enum class ChrtDirection {
/* enum class ChrtDirection {
HORIZONTALE, HORIZONTALE,
VERTICALE VERTICALE
}; };
@@ -33,13 +32,12 @@ public:
TWO_THIRD_TOPE TWO_THIRD_TOPE
}; */ }; */
// Define default chart range and range step for each boat data type Chart(RingBuffer<uint16_t>& dataBuf, CommonData& common, bool useSimuData); // Chart object of data chart
static std::map<String, ChartProps> dfltChrtDta;
Chart(RingBuffer<uint16_t>& dataBuf, double dfltRng, CommonData& common, bool useSimuData); // Chart object of data chart
~Chart(); ~Chart();
bool init(); // initialize chart object parameters
bool isValid() { return initValid; }; // Checks if chart object has been fully initialized
void showChrt(const char chrtDir, const int8_t chrtSz, const int8_t chrtIntv, bool prntName, bool showCurrValue, GwApi::BoatValue currValue); // Perform all actions to draw chart void showChrt(const char chrtDir, const int8_t chrtSz, const int8_t chrtIntv, bool prntName, bool showCurrValue, GwApi::BoatValue currValue); // Perform all actions to draw chart
// void showChrt(ChrtDirection chrtDir, ChrtSize chrtSz, const int8_t chrtIntv, bool prntName, bool showCurrValue, GwApi::BoatValue currValue); // Perform all actions to draw chart // void showChrt(ChrtDirection chrtDir, ChrtSize chrtSz, const int8_t chrtIntv, bool prntName, bool showCurrValue, GwApi::BoatValue currValue); // Perform all actions to draw chart
protected: protected:
CommonData* commonData; CommonData* commonData;
@@ -69,6 +67,7 @@ protected:
static constexpr bool NO_SIMUDATA = true; // switch off simulation feature of <formatValue> function static constexpr bool NO_SIMUDATA = true; // switch off simulation feature of <formatValue> function
RingBuffer<uint16_t>& dataBuf; // Buffer to display RingBuffer<uint16_t>& dataBuf; // Buffer to display
bool initValid = false; // indicates whether object holds valid initialization data or not
double dfltRng; // Default range of chart, e.g. 30 = [0..30] double dfltRng; // Default range of chart, e.g. 30 = [0..30]
uint16_t fgColor; // color code for any screen writing uint16_t fgColor; // color code for any screen writing
uint16_t bgColor; // color code for screen background uint16_t bgColor; // color code for screen background
@@ -113,8 +112,19 @@ protected:
int x, y; // x and y coordinates for drawing int x, y; // x and y coordinates for drawing
int prevX, prevY; // Last x and y coordinates for drawing int prevX, prevY; // Last x and y coordinates for drawing
// Default ranges for various boat data types
// Parameters: <1st value> default range, <2nd value> step for range adjustment
std::map<String, ChartProps> dfltChrtDta = {
{ "formatWind", { 60.0 * DEG_TO_RAD, 10.0 * DEG_TO_RAD } }, // default wind range 60 degrees
{ "formatCourse", { 60.0 * DEG_TO_RAD, 10.0 * DEG_TO_RAD } }, // default course range 60 degrees
{ "formatKnots", { 2.572, 2.572 } }, // default speed range in m/s
{ "formatDepth", { 10.0, 5.0 } }, // default depth range in m
{ "kelvinToC", { 20.0, 5.0 } }, // default temp range in °C/K
{ "formatXdr:P:P", { 4000.0, 1000.0 } } // default pressure range in Pascal (hPa * 100); XDR <B> (bar) format is represented in gateway in the same way
};
bool setChartDimensions(const char direction, const int8_t size); // define dimensions and start points for chart bool setChartDimensions(const char direction, const int8_t size); // define dimensions and start points for chart
// bool setChartDimensions(const ChrtDirection direction, const ChrtSize size); // define dimensions and start points for chart // bool setChartDimensions(const ChrtDirection direction, const ChrtSize size); // define dimensions and start points for chart
void drawChrt(const char chrtDir, const int8_t chrtIntv, GwApi::BoatValue& currValue); // Draw chart line void drawChrt(const char chrtDir, const int8_t chrtIntv, GwApi::BoatValue& currValue); // Draw chart line
void getBufferStartNSize(const int8_t chrtIntv); // Identify buffer size and buffer start position for chart void getBufferStartNSize(const int8_t chrtIntv); // Identify buffer size and buffer start position for chart
void calcChrtBorders(double& rngMin, double& rngMid, double& rngMax, double& rng); // Calculate chart points for value axis and return range between <min> and <max> void calcChrtBorders(double& rngMin, double& rngMid, double& rngMax, double& rng); // Calculate chart points for value axis and return range between <min> and <max>
+1 -2
View File
@@ -503,7 +503,7 @@ void OBP60Task(GwApi *api){
} }
// Read the specified boat data types of relevant pages and create a history buffer for each type for later use in charts // Read the specified boat data types of relevant pages and create a history buffer for each type for later use in charts
// applies only for pages that uses charts // applies only to pages that uses charts
if (pages[i].parameters.pageName == "OneValue" || pages[i].parameters.pageName == "TwoValues" if (pages[i].parameters.pageName == "OneValue" || pages[i].parameters.pageName == "TwoValues"
|| pages[i].parameters.pageName == "WindPlot" || pages[i].parameters.pageName == "Weather") { || pages[i].parameters.pageName == "WindPlot" || pages[i].parameters.pageName == "Weather") {
for (auto pVal : pages[i].parameters.values) { for (auto pVal : pages[i].parameters.values) {
@@ -512,7 +512,6 @@ void OBP60Task(GwApi *api){
} }
// Add list of history buffers to page parameters // Add list of history buffers to page parameters
pages[i].parameters.hstryBuffers = &hstryBufferList; pages[i].parameters.hstryBuffers = &hstryBufferList;
} }
// add out of band system page (always available) // add out of band system page (always available)