Merge pull request #172 from Scorgan01/Smoothing
Smoothing of data value; extension of calibration of data types (PR #171)
This commit is contained in:
commit
e72ece8452
|
@ -0,0 +1,203 @@
|
|||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||
|
||||
#include "BoatDataCalibration.h"
|
||||
#include <cmath>
|
||||
#include <math.h>
|
||||
#include <unordered_map>
|
||||
|
||||
CalibrationDataList calibrationData;
|
||||
|
||||
void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger)
|
||||
// Initial load of calibration data into internal list
|
||||
// This method is called once at init phase of <OBP60task> to read the configuration values
|
||||
{
|
||||
String instance;
|
||||
double offset;
|
||||
double slope;
|
||||
double smooth;
|
||||
|
||||
String calInstance = "";
|
||||
String calOffset = "";
|
||||
String calSlope = "";
|
||||
String calSmooth = "";
|
||||
|
||||
// Load user format configuration values
|
||||
String lengthFormat = config->getString(config->lengthFormat); // [m|ft]
|
||||
String distanceFormat = config->getString(config->distanceFormat); // [m|km|nm]
|
||||
String speedFormat = config->getString(config->speedFormat); // [m/s|km/h|kn]
|
||||
String windspeedFormat = config->getString(config->windspeedFormat); // [m/s|km/h|kn|bft]
|
||||
String tempFormat = config->getString(config->tempFormat); // [K|C|F]
|
||||
|
||||
// Read calibration settings for data instances
|
||||
for (int i = 0; i < maxCalibrationData; i++) {
|
||||
calInstance = "calInstance" + String(i + 1);
|
||||
calOffset = "calOffset" + String(i + 1);
|
||||
calSlope = "calSlope" + String(i + 1);
|
||||
calSmooth = "calSmooth" + String(i + 1);
|
||||
calibrationData.list[i] = { "---", 0.0f, 1.0f, 1, 0.0f, false };
|
||||
|
||||
instance = config->getString(calInstance, "---");
|
||||
if (instance == "---") {
|
||||
LOG_DEBUG(GwLog::LOG, "no calibration data for instance no. %d", i + 1);
|
||||
continue;
|
||||
}
|
||||
offset = (config->getString(calOffset, "")).toFloat();
|
||||
slope = (config->getString(calSlope, "")).toFloat();
|
||||
smooth = (config->getString(calSmooth, "")).toInt();
|
||||
|
||||
// Convert calibration values to internal standard formats
|
||||
if (instance == "AWS" || instance == "TWS") {
|
||||
if (windspeedFormat == "m/s") {
|
||||
// No conversion needed
|
||||
} else if (windspeedFormat == "km/h") {
|
||||
offset /= 3.6; // Convert km/h to m/s
|
||||
} else if (windspeedFormat == "kn") {
|
||||
offset /= 1.94384; // Convert kn to m/s
|
||||
} else if (windspeedFormat == "bft") {
|
||||
offset *= 0.5; // Convert Bft to m/s (approx) -> to be improved
|
||||
}
|
||||
|
||||
} else if (instance == "AWA" || instance == "TWA" || instance == "TWD" || instance == "HDM" || instance == "PRPOS" || instance == "RPOS") {
|
||||
offset *= M_PI / 180; // Convert deg to rad
|
||||
|
||||
} else if (instance == "DBT") {
|
||||
if (lengthFormat == "m") {
|
||||
// No conversion needed
|
||||
} else if (lengthFormat == "ft") {
|
||||
offset /= 3.28084; // Convert ft to m
|
||||
}
|
||||
|
||||
} else if (instance == "STW") {
|
||||
if (speedFormat == "m/s") {
|
||||
// No conversion needed
|
||||
} else if (speedFormat == "km/h") {
|
||||
offset /= 3.6; // Convert km/h to m/s
|
||||
} else if (speedFormat == "kn") {
|
||||
offset /= 1.94384; // Convert kn to m/s
|
||||
}
|
||||
|
||||
} else if (instance == "WTemp") {
|
||||
if (tempFormat == "K" || tempFormat == "C") {
|
||||
// No conversion needed
|
||||
} else if (tempFormat == "F") {
|
||||
offset *= 9.0 / 5.0; // Convert °F to K
|
||||
slope *= 9.0 / 5.0; // Convert °F to K
|
||||
}
|
||||
}
|
||||
|
||||
// transform smoothing factor from {0.01..10} to {0.3..0.95} and invert for exponential smoothing formula
|
||||
if (smooth <= 0) {
|
||||
smooth = 0;
|
||||
} else {
|
||||
if (smooth > 10) {
|
||||
smooth = 10;
|
||||
}
|
||||
// calibrationData.list[i].smooth = 1 - (smooth / 10.0); // smooth factor is between 0 and 1
|
||||
smooth = 0.3 + ((smooth - 0.01) * (0.95 - 0.3) / (10 - 0.01));
|
||||
}
|
||||
smooth = 1 - smooth;
|
||||
|
||||
calibrationData.list[i].instance = instance;
|
||||
calibrationData.list[i].offset = offset;
|
||||
calibrationData.list[i].slope = slope;
|
||||
calibrationData.list[i].smooth = smooth;
|
||||
calibrationData.list[i].isCalibrated = false;
|
||||
LOG_DEBUG(GwLog::LOG, "stored calibration data: %s, offset: %f, slope: %f, smoothing: %f", calibrationData.list[i].instance.c_str(),
|
||||
calibrationData.list[i].offset, calibrationData.list[i].slope, calibrationData.list[i].smooth);
|
||||
}
|
||||
LOG_DEBUG(GwLog::LOG, "all calibration data read");
|
||||
}
|
||||
|
||||
int CalibrationDataList::getInstanceListNo(String instance)
|
||||
// Method to get the index of the requested instance in the list
|
||||
{
|
||||
// Check if instance is in the list
|
||||
for (int i = 0; i < maxCalibrationData; i++) {
|
||||
if (calibrationData.list[i].instance == instance) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1; // instance not found
|
||||
}
|
||||
|
||||
/* void CalibrationDataList::updateBoatDataValidity(String instance)
|
||||
{
|
||||
for (int i = 0; i < maxCalibrationData; i++) {
|
||||
if (calibrationData.list[i].instance == instance) {
|
||||
// test for boat data value validity - to be implemented
|
||||
calibrationData.list[i].isValid = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
void CalibrationDataList::calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger)
|
||||
// Method to calibrate the boat data value
|
||||
{
|
||||
double offset = 0;
|
||||
double slope = 1.0;
|
||||
double dataValue = 0;
|
||||
|
||||
int listNo = getInstanceListNo(instance);
|
||||
if (listNo < 0) {
|
||||
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s not found in calibration data list", instance.c_str());
|
||||
return;
|
||||
} else {
|
||||
offset = calibrationData.list[listNo].offset;
|
||||
slope = calibrationData.list[listNo].slope;
|
||||
|
||||
if (!boatDataValue->valid) { // no valid boat data value, so we don't want to apply calibration data
|
||||
return;
|
||||
} else {
|
||||
dataValue = boatDataValue->value;
|
||||
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: value: %f, format: %s", boatDataValue->getName().c_str(), boatDataValue->value, boatDataValue->getFormat().c_str());
|
||||
|
||||
if (boatDataValue->getFormat() == "formatWind") { // instance is of type angle
|
||||
dataValue = (dataValue * slope) + offset;
|
||||
dataValue = fmod(dataValue, 2 * M_PI);
|
||||
if (dataValue > (M_PI)) {
|
||||
dataValue -= (2 * M_PI);
|
||||
} else if (dataValue < (M_PI * -1)) {
|
||||
dataValue += (2 * M_PI);
|
||||
}
|
||||
} else if (boatDataValue->getFormat() == "formatCourse") { // instance is of type direction
|
||||
dataValue = (dataValue * slope) + offset;
|
||||
dataValue = fmod(dataValue, 2 * M_PI);
|
||||
if (dataValue < 0) {
|
||||
dataValue += (2 * M_PI);
|
||||
}
|
||||
} else if (boatDataValue->getFormat() == "kelvinToC") { // instance is of type temperature
|
||||
dataValue = ((dataValue - 273.15) * slope) + offset + 273.15;
|
||||
} else {
|
||||
dataValue = (dataValue * slope) + offset;
|
||||
}
|
||||
|
||||
calibrationData.smoothInstance(instance, dataValue, logger); // smooth the boat data value
|
||||
calibrationData.list[listNo].value = dataValue;
|
||||
calibrationData.list[listNo].isCalibrated = true;
|
||||
boatDataValue->value = dataValue;
|
||||
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: Offset: %f, Slope: %f, Result: %f", instance.c_str(), offset, slope, boatDataValue->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalibrationDataList::smoothInstance(String instance, double& dataValue, GwLog* logger)
|
||||
// Method to smoothen the boat data value
|
||||
{
|
||||
// array for last values of smoothed boat data values
|
||||
static std::unordered_map<std::string, double> lastValue;
|
||||
|
||||
double oldValue = 0;
|
||||
double smoothFactor = calibrationData.list[getInstanceListNo(instance)].smooth;
|
||||
|
||||
if (lastValue.find(instance.c_str()) != lastValue.end()) {
|
||||
oldValue = lastValue[instance.c_str()];
|
||||
|
||||
dataValue = oldValue + (smoothFactor * (dataValue - oldValue)); // exponential smoothing algorithm
|
||||
}
|
||||
lastValue[instance.c_str()] = dataValue; // store the new value for next cycle; first time, store only the current value and return
|
||||
|
||||
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: Smoothing factor: %f, Smoothed value: %f", instance.c_str(), smoothFactor, dataValue);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
// Functions lib for data instance calibration
|
||||
|
||||
#ifndef _BOATDATACALIBRATION_H
|
||||
#define _BOATDATACALIBRATION_H
|
||||
|
||||
#include "Pagedata.h"
|
||||
#include "WString.h"
|
||||
|
||||
typedef struct {
|
||||
String instance; // data type/instance to be calibrated
|
||||
double offset; // calibration offset
|
||||
double slope; // calibration slope
|
||||
double smooth; // smoothing factor
|
||||
double value; // calibrated data value
|
||||
bool isCalibrated; // is data instance value calibrated?
|
||||
} CalibData;
|
||||
|
||||
const int maxCalibrationData = 3; // maximum number of calibration data instances
|
||||
|
||||
class CalibrationDataList {
|
||||
public:
|
||||
CalibData list[maxCalibrationData]; // list of calibration data instances
|
||||
|
||||
static void readConfig(GwConfigHandler* config, GwLog* logger);
|
||||
static int getInstanceListNo(String instance);
|
||||
static void calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger);
|
||||
void smoothInstance(String instance, double &dataValue, GwLog* logger);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
extern CalibrationDataList calibrationData; // this list holds all calibration data
|
||||
|
||||
#endif
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "BoatDataCalibration.h"
|
||||
|
||||
class PageFourValues : public Page
|
||||
{
|
||||
|
@ -47,6 +48,7 @@ class PageFourValues : public Page
|
|||
name1 = name1.substring(0, 6); // String length limit for value name
|
||||
double value1 = bvalue1->value; // Value as double in SI unit
|
||||
bool valid1 = bvalue1->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
|
||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||
|
||||
|
@ -56,6 +58,7 @@ class PageFourValues : public Page
|
|||
name2 = name2.substring(0, 6); // String length limit for value name
|
||||
double value2 = bvalue2->value; // Value as double in SI unit
|
||||
bool valid2 = bvalue2->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
|
||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||
|
||||
|
@ -65,6 +68,7 @@ class PageFourValues : public Page
|
|||
name3 = name3.substring(0, 6); // String length limit for value name
|
||||
double value3 = bvalue3->value; // Value as double in SI unit
|
||||
bool valid3 = bvalue3->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated
|
||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
||||
|
||||
|
@ -74,6 +78,7 @@ class PageFourValues : public Page
|
|||
name4 = name4.substring(0, 6); // String length limit for value name
|
||||
double value4 = bvalue4->value; // Value as double in SI unit
|
||||
bool valid4 = bvalue4->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name4, bvalue4, logger); // Check if boat data value is to be calibrated
|
||||
String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "BoatDataCalibration.h"
|
||||
|
||||
class PageFourValues2 : public Page
|
||||
{
|
||||
|
@ -47,6 +48,7 @@ class PageFourValues2 : public Page
|
|||
name1 = name1.substring(0, 6); // String length limit for value name
|
||||
double value1 = bvalue1->value; // Value as double in SI unit
|
||||
bool valid1 = bvalue1->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
|
||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||
|
||||
|
@ -56,6 +58,7 @@ class PageFourValues2 : public Page
|
|||
name2 = name2.substring(0, 6); // String length limit for value name
|
||||
double value2 = bvalue2->value; // Value as double in SI unit
|
||||
bool valid2 = bvalue2->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
|
||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||
|
||||
|
@ -65,6 +68,7 @@ class PageFourValues2 : public Page
|
|||
name3 = name3.substring(0, 6); // String length limit for value name
|
||||
double value3 = bvalue3->value; // Value as double in SI unit
|
||||
bool valid3 = bvalue3->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated
|
||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
||||
|
||||
|
@ -74,6 +78,7 @@ class PageFourValues2 : public Page
|
|||
name4 = name4.substring(0, 6); // String length limit for value name
|
||||
double value4 = bvalue4->value; // Value as double in SI unit
|
||||
bool valid4 = bvalue4->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name4, bvalue4, logger); // Check if boat data value is to be calibrated
|
||||
String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "BoatDataCalibration.h"
|
||||
|
||||
class PageOneValue : public Page
|
||||
{
|
||||
|
@ -39,6 +40,7 @@ class PageOneValue : public Page
|
|||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||
name1 = name1.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
|
||||
double value1 = bvalue1->value; // Value as double in SI unit
|
||||
bool valid1 = bvalue1->valid; // Valid information
|
||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "BoatDataCalibration.h"
|
||||
|
||||
class PageRudderPosition : public Page
|
||||
{
|
||||
|
@ -40,24 +41,25 @@ public:
|
|||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list
|
||||
String name1 = bvalue1->getName().c_str(); // Value name
|
||||
name1 = name1.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
|
||||
value1 = bvalue1->value; // Raw value without unit convertion
|
||||
bool valid1 = bvalue1->valid; // Valid information
|
||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||
|
||||
if(valid1 == true){
|
||||
value1old = value1; // Save old value
|
||||
unit1old = unit1; // Save old unit
|
||||
} else {
|
||||
if(simulation == true){
|
||||
value1 = (3 + float(random(0, 50)) / 10.0)/360*2*PI;
|
||||
unit1 = "Deg";
|
||||
}
|
||||
else{
|
||||
value1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(simulation == true){
|
||||
value1 = (3 + float(random(0, 50)) / 10.0)/360*2*PI;
|
||||
unit1 = "Deg";
|
||||
}
|
||||
else{
|
||||
value1 = 0;
|
||||
}
|
||||
|
||||
|
||||
// Optical warning by limit violation (unused)
|
||||
if(String(flashLED) == "Limit Violation"){
|
||||
setBlinkingLED(false);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "BoatDataCalibration.h"
|
||||
|
||||
#include "DSEG7Classic-BoldItalic26pt7b.h"
|
||||
|
||||
|
@ -61,6 +62,7 @@ class PageSixValues : public Page
|
|||
DataName[i] = xdrDelete(bvalue->getName());
|
||||
DataName[i] = DataName[i].substring(0, 6); // String length limit for value name
|
||||
DataValue[i] = bvalue->value; // Value as double in SI unit
|
||||
calibrationData.calibrateInstance(DataName[i], bvalue, logger); // Check if boat data value is to be calibrated
|
||||
DataValid[i] = bvalue->valid;
|
||||
DataText[i] = formatValue(bvalue, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
DataUnits[i] = formatValue(bvalue, *commonData).unit;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "BoatDataCalibration.h"
|
||||
|
||||
class PageThreeValues : public Page
|
||||
{
|
||||
|
@ -45,6 +46,7 @@ class PageThreeValues : public Page
|
|||
name1 = name1.substring(0, 6); // String length limit for value name
|
||||
double value1 = bvalue1->value; // Value as double in SI unit
|
||||
bool valid1 = bvalue1->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
|
||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||
|
||||
|
@ -54,6 +56,7 @@ class PageThreeValues : public Page
|
|||
name2 = name2.substring(0, 6); // String length limit for value name
|
||||
double value2 = bvalue2->value; // Value as double in SI unit
|
||||
bool valid2 = bvalue2->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
|
||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||
|
||||
|
@ -63,6 +66,7 @@ class PageThreeValues : public Page
|
|||
name3 = name3.substring(0, 6); // String length limit for value name
|
||||
double value3 = bvalue3->value; // Value as double in SI unit
|
||||
bool valid3 = bvalue3->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated
|
||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "BoatDataCalibration.h"
|
||||
|
||||
class PageTwoValues : public Page
|
||||
{
|
||||
|
@ -43,6 +44,7 @@ class PageTwoValues : public Page
|
|||
name1 = name1.substring(0, 6); // String length limit for value name
|
||||
double value1 = bvalue1->value; // Value as double in SI unit
|
||||
bool valid1 = bvalue1->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
|
||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||
|
||||
|
@ -52,6 +54,7 @@ class PageTwoValues : public Page
|
|||
name2 = name2.substring(0, 6); // String length limit for value name
|
||||
double value2 = bvalue2->value; // Value as double in SI unit
|
||||
bool valid2 = bvalue2->valid; // Valid information
|
||||
calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
|
||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "N2kMessages.h"
|
||||
#include "BoatDataCalibration.h"
|
||||
|
||||
#define front_width 120
|
||||
#define front_height 162
|
||||
|
@ -323,6 +324,7 @@ public:
|
|||
}
|
||||
String name1 = bvalue1->getName().c_str(); // Value name
|
||||
name1 = name1.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
|
||||
double value1 = bvalue1->value; // Value as double in SI unit
|
||||
// bool valid1 = bvalue1->valid; // Valid information
|
||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
@ -336,6 +338,7 @@ public:
|
|||
}
|
||||
String name2 = bvalue2->getName().c_str(); // Value name
|
||||
name2 = name2.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
|
||||
double value2 = bvalue2->value; // Value as double in SI unit
|
||||
// bool valid2 = bvalue2->valid; // Valid information
|
||||
if (simulation) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "BoatDataCalibration.h"
|
||||
|
||||
class PageWindRose : public Page
|
||||
{
|
||||
|
@ -51,6 +52,7 @@ public:
|
|||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||
name1 = name1.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
|
||||
double value1 = bvalue1->value; // Value as double in SI unit
|
||||
bool valid1 = bvalue1->valid; // Valid information
|
||||
value1 = formatValue(bvalue1, *commonData).value;// Format only nesaccery for simulation data for pointer
|
||||
|
@ -65,6 +67,7 @@ public:
|
|||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // First element in list (only one value by PageOneValue)
|
||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
||||
name2 = name2.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
|
||||
double value2 = bvalue2->value; // Value as double in SI unit
|
||||
bool valid2 = bvalue2->valid; // Valid information
|
||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
@ -78,6 +81,7 @@ public:
|
|||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
|
||||
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
||||
name3 = name3.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated
|
||||
double value3 = bvalue3->value; // Value as double in SI unit
|
||||
bool valid3 = bvalue3->valid; // Valid information
|
||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
@ -91,6 +95,7 @@ public:
|
|||
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
|
||||
String name4 = xdrDelete(bvalue4->getName()); // Value name
|
||||
name4 = name4.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name4, bvalue4, logger); // Check if boat data value is to be calibrated
|
||||
double value4 = bvalue4->value; // Value as double in SI unit
|
||||
bool valid4 = bvalue4->valid; // Valid information
|
||||
String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
@ -104,6 +109,7 @@ public:
|
|||
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Second element in list (only one value by PageOneValue)
|
||||
String name5 = xdrDelete(bvalue5->getName()); // Value name
|
||||
name5 = name5.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name5, bvalue5, logger); // Check if boat data value is to be calibrated
|
||||
double value5 = bvalue5->value; // Value as double in SI unit
|
||||
bool valid5 = bvalue5->valid; // Valid information
|
||||
String svalue5 = formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
@ -117,6 +123,7 @@ public:
|
|||
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Second element in list (only one value by PageOneValue)
|
||||
String name6 = xdrDelete(bvalue6->getName()); // Value name
|
||||
name6 = name6.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name6, bvalue6, logger); // Check if boat data value is to be calibrated
|
||||
double value6 = bvalue6->value; // Value as double in SI unit
|
||||
bool valid6 = bvalue6->valid; // Valid information
|
||||
String svalue6 = formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "BoatDataCalibration.h"
|
||||
|
||||
class PageWindRoseFlex : public Page
|
||||
{
|
||||
|
@ -51,6 +52,7 @@ public:
|
|||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||
name1 = name1.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
|
||||
double value1 = bvalue1->value; // Value as double in SI unit
|
||||
bool valid1 = bvalue1->valid; // Valid information
|
||||
value1 = formatValue(bvalue1, *commonData).value;// Format only nesaccery for simulation data for pointer
|
||||
|
@ -65,6 +67,7 @@ public:
|
|||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // First element in list (only one value by PageOneValue)
|
||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
||||
name2 = name2.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
|
||||
double value2 = bvalue2->value; // Value as double in SI unit
|
||||
bool valid2 = bvalue2->valid; // Valid information
|
||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
@ -78,6 +81,7 @@ public:
|
|||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
|
||||
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
||||
name3 = name3.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated
|
||||
double value3 = bvalue3->value; // Value as double in SI unit
|
||||
bool valid3 = bvalue3->valid; // Valid information
|
||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
@ -91,6 +95,7 @@ public:
|
|||
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
|
||||
String name4 = xdrDelete(bvalue4->getName()); // Value name
|
||||
name4 = name4.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name4, bvalue4, logger); // Check if boat data value is to be calibrated
|
||||
double value4 = bvalue4->value; // Value as double in SI unit
|
||||
bool valid4 = bvalue4->valid; // Valid information
|
||||
String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
@ -104,6 +109,7 @@ public:
|
|||
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Second element in list (only one value by PageOneValue)
|
||||
String name5 = xdrDelete(bvalue5->getName()); // Value name
|
||||
name5 = name5.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name5, bvalue5, logger); // Check if boat data value is to be calibrated
|
||||
double value5 = bvalue5->value; // Value as double in SI unit
|
||||
bool valid5 = bvalue5->valid; // Valid information
|
||||
String svalue5 = formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
@ -117,6 +123,7 @@ public:
|
|||
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Second element in list (only one value by PageOneValue)
|
||||
String name6 = xdrDelete(bvalue6->getName()); // Value name
|
||||
name6 = name6.substring(0, 6); // String length limit for value name
|
||||
calibrationData.calibrateInstance(name6, bvalue6, logger); // Check if boat data value is to be calibrated
|
||||
double value6 = bvalue6->value; // Value as double in SI unit
|
||||
bool valid6 = bvalue6->valid; // Valid information
|
||||
String svalue6 = formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||
|
|
|
@ -686,6 +686,189 @@
|
|||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calInstance1",
|
||||
"label": "Calibration Data Instance 1",
|
||||
"type": "list",
|
||||
"default": "---",
|
||||
"description": "Data instance for calibration",
|
||||
"list": [
|
||||
"---",
|
||||
"AWA",
|
||||
"AWS",
|
||||
"DBT",
|
||||
"HDM",
|
||||
"PRPOS",
|
||||
"RPOS",
|
||||
"STW",
|
||||
"TWA",
|
||||
"TWS",
|
||||
"TWD",
|
||||
"WTemp"
|
||||
],
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calOffset1",
|
||||
"label": "Data Instance 1 Calibration Offset",
|
||||
"type": "number",
|
||||
"default": "0.00",
|
||||
"description": "Offset for data instance 1",
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calSlope1",
|
||||
"label": "Data Instance 1 Calibration Slope",
|
||||
"type": "number",
|
||||
"default": "1.00",
|
||||
"description": "Slope for data instance 1",
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calSmooth1",
|
||||
"label": "Data Instance 1 Smoothing",
|
||||
"type": "number",
|
||||
"default": "0",
|
||||
"check": "checkMinMax",
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"description": "Smoothing factor for data instance 1",
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calInstance2",
|
||||
"label": "Calibration Data Instance 2",
|
||||
"type": "list",
|
||||
"default": "---",
|
||||
"description": "Data instance for calibration",
|
||||
"list": [
|
||||
"---",
|
||||
"AWA",
|
||||
"AWS",
|
||||
"DBT",
|
||||
"HDM",
|
||||
"PRPOS",
|
||||
"RPOS",
|
||||
"STW",
|
||||
"TWA",
|
||||
"TWS",
|
||||
"TWD",
|
||||
"WTemp"
|
||||
],
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calOffset2",
|
||||
"label": "Data Instance 2 Calibration Offset",
|
||||
"type": "number",
|
||||
"default": "0.00",
|
||||
"description": "Offset for data instance 2",
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calSlope2",
|
||||
"label": "Data Instance 2 Calibration Slope",
|
||||
"type": "number",
|
||||
"default": "1.00",
|
||||
"description": "Slope for data instance 2",
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calSmooth2",
|
||||
"label": "Data Instance 2 Smoothing",
|
||||
"type": "number",
|
||||
"default": "0",
|
||||
"check": "checkMinMax",
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"description": "Smoothing factor for data instance 2",
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calInstance3",
|
||||
"label": "Calibration Data Instance 3",
|
||||
"type": "list",
|
||||
"default": "---",
|
||||
"description": "Data instance for calibration",
|
||||
"list": [
|
||||
"---",
|
||||
"AWA",
|
||||
"AWS",
|
||||
"DBT",
|
||||
"HDM",
|
||||
"PRPOS",
|
||||
"RPOS",
|
||||
"STW",
|
||||
"TWA",
|
||||
"TWS",
|
||||
"TWD",
|
||||
"WTemp"
|
||||
],
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calOffset3",
|
||||
"label": "Data Instance 3 Calibration Offset",
|
||||
"type": "number",
|
||||
"default": "0.00",
|
||||
"description": "Offset for data instance 3",
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calSlope3",
|
||||
"label": "Data Instance 3 Calibration Slope",
|
||||
"type": "number",
|
||||
"default": "1.00",
|
||||
"description": "Slope for data instance 3",
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calSmooth3",
|
||||
"label": "Data Instance 3 Smoothing",
|
||||
"type": "number",
|
||||
"default": "0",
|
||||
"check": "checkMinMax",
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"description": "Smoothing factor for data instance 3",
|
||||
"category": "OBP60 Calibrations",
|
||||
"capabilities": {
|
||||
"obp60":"true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "display",
|
||||
"label": "Display Mode",
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <GxEPD2_BW.h> // GxEPD2 lib for b/w E-Ink displays
|
||||
#include "OBP60Extensions.h" // Functions lib for extension board
|
||||
#include "OBP60Keypad.h" // Functions for keypad
|
||||
#include "BoatDataCalibration.h" // Functions lib for data instance calibration
|
||||
|
||||
#ifdef BOARD_OBP40S3
|
||||
#include "driver/rtc_io.h" // Needs for weakup from deep sleep
|
||||
|
@ -524,6 +525,9 @@ void OBP60Task(GwApi *api){
|
|||
// add out of band system page (always available)
|
||||
Page *syspage = allPages.pages[0]->creator(commonData);
|
||||
|
||||
// Read all calibration data settings from config
|
||||
calibrationData.readConfig(config, logger);
|
||||
|
||||
// Display screenshot handler for HTTP request
|
||||
// http://192.168.15.1/api/user/OBP60Task/screenshot
|
||||
api->registerRequestHandler("screenshot", [api, &pageNumber, pages](AsyncWebServerRequest *request) {
|
||||
|
|
Loading…
Reference in New Issue