mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2026-09-11 19:55:14 +02:00
Fix how chart smoothing handles angular value averages; move smoothing calculation of data from chart function to history buffer, because new method needs too much time in chart function
This commit is contained in:
@@ -28,11 +28,6 @@ Chart::Chart(RingBuffer<uint16_t>& dataBuf, CommonData& common, bool useSimuData
|
||||
dHeight = getdisplay().height();
|
||||
#endif
|
||||
|
||||
smoothCharts = commonData->config->getBool(commonData->config->smoothCharts);
|
||||
if (smoothCharts) {
|
||||
chrtAvg.begin();
|
||||
}
|
||||
|
||||
init();
|
||||
};
|
||||
|
||||
@@ -51,7 +46,7 @@ bool Chart::init()
|
||||
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);
|
||||
// LOG_DEBUG(GwLog::DEBUG, "Chart Init: dbMIN_VAL: %.2f, dbMAX_VAL: %.2fd, bufSize: %d", dbMIN_VAL, dbMAX_VAL, bufSize);
|
||||
|
||||
// Initialize chart data format; shorter version of standard format indicator
|
||||
if (dbFormat == "formatCourse" || dbFormat == "formatWind") {
|
||||
@@ -214,7 +209,7 @@ void Chart::drawChrt(const ChrtDir chrtDir, const int8_t chrtIntv, GwApi::BoatVa
|
||||
// LOG_DEBUG(GwLog::DEBUG, "Chart:drawChart: min: %.1f, mid: %.1f, max: %.1f, rng: %.1f", chrtMin, chrtMid, chrtMax, chrtRng);
|
||||
calcChrtBorders(chrtMin, chrtMid, chrtMax, chrtRng);
|
||||
chrtScale = double(valAxis) / chrtRng; // Chart scale: pixels per value step
|
||||
LOG_DEBUG(GwLog::DEBUG, "Chart:drawChart: min: %.1f, mid: %.1f, max: %.1f, rng: %.1f, data valid: %d", chrtMin, chrtMid, chrtMax, chrtRng, currValue.valid);
|
||||
// LOG_DEBUG(GwLog::DEBUG, "Chart:drawChart: min: %.1f, mid: %.1f, max: %.1f, rng: %.1f, data valid: %d", chrtMin, chrtMid, chrtMax, chrtRng, currValue.valid);
|
||||
|
||||
// Do we have valid buffer data?
|
||||
if (dataBuf.getMax() == dbMAX_VAL) { // only <MAX_VAL> values in buffer -> no valid wind data available
|
||||
@@ -285,7 +280,6 @@ void Chart::calcChrtBorders(double& rngMin, double& rngMid, double& rngMax, doub
|
||||
rngMid = 0;
|
||||
} else {
|
||||
rngMid = std::round(rngMid / rngStep) * rngStep; // round new center value to next <rngStep> value
|
||||
|
||||
}
|
||||
recalcRngMid = false; // Reset flag for <rngMid> determination
|
||||
|
||||
@@ -359,23 +353,6 @@ void Chart::drawChartLines(const ChrtDir chrtDir, const int8_t chrtIntv, const d
|
||||
double chrtVal; // Current data value
|
||||
Pos point, prevPoint; // current and previous chart point
|
||||
|
||||
if (smoothCharts) {
|
||||
// prime moving average filter to ensure the first plotted point is already averaged
|
||||
|
||||
chrtAvg.reset();
|
||||
|
||||
// Feed the filter the 10 values preceding bufStart
|
||||
for (int p = 10; p > 0; p--) {
|
||||
// Calculate index with wrapping: (start - offset + size) % size
|
||||
int primeIdx = (bufStart - (p * chrtIntv));
|
||||
double primeVal = dataBuf.get(primeIdx);
|
||||
|
||||
if (primeVal != dbMAX_VAL) {
|
||||
chrtAvg.reading(primeVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (numBufVals / chrtIntv); i++) {
|
||||
|
||||
chrtVal = dataBuf.get(bufStart + (i * chrtIntv)); // show the latest wind values in buffer; keep 1st value constant in a rolling buffer
|
||||
@@ -384,10 +361,6 @@ void Chart::drawChartLines(const ChrtDir chrtDir, const int8_t chrtIntv, const d
|
||||
chrtPrevVal = dbMAX_VAL;
|
||||
} else {
|
||||
|
||||
if (smoothCharts) {
|
||||
chrtVal = chrtAvg.reading(chrtVal); // if chart lines shall be smoothed, apply moving average filter of the last 10 values
|
||||
}
|
||||
|
||||
point = setChartPoint(i, chrtDir, chrtVal, chrtScale);
|
||||
// if (i >= (numBufVals / chrtIntv) - 5) // log chart data of x lines (adjust for test purposes)
|
||||
// LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Chart: i: %d, chrtVal: %.2f, chrtMin: %.2f, {x,y} {%d,%d}", i, chrtVal, chrtMin, point.x, point.y);
|
||||
@@ -419,13 +392,15 @@ void Chart::drawChartLines(const ChrtDir chrtDir, const int8_t chrtIntv, const d
|
||||
}
|
||||
}
|
||||
|
||||
// test position of chart point against chart middle
|
||||
// test position of chart point against chart middle; ignore first values which we don't show next time anyway
|
||||
if (i > MIN_FREE_VALUES) {
|
||||
double d = WindUtils::toPI(chrtVal - chrtMid);
|
||||
if (d > 0) // point is right of mid point
|
||||
allLeft = false;
|
||||
if (d < 0) // point is left of mid point
|
||||
allRight = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (chrtDataFmt == DEPTH) {
|
||||
if (chrtDir == HORIZONTAL) { // horizontal chart
|
||||
@@ -446,11 +421,11 @@ void Chart::drawChartLines(const ChrtDir chrtDir, const int8_t chrtIntv, const d
|
||||
oldChrtIntv = 0; // force reset of buffer start and number of values to show in next display loop
|
||||
|
||||
if (chrtDataFmt == WIND) { // degree of course or wind
|
||||
if (allLeft || allRight) {
|
||||
if (allLeft || allRight || chrtRng == M_PI) {
|
||||
recalcRngMid = true;
|
||||
}
|
||||
LOG_DEBUG(GwLog::DEBUG, "OBPcharts: WIND chart end: timAxis: %d, i: %d, bufStart: %d, numBufVals: %d, recalcRngCntr: %d, allLeft: %d, allRight: %d", timAxis, i, bufStart,
|
||||
numBufVals, recalcRngMid, allLeft, allRight);
|
||||
// LOG_DEBUG(GwLog::DEBUG, "OBPcharts: WIND chart end: timAxis: %d, i: %d, bufStart: %d, numBufVals: %d, recalcRngCntr: %d, allLeft: %d, allRight: %d", timAxis, i, bufStart,
|
||||
// numBufVals, recalcRngMid, allLeft, allRight);
|
||||
allLeft = true; // reset marker for all left/right chart points
|
||||
allRight = true;
|
||||
}
|
||||
|
||||
@@ -106,9 +106,7 @@ protected:
|
||||
bool bufDataValid = false; // Flag to indicate if buffer data is valid
|
||||
int oldChrtIntv = 0; // remember recent user selection of data interval
|
||||
|
||||
movingAvg<double> chrtAvg { 7 }; // Store average of the last 7 chart values if chart gradient shall be smoothed
|
||||
double chrtPrevVal; // Last data value in chart area
|
||||
// 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
|
||||
|
||||
@@ -462,6 +462,13 @@ void OBP60Task(GwApi *api){
|
||||
WindUtils trueWind(&boatValues, logger); // Create helper object for true wind calculation
|
||||
CalibrationData calibrationDataList(logger); // all boat data types which are supposed to be calibrated
|
||||
|
||||
// Read user settings from config file
|
||||
bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false);
|
||||
bool smoothCharts = api->getConfig()->getBool(api->getConfig()->smoothCharts, false);
|
||||
bool useSimuData = api->getConfig()->getBool(api->getConfig()->useSimuData, false);
|
||||
// Read user calibration data settings from config file
|
||||
calibrationDataList.readConfig(config);
|
||||
|
||||
//fill the page data from config
|
||||
numPages=config->getInt(config->visiblePages,1);
|
||||
if (numPages < 1) numPages=1;
|
||||
@@ -507,7 +514,7 @@ void OBP60Task(GwApi *api){
|
||||
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) {
|
||||
hstryBufferList.addBuffer(pVal->getName());
|
||||
hstryBufferList.addBuffer(pVal->getName(), smoothCharts);
|
||||
}
|
||||
}
|
||||
// Add list of history buffers to page parameters
|
||||
@@ -517,12 +524,6 @@ void OBP60Task(GwApi *api){
|
||||
// add out of band system page (always available)
|
||||
Page *syspage = allPages.pages[0]->creator(commonData);
|
||||
|
||||
// Read user settings from config file
|
||||
bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false);
|
||||
bool useSimuData = api->getConfig()->getBool(api->getConfig()->useSimuData, false);
|
||||
// Read user calibration data settings from config file
|
||||
calibrationDataList.readConfig(config);
|
||||
|
||||
// Display screenshot handler for HTTP request
|
||||
// http://192.168.15.1/api/user/OBP60Task/screenshot
|
||||
api->registerRequestHandler("screenshot", [api, &pageNumber, pages](AsyncWebServerRequest *request) {
|
||||
@@ -848,12 +849,12 @@ void OBP60Task(GwApi *api){
|
||||
api->getBoatDataValues(boatValues.numValues,boatValues.allBoatValues);
|
||||
api->getStatus(commonData.status);
|
||||
|
||||
// ulong startHndl = millis();
|
||||
// ulong startHandl = millis();
|
||||
trueWind.handleWinds(calcTrueWnds); // calculate true wind data from apparent wind values
|
||||
trueWind.setMaxWs(); // maintain MaxTWS value in any case; invalid TWS value is considered automatically
|
||||
calibrationDataList.handleCalibration(&boatValues); // Process calibration for all boat data in <calibrationDataList>
|
||||
hstryBufferList.handleHstryBufs(useSimuData, commonData); // Handle history buffers for certain boat data for charts and other usage
|
||||
// LOG_DEBUG(GwLog::DEBUG, "obp60task: data handling: %d ms", millis() - startHndl);
|
||||
// LOG_DEBUG(GwLog::DEBUG, "obp60task: data handling: %d ms", millis() - startHandl);
|
||||
|
||||
// Clear display
|
||||
// getdisplay().fillRect(0, 0, getdisplay().width(), getdisplay().height(), commonData.bgcolor);
|
||||
|
||||
Reference in New Issue
Block a user