From 68769368f243e6e3aac83893a40647320f46a49c Mon Sep 17 00:00:00 2001 From: andreas Date: Mon, 18 Oct 2021 21:58:32 +0200 Subject: [PATCH] further move to dynamic boat data --- lib/boatData/GwBoatData.h | 18 ++++++++++----- lib/nmea2kto0183/N2kDataToNMEA0183.cpp | 32 +++++++++++++++----------- lib/nmea2kto0183/N2kDataToNMEA0183.h | 8 +++---- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h index f00e2b1..f88fb16 100644 --- a/lib/boatData/GwBoatData.h +++ b/lib/boatData/GwBoatData.h @@ -43,30 +43,36 @@ class GwBoatData{ friend class GwBoatItemBase; }; template class GwBoatItem : public GwBoatItemBase{ + public: + typedef T (*Formatter)(T); private: T data; + Formatter fmt; public: - GwBoatItem(long invalidTime=INVALID_TIME): GwBoatItemBase(invalidTime){} + GwBoatItem(long invalidTime=INVALID_TIME,Formatter fmt=NULL): GwBoatItemBase(invalidTime){ + this->fmt=fmt; + } virtual ~GwBoatItem(){} void update(T nv){ data=nv; uls(); } - T getData(){ - return data; + T getData(bool useFormatter=false){ + if (! useFormatter || fmt == NULL) return data; + return (*fmt)(data); } virtual void toJsonDoc(DynamicJsonDocument *doc,String name){ - (*doc)[name]=data; + (*doc)[name]=getData(true); } static GwBoatItem *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::iterator it; if ((it=values->find(name)) != values->end()){ return (GwBoatItem *)it->second; } if (! doCreate) return NULL; - GwBoatItem *ni=new GwBoatItem(invalidTime); + GwBoatItem *ni=new GwBoatItem(invalidTime,fmt); (*values)[name]=ni; return ni; } diff --git a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp index 2b9b585..8623e32 100644 --- a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp @@ -33,24 +33,30 @@ static void updateDouble(GwBoatItem *item,double value){ if (value == N2kDoubleNA) return; 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){ SendNMEA0183MessageCallback=0; pNMEA0183=NMEA0183; - Variation=N2kDoubleNA; COG=N2kDoubleNA; SOG=N2kDoubleNA; + Variation=N2kDoubleNA; SecondsSinceMidnight=N2kDoubleNA; DaysSince1970=N2kUInt16NA; LastPosSend=0; lastLoopTime=0; NextRMCSend=millis()+RMCPeriod; - LastHeadingTime=0; - LastCOGSOGTime=0; LastWindTime=0; this->logger=logger; this->boatData=boatData; - heading=GwBoatItem::findOrCreate(boatData,F("Heading"),true,2000); + heading=GwBoatItem::findOrCreate(boatData,F("Heading"),true,2000,&formatCourse); latitude=GwBoatItem::findOrCreate(boatData,F("Latitude"),true,4000); longitude=GwBoatItem::findOrCreate(boatData,F("Longitude"),true,4000); altitude=GwBoatItem::findOrCreate(boatData,F("Altitude"),true,4000); + cog=GwBoatItem::findOrCreate(boatData,F("COG"),true,2000,&formatCourse); + sog=GwBoatItem::findOrCreate(boatData,F("SOG"),true,2000,&formatKnots); } //***************************************************************************** @@ -76,10 +82,6 @@ void N2kDataToNMEA0183::loop() { if ( now < (lastLoopTime + 100)) return; lastLoopTime=now; SendRMC(); - if ( (LastCOGSOGTime + 2000) < now ) { - COG = N2kDoubleNA; - SOG = N2kDoubleNA; - } if ( ( LastWindTime + 2000) < now ) { AWS = N2kDoubleNA; AWA = N2kDoubleNA; @@ -201,9 +203,11 @@ void N2kDataToNMEA0183::HandleCOGSOG(const tN2kMsg &N2kMsg) { unsigned char SID; tN2kHeadingReference HeadingReference; tNMEA0183Msg NMEA0183Msg; - + double COG; + double 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 ); if ( HeadingReference == N2khr_magnetic ) { MCOG = COG; @@ -264,7 +268,7 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) { 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; if (AWD>360) AWD=AWD-360; @@ -273,8 +277,8 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) { x = WindSpeed * cos(WindAngle); y = WindSpeed * sin(WindAngle); - TWA = atan2(y, -SOG + x); - TWS = sqrt(( y*y) + ((-SOG+x)*(-SOG+x))); + TWA = atan2(y, -sog->getData() + x); + TWS = sqrt(( y*y) + ((- sog->getData()+x)*(-sog->getData()+x))); if (TWS > MaxTws) MaxTws=TWS; @@ -308,7 +312,7 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) { long now=millis(); if ( NextRMCSend <= millis() && latitude->isValid(now) ) { 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); } SetNextRMCSend(); diff --git a/lib/nmea2kto0183/N2kDataToNMEA0183.h b/lib/nmea2kto0183/N2kDataToNMEA0183.h index 45cbad9..ceab287 100644 --- a/lib/nmea2kto0183/N2kDataToNMEA0183.h +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.h @@ -41,8 +41,8 @@ protected: GwBoatItem * altitude; double Variation; GwBoatItem *heading; - double COG; - double SOG; + GwBoatItem *cog; + GwBoatItem *sog; double STW; double TWS; @@ -65,9 +65,7 @@ protected: uint16_t DaysSince1970; double SecondsSinceMidnight; - - unsigned long LastHeadingTime; - unsigned long LastCOGSOGTime; + unsigned long LastPosSend; unsigned long LastWindTime; unsigned long NextRMCSend;