diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2011-09-29 21:18:51 -0400 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2011-09-29 21:18:51 -0400 |
commit | 44c6a6b7f969e0c31044a6f478a2f6fdad392e92 (patch) | |
tree | d6a3b6cdefbb476726c73b3697b7b3025f695328 | |
parent | 104f47e1ebf631650bb7be15f2390c4632e82316 (diff) | |
download | gpsd-44c6a6b7f969e0c31044a6f478a2f6fdad392e92.tar.gz |
Refactoring and splint cleanup.
-rw-r--r-- | cgps.c | 80 | ||||
-rw-r--r-- | gpsdclient.c | 74 | ||||
-rw-r--r-- | gpsdclient.h | 5 | ||||
-rw-r--r-- | gpxlogger.c | 16 |
4 files changed, 91 insertions, 84 deletions
@@ -131,74 +131,6 @@ static bool compass_flag = false; #define GPS_ERROR -2 /* low-level failure in GPS read */ #define GPS_TIMEOUT -3 /* low-level failure in GPS waiting */ -/* Convert true heading to magnetic. Taken from the Aviation - Formulary v1.43. Valid to within two degrees within the - continiental USA except for the following airports: MO49 MO86 MO50 - 3K6 02K and KOOA. AK correct to better than one degree. Western - Europe correct to within 0.2 deg. - - If you're not in one of these areas, I apologize, I don't have the - math to compute your varation. This is obviously extremely - floating-point heavy, so embedded people, beware of using. - - Note that there are issues with using magnetic heading. This code - does not account for the possibility of travelling into or out of - an area of valid calculation beyond forcing the magnetic conversion - off. A better way to communicate this to the user is probably - desirable (in case the don't notice the subtle change from "(mag)" - to "(true)" on their display). - */ -static float true2magnetic(double lat, double lon, double heading) -{ - /* Western Europe */ - /*@ -evalorder +relaxtypes @*/ - if ((lat > 36.0) && (lat < 68.0) && (lon > -10.0) && (lon < 28.0)) { - heading = - (10.4768771667158 - (0.507385322418858 * lon) + - (0.00753170031703826 * pow(lon, 2)) - - (1.40596203924748e-05 * pow(lon, 3)) - - (0.535560699962353 * lat) - + (0.0154348808069955 * lat * lon) - - (8.07756425110592e-05 * lat * pow(lon, 2)) - + (0.00976887198864442 * pow(lat, 2)) - - (0.000259163929798334 * lon * pow(lat, 2)) - - (3.69056939266123e-05 * pow(lat, 3)) + heading); - } - /* USA */ - else if ((lat > 24.0) && (lat < 50.0) && (lon > 66.0) && (lon < 125.0)) { - lon = 0.0 - lon; - heading = - ((-65.6811) + (0.99 * lat) + (0.0128899 * pow(lat, 2)) - - (0.0000905928 * pow(lat, 3)) + (2.87622 * lon) - - (0.0116268 * lat * lon) - (0.00000603925 * lon * pow(lat, 2)) - - (0.0389806 * pow(lon, 2)) - - (0.0000403488 * lat * pow(lon, 2)) + - (0.000168556 * pow(lon, 3)) + heading); - } - /* AK */ - else if ((lat > 54.0) && (lon > 130.0) && (lon < 172.0)) { - lon = 0.0 - lon; - heading = - (618.854 + (2.76049 * lat) - (0.556206 * pow(lat, 2)) + - (0.00251582 * pow(lat, 3)) - (12.7974 * lon) - + (0.408161 * lat * lon) + (0.000434097 * lon * pow(lat, 2)) - - (0.00602173 * pow(lon, 2)) - - (0.00144712 * lat * pow(lon, 2)) + - (0.000222521 * pow(lon, 3)) + heading); - } else { - /* We don't know how to compute magnetic heading for this - * location. */ - magnetic_flag = false; - } - - /* No negative headings. */ - if (heading < 0.0) - heading += 360.0; - - return (heading); - /*@ +evalorder -relaxtypes @*/ -} - /* Function to call when we're all done. Does a bit of clean-up. */ static void die(int sig) { @@ -584,15 +516,17 @@ static void update_gps_panel(struct gps_data_t *gpsdata) (void)mvwprintw(datawin, 5, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); /* Fill in the heading. */ - if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track) == 0) - if (!magnetic_flag) { + if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track) == 0) { + double magheading = true2magnetic(gpsdata->fix.latitude, + gpsdata->fix.longitude, + gpsdata->fix.track); + if (!magnetic_flag || isnan(magheading) != 0) { (void)snprintf(scr, sizeof(scr), "%.1f deg (true)", gpsdata->fix.track); } else { (void)snprintf(scr, sizeof(scr), "%.1f deg (mag) ", - true2magnetic(gpsdata->fix.latitude, - gpsdata->fix.longitude, - gpsdata->fix.track)); + magheading); + } } else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 6, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); diff --git a/gpsdclient.c b/gpsdclient.c index e56afc28..1e3a96a8 100644 --- a/gpsdclient.c +++ b/gpsdclient.c @@ -232,9 +232,10 @@ char *maidenhead(double n, double e) #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0])) /* from gpsd.h-tail */ -/*null observer*/struct exportmethod_t *export_lookup(const char *name) +/*@null observer@*/struct exportmethod_t *export_lookup(const char *name) /* Look up an available export method by name */ { + /*@-globstate@*/ struct exportmethod_t *mp, *method = NULL; for (mp = exportmethods; @@ -243,6 +244,7 @@ char *maidenhead(double n, double e) if (strcmp(mp->name, name) == 0) method = mp; return method; + /*@+globstate@*/ } void export_list(FILE *fp) @@ -256,9 +258,77 @@ void export_list(FILE *fp) (void)fprintf(fp, "%s: %s\n", method->name, method->description); } -/*null observer*/struct exportmethod_t *export_default(void) +/*@null observer@*/struct exportmethod_t *export_default(void) { return (NITEMS(exportmethods) > 0) ? &exportmethods[0] : NULL; } +/* Convert true heading to magnetic. Taken from the Aviation + Formulary v1.43. Valid to within two degrees within the + continiental USA except for the following airports: MO49 MO86 MO50 + 3K6 02K and KOOA. AK correct to better than one degree. Western + Europe correct to within 0.2 deg. + + If you're not in one of these areas, I apologize, I don't have the + math to compute your varation. This is obviously extremely + floating-point heavy, so embedded people, beware of using. + + Note that there are issues with using magnetic heading. This code + does not account for the possibility of travelling into or out of + an area of valid calculation beyond forcing the magnetic conversion + off. A better way to communicate this to the user is probably + desirable (in case the don't notice the subtle change from "(mag)" + to "(true)" on their display). + */ +float true2magnetic(double lat, double lon, double heading) +{ + /* Western Europe */ + /*@ -evalorder +relaxtypes @*/ + if ((lat > 36.0) && (lat < 68.0) && (lon > -10.0) && (lon < 28.0)) { + heading = + (10.4768771667158 - (0.507385322418858 * lon) + + (0.00753170031703826 * pow(lon, 2)) + - (1.40596203924748e-05 * pow(lon, 3)) - + (0.535560699962353 * lat) + + (0.0154348808069955 * lat * lon) - + (8.07756425110592e-05 * lat * pow(lon, 2)) + + (0.00976887198864442 * pow(lat, 2)) - + (0.000259163929798334 * lon * pow(lat, 2)) + - (3.69056939266123e-05 * pow(lat, 3)) + heading); + } + /* USA */ + else if ((lat > 24.0) && (lat < 50.0) && (lon > 66.0) && (lon < 125.0)) { + lon = 0.0 - lon; + heading = + ((-65.6811) + (0.99 * lat) + (0.0128899 * pow(lat, 2)) - + (0.0000905928 * pow(lat, 3)) + (2.87622 * lon) + - (0.0116268 * lat * lon) - (0.00000603925 * lon * pow(lat, 2)) - + (0.0389806 * pow(lon, 2)) + - (0.0000403488 * lat * pow(lon, 2)) + + (0.000168556 * pow(lon, 3)) + heading); + } + /* AK */ + else if ((lat > 54.0) && (lon > 130.0) && (lon < 172.0)) { + lon = 0.0 - lon; + heading = + (618.854 + (2.76049 * lat) - (0.556206 * pow(lat, 2)) + + (0.00251582 * pow(lat, 3)) - (12.7974 * lon) + + (0.408161 * lat * lon) + (0.000434097 * lon * pow(lat, 2)) - + (0.00602173 * pow(lon, 2)) + - (0.00144712 * lat * pow(lon, 2)) + + (0.000222521 * pow(lon, 3)) + heading); + } else { + /* We don't know how to compute magnetic heading for this + * location. */ + heading = NAN; + } + + /* No negative headings. */ + if (isnan(heading)== 0 && heading < 0.0) + heading += 360.0; + + return (heading); + /*@ +evalorder -relaxtypes @*/ +} + /* gpsclient.c ends here */ diff --git a/gpsdclient.h b/gpsdclient.h index 20b9abc2..a3169586 100644 --- a/gpsdclient.h +++ b/gpsdclient.h @@ -26,12 +26,13 @@ struct fixsource_t /*@null@*/char *device; }; -/*null observer*/struct exportmethod_t *export_lookup(const char *); -/*null observer*/struct exportmethod_t *export_default(void); +/*@null observer@*/struct exportmethod_t *export_lookup(const char *); +/*@null observer@*/struct exportmethod_t *export_default(void); void export_list(FILE *); enum unit {unspecified, imperial, nautical, metric}; enum unit gpsd_units(void); enum deg_str_type { deg_dd, deg_ddmm, deg_ddmmss }; +float true2magnetic(double, double, double); extern /*@observer@*/ char *deg_to_str( enum deg_str_type type, double f); diff --git a/gpxlogger.c b/gpxlogger.c index 3ab41d9c..d0688ece 100644 --- a/gpxlogger.c +++ b/gpxlogger.c @@ -184,11 +184,13 @@ static void quit_handler(int signum) static void usage(void) { + /*@-nullderef@*/ fprintf(stderr, "Usage: %s [-V] [-h] [-d] [-i timeout] [-f filename] [-m minmove]\n" "\t[-e exportmethod] [server[:port:[device]]]\n\n" "defaults to '%s -i 5 -e %s localhost:2947'\n", progname, progname, export_default()->name); + /*@-nullderef@*/ exit(1); } @@ -198,7 +200,7 @@ int main(int argc, char **argv) int ch; bool daemonize = false; unsigned int flags = WATCH_ENABLE; - struct exportmethod_t *method; + struct exportmethod_t *method = NULL; progname = argv[0]; @@ -259,6 +261,7 @@ int main(int argc, char **argv) break; case 'l': export_list(stderr); + break; case 'm': minmove = (double )atoi(optarg); break; @@ -276,12 +279,11 @@ int main(int argc, char **argv) exit(1); } - if (method == NULL) - method = export_default(); - if (method->magic != NULL) { - source.server = (char *)method->magic; - source.port = NULL; - } + if (method != NULL) + if (method->magic != NULL) { + source.server = (char *)method->magic; + source.port = NULL; + } if (optind < argc) { gpsd_source_spec(argv[optind], &source); |