summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-01-20 15:21:23 -0500
committerEric S. Raymond <esr@thyrsus.com>2011-01-20 15:21:23 -0500
commitcc0126b8f7d1f57b5871470829b3e59cdb4ef0ef (patch)
tree505713cc4c75a53d0d171851f8a413b880f16c0c
parentc46ae044e399113f040196fc156489e1e2f303f9 (diff)
downloadgpsd-cc0126b8f7d1f57b5871470829b3e59cdb4ef0ef.tar.gz
Document gpsd's assumption about the host system clock correctly.
We're more dependent on it than I realized. At least all the dependencies are in one module now, and we may be able to do something about relaxing them.
-rw-r--r--gpsutils.c11
-rw-r--r--timebase.c154
-rw-r--r--www/NMEA.txt53
-rw-r--r--www/hacking.html12
4 files changed, 111 insertions, 119 deletions
diff --git a/gpsutils.c b/gpsutils.c
index e41bc19a..b96ff362 100644
--- a/gpsutils.c
+++ b/gpsutils.c
@@ -157,17 +157,6 @@ double iso8601_to_unix( /*@in@*/ char *isotime)
}
/* *INDENT-ON* */
-#ifdef __UNUSED__
-void unix_to_gpstime(double unixtime,
- /*@out@*/ int *week,
- /*@out@*/ double *tow)
-{
- unixtime -= GPS_EPOCH;
- *week = (int)(unixtime / SECS_PER_WEEK);
- *tow = fmod(unixtime, SECS_PER_WEEK);
-}
-#endif
-
#define Deg2Rad(n) ((n) * DEG_2_RAD)
/* Distance in meters between two points specified in degrees, optionally
diff --git a/timebase.c b/timebase.c
index 5087928d..02bd21fe 100644
--- a/timebase.c
+++ b/timebase.c
@@ -1,79 +1,42 @@
/*****************************************************************************
-Excerpted from my blog entry on this code:
-
-The root cause of the Rollover of Doom is the peculiar time
-reference that GPS uses. Times are expressed as two numbers: a count
-of weeks since the start of 1980, and a count of seconds in the
-week. So far so good - except that, for hysterical raisins, the week
-counter is only 10 bits long. The first week rollover was in 1999;
-the second will be in 2019.
-
-So, what happens on your GPS when you reach counter zero? Why, the
-time it reports warps back to the date of the last rollover, currently
-1999. Obviously, if you are logging or computing anything
-time-dependent through a rollover and relying on GPS time, you are
-screwed.
-
-Now, we do get one additional piece of time information: the current
-leap-second offset. The object of this exercise is to figure out what
-you can do with it.
-
-In order to allow UTC to be computed from the GPS-week/GPS-second
-pair, the satellite also broadcasts a cumulative leap-second offset.
-The offset was 0 when the system first went live; in January 2010
-it is 15 seconds. It is updated every 6 months based on spin measurements
-by the <a href="http://www.iers.org/">IERS</a>.
-
-For purposes of this exercise, you get to assume that you have a table
-of leap seconds handy, in Unix time (seconds since midnight before 1
-Jan 1970, UTC corrected). You do *not* get to assume that your table
-of leap seconds is current to date, only up to when you shipped your
-software.
-
-For extra evilness, you also do not get to assume that the week rollover
-period is constant. The not-yet-deployed Block III satellites will have
-13-bit week rollover counters, pushing the next rollover back to 2173AD.
-
-For extra-special evilness, there are two different ways your GPS date
-could be clobbered. after a rollover. If your receiver firmware was
-designed by an idiot, all GPS week/second pairs will be translated
-into an offset from the last rollover, and date reporting will go
-wonky precisely on the next rollover. If your designer is slightly
-more clever, GPS dates between the last rollover and the ship date of
-the receiver firmware will be mapped into offsets from the *next*
-rollover, and date reporting will stay sane for an entire 19 years
-from that ship date.
-
-You are presented with a GPS time (a week-counter/seconds-in-week
-pair), and a leap-second offset. You also have your (incomplete) table
-of leap seconds. The GPS week counter may invalid due to the Rollover
-of Doom. Specify an algorithm that detects rollover cases as often as
-possible, and explain which cases you cannot detect.
-
-Hint: This problem is a Chinese finger-trap for careful and conscientious
-programmers. The better you are, the worse this problem is likely to hurt
-your brain. Embrace the suck.
-
-Here is what you can do.
-
-If the timestamp you are handed is within the range of the first and
-last entries, check the leap-second offset. If it is correct for that
-range, there has been no rollover. If it does not match the
-leap-second offset for that range, your date is from a later rollover
-period than your receiver was designed to handle and has gotten
-clobbered.
-
-The odd thing about this test is the range of rollover cases it can detect.
-If your table covers a range of N seconds after the last rollover, it will
-detect rollover from all future weeks as long as they are within N seconds
-after *their* rollover. It will be leaast effective from a software release
-immediately after a rollover and most effective from a release immediately
-before one.
-
-Much of the time, this algorithm will return "I cannot tell". The reason this
-problem is like a Chinese finger trap is because good programmers will hurt
-their brains trying to come up with a solution that does not punt any cases.
+All of gpsd's assumptions about time and GPS time reporting live in this file.
+
+This is a work in progress. Currently GPSD requires that the host system
+clock be accurate to within one second. We are attempting to relax this
+to "accurate within one GPS rollover period".
+
+Date and time in GPS is represented as number of weeks from the start
+of zero second of 6 January 1980, plus number of seconds into the
+week. GPS time is not leap-second corrected, though satellites also
+broadcast a current leap-second correction which is updated on
+six-month boundaries according to rotational bulletins issued by the
+International Earth Rotation and Reference Systems Service (IERS).
+
+The leap-second correction is only included in the satellite subframre
+broadcast, roughly once ever 20 minutes. While the satellites do
+notify GPSes of upcoming leap-seconds, this notification is not
+necessarily processed correctly on consumer-grade devices, and will
+not be available at all when a GPS receiver has just
+cold-booted. Thus, UTC time reported from NMEA devices may be slightly
+inaccurate between a cold boot or leap second and the following
+subframe broadcast.
+
+GPS date and time are subject to a rollover problem in the 10-bit week
+number counter, which will re-zero every 1024 weeks (roughly every 20
+years). The last rollover (and the first since GPS went live in 1980)
+was in 1999; the next would fall in 2019, but plans are afoot to
+upgrade the satellite counters to 13 bits; this will delay the next
+rollover until 2173.
+
+For accurate time reporting, therefore, a GPS requires a supplemental
+time references sufficient to identify the current rollover period,
+e.g. accurate to within 512 weeks. Many NMEA GPSes have a wired-in
+assumption about the UTC time of the last rollover and will thus report
+incorrect times outside the rollover period they were designed in.
+
+This file is Copyright (c) 2010 by the GPSD project
+BSD terms apply: see the file COPYING in the distribution root for details.
*****************************************************************************/
@@ -145,22 +108,6 @@ static int gpsd_check_utc(const int leap, const double unixtime)
#define SECS_PER_WEEK (60*60*24*7) /* seconds per week */
#define GPS_ROLLOVER (1024*SECS_PER_WEEK) /* rollover period */
-static double gpstime_to_unix(int week, double tow)
-{
- double fixtime;
-
- if (week >= 1024)
- fixtime = GPS_EPOCH + (week * SECS_PER_WEEK) + tow;
- else {
- time_t now, last_rollover;
- (void)time(&now);
- last_rollover =
- GPS_EPOCH + ((now - GPS_EPOCH) / GPS_ROLLOVER) * GPS_ROLLOVER;
- /*@i@*/ fixtime = last_rollover + (week * SECS_PER_WEEK) + tow;
- }
- return fixtime;
-}
-
void gpsd_rollover_check(/*@in@*/struct gps_device_t *session,
const double unixtime)
{
@@ -202,6 +149,33 @@ void gpsd_rollover_check(/*@in@*/struct gps_device_t *session,
}
}
+#ifdef __UNUSED__
+void unix_to_gpstime(double unixtime,
+ /*@out@*/ int *week,
+ /*@out@*/ double *tow)
+{
+ unixtime -= GPS_EPOCH;
+ *week = (int)(unixtime / SECS_PER_WEEK);
+ *tow = fmod(unixtime, SECS_PER_WEEK);
+}
+#endif
+
+static double gpstime_to_unix(int week, double tow)
+{
+ double fixtime;
+
+ if (week >= 1024)
+ fixtime = GPS_EPOCH + (week * SECS_PER_WEEK) + tow;
+ else {
+ time_t now, last_rollover;
+ (void)time(&now);
+ last_rollover =
+ GPS_EPOCH + ((now - GPS_EPOCH) / GPS_ROLLOVER) * GPS_ROLLOVER;
+ /*@i@*/ fixtime = last_rollover + (week * SECS_PER_WEEK) + tow;
+ }
+ return fixtime;
+}
+
double gpsd_resolve_time(/*@in@*/struct gps_device_t *session,
unsigned short week, double tow)
{
diff --git a/www/NMEA.txt b/www/NMEA.txt
index 316e9f60..a36576ae 100644
--- a/www/NMEA.txt
+++ b/www/NMEA.txt
@@ -1,6 +1,6 @@
= NMEA Revealed =
Eric S. Raymond <esr@thyrsus.com>
-v2.6, Jan 2011
+v2.7, Jan 2011
This is a list of NMEA 0183 sentences with field descriptions.
It is primarily intended to help people understand GPS reports.
@@ -121,18 +121,45 @@ no valid data for it. However, many receivers violate this. It's
common, for example, to see latitude/longitude/altitude figures filled
with zeros when the GPS has no valid data.
-Date and time in GPS is computed as number of weeks from the zero
-second of 6 January 1980, plus number of seconds into the week. GPS
-time is not leap-second corrected, though satellites also broadcast a
-current leap-second correction which is updated on six-month
-boundaries according to rotational bulletins issued by the
+== Dates and times ==
+
+NMEA devices report date and time in UTC, aka GMT, aka Zulu time (as
+opposed to local time). But the way this report is computed results
+in some odd bugs and inaccuracies.
+
+Date and time in GPS is represented as number of weeks from the start
+of zero second of 6 January 1980, plus number of seconds into the
+week. GPS time is not leap-second corrected, though satellites also
+broadcast a current leap-second correction which is updated on
+six-month boundaries according to rotational bulletins issued by the
International Earth Rotation and Reference Systems Service (IERS).
-GPS date and time are subject to a rollover problem in the 10-bit
-week number counter, which will re-zero every 1024 weeks (roughly
-every 20 years). The next rollover would fall in 2019, but plans
-are afoot to upgrade the satellite counters to 13 bits; this will
-delay the next rollover until 2173.
+The leap-second correction is only included in the satellite subframre
+broadcast, roughly once ever 20 minutes. While the satellites do
+notify GPSes of upcoming leap-seconds, this notification is not
+necessarily processed correctly on consumer-grade devices, and will
+not be available at all when a GPS receiver has just
+cold-booted. Thus, reported UTC time may be slightly inaccurate
+between a cold boot or leap second and the following subframe
+broadcast.
+
+GPS date and time are subject to a rollover problem in the 10-bit week
+number counter, which will re-zero every 1024 weeks (roughly every 20
+years). The last rollover (and the first since GPS went live in 1980)
+was in 1999; the next would fall in 2019, but plans are afoot to
+upgrade the satellite counters to 13 bits; this will delay the next
+rollover until 2173.
+
+For accurate time reporting, therefore, a GPS requires a supplemental
+time references sufficient to identify the current rollover period,
+e.g. accurate to within 512 weeks. Many NMEA GPSes have a wired-in
+assumption about the UTC time of the last rollover and will thus report
+incorrect times outside the rollover period they were designed in.
+
+For these reasons, NMEA GPS should not be considered high-quality
+references for absolute time. Some do, however, emit pulse-per-second
+RS232 signals which can be used to improve the precision of an
+external clock. See [PPS] for discussion.
== Error status indications
@@ -2229,3 +2256,7 @@ Only emitted by uBlox Antaris chipset.
- [[[WAAS]]]
"WAAS Information"
http://gpsinformation.net/exe/waas.html
+
+- [[[PPS]]]
+ "Pulse per second"
+ http://en.wikipedia.org/wiki/Pulse_per_second
diff --git a/www/hacking.html b/www/hacking.html
index b14f1ce7..73e92500 100644
--- a/www/hacking.html
+++ b/www/hacking.html
@@ -927,14 +927,12 @@ PIRN-002 that whether you can get 10 or 13 bits is a function of the
satellite firmware revision, with 13 bits in the Block IIF and later
birds (the first of these was launched in May 2010). Of course your
receiver firmware also has to know that the extra three bits are
-present; at time of writing in late 2010 this capability is at best
-rare and possibly nonexistent.</p>
+present; at time of writing in late 2010 this capability is very rare
+and unavailable on consumer-grade receivers.</p>
-<p>See the timebase.h file for one or more constants that need to
-be tweaked occasionally to cope with these problems.</p>
-
-<p>Note that gpsd does not rely on the system clock in any way. This
-is so you can use it to set the system clock.</p>
+<p>For these reasons, GPSD needs the host computer's system clock to
+be accurate to within one second. (Work is in progress to relax this
+requirement to accuracy within half of a rollover period.)</p>
<p>When debugging time and date issues, you may find an
<a href="http://adn.agi.com/GNSSWeb/">interactive GPS calendar</a>