summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-09-29 21:18:51 -0400
committerEric S. Raymond <esr@thyrsus.com>2011-09-29 21:18:51 -0400
commit44c6a6b7f969e0c31044a6f478a2f6fdad392e92 (patch)
treed6a3b6cdefbb476726c73b3697b7b3025f695328
parent104f47e1ebf631650bb7be15f2390c4632e82316 (diff)
downloadgpsd-44c6a6b7f969e0c31044a6f478a2f6fdad392e92.tar.gz
Refactoring and splint cleanup.
-rw-r--r--cgps.c80
-rw-r--r--gpsdclient.c74
-rw-r--r--gpsdclient.h5
-rw-r--r--gpxlogger.c16
4 files changed, 91 insertions, 84 deletions
diff --git a/cgps.c b/cgps.c
index e60099ed..8a70a6d0 100644
--- a/cgps.c
+++ b/cgps.c
@@ -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);