From 54d6d51519a65c8cab6af187a8286d85b5ded2a1 Mon Sep 17 00:00:00 2001 From: quantenschaum Date: Wed, 21 Aug 2024 14:57:36 +0200 Subject: [PATCH] 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); - } + } */ } } //*****************************************************************************