[Top][All Lists]
[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
- [gpsd-dev] [RFC] Add support for Airmar PB200 Weather station, chris, 2012/04/21
- [gpsd-dev] [PATCH 1/6] Add missing attitude field initialisation in NMEA TNTHTM, chris, 2012/04/21
- [gpsd-dev] [PATCH 2/6] Add new NMEA talker ID (WI, HC and TI), chris, 2012/04/21
- [gpsd-dev] [PATCH 5/6] Add a wind data structure, chris, 2012/04/21
- [gpsd-dev] [PATCH 3/6] Add new fields to the attitude data structure, chris, 2012/04/21
- [gpsd-dev] [PATCH 4/6] Add heading and rate of turn NMEA sentences (HDG, ROT), chris, 2012/04/21
- [gpsd-dev] [PATCH 6/6] Add Wind related NMEA sentence (MWD, MWV, VWR, VWT),
chris <=
- Re: [gpsd-dev] [RFC] Add support for Airmar PB200 Weather station, Eric S. Raymond, 2012/04/21
- Re: [gpsd-dev] [RFC] Add support for Airmar PB200 Weather station, address@hidden, 2012/04/21