diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2006-02-18 18:01:03 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2006-02-18 18:01:03 +0000 |
commit | 9a64213d774f75b14da913c6a5024844325af6cd (patch) | |
tree | 7fa0e48f598597c5bcca8fd280adf26fc7458767 | |
parent | 1a878797a2b060d46c892fbf8174bb66cb1b5bc0 (diff) | |
download | gpsd-9a64213d774f75b14da913c6a5024844325af6cd.tar.gz |
Folded in the smoothing patch to xgps.c.
-rw-r--r-- | tsip.c | 2 | ||||
-rw-r--r-- | xgps.1 | 5 | ||||
-rw-r--r-- | xgps.c | 337 | ||||
-rw-r--r-- | xgps.xml | 8 |
4 files changed, 191 insertions, 161 deletions
@@ -223,7 +223,7 @@ static gps_mask_t tsip_analyze(struct gps_device_t *session) session->driver.tsip.last_46 = now; u1 = getub(buf,0); /* Status code */ u2 = getub(buf,1); /* Antenna/Battery */ - if (u1) { + if (u1 != (uchar)0) { session->gpsdata.status = STATUS_NO_FIX; mask |= STATUS_SET; } @@ -24,7 +24,7 @@ xgps, xgpsspeed, cgps \- test clients for gpsd .ad l .hy 0 .HP 5 -\fBxgps\fR [\fIX\-options\fR] [\-h] [\-v] [\-speedunits\ {\fBmph\fR\ |\ \fBkph\fR\ |\ \fBknots\fR}] [\-altunits\ {\fBfeet\fR\ |\ \fBmeters\fR}] [\-l\ [\fBd\fR\ |\ \fBm\fR\ |\ \fBs\fR]] [\fIserver\fR [\fI:port\fR [\fI:device\fR]]] +\fBxgps\fR [\fIX\-options\fR] [\-h] [\-v] [\-speedunits\ {\fBmph\fR\ |\ \fBkph\fR\ |\ \fBknots\fR}] [\-altunits\ {\fBfeet\fR\ |\ \fBmeters\fR}] [\-l\ [\fBd\fR\ |\ \fBm\fR\ |\ \fBs\fR]] [\-s\ \fIsmoothing\fR] [\fIserver\fR [\fI:port\fR [\fI:device\fR]]] .ad .hy .ad l @@ -63,6 +63,9 @@ The \fB\-altunits\fR option can be used to set the altitude units for display; f The \fB\-l\fR option sets the format of latitude and longitude reports\&. The value 'd' produces decimal degrees and is the default\&. The value 'm' produces degrees and decimal minutes\&. The value 's' produces degrees, minutes, and decimal seconds\&. .PP +The \fB\-s\fR option sets the number of received sentences to process after any fix is received before blanking any field\&. By default it is set to 4, which prevents annoying display flicker on NMEA devices that send several difference sentence types per update cycle, only one of which is a true fix\&. Set this option to zero to disable smoothing and see each update exactly as it is sent\&. + +.PP There is a known bug in xgps; it assumes the default font size is no more than 18 pixels\&. If this is not the case, the satellite data display will show fewer than 12 satellites\&. .SS "xgpsspeed" @@ -156,18 +156,18 @@ static void build_gui(Widget toplevel) /*@ -immediatetrans @*/ XtSetArg(args[0], XmNorientation, XmHORIZONTAL); /*@ +immediatetrans @*/ - rowColumn_11 = XtCreateManagedWidget("time", xmRowColumnWidgetClass, left, args, 1); + rowColumn_11 = XtCreateManagedWidget("time ", xmRowColumnWidgetClass, left, args, 1); - rowColumn_12 = XtCreateManagedWidget("latitude", xmRowColumnWidgetClass, left, args, 1); + rowColumn_12 = XtCreateManagedWidget("latitude ", xmRowColumnWidgetClass, left, args, 1); rowColumn_13 = XtCreateManagedWidget("longitude", xmRowColumnWidgetClass, left, args, 1); - rowColumn_14 = XtCreateManagedWidget("altitude", xmRowColumnWidgetClass, left, args, 1); - rowColumn_15 = XtCreateManagedWidget("speed", xmRowColumnWidgetClass, left, args, 1); - rowColumn_16 = XtCreateManagedWidget("track", xmRowColumnWidgetClass, left, args, 1); - rowColumn_17 = XtCreateManagedWidget("eph", xmRowColumnWidgetClass, left, args, 1); - rowColumn_18 = XtCreateManagedWidget("epv", xmRowColumnWidgetClass, left, args, 1); - rowColumn_19 = XtCreateManagedWidget("climb", xmRowColumnWidgetClass, left, args, 1); - rowColumn_20 = XtCreateManagedWidget("status", xmRowColumnWidgetClass, left, args, 1); - rowColumn_21 = XtCreateManagedWidget("quit", xmRowColumnWidgetClass, left, args, 1); + rowColumn_14 = XtCreateManagedWidget("altitude ", xmRowColumnWidgetClass, left, args, 1); + rowColumn_15 = XtCreateManagedWidget("speed ", xmRowColumnWidgetClass, left, args, 1); + rowColumn_16 = XtCreateManagedWidget("track ", xmRowColumnWidgetClass, left, args, 1); + rowColumn_17 = XtCreateManagedWidget("eph ", xmRowColumnWidgetClass, left, args, 1); + rowColumn_18 = XtCreateManagedWidget("epv ", xmRowColumnWidgetClass, left, args, 1); + rowColumn_19 = XtCreateManagedWidget("climb ", xmRowColumnWidgetClass, left, args, 1); + rowColumn_20 = XtCreateManagedWidget("status ", xmRowColumnWidgetClass, left, args, 1); + rowColumn_21 = XtCreateManagedWidget("quit ", xmRowColumnWidgetClass, left, args, 1); label_1 = XtCreateManagedWidget("Time ", xmLabelWidgetClass, rowColumn_11, args, 0); label_2 = XtCreateManagedWidget("Latitude ", xmLabelWidgetClass, rowColumn_12, args, 0); @@ -243,6 +243,7 @@ static void handle_time_out(XtPointer client_data UNUSED, static struct gps_data_t *gpsdata; static time_t timer; /* time of last state change */ static int state = 0; /* or MODE_NO_FIX=1, MODE_2D=2, MODE_3D=3 */ +static int smoothing = 4; /* # of transmitted sentences to smooth across */ static XtAppContext app; static XtIntervalId timeout; static enum deg_str_type deg_type = deg_dd; @@ -261,8 +262,9 @@ static void update_panel(struct gps_data_t *gpsdata, size_t len UNUSED, int level UNUSED) /* runs on each sentence */ { + static int lfok = 0; unsigned int i; - int newstate; + int newstate, newtxt; XmString string[MAXCHANNELS+1]; char s[128], *latlon, *sp; @@ -289,159 +291,176 @@ static void update_panel(struct gps_data_t *gpsdata, XmStringFree(string[i]); } /* here are the value fields */ - if (isnan(gpsdata->fix.time)==0) - (void)unix_to_iso8601(gpsdata->fix.time, s, (int)sizeof(s)); - else - (void)strcpy(s, "n/a"); - XmTextFieldSetString(text_1, s); - if (gpsdata->fix.mode >= MODE_2D) { - latlon = deg_to_str(deg_type, fabs(gpsdata->fix.latitude)); - (void)snprintf(s, sizeof(s), "%s %c", latlon, (gpsdata->fix.latitude < 0) ? 'S' : 'N'); - } else - (void)strcpy(s, "n/a"); - XmTextFieldSetString(text_2, s); - if (gpsdata->fix.mode >= MODE_2D) { - latlon = deg_to_str(deg_type, fabs(gpsdata->fix.longitude)); - (void)snprintf(s, sizeof(s), "%s %c", latlon, (gpsdata->fix.longitude < 0) ? 'W' : 'E'); - } else - (void)strcpy(s, "n/a"); - XmTextFieldSetString(text_3, s); - if (gpsdata->fix.mode == MODE_3D) - (void)snprintf(s, sizeof(s), "%f %s",gpsdata->fix.altitude*altunits->factor, altunits->legend); - else - (void)strcpy(s, "n/a"); - XmTextFieldSetString(text_4, s); - if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track)==0) - (void)snprintf(s, sizeof(s), "%f %s", gpsdata->fix.speed*speedunits->factor, speedunits->legend); - else - (void)strcpy(s, "n/a"); - XmTextFieldSetString(text_5, s); - if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track)==0) - (void)snprintf(s, sizeof(s), "%f degrees", gpsdata->fix.track); - else - (void)strcpy(s, "n/a"); - XmTextFieldSetString(text_6, s); - if (isnan(gpsdata->fix.eph)==0) - (void)snprintf(s, sizeof(s), "%f %s", gpsdata->fix.eph * altunits->factor, altunits->legend); - else - (void)strcpy(s, "n/a"); - XmTextFieldSetString(text_7, s); - if (isnan(gpsdata->fix.epv)==0) - (void)snprintf(s, sizeof(s), "%f %s", gpsdata->fix.epv * altunits->factor, altunits->legend); - else - (void)strcpy(s, "n/a"); - XmTextFieldSetString(text_8, s); - if (gpsdata->fix.mode == MODE_3D && isnan(gpsdata->fix.climb)==0) - (void)snprintf(s, sizeof(s), "%f %s/sec", gpsdata->fix.climb * altunits->factor, altunits->legend); - else - (void)strcpy(s, "n/a"); - XmTextFieldSetString(text_9, s); - - if (gpsdata->online == 0) { - newstate = 0; - (void)snprintf(s, sizeof(s), "OFFLINE"); - } else { - newstate = gpsdata->fix.mode; - switch (gpsdata->fix.mode) { - case MODE_2D: - (void)snprintf(s, sizeof(s), "2D %sFIX",(gpsdata->status==STATUS_DGPS_FIX)?"DIFF ":""); - break; - case MODE_3D: - (void)snprintf(s, sizeof(s), "3D %sFIX",(gpsdata->status==STATUS_DGPS_FIX)?"DIFF ":""); - break; - default: - (void)snprintf(s, sizeof(s), "NO FIX"); - break; + if (isnan(gpsdata->fix.time)==0) { + (void)unix_to_iso8601(gpsdata->fix.time, s, (int)sizeof(s)); + newtxt = 1; + } else { + newtxt = (lfok>0) ? 0 : ((void)strcpy(s, "n/a"), 1); } - } - if (newstate != state) { - timer = time(NULL); - state = newstate; - } - (void)snprintf(s+strlen(s), sizeof(s)-strlen(s), - " (%d secs)", (int) (time(NULL) - timer)); - XmTextFieldSetString(text_10, s); - draw_graphics(gpsdata); + if (newtxt != 0) XmTextFieldSetString(text_1, s); + if (gpsdata->fix.mode >= MODE_2D) { + latlon = deg_to_str(deg_type, fabs(gpsdata->fix.latitude)); + newtxt = snprintf(s, sizeof(s), "%s %c", latlon, (gpsdata->fix.latitude < 0) ? 'S' : 'N'); + } else { + newtxt = (lfok>0) ? 0 : ((void)strcpy(s, "n/a"), 1); + } + if (newtxt != 0) XmTextFieldSetString(text_2, s); + if (gpsdata->fix.mode >= MODE_2D) { + latlon = deg_to_str(deg_type, fabs(gpsdata->fix.longitude)); + newtxt = snprintf(s, sizeof(s), "%s %c", latlon, (gpsdata->fix.longitude < 0) ? 'W' : 'E'); + } else { + newtxt = (lfok>0) ? 0 : ((void)strcpy(s, "n/a"), 1); + } + if (newtxt != 0) XmTextFieldSetString(text_3, s); + if (gpsdata->fix.mode == MODE_3D) { + newtxt = snprintf(s, sizeof(s), "%f %s",gpsdata->fix.altitude*altunits->factor, altunits->legend); + } else { + newtxt = (lfok>0) ? 0 : ((void)strcpy(s, "n/a"), 1); + } + if (newtxt != 0) XmTextFieldSetString(text_4, s); + if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track)==0) { + newtxt = snprintf(s, sizeof(s), "%f %s", gpsdata->fix.speed*speedunits->factor, speedunits->legend); + } else { + newtxt = (lfok>0) ? 0 : ((void)strcpy(s, "n/a"), 1); + } + if (newtxt != 0) XmTextFieldSetString(text_5, s); + if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track)==0) { + newtxt = snprintf(s, sizeof(s), "%f degrees", gpsdata->fix.track); + } else { + newtxt = (lfok>0) ? 0 : ((void)strcpy(s, "n/a"), 1); + } + if (newtxt != 0) XmTextFieldSetString(text_6, s); + if (isnan(gpsdata->fix.eph)==0) { + newtxt = snprintf(s, sizeof(s), "%f %s", gpsdata->fix.eph * altunits->factor, altunits->legend); + } else { + newtxt = (lfok>0) ? 0 : ((void)strcpy(s, "n/a"), 1); + } + if (newtxt != 0) XmTextFieldSetString(text_7, s); + if (isnan(gpsdata->fix.epv)==0) { + newtxt = snprintf(s, sizeof(s), "%f %s", gpsdata->fix.epv * altunits->factor, altunits->legend); + } else { + newtxt = (lfok>0) ? 0 : ((void)strcpy(s, "n/a"), 1); + } + if (newtxt != 0) XmTextFieldSetString(text_8, s); + if (gpsdata->fix.mode == MODE_3D && isnan(gpsdata->fix.climb)==0) { + newtxt = snprintf(s, sizeof(s), "%f %s/sec", gpsdata->fix.climb * altunits->factor, altunits->legend); + } else { + newtxt = (lfok>0) ? 0 : ((void)strcpy(s, "n/a"), 1); + } + if (newtxt != 0) XmTextFieldSetString(text_9, s); + + if (gpsdata->online == 0) { + newstate = 0; + (void)snprintf(s, sizeof(s), "OFFLINE"); + lfok = 0; + } else { + newstate = gpsdata->fix.mode; + switch (gpsdata->fix.mode) { + case MODE_2D: + (void)snprintf(s, sizeof(s), "2D %sFIX",(gpsdata->status==STATUS_DGPS_FIX)?"DIFF ":""); + if (lfok>0) lfok--; + break; + case MODE_3D: + (void)snprintf(s, sizeof(s), "3D %sFIX",(gpsdata->status==STATUS_DGPS_FIX)?"DIFF ":""); + lfok = smoothing; + break; + default: + (void)snprintf(s, sizeof(s), "NO FIX"); + lfok = 0; + break; + } + } + if (newstate != state) { + timer = time(NULL); + state = newstate; + } + (void)snprintf(s+strlen(s), sizeof(s)-strlen(s), + " (%d secs)", (int) (time(NULL) - timer)); + XmTextFieldSetString(text_10, s); + draw_graphics(gpsdata); - XtRemoveTimeOut(timeout); - timeout = XtAppAddTimeOut(app, 2000, handle_time_out, NULL); -} + XtRemoveTimeOut(timeout); + timeout = XtAppAddTimeOut(app, 2000, handle_time_out, NULL); + } -static char *get_resource(Widget w, char *name, char *default_value) -{ - XtResource xtr; - char *value = NULL; - - /*@ -observertrans -statictrans -immediatetrans -compdestroy @*/ - xtr.resource_name = name; - xtr.resource_class = "AnyClass"; - xtr.resource_type = XmRString; - xtr.resource_size = (Cardinal)sizeof(String); - xtr.resource_offset = 0; - xtr.default_type = XmRImmediate; - xtr.default_addr = default_value; - XtGetApplicationResources(w, &value, &xtr, 1, NULL, 0); - if (value) return value; - /*@ +observertrans +statictrans +immediatetrans +compdestroy @*/ - /*@i@*/return default_value; -} + static char *get_resource(Widget w, char *name, char *default_value) + { + XtResource xtr; + char *value = NULL; + + /*@ -observertrans -statictrans -immediatetrans -compdestroy @*/ + xtr.resource_name = name; + xtr.resource_class = "AnyClass"; + xtr.resource_type = XmRString; + xtr.resource_size = (Cardinal)sizeof(String); + xtr.resource_offset = 0; + xtr.default_type = XmRImmediate; + xtr.default_addr = default_value; + XtGetApplicationResources(w, &value, &xtr, 1, NULL, 0); + if (value) return value; + /*@ +observertrans +statictrans +immediatetrans +compdestroy @*/ + /*@i@*/return default_value; + } -/*@ -mustfreefresh @*/ -int main(int argc, char *argv[]) -{ - int option; - char *arg = NULL, *colon1, *colon2, *device = NULL, *server = NULL, *port = DEFAULT_GPSD_PORT; - char *su, *au; - char *err_str = NULL; - - /*@ -onlytrans */ - toplevel = XtVaAppInitialize(&app, "xgps", - options, XtNumber(options), - &argc,argv, fallback_resources,NULL); - - /*@ +onlytrans */ - su = get_resource(toplevel, "speedunits", "mph"); - for (speedunits = speedtable; - speedunits < speedtable + sizeof(speedtable)/sizeof(speedtable[0]); - speedunits++) - if (strcmp(speedunits->legend, su) == 0) - goto speedunits_ok; - speedunits = speedtable; - (void)fprintf(stderr, "xgps: unknown speed unit, defaulting to %s\n", speedunits->legend); -speedunits_ok:; - - au = get_resource(toplevel, "altunits", "feet"); - for (altunits = alttable; - altunits < alttable + sizeof(alttable)/sizeof(alttable[0]); - altunits++) - if (strcmp(altunits->legend, au) == 0) - goto altunits_ok; - altunits = alttable; - (void)fprintf(stderr, "xgps: unknown altitude unit, defaulting to %s\n", altunits->legend); -altunits_ok:; - - while ((option = getopt(argc, argv, "hl:v")) != -1) { - switch (option) { - case 'v': - (void)printf("xgps %s\n", VERSION); - exit(0); - case 'l': - switch ( optarg[0] ) { - case 'd': - deg_type = deg_dd; - continue; - case 'm': - deg_type = deg_ddmm; - continue; - case 's': - deg_type = deg_ddmmss; - continue; - default: - (void)fprintf(stderr, "Unknown -l argument: %s\n", optarg); - /*@ -casebreak @*/ - } + /*@ -mustfreefresh @*/ + int main(int argc, char *argv[]) + { + int option; + char *arg = NULL, *colon1, *colon2, *device = NULL, *server = NULL, *port = DEFAULT_GPSD_PORT; + char *su, *au; + char *err_str = NULL; + + /*@ -onlytrans */ + toplevel = XtVaAppInitialize(&app, "xgps", + options, XtNumber(options), + &argc,argv, fallback_resources,NULL); + + /*@ +onlytrans */ + su = get_resource(toplevel, "speedunits", "mph"); + for (speedunits = speedtable; + speedunits < speedtable + sizeof(speedtable)/sizeof(speedtable[0]); + speedunits++) + if (strcmp(speedunits->legend, su) == 0) + goto speedunits_ok; + speedunits = speedtable; + (void)fprintf(stderr, "xgps: unknown speed unit, defaulting to %s\n", speedunits->legend); + speedunits_ok:; + + au = get_resource(toplevel, "altunits", "feet"); + for (altunits = alttable; + altunits < alttable + sizeof(alttable)/sizeof(alttable[0]); + altunits++) + if (strcmp(altunits->legend, au) == 0) + goto altunits_ok; + altunits = alttable; + (void)fprintf(stderr, "xgps: unknown altitude unit, defaulting to %s\n", altunits->legend); + altunits_ok:; + + while ((option = getopt(argc, argv, "hl:s:v")) != -1) { + switch (option) { + case 'v': + (void)printf("xgps %s\n", VERSION); + exit(0); + case 'l': + switch ( optarg[0] ) { + case 'd': + deg_type = deg_dd; + continue; + case 'm': + deg_type = deg_ddmm; + continue; + case 's': + deg_type = deg_ddmmss; + continue; + default: + (void)fprintf(stderr, "Unknown -l argument: %s\n", optarg); + /*@ -casebreak @*/ + } + case 's': + smoothing = atoi(optarg); + break; case 'h': default: - (void)fputs("usage: xgps [-hv] [-speedunits {mph,kph,knots}] [-altunits {ft,meters}] [-l {d|m|s}] [server[:port:[device]]]\n", stderr); + (void)fputs("usage: xgps [-hv] [-speedunits {mph,kph,knots}] [-altunits {ft,meters}] [-l {d|m|s}] [-s smoothing] [server[:port:[device]]]\n", stderr); exit(1); } } @@ -24,6 +24,7 @@ <arg choice='opt'>-speedunits <group choice='req'><arg>mph</arg><arg>kph</arg><arg>knots</arg></group></arg> <arg choice='opt'>-altunits <group choice='req'><arg>feet</arg><arg>meters</arg></group></arg> <arg choice='opt'>-l <group><arg>d</arg><arg>m</arg><arg>s</arg></group></arg> + <arg choice='opt'>-s <replaceable>smoothing</replaceable></arg> <group> <replaceable>server</replaceable> <group> @@ -101,6 +102,13 @@ longitude reports. The value 'd' produces decimal degrees and is the default. The value 'm' produces degrees and decimal minutes. The value 's' produces degrees, minutes, and decimal seconds.</para> +<para>The <option>-s</option> option sets the number of received +sentences to process after any fix is received before blanking any +field. By default it is set to 4, which prevents annoying display flicker +on NMEA devices that send several difference sentence types per +update cycle, only one of which is a true fix. Set this option to zero to +disable smoothing and see each update exactly as it is sent. </para> + <para>There is a known bug in <application>xgps</application>; it assumes the default font size is no more than 18 pixels. If this is not the case, the satellite data display will show fewer than |