diff --git a/lib/obp60task/OBPcharts.cpp b/lib/obp60task/OBPcharts.cpp index cdb9dc2..4fe0eb6 100644 --- a/lib/obp60task/OBPcharts.cpp +++ b/lib/obp60task/OBPcharts.cpp @@ -3,17 +3,6 @@ #include "OBPDataOperations.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 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 (bar) format is represented in gateway in the same way -}; - // --- Class Chart --------------- // Chart - object holding the actual chart, incl. data buffer and format definition @@ -21,9 +10,8 @@ std::map Chart::dfltChrtDta = { // default range of chart, e.g. 30 = [0..30] // common program data; required for logger and color data // flag to indicate if simulation data is active -Chart::Chart(RingBuffer& dataBuf, double dfltRng, CommonData& common, bool useSimuData) +Chart::Chart(RingBuffer& dataBuf, CommonData& common, bool useSimuData) : dataBuf(dataBuf) - , dfltRng(dfltRng) , commonData(&common) , useSimuData(useSimuData) { @@ -40,17 +28,31 @@ Chart::Chart(RingBuffer& dataBuf, double dfltRng, CommonData& common, dHeight = getdisplay().height(); #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); dbMIN_VAL = dataBuf.getMinVal(); dbMAX_VAL = dataBuf.getMaxVal(); bufSize = dataBuf.getCapacity(); 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 if (dbFormat == "formatCourse" || dbFormat == "formatWind") { chrtDataFmt = WIND; // Chart is showing data of course / wind format @@ -97,14 +99,18 @@ Chart::Chart(RingBuffer& dataBuf, double dfltRng, CommonData& common, chrtMax = chrtMin + dfltRng; chrtMid = (chrtMin + chrtMax) / 2; chrtRng = dfltRng; - recalcRngMid = true; // initialize and chart borders on first screen call + recalcRngMid = true; // initialize 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", - dWidth, dHeight, timAxis, valAxis, cRoot.x, cRoot.y, dbName, rngStep, chrtDataFmt); -}; + if (dbFormat.isEmpty()) { + // 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 @@ -325,8 +331,15 @@ void Chart::calcChrtBorders(double& rngMin, double& rngMid, double& rngMax, doub double currMinVal = dataBuf.getMin(numBufVals); double currMaxVal = dataBuf.getMax(numBufVals); - if (currMinVal == dbMAX_VAL || currMaxVal == dbMAX_VAL) { - // return; // no valid data + if (currMinVal == dbMAX_VAL || currMaxVal == dbMAX_VAL) { // 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 @@ -350,13 +363,6 @@ void Chart::calcChrtBorders(double& rngMin, double& rngMid, double& rngMax, doub rngMid = (rngMin + rngMax) / 2.0; 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", currMinVal, currMaxVal, rngMin, rngMid, rngMax, rng, rngStep, zeroValue, dbMIN_VAL); } diff --git a/lib/obp60task/OBPcharts.h b/lib/obp60task/OBPcharts.h index 2bfd63c..658053b 100644 --- a/lib/obp60task/OBPcharts.h +++ b/lib/obp60task/OBPcharts.h @@ -20,26 +20,24 @@ class GwLog; class Chart { public: + /* enum class ChrtDirection { + HORIZONTALE, + VERTICALE + }; -/* enum class ChrtDirection { - HORIZONTALE, - VERTICALE - }; + enum class ChrtSize { + FULL_SIZEE, + HALF_SIZE_LEFTE, + HALF_SIZE_RIGHTE, + TWO_THIRD_TOPE + }; */ - enum class ChrtSize { - FULL_SIZEE, - HALF_SIZE_LEFTE, - HALF_SIZE_RIGHTE, - TWO_THIRD_TOPE - }; */ - - // Define default chart range and range step for each boat data type - static std::map dfltChrtDta; - - Chart(RingBuffer& dataBuf, double dfltRng, CommonData& common, bool useSimuData); // Chart object of data chart + Chart(RingBuffer& dataBuf, CommonData& common, bool useSimuData); // Chart object of data 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(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: CommonData* commonData; @@ -69,6 +67,7 @@ protected: static constexpr bool NO_SIMUDATA = true; // switch off simulation feature of function RingBuffer& 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] uint16_t fgColor; // color code for any screen writing uint16_t bgColor; // color code for screen background @@ -113,8 +112,19 @@ protected: int x, y; // 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 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 (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 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 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 and diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 7e3ef01..3a900db 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -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 - // 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" || pages[i].parameters.pageName == "WindPlot" || pages[i].parameters.pageName == "Weather") { for (auto pVal : pages[i].parameters.values) { @@ -512,7 +512,6 @@ void OBP60Task(GwApi *api){ } // Add list of history buffers to page parameters pages[i].parameters.hstryBuffers = &hstryBufferList; - } // add out of band system page (always available)