gpsd-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gpsd-dev] [PATCH 6/6] Add Wind related NMEA sentence (MWD, MWV, VWR, VW


From: chris
Subject: [gpsd-dev] [PATCH 6/6] Add Wind related NMEA sentence (MWD, MWV, VWR, VWT)
Date: Sat, 21 Apr 2012 10:34:22 +0100

From: Christian Gagneraud <address@hidden>

For now only MWD and MWV have been tested and manually checked with live data.
Manual check was input NMEA vs output JSON, with NMEA units in knots.
---
 driver_nmea0183.c |  198 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 gps.h             |    2 +
 2 files changed, 197 insertions(+), 3 deletions(-)

diff --git a/driver_nmea0183.c b/driver_nmea0183.c
index d2e45fa..8495468 100644
--- a/driver_nmea0183.c
+++ b/driver_nmea0183.c
@@ -888,7 +888,7 @@ static gps_mask_t processROT(int c UNUSED, char *field[],
      * <2> Status: A = Data Valid; V = Data Invalid.
      */
     gps_mask_t mask;
-    if (field[2][0] != 'V')
+    if (field[2][0] != 'A')
         return 0;
     mask = ONLINE_SET;
 
@@ -918,9 +918,9 @@ static gps_mask_t processROT(int c UNUSED, char *field[],
     session->gpsdata.attitude.depth = NAN;
     mask |= (ATTITUDE_SET);
 
-    gpsd_report(LOG_RAW, "time %.3f, heading %lf.\n",
+    gpsd_report(LOG_RAW, "time %.3f,rate of turn %.1f\n",
                session->newdata.time,
-               session->gpsdata.attitude.heading);
+               session->gpsdata.attitude.rot);
     return mask;
 }
 
@@ -971,6 +971,194 @@ static gps_mask_t processDBT(int c UNUSED, char *field[],
     return mask;
 }
 
+static gps_mask_t processMWD(int c UNUSED, char *field[],
+                               struct gps_device_t *session)
+{
+    /*
+     * $WIMWD,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>*hh
+     *
+     * NMEA 0183 standard Wind Direction and Speed, with respect to north.
+     *
+     * <1> Wind direction, 0.0 to 359.9 degrees True, to the nearest 0.1 degree
+     * <2> T = True
+     * <3> Wind direction, 0.0 to 359.9 degrees Magnetic, to the nearest 0.1 
degree
+     * <4> M = Magnetic
+     * <5> Wind speed, knots, to the nearest 0.1 knot.
+     * <6> N = Knots
+     * <7> Wind speed, meters/second, to the nearest 0.1 m/s.
+     * <8> M = Meters/second
+     */
+    gps_mask_t mask;
+    mask = ONLINE_SET;
+
+    session->gpsdata.wind.dir_type = WIND_DIR_NORTH;
+    session->gpsdata.wind.dir = safe_atof(field[1]);
+    session->gpsdata.wind.dir_mag = safe_atof(field[3]);
+    session->gpsdata.wind.speed_type = WIND_SPEED_VESSEL;
+    session->gpsdata.wind.speed = safe_atof(field[7]);
+    mask |= (WIND_SET);
+
+    gpsd_report(LOG_RAW, "wind speed %.1f, wind direction %.1f\n",
+               session->gpsdata.wind.speed,
+               session->gpsdata.wind.dir);
+    return mask;
+}
+
+static gps_mask_t processMWV(int c UNUSED, char *field[],
+                               struct gps_device_t *session)
+{
+    /*
+     * $WIMWV,<1>,<2>,<3>,<4>,<5>*hh
+     *
+     * NMEA 0183 standard Wind Speed and Angle, in relation to the vessel’s 
bow/centerline.
+     *
+     * <1> Wind angle, 0.0 to 359.9 degrees, in relation to the vessel’s 
bow/centerline, 
+     *     to the nearest 0.1 degree
+     * <2> Reference: 'R' for relative (apparent wind, as felt when standing 
on the
+     *                                  moving ship)
+     *                'T' for theorical (calculated actual wind, as though the 
vessel
+     *                                   were stationary)
+     * <3> Wind speed, to the nearest tenth of a unit.
+     * <4> Wind speed units: K = km/hr, M = m/s, N = knots, S = statute 
miles/hr
+     * <5> Status: A = data valid; V = data invalid
+     */
+    gps_mask_t mask;
+
+    if (field[5][0] != 'A' || (field[2][0] != 'R' && field[2][0] != 'T') ||
+       (field[4][0] != 'K' && field[4][0] != 'M' && field[4][0] != 'N' && 
+        field[4][0] != 'S'))
+        return 0;
+
+    mask = ONLINE_SET;
+
+    session->gpsdata.wind.dir_type = WIND_DIR_VESSEL;
+    // Is wind angle same as wind direction?
+    session->gpsdata.wind.dir = safe_atof(field[1]);
+    session->gpsdata.wind.dir_mag = NAN;
+    if (field[2][0] == 'R')
+        session->gpsdata.wind.speed_type = WIND_SPEED_VESSEL;
+    else
+        session->gpsdata.wind.speed_type = WIND_SPEED_GROUND;
+    if (field[4][0] == 'M')
+        session->gpsdata.wind.speed = safe_atof(field[3]);
+    else if (field[4][0] == 'K')
+        session->gpsdata.wind.speed = safe_atof(field[3]) / KPH_TO_MPS;
+    else if (field[4][0] == 'N')
+        session->gpsdata.wind.speed = safe_atof(field[3]) / KNOTS_TO_MPS;
+    else if (field[4][0] == 'S')
+        session->gpsdata.wind.speed = safe_atof(field[3]) / MPH_TO_MPS;
+
+    mask |= (WIND_SET);
+
+    gpsd_report(LOG_RAW, "wind speed %.1f, wind direction %.1f\n",
+               session->gpsdata.wind.speed,
+               session->gpsdata.wind.dir);
+    return mask;
+}
+
+static gps_mask_t processVWR(int c UNUSED, char *field[],
+                               struct gps_device_t *session)
+{
+    /*
+     * $WIVWR,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>*hh
+     *
+     * NMEA 0183 Relative (Apparent) Wind Speed and Angle. Wind angle in 
relation
+     * to the vessel’s heading, and wind speed measured relative to the 
moving vessel.
+     *
+     * <1> Measured wind angle relative to the vessel, 0 to 180°, left/right 
of
+     *     vessel heading, to the nearest 0.1 degree
+     * <2> L = left, or R = right
+     * <3> Measured wind speed, knots, to the nearest 0.1 knot
+     * <4> N = knots
+     * <5> Wind speed, meters per second, to the nearest 0.1 m/s
+     * <6> M = meters per second
+     * <7> Wind speed, km/h, to the nearest km/h
+     * <8> K = km/h
+     *
+     * TODO: Is wind angle same as wind direction?
+     */
+    gps_mask_t mask;
+
+    if ((field[2][0] != 'R' && field[2][0] == 'L') ||
+       field[4][0] != 'N' || field[6][0] != 'M' || field[8][0] != 'K')
+        return 0;
+
+    mask = ONLINE_SET;
+
+    session->gpsdata.wind.dir_type = WIND_DIR_HEADING;
+    session->gpsdata.wind.dir_mag = NAN;
+    if (field[2][0] == 'R')
+      session->gpsdata.wind.dir = safe_atof(field[1]);
+    else
+      session->gpsdata.wind.dir = 180.0 + safe_atof(field[1]);
+    session->gpsdata.wind.speed_type = WIND_SPEED_VESSEL;
+    if (field[5][0] != '\0')
+        session->gpsdata.wind.speed = safe_atof(field[5]);
+    else if (field[3][0] == '\0')
+        session->gpsdata.wind.speed = safe_atof(field[4]) / KNOTS_TO_MPS;
+    else if (field[7][0] == '\0')
+        session->gpsdata.wind.speed = safe_atof(field[8]) / KPH_TO_MPS;
+
+    mask |= (WIND_SET);
+
+    gpsd_report(LOG_RAW, "wind speed %.1f, wind direction %.1f\n",
+               session->gpsdata.wind.speed,
+               session->gpsdata.wind.dir);
+    return mask;
+}
+
+static gps_mask_t processVWT(int c UNUSED, char *field[],
+                               struct gps_device_t *session)
+{
+    /*
+     * $WIVWT,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>*hh
+     *
+     * NMEA 0183 True wind angle in relation to the vessel’s heading, and 
true wind
+     * speed referenced to the water. True wind is the vector sum of the 
Relative
+     * (apparent) wind vector and the vessel’s velocity vector relative to 
the water along
+     * the heading line of the vessel. It represents the wind at the vessel if 
it were
+     * stationary relative to the water and heading in the same direction.
+     *
+     * <1> Calculated wind angle relative to the vessel, 0 to 180°, 
left/right of
+     *     vessel heading, to the nearest 0.1 degree
+     * <2> L = left, or R = right
+     * <3> Calculated wind speed, knots, to the nearest 0.1 knot
+     * <4> N = knots
+     * <5> Wind speed, meters per second, to the nearest 0.1 m/s
+     * <6> M = meters per second
+     * <7> Wind speed, km/h, to the nearest km/h
+     * <8> K = km/h
+     */
+    gps_mask_t mask;
+
+    if ((field[2][0] != 'R' && field[2][0] == 'L') ||
+       field[4][0] != 'N' || field[6][0] != 'M' || field[8][0] != 'K')
+        return 0;
+
+    mask = ONLINE_SET;
+
+    session->gpsdata.wind.dir_type = WIND_DIR_HEADING;
+    session->gpsdata.wind.dir_mag = NAN;
+    if (field[2][0] == 'R')
+      session->gpsdata.wind.dir = safe_atof(field[1]);
+    else
+      session->gpsdata.wind.dir = 180.0 + safe_atof(field[1]);
+    session->gpsdata.wind.speed_type = WIND_SPEED_WATER;
+    if (field[5][0] != '\0')
+        session->gpsdata.wind.speed = safe_atof(field[5]);
+    else if (field[3][0] == '\0')
+        session->gpsdata.wind.speed = safe_atof(field[4]) / KNOTS_TO_MPS;
+    else if (field[7][0] == '\0')
+        session->gpsdata.wind.speed = safe_atof(field[8]) / KPH_TO_MPS;
+
+    mask |= (WIND_SET);
+
+    gpsd_report(LOG_RAW, "wind speed %.1f, wind direction %.1f\n",
+               session->gpsdata.wind.speed,
+               session->gpsdata.wind.dir);
+    return mask;
+}
+
 #ifdef TNT_ENABLE
 static gps_mask_t processTNTHTM(int c UNUSED, char *field[],
                                struct gps_device_t *session)
@@ -1227,6 +1415,10 @@ gps_mask_t nmea_parse(char *sentence, struct 
gps_device_t * session)
         {"HDT", 1,  false, processHDT},
         {"ROT", 3,  false, processROT},
        {"DBT", 7,  true,  processDBT},
+       {"MWD", 9,  false,  processMWD},
+       {"MWV", 6,  false,  processMWV},
+       {"VWR", 9,  false,  processVWR},
+       {"VWT", 9,  false,  processVWT},
 #ifdef TNT_ENABLE
        {"PTNTHTM", 9, false, processTNTHTM},
 #endif /* TNT_ENABLE */
diff --git a/gps.h b/gps.h
index 47d4fe9..82ad835 100644
--- a/gps.h
+++ b/gps.h
@@ -1782,6 +1782,8 @@ extern double wgs84_separation(double, double);
 #define MPS_TO_KPH     3.6             /* Meters per second to klicks/hr */
 #define MPS_TO_MPH     2.2369363       /* Meters/second to miles per hour */
 #define MPS_TO_KNOTS   1.9438445       /* Meters per second to knots */
+#define KPH_TO_MPS      0.27777778      /* Kilometers per hout to meters per 
second */
+#define MPH_TO_MPS      0.44704         /* Miles per hour to meter per second 
*/
 /* miles and knots are both the international standard versions of the units */
 
 /* angle conversion multipliers */
-- 
1.7.0.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]