[prev in list] [next in list] [prev in thread] [next in thread]
List: gpsd-dev
Subject: [gpsd-dev] [PATCH 6/6] Add Wind related NMEA sentence (MWD, MWV, VWR, VWT)
From: chris () techworks ! ie
Date: 2012-04-21 9:34:22
Message-ID: 1335000862-15312-7-git-send-email-chris () techworks ! ie
[Download RAW message or body]
From: Christian Gagneraud <chgans@gna.org>
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
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic