further move to dynamic boat data

This commit is contained in:
andreas 2021-10-18 21:58:32 +02:00
parent 9fa577c768
commit 68769368f2
3 changed files with 33 additions and 25 deletions

View File

@ -43,30 +43,36 @@ class GwBoatData{
friend class GwBoatItemBase; friend class GwBoatItemBase;
}; };
template<class T> class GwBoatItem : public GwBoatItemBase{ template<class T> class GwBoatItem : public GwBoatItemBase{
public:
typedef T (*Formatter)(T);
private: private:
T data; T data;
Formatter fmt;
public: public:
GwBoatItem(long invalidTime=INVALID_TIME): GwBoatItemBase(invalidTime){} GwBoatItem(long invalidTime=INVALID_TIME,Formatter fmt=NULL): GwBoatItemBase(invalidTime){
this->fmt=fmt;
}
virtual ~GwBoatItem(){} virtual ~GwBoatItem(){}
void update(T nv){ void update(T nv){
data=nv; data=nv;
uls(); uls();
} }
T getData(){ T getData(bool useFormatter=false){
return data; if (! useFormatter || fmt == NULL) return data;
return (*fmt)(data);
} }
virtual void toJsonDoc(DynamicJsonDocument *doc,String name){ virtual void toJsonDoc(DynamicJsonDocument *doc,String name){
(*doc)[name]=data; (*doc)[name]=getData(true);
} }
static GwBoatItem<T> *findOrCreate(GwBoatData *handler, String name,bool doCreate=true, static GwBoatItem<T> *findOrCreate(GwBoatData *handler, String name,bool doCreate=true,
long invalidTime=GwBoatItemBase::INVALID_TIME){ long invalidTime=GwBoatItemBase::INVALID_TIME, Formatter fmt=NULL){
GwBoatItemMap *values=handler->getValues(); GwBoatItemMap *values=handler->getValues();
GwBoatItemMap::iterator it; GwBoatItemMap::iterator it;
if ((it=values->find(name)) != values->end()){ if ((it=values->find(name)) != values->end()){
return (GwBoatItem<T> *)it->second; return (GwBoatItem<T> *)it->second;
} }
if (! doCreate) return NULL; if (! doCreate) return NULL;
GwBoatItem<T> *ni=new GwBoatItem<T>(invalidTime); GwBoatItem<T> *ni=new GwBoatItem<T>(invalidTime,fmt);
(*values)[name]=ni; (*values)[name]=ni;
return ni; return ni;
} }

View File

@ -33,24 +33,30 @@ static void updateDouble(GwBoatItem<double> *item,double value){
if (value == N2kDoubleNA) return; if (value == N2kDoubleNA) return;
item->update(value); item->update(value);
} }
static double formatCourse(double cv){
return cv * radToDeg;
}
static double formatKnots(double cv){
return cv* 3600.0/1852.0;
}
N2kDataToNMEA0183::N2kDataToNMEA0183(GwLog * logger, GwBoatData *boatData, tNMEA2000 *NMEA2000, tNMEA0183 *NMEA0183) : tNMEA2000::tMsgHandler(0,NMEA2000){ N2kDataToNMEA0183::N2kDataToNMEA0183(GwLog * logger, GwBoatData *boatData, tNMEA2000 *NMEA2000, tNMEA0183 *NMEA0183) : tNMEA2000::tMsgHandler(0,NMEA2000){
SendNMEA0183MessageCallback=0; SendNMEA0183MessageCallback=0;
pNMEA0183=NMEA0183; pNMEA0183=NMEA0183;
Variation=N2kDoubleNA; COG=N2kDoubleNA; SOG=N2kDoubleNA; Variation=N2kDoubleNA;
SecondsSinceMidnight=N2kDoubleNA; DaysSince1970=N2kUInt16NA; SecondsSinceMidnight=N2kDoubleNA; DaysSince1970=N2kUInt16NA;
LastPosSend=0; LastPosSend=0;
lastLoopTime=0; lastLoopTime=0;
NextRMCSend=millis()+RMCPeriod; NextRMCSend=millis()+RMCPeriod;
LastHeadingTime=0;
LastCOGSOGTime=0;
LastWindTime=0; LastWindTime=0;
this->logger=logger; this->logger=logger;
this->boatData=boatData; this->boatData=boatData;
heading=GwBoatItem<double>::findOrCreate(boatData,F("Heading"),true,2000); heading=GwBoatItem<double>::findOrCreate(boatData,F("Heading"),true,2000,&formatCourse);
latitude=GwBoatItem<double>::findOrCreate(boatData,F("Latitude"),true,4000); latitude=GwBoatItem<double>::findOrCreate(boatData,F("Latitude"),true,4000);
longitude=GwBoatItem<double>::findOrCreate(boatData,F("Longitude"),true,4000); longitude=GwBoatItem<double>::findOrCreate(boatData,F("Longitude"),true,4000);
altitude=GwBoatItem<double>::findOrCreate(boatData,F("Altitude"),true,4000); altitude=GwBoatItem<double>::findOrCreate(boatData,F("Altitude"),true,4000);
cog=GwBoatItem<double>::findOrCreate(boatData,F("COG"),true,2000,&formatCourse);
sog=GwBoatItem<double>::findOrCreate(boatData,F("SOG"),true,2000,&formatKnots);
} }
//***************************************************************************** //*****************************************************************************
@ -76,10 +82,6 @@ void N2kDataToNMEA0183::loop() {
if ( now < (lastLoopTime + 100)) return; if ( now < (lastLoopTime + 100)) return;
lastLoopTime=now; lastLoopTime=now;
SendRMC(); SendRMC();
if ( (LastCOGSOGTime + 2000) < now ) {
COG = N2kDoubleNA;
SOG = N2kDoubleNA;
}
if ( ( LastWindTime + 2000) < now ) { if ( ( LastWindTime + 2000) < now ) {
AWS = N2kDoubleNA; AWS = N2kDoubleNA;
AWA = N2kDoubleNA; AWA = N2kDoubleNA;
@ -201,9 +203,11 @@ void N2kDataToNMEA0183::HandleCOGSOG(const tN2kMsg &N2kMsg) {
unsigned char SID; unsigned char SID;
tN2kHeadingReference HeadingReference; tN2kHeadingReference HeadingReference;
tNMEA0183Msg NMEA0183Msg; tNMEA0183Msg NMEA0183Msg;
double COG;
double SOG;
if ( ParseN2kCOGSOGRapid(N2kMsg, SID, HeadingReference, COG, SOG) ) { if ( ParseN2kCOGSOGRapid(N2kMsg, SID, HeadingReference, COG, SOG) ) {
LastCOGSOGTime = millis(); cog->update(COG);
sog->update(SOG);
double MCOG = ( !N2kIsNA(COG) && !N2kIsNA(Variation) ? COG - Variation : NMEA0183DoubleNA ); double MCOG = ( !N2kIsNA(COG) && !N2kIsNA(Variation) ? COG - Variation : NMEA0183DoubleNA );
if ( HeadingReference == N2khr_magnetic ) { if ( HeadingReference == N2khr_magnetic ) {
MCOG = COG; MCOG = COG;
@ -264,7 +268,7 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) {
if ( NMEA0183SetMWV(NMEA0183Msg, WindAngle*radToDeg, NMEA0183Reference , WindSpeed)) SendMessage(NMEA0183Msg); if ( NMEA0183SetMWV(NMEA0183Msg, WindAngle*radToDeg, NMEA0183Reference , WindSpeed)) SendMessage(NMEA0183Msg);
if (WindReference == N2kWind_Apparent && SOG != N2kDoubleNA) { // Lets calculate and send TWS/TWA if SOG is available if (WindReference == N2kWind_Apparent && sog->isValid(millis())) { // Lets calculate and send TWS/TWA if SOG is available
AWD=WindAngle*radToDeg + heading->getData()*radToDeg; AWD=WindAngle*radToDeg + heading->getData()*radToDeg;
if (AWD>360) AWD=AWD-360; if (AWD>360) AWD=AWD-360;
@ -273,8 +277,8 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) {
x = WindSpeed * cos(WindAngle); x = WindSpeed * cos(WindAngle);
y = WindSpeed * sin(WindAngle); y = WindSpeed * sin(WindAngle);
TWA = atan2(y, -SOG + x); TWA = atan2(y, -sog->getData() + x);
TWS = sqrt(( y*y) + ((-SOG+x)*(-SOG+x))); TWS = sqrt(( y*y) + ((- sog->getData()+x)*(-sog->getData()+x)));
if (TWS > MaxTws) MaxTws=TWS; if (TWS > MaxTws) MaxTws=TWS;
@ -308,7 +312,7 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) {
long now=millis(); long now=millis();
if ( NextRMCSend <= millis() && latitude->isValid(now) ) { if ( NextRMCSend <= millis() && latitude->isValid(now) ) {
tNMEA0183Msg NMEA0183Msg; tNMEA0183Msg NMEA0183Msg;
if ( NMEA0183SetRMC(NMEA0183Msg, SecondsSinceMidnight, latitude->getData(), longitude->getData(), COG, SOG, DaysSince1970, Variation) ) { if ( NMEA0183SetRMC(NMEA0183Msg, SecondsSinceMidnight, latitude->getData(), longitude->getData(), cog->getData(), sog->getData(), DaysSince1970, Variation) ) {
SendMessage(NMEA0183Msg); SendMessage(NMEA0183Msg);
} }
SetNextRMCSend(); SetNextRMCSend();

View File

@ -41,8 +41,8 @@ protected:
GwBoatItem<double> * altitude; GwBoatItem<double> * altitude;
double Variation; double Variation;
GwBoatItem<double> *heading; GwBoatItem<double> *heading;
double COG; GwBoatItem<double> *cog;
double SOG; GwBoatItem<double> *sog;
double STW; double STW;
double TWS; double TWS;
@ -65,9 +65,7 @@ protected:
uint16_t DaysSince1970; uint16_t DaysSince1970;
double SecondsSinceMidnight; double SecondsSinceMidnight;
unsigned long LastHeadingTime;
unsigned long LastCOGSOGTime;
unsigned long LastPosSend; unsigned long LastPosSend;
unsigned long LastWindTime; unsigned long LastWindTime;
unsigned long NextRMCSend; unsigned long NextRMCSend;