From 54d6d51519a65c8cab6af187a8286d85b5ded2a1 Mon Sep 17 00:00:00 2001 From: quantenschaum Date: Wed, 21 Aug 2024 14:57:36 +0200 Subject: [PATCH 1/3] tried to fix wind conversion, disabled wind calculation --- lib/boatData/GwBoatData.h | 53 +++++++++++++------------ lib/nmea0183ton2k/NMEA0183DataToN2K.cpp | 37 ++++++++--------- lib/nmea2kto0183/N2kDataToNMEA0183.cpp | 41 +++++++++++-------- 3 files changed, 69 insertions(+), 62 deletions(-) diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h index 6d3ab19..fd57a87 100644 --- a/lib/boatData/GwBoatData.h +++ b/lib/boatData/GwBoatData.h @@ -175,41 +175,42 @@ class GwBoatData{ GwBoatItemBase::GwBoatItemMap values; public: - GWBOATDATA(double,COG,4000,formatCourse) - GWBOATDATA(double,TWD,4000,formatCourse) - GWBOATDATA(double,SOG,4000,formatKnots) - GWBOATDATA(double,STW,4000,formatKnots) - GWBOATDATA(double,TWS,4000,formatKnots) - GWBOATDATA(double,AWS,4000,formatKnots) - GWBOATDATA(double,MaxTws,0,formatKnots) + GWBOATDATA(double,COG,4000,formatCourse) // course over ground + GWBOATDATA(double,SOG,4000,formatKnots) // speed over ground + GWBOATDATA(double,HDG,4000,formatCourse) // true heading + GWBOATDATA(double,MHDG,4000,formatCourse) // magnetic heading + GWBOATDATA(double,STW,4000,formatKnots) // water speed + GWBOATDATA(double,VAR,4000,formatCourse) // variation + GWBOATDATA(double,DEV,4000,formatCourse) // deviation + GWBOATDATA(double,AWA,4000,formatWind) // apparent wind ANGLE + GWBOATDATA(double,AWS,4000,formatKnots) // apparent wind speed GWBOATDATA(double,MaxAws,0,formatKnots) - GWBOATDATA(double,AWA,4000,formatWind) - GWBOATDATA(double,HDG,4000,formatCourse) //true heading - GWBOATDATA(double,MHDG,4000,formatCourse) //magnetic heading - GWBOATDATA(double,ROT,4000,formatRot) - GWBOATDATA(double,VAR,4000,formatCourse) //Variation - GWBOATDATA(double,DEV,4000,formatCourse) //Deviation + GWBOATDATA(double,TWD,4000,formatCourse) // true wind DIRECTION + GWBOATDATA(double,TWA,4000,formatCourse) // true wind ANGLE + GWBOATDATA(double,TWS,4000,formatKnots) // true wind speed + GWBOATDATA(double,MaxTws,0,formatKnots) + GWBOATDATA(double,ROT,4000,formatRot) // rate of turn + GWBOATDATA(double,RPOS,4000,formatWind) // rudder position + GWBOATDATA(double,PRPOS,4000,formatWind) // secondary rudder position + GWBOATDATA(double,LAT,4000,formatLatitude) + GWBOATDATA(double,LON,4000,formatLongitude) + GWBOATDATA(double,ALT,4000,formatFixed0) //altitude GWBOATDATA(double,HDOP,4000,formatDop) GWBOATDATA(double,PDOP,4000,formatDop) GWBOATDATA(double,VDOP,4000,formatDop) - GWBOATDATA(double,RPOS,4000,formatWind) //RudderPosition - GWBOATDATA(double,PRPOS,4000,formatWind) //second rudder pos - GWBOATDATA(double,LAT,4000,formatLatitude) - GWBOATDATA(double,LON,4000,formatLongitude) - GWBOATDATA(double,ALT,4000,formatFixed0) //altitude GWBOATDATA(double,DBS,4000,formatDepth) //waterDepth (below surface) GWBOATDATA(double,DBT,4000,formatDepth) //DepthTransducer - GWBOATDATA(double,GPST,4000,formatTime) //GpsTime + GWBOATDATA(double,GPST,4000,formatTime) // GPS time (seconds of day) + GWBOATDATA(uint32_t,GPSD,4000,formatDate) // GPS date (days since 1979-01-01) + GWBOATDATA(int16_t,TZ,8000,formatFixed0) GWBOATDATA(double,WTemp,4000,kelvinToC) - GWBOATDATA(double,XTE,4000,formatXte) - GWBOATDATA(double,DTW,4000,mtr2nm) //distance wp - GWBOATDATA(double,BTW,4000,formatCourse) //bearing wp - GWBOATDATA(double,WPLat,4000,formatLatitude) - GWBOATDATA(double,WPLon,4000,formatLongitude) GWBOATDATA(uint32_t,Log,16000,mtr2nm) GWBOATDATA(uint32_t,TripLog,16000,mtr2nm) - GWBOATDATA(uint32_t,GPSD,4000,formatDate) //Date - GWBOATDATA(int16_t,TZ,8000,formatFixed0) + GWBOATDATA(double,DTW,4000,mtr2nm) // distance to waypoint + GWBOATDATA(double,BTW,4000,formatCourse) // bearing to waypoint + GWBOATDATA(double,XTE,4000,formatXte) // cross track error + GWBOATDATA(double,WPLat,4000,formatLatitude) // waypoint latitude + GWBOATDATA(double,WPLon,4000,formatLongitude) // waypoint longitude GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::lifeTime,formatFixed0); public: GwBoatData(GwLog *logger); diff --git a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp index bfed8fd..8477ab8 100644 --- a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp +++ b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp @@ -399,20 +399,20 @@ private: return; } tN2kMsg n2kMsg; - tN2kWindReference n2kRef; + tN2kWindReference n2kRef; bool shouldSend=false; WindAngle=formatDegToRad(WindAngle); switch(Reference){ case NMEA0183Wind_Apparent: n2kRef=N2kWind_Apparent; shouldSend=updateDouble(boatData->AWA,WindAngle,msg.sourceId) && - updateDouble(boatData->AWS,WindSpeed,msg.sourceId); + updateDouble(boatData->AWS,WindSpeed,msg.sourceId); if (WindSpeed != NMEA0183DoubleNA) boatData->MaxAws->updateMax(WindSpeed); break; case NMEA0183Wind_True: - n2kRef=N2kWind_True_North; - shouldSend=updateDouble(boatData->TWD,WindAngle,msg.sourceId) && - updateDouble(boatData->TWS,WindSpeed,msg.sourceId); + n2kRef=N2kWind_True_water; + shouldSend=updateDouble(boatData->TWA,WindAngle,msg.sourceId) && + updateDouble(boatData->TWS,WindSpeed,msg.sourceId); if (WindSpeed != NMEA0183DoubleNA) boatData->MaxTws->updateMax(WindSpeed); break; default: @@ -467,8 +467,7 @@ private: void convertMWD(const SNMEA0183Msg &msg) { - double WindAngle = NMEA0183DoubleNA, WindAngleMagnetic=NMEA0183DoubleNA, - WindSpeed = NMEA0183DoubleNA; + double WindDirection = NMEA0183DoubleNA, WindDirectionMagnetic=NMEA0183DoubleNA, WindSpeed = NMEA0183DoubleNA; if (msg.FieldCount() < 8 ) { LOG_DEBUG(GwLog::DEBUG, "failed to parse MWD %s", msg.line); @@ -476,11 +475,11 @@ private: } if (msg.FieldLen(0) > 0 && msg.Field(1)[0] == 'T') { - WindAngle = formatDegToRad(atof(msg.Field(0))); + WindDirection = formatDegToRad(atof(msg.Field(0))); } if (msg.FieldLen(2) > 0 && msg.Field(3)[0] == 'M') { - WindAngleMagnetic = formatDegToRad(atof(msg.Field(2))); + WindDirectionMagnetic = formatDegToRad(atof(msg.Field(2))); } if (msg.FieldLen(4) > 0 && msg.Field(5)[0] == 'N') { @@ -497,19 +496,17 @@ private: } tN2kMsg n2kMsg; bool shouldSend = false; - if (WindAngle != NMEA0183DoubleNA){ - shouldSend = updateDouble(boatData->TWD, WindAngle, msg.sourceId) && + if (WindDirection != NMEA0183DoubleNA){ + shouldSend = updateDouble(boatData->TWD, WindDirection, msg.sourceId) && updateDouble(boatData->TWS, WindSpeed, msg.sourceId); if (WindSpeed != NMEA0183DoubleNA) boatData->MaxTws->updateMax(WindSpeed); - } - if (shouldSend) - { - SetN2kWindSpeed(n2kMsg, 1, WindSpeed, WindAngle, N2kWind_True_North); - send(n2kMsg,msg.sourceId,String(n2kMsg.PGN)+String((int)N2kWind_True_North)); - } - if (WindAngleMagnetic != NMEA0183DoubleNA && shouldSend){ - SetN2kWindSpeed(n2kMsg, 1, WindSpeed, WindAngleMagnetic, N2kWind_Magnetic); - send(n2kMsg,msg.sourceId,String(n2kMsg.PGN)+String((int)N2kWind_Magnetic)); + if(shouldSend && boatData->HDG->isValid()) { + double twa = WindDirection-boatData->HDG->getData(); + if(twa<0) { twa+=2*M_PI; } + updateDouble(boatData->TWA, twa, msg.sourceId); + SetN2kWindSpeed(n2kMsg, 1, WindSpeed, twa, N2kWind_True_water); + send(n2kMsg,msg.sourceId,String(n2kMsg.PGN)+String((int)N2kWind_True_water)); + } } } diff --git a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp index 26c6811..b08ac7d 100644 --- a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp @@ -468,37 +468,46 @@ private: { unsigned char SID; tN2kWindReference WindReference; - tNMEA0183WindReference NMEA0183Reference = NMEA0183Wind_True; - - double x, y; double WindAngle=N2kDoubleNA, WindSpeed=N2kDoubleNA; - if (ParseN2kWindSpeed(N2kMsg, SID, WindSpeed, WindAngle, WindReference)) - { + if (ParseN2kWindSpeed(N2kMsg, SID, WindSpeed, WindAngle, WindReference)) { tNMEA0183Msg NMEA0183Msg; + tNMEA0183WindReference NMEA0183Reference; + bool shouldSend = false; - if (WindReference == N2kWind_Apparent) - { + // MWV sentence contains apparent/true ANGLE and SPEED + // https://gpsd.gitlab.io/gpsd/NMEA.html#_mwv_wind_speed_and_angle + // https://docs.vaisala.com/r/M211109EN-L/en-US/GUID-7402DEF8-5E82-446F-B63E-998F49F3D743/GUID-C77934C7-2A72-466E-BC52-CE6B8CC7ACB6 + + if (WindReference == N2kWind_Apparent) { NMEA0183Reference = NMEA0183Wind_Apparent; updateDouble(boatData->AWA, WindAngle); updateDouble(boatData->AWS, WindSpeed); setMax(boatData->MaxAws, boatData->AWS); - } - if (WindReference == N2kWind_True_North) - { + shouldSend = true; + } + if (WindReference == N2kWind_True_water) { NMEA0183Reference = NMEA0183Wind_True; - updateDouble(boatData->TWD, WindAngle); + updateDouble(boatData->TWA, WindAngle); updateDouble(boatData->TWS, WindSpeed); + setMax(boatData->MaxTws, boatData->TWS); + shouldSend = true; + if (boatData->HDG->isValid()) { + double twd = WindAngle+boatData->HDG->getData(); + if (twd>2*M_PI) { twd-=2*M_PI; } + updateDouble(boatData->TWD, twd); + } } - if (NMEA0183SetMWV(NMEA0183Msg, formatCourse(WindAngle), NMEA0183Reference, WindSpeed,talkerId)) + if (shouldSend && NMEA0183SetMWV(NMEA0183Msg, formatCourse(WindAngle), NMEA0183Reference, WindSpeed, talkerId)) { SendMessage(NMEA0183Msg); + } - if (WindReference == N2kWind_Apparent && boatData->SOG->isValid()) + /* if (WindReference == N2kWind_Apparent && boatData->SOG->isValid()) { // Lets calculate and send TWS/TWA if SOG is available - x = WindSpeed * cos(WindAngle); - y = WindSpeed * sin(WindAngle); + double x = WindSpeed * cos(WindAngle); + double y = WindSpeed * sin(WindAngle); updateDouble(boatData->TWD, atan2(y, -boatData->SOG->getData() + x)); updateDouble(boatData->TWS, sqrt((y * y) + ((-boatData->SOG->getData() + x) * (-boatData->SOG->getData() + x)))); @@ -534,7 +543,7 @@ private: return; SendMessage(NMEA0183Msg); - } + } */ } } //***************************************************************************** From 1fa10497594d4155fc4b345b6443f870c248bf68 Mon Sep 17 00:00:00 2001 From: quantenschaum Date: Thu, 22 Aug 2024 15:16:23 +0200 Subject: [PATCH 2/3] renamed HDG->HDT, MHDG->HDM --- lib/boatData/GwBoatData.h | 4 +-- lib/nmea0183ton2k/NMEA0183DataToN2K.cpp | 35 +++++++++++++------------ lib/nmea2kto0183/N2kDataToNMEA0183.cpp | 16 +++++------ 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h index fd57a87..b4df0ec 100644 --- a/lib/boatData/GwBoatData.h +++ b/lib/boatData/GwBoatData.h @@ -177,8 +177,8 @@ class GwBoatData{ GWBOATDATA(double,COG,4000,formatCourse) // course over ground GWBOATDATA(double,SOG,4000,formatKnots) // speed over ground - GWBOATDATA(double,HDG,4000,formatCourse) // true heading - GWBOATDATA(double,MHDG,4000,formatCourse) // magnetic heading + GWBOATDATA(double,HDT,4000,formatCourse) // true heading + GWBOATDATA(double,HDM,4000,formatCourse) // magnetic heading GWBOATDATA(double,STW,4000,formatKnots) // water speed GWBOATDATA(double,VAR,4000,formatCourse) // variation GWBOATDATA(double,DEV,4000,formatCourse) // deviation diff --git a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp index 8477ab8..7868eaf 100644 --- a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp +++ b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp @@ -500,8 +500,8 @@ private: shouldSend = updateDouble(boatData->TWD, WindDirection, msg.sourceId) && updateDouble(boatData->TWS, WindSpeed, msg.sourceId); if (WindSpeed != NMEA0183DoubleNA) boatData->MaxTws->updateMax(WindSpeed); - if(shouldSend && boatData->HDG->isValid()) { - double twa = WindDirection-boatData->HDG->getData(); + if(shouldSend && boatData->HDT->isValid()) { + double twa = WindDirection-boatData->HDT->getData(); if(twa<0) { twa+=2*M_PI; } updateDouble(boatData->TWA, twa, msg.sourceId); SetN2kWindSpeed(n2kMsg, 1, WindSpeed, twa, N2kWind_True_water); @@ -511,15 +511,15 @@ private: } void convertHDM(const SNMEA0183Msg &msg){ - double MHDG=NMEA0183DoubleNA; - if (!NMEA0183ParseHDM_nc(msg, MHDG)) + double HDM=NMEA0183DoubleNA; + if (!NMEA0183ParseHDM_nc(msg, HDM)) { LOG_DEBUG(GwLog::DEBUG, "failed to parse HDM %s", msg.line); return; } - if (! UD(MHDG)) return; + if (! UD(HDM)) return; tN2kMsg n2kMsg; - SetN2kMagneticHeading(n2kMsg,1,MHDG, + SetN2kMagneticHeading(n2kMsg,1,HDM, boatData->VAR->getDataWithDefault(N2kDoubleNA), boatData->DEV->getDataWithDefault(N2kDoubleNA) ); @@ -527,28 +527,29 @@ private: } void convertHDT(const SNMEA0183Msg &msg){ - double HDG=NMEA0183DoubleNA; - if (!NMEA0183ParseHDT_nc(msg, HDG)) + double HDT=NMEA0183DoubleNA; + if (!NMEA0183ParseHDT_nc(msg, HDT)) { LOG_DEBUG(GwLog::DEBUG, "failed to parse HDT %s", msg.line); return; } - if (! UD(HDG)) return; + if (! UD(HDT)) return; tN2kMsg n2kMsg; - SetN2kTrueHeading(n2kMsg,1,HDG); + SetN2kTrueHeading(n2kMsg,1,HDT); send(n2kMsg,msg.sourceId); } + void convertHDG(const SNMEA0183Msg &msg){ - double MHDG=NMEA0183DoubleNA; - double VAR=NMEA0183DoubleNA; + double HDM=NMEA0183DoubleNA; double DEV=NMEA0183DoubleNA; + double VAR=NMEA0183DoubleNA; if (msg.FieldCount() < 5) { LOG_DEBUG(GwLog::DEBUG, "failed to parse HDG %s", msg.line); return; } if (msg.FieldLen(0)>0){ - MHDG=formatDegToRad(atof(msg.Field(0))); + HDM=formatDegToRad(atof(msg.Field(0))); } else{ return; @@ -562,11 +563,11 @@ private: if (msg.Field(4)[0] == 'W') VAR=-VAR; } - if (! UD(MHDG)) return; + if (! UD(HDM)) return; UD(VAR); UD(DEV); tN2kMsg n2kMsg; - SetN2kMagneticHeading(n2kMsg,1,MHDG,DEV,VAR); + SetN2kMagneticHeading(n2kMsg,1,HDM,DEV,VAR); send(n2kMsg,msg.sourceId,"127250M"); } @@ -702,11 +703,11 @@ private: return; } tN2kMsg n2kMsg; - if (updateDouble(boatData->HDG,TrueHeading,msg.sourceId)){ + if (updateDouble(boatData->HDT,TrueHeading,msg.sourceId)){ SetN2kTrueHeading(n2kMsg,1,TrueHeading); send(n2kMsg,msg.sourceId); } - if(updateDouble(boatData->MHDG,MagneticHeading,msg.sourceId)){ + if(updateDouble(boatData->HDM,MagneticHeading,msg.sourceId)){ SetN2kMagneticHeading(n2kMsg,1,MagneticHeading, boatData->DEV->getDataWithDefault(N2kDoubleNA), boatData->VAR->getDataWithDefault(N2kDoubleNA) diff --git a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp index b08ac7d..390d7f1 100644 --- a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp @@ -185,13 +185,13 @@ private: if (N2kIsNA(Variation)){ //no variation if (ref == N2khr_magnetic){ - updateDouble(boatData->MHDG,Heading); + updateDouble(boatData->HDM,Heading); if (NMEA0183SetHDM(NMEA0183Msg,Heading,talkerId)){ SendMessage(NMEA0183Msg); } } if (ref == N2khr_true){ - updateDouble(boatData->HDG,Heading); + updateDouble(boatData->HDT,Heading); if (NMEA0183SetHDT(NMEA0183Msg,Heading,talkerId)){ SendMessage(NMEA0183Msg); } @@ -206,8 +206,8 @@ private: if (ref == N2khr_true){ MagneticHeading=Heading-Variation; } - updateDouble(boatData->MHDG,MagneticHeading); - updateDouble(boatData->HDG,Heading); + updateDouble(boatData->HDM,MagneticHeading); + updateDouble(boatData->HDT,Heading); if (!N2kIsNA(MagneticHeading)){ if (NMEA0183SetHDG(NMEA0183Msg, MagneticHeading,_Deviation, Variation,talkerId)) @@ -252,8 +252,8 @@ private: tNMEA0183Msg NMEA0183Msg; updateDouble(boatData->STW, WaterReferenced); unsigned long now = millis(); - double MagneticHeading = (boatData->HDG->isValid(now) && boatData->VAR->isValid(now)) ? boatData->HDG->getData() + boatData->VAR->getData() : NMEA0183DoubleNA; - if (NMEA0183SetVHW(NMEA0183Msg, boatData->HDG->getDataWithDefault(NMEA0183DoubleNA), MagneticHeading, WaterReferenced,talkerId)) + double MagneticHeading = (boatData->HDT->isValid(now) && boatData->VAR->isValid(now)) ? boatData->HDT->getData() + boatData->VAR->getData() : NMEA0183DoubleNA; + if (NMEA0183SetVHW(NMEA0183Msg, boatData->HDT->getDataWithDefault(NMEA0183DoubleNA), MagneticHeading, WaterReferenced,talkerId)) { SendMessage(NMEA0183Msg); } @@ -492,8 +492,8 @@ private: updateDouble(boatData->TWS, WindSpeed); setMax(boatData->MaxTws, boatData->TWS); shouldSend = true; - if (boatData->HDG->isValid()) { - double twd = WindAngle+boatData->HDG->getData(); + if (boatData->HDT->isValid()) { + double twd = WindAngle+boatData->HDT->getData(); if (twd>2*M_PI) { twd-=2*M_PI; } updateDouble(boatData->TWD, twd); } From 26d1fd40eebfc08a77e1264f032131eff7d29d16 Mon Sep 17 00:00:00 2001 From: quantenschaum Date: Thu, 22 Aug 2024 15:17:16 +0200 Subject: [PATCH 3/3] adjusted formatting --- lib/boatData/GwBoatData.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h index b4df0ec..f5af8e8 100644 --- a/lib/boatData/GwBoatData.h +++ b/lib/boatData/GwBoatData.h @@ -180,13 +180,13 @@ class GwBoatData{ GWBOATDATA(double,HDT,4000,formatCourse) // true heading GWBOATDATA(double,HDM,4000,formatCourse) // magnetic heading GWBOATDATA(double,STW,4000,formatKnots) // water speed - GWBOATDATA(double,VAR,4000,formatCourse) // variation - GWBOATDATA(double,DEV,4000,formatCourse) // deviation + GWBOATDATA(double,VAR,4000,formatWind) // variation + GWBOATDATA(double,DEV,4000,formatWind) // deviation GWBOATDATA(double,AWA,4000,formatWind) // apparent wind ANGLE GWBOATDATA(double,AWS,4000,formatKnots) // apparent wind speed GWBOATDATA(double,MaxAws,0,formatKnots) GWBOATDATA(double,TWD,4000,formatCourse) // true wind DIRECTION - GWBOATDATA(double,TWA,4000,formatCourse) // true wind ANGLE + GWBOATDATA(double,TWA,4000,formatWind) // true wind ANGLE GWBOATDATA(double,TWS,4000,formatKnots) // true wind speed GWBOATDATA(double,MaxTws,0,formatKnots) GWBOATDATA(double,ROT,4000,formatRot) // rate of turn