summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgps.c315
-rw-r--r--contrib/README2
-rw-r--r--contrib/clock_test.c110
-rwxr-xr-xxgps108
4 files changed, 123 insertions, 412 deletions
diff --git a/cgps.c b/cgps.c
index 25467ecc..db67a487 100644
--- a/cgps.c
+++ b/cgps.c
@@ -47,7 +47,7 @@
/* This is how far over in the 'datawin' window to indent the field
descriptions. */
-#define DATAWIN_DESC_OFFSET 2
+#define DATAWIN_DESC_OFFSET 5
/* This is how far over in the 'datawin' window to indent the field
values. */
@@ -67,26 +67,23 @@
You shouldn't have to modify any #define values below this line.
================================================================ */
-/* This is the minimum ysize we'll accept for the 'datawin' window in
+/* This is the minimum size we'll accept for the 'datawin' window in
GPS mode. */
-#define MIN_GPS_DATAWIN_YSIZE (DATAWIN_GPS_FIELDS + DATAWIN_OVERHEAD)
+#define MIN_GPS_DATAWIN_SIZE (DATAWIN_GPS_FIELDS + DATAWIN_OVERHEAD)
-/* And the maximum ysize we'll try to use */
-#define MAX_GPS_DATAWIN_YSIZE (DATAWIN_GPS_FIELDS + DATAWIN_OPTIONAL_FIELDS + DATAWIN_OVERHEAD)
+/* And the maximum size we'll try to use */
+#define MAX_GPS_DATAWIN_SIZE (DATAWIN_GPS_FIELDS + DATAWIN_OPTIONAL_FIELDS + DATAWIN_OVERHEAD)
-/* This is the minimum ysize we'll accept for the 'datawin' window in
+/* This is the minimum size we'll accept for the 'datawin' window in
COMPASS mode. */
-#define MIN_COMPASS_DATAWIN_YSIZE (DATAWIN_COMPASS_FIELDS + DATAWIN_OVERHEAD)
+#define MIN_COMPASS_DATAWIN_SIZE (DATAWIN_COMPASS_FIELDS + DATAWIN_OVERHEAD)
/* This is the maximum number of satellites gpsd can track. */
#define MAX_POSSIBLE_SATS (MAXCHANNELS - 2)
-/* This is the maximum ysize we need for the 'satellites' window. */
+/* This is the maximum size we need for the 'satellites' window. */
#define MAX_SATWIN_SIZE (MAX_POSSIBLE_SATS + SATWIN_OVERHEAD)
-/* Minimum xsize to display 3rd window with DOPs, etc. */
-#define MIN_ERRWIN_SIZE 100
-
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
@@ -121,12 +118,10 @@ static int debug;
static WINDOW *datawin, *satellites, *messages;
static bool raw_flag = false;
-static bool err_flag = false;
-static bool dop_flag = false; /* tall screen, show more DOPs */
static bool silent_flag = false;
static bool magnetic_flag = false;
-static int window_ysize = 0;
-static int display_sats = 0;
+static int window_length;
+static int display_sats;
#ifdef TRUENORTH
static bool compass_flag = false;
#endif /* TRUENORTH */
@@ -137,30 +132,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 */
-/* format a dop into a 5 char string, handle NAN, INFINITE */
-static char *dop_to_str(double dop)
-{
- static char buf[20];
-
- if (isfinite(dop) == 0) {
- return " n/a ";
- }
- (void)snprintf(buf, sizeof(buf), "%5.2f", dop);
- return buf;
-}
-
-/* format an ep into a string, handle NAN, INFINITE */
-static char *ep_to_str(double ep, double factor, char *units)
-{
- static char buf[128];
-
- if (isfinite(ep) == 0) {
- return " n/a ";
- }
- (void)snprintf(buf, sizeof(buf), "+/-%4d %.10s", (int)(ep * factor), units);
- return buf;
-}
-
/* Function to call when we're all done. Does a bit of clean-up. */
static void die(int sig)
{
@@ -203,7 +174,7 @@ static void die(int sig)
static enum deg_str_type deg_type = deg_dd;
static void windowsetup(void)
-/* initialize curses and set up screen windows */
+/* inotialize curses and set up screen windows */
{
/* Set the window sizes per the following criteria:
*
@@ -221,12 +192,9 @@ static void windowsetup(void)
* the satellite list is truncated, omit the satellites not used to
* obtain the current fix.)
*
- * 3. If the screen is tall enough to display all possible
+ * 3. If the screen is large enough to display all possible
* satellites (MAXCHANNELS - 2) with space still left at the bottom,
* add a window at the bottom in which to scroll raw gpsd data.
- *
- * 4. If the screen is wide enough to display extra data, add a
- * window on the right for PDOP, etc.
*/
int xsize, ysize;
@@ -237,16 +205,16 @@ static void windowsetup(void)
#ifdef TRUENORTH
if (compass_flag) {
- if (ysize == MIN_COMPASS_DATAWIN_YSIZE) {
+ if (ysize == MIN_COMPASS_DATAWIN_SIZE) {
raw_flag = false;
- window_ysize = MIN_COMPASS_DATAWIN_YSIZE;
- } else if (ysize > MIN_COMPASS_DATAWIN_YSIZE) {
+ window_length = MIN_COMPASS_DATAWIN_SIZE;
+ } else if (ysize > MIN_COMPASS_DATAWIN_SIZE) {
raw_flag = true;
- window_ysize = MIN_COMPASS_DATAWIN_YSIZE;
+ window_length = MIN_COMPASS_DATAWIN_SIZE;
} else {
(void)mvprintw(0, 0,
"Your screen must be at least 80x%d to run cgps.",
- MIN_COMPASS_DATAWIN_YSIZE);
+ MIN_COMPASS_DATAWIN_SIZE);
(void)refresh();
(void)sleep(5);
die(0);
@@ -254,41 +222,27 @@ static void windowsetup(void)
} else
#endif /* TRUENORTH */
{
- if (ysize > MAX_GPS_DATAWIN_YSIZE + 6) {
+ if (ysize > MAX_GPS_DATAWIN_SIZE) {
raw_flag = true;
- dop_flag = true;
- window_ysize = MAX_GPS_DATAWIN_YSIZE + 4;
- } else if (ysize > MAX_GPS_DATAWIN_YSIZE) {
- raw_flag = true;
- dop_flag = false;
- window_ysize = MAX_GPS_DATAWIN_YSIZE;
- } else if (ysize == MAX_GPS_DATAWIN_YSIZE) {
+ window_length = MAX_GPS_DATAWIN_SIZE;
+ } else if (ysize == MAX_GPS_DATAWIN_SIZE) {
raw_flag = false;
- dop_flag = false;
- window_ysize = MAX_GPS_DATAWIN_YSIZE;
- } else if (ysize > MIN_GPS_DATAWIN_YSIZE) {
+ window_length = MAX_GPS_DATAWIN_SIZE;
+ } else if (ysize > MIN_GPS_DATAWIN_SIZE) {
raw_flag = true;
- dop_flag = false;
- window_ysize = MIN_GPS_DATAWIN_YSIZE;
- } else if (ysize == MIN_GPS_DATAWIN_YSIZE) {
+ window_length = MIN_GPS_DATAWIN_SIZE;
+ } else if (ysize == MIN_GPS_DATAWIN_SIZE) {
raw_flag = false;
- dop_flag = false;
- window_ysize = MIN_GPS_DATAWIN_YSIZE;
+ window_length = MIN_GPS_DATAWIN_SIZE;
} else {
(void)mvprintw(0, 0,
"Your screen must be at least 80x%d to run cgps.",
- MIN_GPS_DATAWIN_YSIZE);
+ MIN_GPS_DATAWIN_SIZE);
(void)refresh();
(void)sleep(5);
die(0);
}
- display_sats = window_ysize - SATWIN_OVERHEAD - (int)raw_flag;
- }
- /* wide enough to show err box? */
- if (xsize > MIN_ERRWIN_SIZE) {
- err_flag = true;
- } else {
- err_flag = false;
+ display_sats = window_length - SATWIN_OVERHEAD - (int)raw_flag;
}
#ifdef TRUENORTH
@@ -296,13 +250,13 @@ static void windowsetup(void)
if (compass_flag) {
/* We're a compass, set up accordingly. */
- datawin = newwin(window_ysize, DATAWIN_WIDTH, 0, 0);
+ datawin = newwin(window_length, DATAWIN_WIDTH, 0, 0);
(void)nodelay(datawin, (bool) TRUE);
if (raw_flag) {
- messages = newwin(0, 0, window_ysize, 0);
+ messages = newwin(0, 0, window_length, 0);
(void)scrollok(messages, true);
- (void)wsetscrreg(messages, 0, ysize - (window_ysize));
+ (void)wsetscrreg(messages, 0, ysize - (window_length));
}
(void)refresh();
@@ -321,16 +275,16 @@ static void windowsetup(void)
{
/* We're a GPS, set up accordingly. */
- datawin = newwin(window_ysize, DATAWIN_WIDTH, 0, 0);
+ datawin = newwin(window_length, DATAWIN_WIDTH, 0, 0);
satellites =
- newwin(window_ysize, SATELLITES_WIDTH, 0, DATAWIN_WIDTH);
+ newwin(window_length, SATELLITES_WIDTH, 0, DATAWIN_WIDTH);
(void)nodelay(datawin, (bool) TRUE);
if (raw_flag) {
messages =
- newwin(ysize - (window_ysize), xsize, window_ysize, 0);
+ newwin(ysize - (window_length), xsize, window_length, 0);
(void)scrollok(messages, true);
- (void)wsetscrreg(messages, 0, ysize - (window_ysize));
+ (void)wsetscrreg(messages, 0, ysize - (window_length));
}
(void)refresh();
@@ -353,42 +307,22 @@ static void windowsetup(void)
* there in the first place because I arbitrarily thought they
* sounded interesting. ;^) */
- if (window_ysize >= MAX_GPS_DATAWIN_YSIZE) {
- int row = 9;
-
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "Long Err (XDOP, EPX):");
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "Lat Err (YDOP, EPY):");
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "Alt Err (VDOP, EPV):");
-
- if (dop_flag){
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "2D Err (HDOP, CEP):");
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "3D Err (PDOP, SEP):");
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "Time Err (TDOP):");
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "Geo Err (GDOP):");
- }
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "Speed Err (EPS):");
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "Head Err (EPD):");
+ if (window_length == MAX_GPS_DATAWIN_SIZE) {
+ (void)mvwprintw(datawin, 9, DATAWIN_DESC_OFFSET,
+ "Longitude Err:");
+ (void)mvwprintw(datawin, 10, DATAWIN_DESC_OFFSET,
+ "Latitude Err:");
+ (void)mvwprintw(datawin, 11, DATAWIN_DESC_OFFSET,
+ "Altitude Err:");
+ (void)mvwprintw(datawin, 12, DATAWIN_DESC_OFFSET, "Course Err:");
+ (void)mvwprintw(datawin, 13, DATAWIN_DESC_OFFSET, "Speed Err:");
/* it's actually esr that thought *these* were interesting */
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "Time offset:");
- (void)mvwprintw(datawin, row++, DATAWIN_DESC_OFFSET,
- "Grid Square:");
+ (void)mvwprintw(datawin, 14, DATAWIN_DESC_OFFSET, "Time offset:");
+ (void)mvwprintw(datawin, 15, DATAWIN_DESC_OFFSET, "Grid Square:");
}
(void)wborder(datawin, 0, 0, 0, 0, 0, 0, 0, 0);
- /* PRN is not unique, starting at 1, for GPS, GAILEO, etc. */
- /* what we really have is USI, Universal Sat ID */
- /* GPS is USI 1 to 32, SBAS is 33 to 64, GLONASS is 65 to 96, YMMV */
- (void)mvwprintw(satellites, 1, 1, " USI Elev Azim SNR Used ");
+ (void)mvwprintw(satellites, 1, 1, "PRN: Elev: Azim: SNR: Used:");
(void)wborder(satellites, 0, 0, 0, 0, 0, 0, 0, 0);
}
}
@@ -483,9 +417,6 @@ static void update_gps_panel(struct gps_data_t *gpsdata)
* xgps.c. Note that the satellite list may be truncated based on
* available screen size, or may only show satellites used for the
* fix. */
- (void)mvwprintw(satellites, 0, 27, "Seen %2d", gpsdata->satellites_visible);
- (void)mvwprintw(satellites, 1, 32, "%2d", gpsdata->satellites_used);
-
if (gpsdata->satellites_visible != 0) {
int i;
qsort( gpsdata->skyview, gpsdata->satellites_visible,
@@ -494,7 +425,7 @@ static void update_gps_panel(struct gps_data_t *gpsdata)
for (i = 0; i < MAX_POSSIBLE_SATS; i++) {
if (i < gpsdata->satellites_visible) {
(void)snprintf(scr, sizeof(scr),
- " %3d %2d %3d %2d %c",
+ " %3d %02d %03d %02d %c",
gpsdata->skyview[i].PRN,
gpsdata->skyview[i].elevation,
gpsdata->skyview[i].azimuth,
@@ -514,7 +445,7 @@ static void update_gps_panel(struct gps_data_t *gpsdata)
&& (gpsdata->skyview[i].used
|| (gpsdata->satellites_visible <= display_sats))) {
(void)snprintf(scr, sizeof(scr),
- " %3d %2d %3d %2d %c",
+ " %3d %02d %03d %02d %c",
gpsdata->skyview[i].PRN,
gpsdata->skyview[i].elevation,
gpsdata->skyview[i].azimuth,
@@ -547,7 +478,7 @@ static void update_gps_panel(struct gps_data_t *gpsdata)
/* Fill in the latitude. */
if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.latitude) == 0) {
- (void)snprintf(scr, sizeof(scr), " %s %c",
+ (void)snprintf(scr, sizeof(scr), "%s %c",
deg_to_str(deg_type, fabs(gpsdata->fix.latitude)),
(gpsdata->fix.latitude < 0) ? 'S' : 'N');
} else
@@ -555,8 +486,8 @@ static void update_gps_panel(struct gps_data_t *gpsdata)
(void)mvwprintw(datawin, 2, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);
/* Fill in the longitude. */
- if (gpsdata->fix.mode >= MODE_2D && isfinite(gpsdata->fix.longitude) != 0) {
- (void)snprintf(scr, sizeof(scr), " %s %c",
+ if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.longitude) == 0) {
+ (void)snprintf(scr, sizeof(scr), "%s %c",
deg_to_str(deg_type, fabs(gpsdata->fix.longitude)),
(gpsdata->fix.longitude < 0) ? 'W' : 'E');
} else
@@ -564,40 +495,40 @@ static void update_gps_panel(struct gps_data_t *gpsdata)
(void)mvwprintw(datawin, 3, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);
/* Fill in the altitude. */
- if (gpsdata->fix.mode >= MODE_3D && isfinite(gpsdata->fix.altitude) != 0)
- (void)snprintf(scr, sizeof(scr), "%9.3f %s",
+ if (gpsdata->fix.mode >= MODE_3D && isnan(gpsdata->fix.altitude) == 0)
+ (void)snprintf(scr, sizeof(scr), "%.3f %s",
gpsdata->fix.altitude * altfactor, altunits);
else
(void)snprintf(scr, sizeof(scr), "n/a");
(void)mvwprintw(datawin, 4, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);
/* Fill in the speed. */
- if (gpsdata->fix.mode >= MODE_2D && isfinite(gpsdata->fix.track) != 0)
- (void)snprintf(scr, sizeof(scr), "%8.2f %s",
+ if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track) == 0)
+ (void)snprintf(scr, sizeof(scr), "%.2f %s",
gpsdata->fix.speed * speedfactor, speedunits);
else
(void)snprintf(scr, sizeof(scr), "n/a");
(void)mvwprintw(datawin, 5, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);
/* Fill in the heading. */
- if (gpsdata->fix.mode >= MODE_2D && isfinite(gpsdata->fix.track) != 0) {
+ 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), "%5.1f deg (true)",
+ (void)snprintf(scr, sizeof(scr), "%.1f deg (true)",
gpsdata->fix.track);
} else {
- (void)snprintf(scr, sizeof(scr), "%5.1f deg (mag) ",
+ (void)snprintf(scr, sizeof(scr), "%.1f deg (mag) ",
magheading);
}
} else
(void)snprintf(scr, sizeof(scr), "n/a");
- (void)mvwprintw(datawin, 6, DATAWIN_VALUE_OFFSET, " %-*s", 25, scr);
+ (void)mvwprintw(datawin, 6, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);
/* Fill in the rate of climb. */
if (gpsdata->fix.mode >= MODE_3D && isnan(gpsdata->fix.climb) == 0)
- (void)snprintf(scr, sizeof(scr), "%8.2f %s/min",
+ (void)snprintf(scr, sizeof(scr), "%.2f %s/min",
gpsdata->fix.climb * altfactor * 60, altunits);
else
(void)snprintf(scr, sizeof(scr), "n/a");
@@ -629,7 +560,7 @@ static void update_gps_panel(struct gps_data_t *gpsdata)
break;
}
}
- (void)mvwprintw(datawin, 8, DATAWIN_VALUE_OFFSET + 1, "%-*s", 26, scr);
+ (void)mvwprintw(datawin, 8, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);
/* Note that the following fields are exceptions to the
* sizing rule. The minimum window size does not include these
@@ -639,101 +570,65 @@ static void update_gps_panel(struct gps_data_t *gpsdata)
* there in the first place because I arbitrarily thought they
* sounded interesting. ;^) */
- if (window_ysize >= (MIN_GPS_DATAWIN_YSIZE + 5)) {
- int row = 9;
- char *ep_str = NULL;
- char *dop_str = NULL;
+ if (window_length >= (MIN_GPS_DATAWIN_SIZE + 5)) {
- /* Fill in the estimated latitude position error. */
- ep_str = ep_to_str(gpsdata->fix.epx, altfactor, altunits);
- dop_str = dop_to_str(gpsdata->dop.xdop);
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 8, "%s, %-*s",
- dop_str, 11, ep_str);
+ /* Fill in the estimated horizontal position error. */
+ if (isnan(gpsdata->fix.epx) == 0)
+ (void)snprintf(scr, sizeof(scr), "+/- %d %s",
+ (int)(gpsdata->fix.epx * altfactor), altunits);
+ else
+ (void)snprintf(scr, sizeof(scr), "n/a");
+ (void)mvwprintw(datawin, 9, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
+ scr);
- /* Fill in the estimated longitude position error YDOP. */
- ep_str = ep_to_str(gpsdata->fix.epy, altfactor, altunits);
- dop_str = dop_to_str(gpsdata->dop.ydop);
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 8, "%s, %-*s",
- dop_str, 11, ep_str);
+ if (isnan(gpsdata->fix.epy) == 0)
+ (void)snprintf(scr, sizeof(scr), "+/- %d %s",
+ (int)(gpsdata->fix.epy * altfactor), altunits);
+ else
+ (void)snprintf(scr, sizeof(scr), "n/a");
+ (void)mvwprintw(datawin, 10, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
+ scr);
/* Fill in the estimated vertical position error. */
- ep_str = ep_to_str(gpsdata->fix.epv, altfactor, altunits);
- dop_str = dop_to_str(gpsdata->dop.vdop);
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 8, "%s, %-*s",
- dop_str, 11, ep_str);
-
- /* extra large screen, show more DOPs */
- if (dop_flag) {
- double cep = NAN; /* 2D EP */
- double sep = NAN; /* 3D EP */
-
- /* Calculate estimated 2D circular position error. */
- if (isfinite(gpsdata->fix.epy) != 0
- && isfinite(gpsdata->fix.epy) != 0) {
- /* http://gauss.gge.unb.ca/papers.pdf/gpsworld.may99.pdf */
- /* cep is just the hypoteneuse of the triangle */
- cep = sqrt((gpsdata->fix.epx * gpsdata->fix.epx) +
- (gpsdata->fix.epy * gpsdata->fix.epy));
- if (isfinite(gpsdata->fix.epv) != 0) {
- sep = sqrt((gpsdata->fix.epx * gpsdata->fix.epx) +
- (gpsdata->fix.epy * gpsdata->fix.epy) +
- (gpsdata->fix.epv * gpsdata->fix.epv));
- }
- }
-
- /* Fill in the estimated 2D (horizontal) position error. */
- ep_str = ep_to_str(cep, altfactor, altunits);
- dop_str = dop_to_str(gpsdata->dop.hdop);
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 8,
- "%s, %-*s", dop_str, 11, ep_str);
-
- /* PDOP, 3D error */
- ep_str = ep_to_str(sep, altfactor, altunits);
- dop_str = dop_to_str(gpsdata->dop.pdop);
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 8,
- "%s, %-*s", dop_str, 11, ep_str);
-
- /* time dilution of precision, TDOP */
- /* FIXME: time ep? */
- dop_str = dop_to_str(gpsdata->dop.tdop);
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 8, "%-*s",
- 18, dop_str);
-
- /* geometric dilution of precision, GDOP */
- /* FIXME: gdop ep? */
- dop_str = dop_to_str(gpsdata->dop.gdop);
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 8, "%-*s",
- 18, dop_str);
-
- }
-
- /* Fill in the estimated speed error. */
- ep_str = ep_to_str(gpsdata->fix.eps, speedfactor, speedunits);
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 8,
- " %-*s", 11,
- ep_str);
+ if (isnan(gpsdata->fix.epv) == 0)
+ (void)snprintf(scr, sizeof(scr), "+/- %d %s",
+ (int)(gpsdata->fix.epv * altfactor), altunits);
+ else
+ (void)snprintf(scr, sizeof(scr), "n/a");
+ (void)mvwprintw(datawin, 11, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
+ scr);
/* Fill in the estimated track error. */
- ep_str = ep_to_str(gpsdata->fix.epd, speedfactor, "deg");
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 8, "%-*s", 18,
- ep_str);
+ if (isnan(gpsdata->fix.epd) == 0)
+ (void)snprintf(scr, sizeof(scr), "+/- %d deg",
+ (int)(gpsdata->fix.epd));
+ else
+ (void)snprintf(scr, sizeof(scr), "n/a");
+ (void)mvwprintw(datawin, 12, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
+ scr);
- /* Fill in the time offset, milli seconds. */
- if (isfinite(gpsdata->fix.time) != 0)
- (void)snprintf(scr, sizeof(scr), "%6.3f sec",
+ /* Fill in the estimated speed error. */
+ if (isnan(gpsdata->fix.eps) == 0)
+ (void)snprintf(scr, sizeof(scr), "+/- %d %s",
+ (int)(gpsdata->fix.eps * speedfactor), speedunits);
+ else
+ (void)snprintf(scr, sizeof(scr), "n/a");
+ (void)mvwprintw(datawin, 13, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
+ scr);
+ /* Fill in the time offset. */
+ if (isnan(gpsdata->fix.time) == 0)
+ (void)snprintf(scr, sizeof(scr), "%.3f",
(double)(timestamp()-gpsdata->fix.time));
else
- (void)snprintf(scr, sizeof(scr), " n/a");
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 8, "%-*s", 18,
+ (void)snprintf(scr, sizeof(scr), "n/a");
+ (void)mvwprintw(datawin, 14, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
scr);
/* Fill in the grid square (esr thought *this* one was interesting). */
if (isnan(gpsdata->fix.longitude)==0 && isnan(gpsdata->fix.latitude)==0)
s = maidenhead(gpsdata->fix.latitude,gpsdata->fix.longitude);
else
s = "n/a";
- (void)mvwprintw(datawin, row++, DATAWIN_VALUE_OFFSET + 9, "%-*s",
- 18, s);
-
+ (void)mvwprintw(datawin, 15, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, s);
}
/* Be quiet if the user requests silence. */
diff --git a/contrib/README b/contrib/README
index 57d4ec34..e069733d 100644
--- a/contrib/README
+++ b/contrib/README
@@ -2,8 +2,6 @@ The following tools are not production-ready. They are included only as
conveniences, examples or rudimetary starting points for other development
efforts.
-clock_test is used to test the latency of the system call clock_getttime().
-
binlog and binreplay are probably only useful for people developing
drivers for new protocols, when gpsfake does not yet know what to do
with a log file. These utilities are not particularly clever - they
diff --git a/contrib/clock_test.c b/contrib/clock_test.c
deleted file mode 100644
index 904c9678..00000000
--- a/contrib/clock_test.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * clock_test. A simple program to test the latency of the clock_gettime() call
- *
- * Compile: gcc clock_test.c -lm -o clock_test
- *
- */
-
-#include <getopt.h> /* for getopt() */
-#include <limits.h> /* for LONG_MAX */
-#include <math.h> /* for pow(), sqrt() */
-#include <stdio.h> /* for printf() */
-#include <stdlib.h> /* for qsort() */
-#include <time.h> /* for time_t */
-
-#define NUM_TESTS 101 /* default samples, make it odd for a clean median */
-#define DELAY 10000000 /* default delay between samples in ns, 10 ms is good */
-
-int compare_long( const void *ap, const void *bp)
-{
- long a = *((long *)ap);
- long b = *((long *)bp);
- if ( a < b ) return -1;
- if ( a > b ) return 1;
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- int i;
- int opt; /* for getopts() */
- int verbose = 0;
- int samples = NUM_TESTS;
- long delay = DELAY;
- long *diffs = NULL;
- long min = LONG_MAX, max = 0, sum = 0, mean = 0, median = 0;
- double stddev = 0.0;
-
- while ((opt = getopt(argc, argv, "d:hvn:")) != -1) {
- switch (opt) {
- case 'd':
- delay = atol(optarg);
- break;
- case 'n':
- samples = atoi(optarg);
- /* make odd, for a good median */
- if ( (samples & 1) == 0) {
- samples += 1;
- }
- break;
- case 'v':
- verbose = 1;
- break;
- case 'h':
- /* fall through */
- default: /* '?' */
- fprintf(stderr, "Usage: %s [-h] [-d nsec] [-n samples] [-v]\n\n", argv[0]);
- fprintf(stderr, "-d nsec : nano seconde paus between samples\n");
- fprintf(stderr, "-h : help\n");
- fprintf(stderr, "-n samples : Number of samples, default %d\n", NUM_TESTS);
- fprintf(stderr, "-v : verbose\n");
- exit(EXIT_FAILURE);
- }
- }
-
- diffs = alloca( sizeof(long) * (samples + 2)); /* add 2 for off by one errors */
-
- /* collect test data */
- for ( i = 0 ; i < samples; i++ ) {
- struct timespec now, now1, sleep, sleep1;
-
- (void)clock_gettime(CLOCK_REALTIME, &now);
- (void)clock_gettime(CLOCK_REALTIME, &now1);
- diffs[i] = now1.tv_nsec - now.tv_nsec;
- if ( now1.tv_sec != now.tv_sec ) {
- /* clock roll over, fix it */
- diffs[i] += 1000000000; /* add one second */
- }
- /* instead of hammering, sleep between tests, let the cache get cold */
- sleep.tv_sec = 0;
- sleep.tv_nsec = delay; /* sleep delay */
- /* sleep1 unused, should not be returning early */
- nanosleep(&sleep, &sleep1);
- }
-
- /* analyze test data */
-
- /* print diffs, calculate min and max */
- for ( i = 0 ; i < samples; i++ ) {
- if ( verbose > 0 ) {
- printf("diff %ld\n", diffs[i]);
- }
- sum += diffs[i];
- if ( diffs[i] < min ) min = diffs[i];
- if ( diffs[i] > max ) max = diffs[i];
- }
- mean = sum / (samples - 1);
-
- qsort( diffs, samples, sizeof(long), compare_long);
- median = diffs[(samples / 2) + 1];
-
-
- for ( i = 0 ; i < samples; i++ ) {
- stddev += pow(diffs[i] - mean, 2);
- }
- stddev = sqrt(stddev/samples);
-
- printf("samples %d, delay %ld ns\n", samples, delay);
- printf("min %ld ns, max %ld ns, mean %ld ns, median %ld ns, StdDev %ld ns\n",
- min, max, mean, median, (long)stddev);
-}
diff --git a/xgps b/xgps
index d6f6c686..78a08a0c 100755
--- a/xgps
+++ b/xgps
@@ -27,7 +27,13 @@ import cairo
# Gtk3 imports. Gtk3 requires the require_version(), which then causes
# pylint to complain about the subsequent "non-top" imports.
import gi
-gi.require_version('Gtk', '3.0')
+try:
+ gi.require_version('Gtk', '3.0')
+except:
+ # Gtk2 may be installed, has no equire_version()
+ sys.stderr.write("Unsupported Gtk version\n")
+ exit(1)
+
from gi.repository import GObject # pylint: disable=wrong-import-position
from gi.repository import Gtk # pylint: disable=wrong-import-position
from gi.repository import Gdk # pylint: disable=wrong-import-position
@@ -47,50 +53,6 @@ MAXCHANNELS = 28
# by default, used at the top, then sort PRN
SKY_VIEW_SORT_FIELDS = ('-used', 'PRN')
-# Each GNSS constellation reuses the same PRNs. To differentiate they are
-# all mushed into the PRN by Universal Satellite Index (USI)
-
-# here is the mapping.
-# USI constellation
-# ----------- | --------------
-# 0 Unused. Ignore satellites with this USI
-# [1...37] GPS PRNs [1...37]
-# [38...69] GLONASS FCNs [-7...24]
-# 70 GLONASS satellite with unknown FCN
-# [71...119] GALILEO PRNs [1...49]
-# [120...142] SBAS PRNs [120...142]
-# [143...192] Reserved
-# [193...197] QZSS PRNs [193...197]
-# [198...210] Reserved
-# [211...247] BeiDou (COMPASS) PRNs [1...37]
-# [248...254] Reserved
-# 255 Unused. Ignore satellites with this USI
-
-# FIXME: should be in gps.py, will move when tested
-def gps_type( prn ):
- # return a string of the GPS constellation this PRN is in
- if prn == 0:
- return 'Unused'
- if prn < 38:
- return 'GPS'
- if prn < 71:
- return 'GLONASS'
- if prn < 120:
- return 'GALILEO'
- if prn < 143:
- return 'SBAS'
- if prn < 193:
- return 'Reserved'
- if prn < 198:
- return 'QZSS'
- if prn < 211:
- return 'Reserved'
- if prn < 248:
- return 'BeiDou'
- if prn < 255:
- return 'Reserved'
- # else 255
- return 'Unused'
class unit_adjustments(object):
"Encapsulate adjustments for unit systems."
@@ -236,32 +198,6 @@ class SkyView(Gtk.DrawingArea):
self.cr.show_text(text)
self.cr.new_path()
- def draw_triangle(self, x, y, radius, filled=False, flip=False):
- "Draw a triangle centered on the specified midpoint."
- lw = self.cr.get_line_width()
- if flip:
- ytop = y + radius
- ybot = y - radius
- else:
- ytop = y - radius
- ybot = y + radius
-
- x1, y1 = fit_to_grid(x, ytop, lw)
- x2, y2 = fit_to_grid(x + radius, ybot, lw)
- x3, y3 = fit_to_grid(x - radius, ybot, lw)
-
- self.cr.move_to(x1, y1)
- self.cr.line_to(x2, y2)
- self.cr.line_to(x3, y3)
- self.cr.close_path()
-
- self.cr.stroke()
-
- if filled:
- self.cr.fill()
- else:
- self.cr.stroke()
-
def pol2cart(self, az, el):
"Polar to Cartesian coordinates within the horizon circle."
az = (az - self.rotate) % 360.0
@@ -326,7 +262,6 @@ class SkyView(Gtk.DrawingArea):
if sat.az == 0 and sat.el == 0:
continue # Skip satellites with unknown position
(x, y) = self.pol2cart(sat.az, sat.el)
- # colorize by signal strength
if sat.ss < 10:
self.set_color("Gray")
elif sat.ss < 30:
@@ -337,18 +272,10 @@ class SkyView(Gtk.DrawingArea):
self.set_color("Green3")
else:
self.set_color("Green1")
-
- # shape by constellation
- constellation = gps_type(sat.PRN)
- if constellation == 'GPS':
- self.draw_circle(x, y, SkyView.SAT_RADIUS, sat.used)
- elif constellation == 'SBAS':
+ if gps.is_sbas(sat.PRN):
self.draw_square(x, y, SkyView.SAT_RADIUS, sat.used)
- elif constellation == 'GALILEO':
- self.draw_triangle(x, y, SkyView.SAT_RADIUS, sat.used, False)
else:
- # QZSS, GLONASS, BeiDou, Reserved or Unused
- self.draw_triangle(x, y, SkyView.SAT_RADIUS, sat.used, True)
+ self.draw_circle(x, y, SkyView.SAT_RADIUS, sat.used)
self.cr.set_source_rgb(1, 1, 1)
self.draw_string(x + SkyView.SAT_RADIUS,
@@ -679,7 +606,8 @@ class Base(object):
self.satlist = Gtk.ListStore(str, str, str, str, str)
view = Gtk.TreeView(model=self.satlist)
- for (i, label) in enumerate(('PRN', 'Elev', 'Azim', 'SNR', 'Used')):
+ for (i, label) in enumerate(('PRN:', 'Elev:', 'Azim:', 'SNR:',
+ 'Used:')):
column = Gtk.TreeViewColumn(label)
renderer = Gtk.CellRendererText()
column.pack_start(renderer, expand=True)
@@ -824,7 +752,7 @@ class Base(object):
def update_altitude(self, data):
if data.mode >= gps.MODE_3D and hasattr(data, "alt"):
- return "%9.3f %s" % (
+ return "%.3f %s" % (
data.alt * self.conversions.altfactor,
self.conversions.altunits)
else:
@@ -832,7 +760,7 @@ class Base(object):
def update_speed(self, data):
if hasattr(data, "speed"):
- return "%9.3f %s" % (
+ return "%.3f %s" % (
data.speed * self.conversions.speedfactor,
self.conversions.speedunits)
else:
@@ -840,7 +768,7 @@ class Base(object):
def update_climb(self, data):
if hasattr(data, "climb"):
- return "%9.3f %s" % (
+ return "%.3f %s" % (
data.climb * self.conversions.speedfactor,
self.conversions.speedunits)
else:
@@ -910,10 +838,10 @@ class Base(object):
key=lambda x: x[fld], reverse=rev)
for (i, satellite) in enumerate(satellites):
- self.set_satlist_field(i, 0, "%3d" % satellite.PRN)
- self.set_satlist_field(i, 1, "%3d" % satellite.el)
- self.set_satlist_field(i, 2, "%3d" % satellite.az)
- self.set_satlist_field(i, 3, "%3d" % satellite.ss)
+ self.set_satlist_field(i, 0, satellite.PRN)
+ self.set_satlist_field(i, 1, satellite.el)
+ self.set_satlist_field(i, 2, satellite.az)
+ self.set_satlist_field(i, 3, satellite.ss)
yesno = 'N'
if satellite.used:
yesno = 'Y'