summaryrefslogtreecommitdiff
path: root/geoid.c
diff options
context:
space:
mode:
authorChris Kuethe <chris.kuethe@gmail.com>2007-01-18 03:56:43 +0000
committerChris Kuethe <chris.kuethe@gmail.com>2007-01-18 03:56:43 +0000
commit5fa1d0f507ed636455319ed618d8b27972a302a2 (patch)
tree35cb6ab401c48a6b9ed288735c6f881024207710 /geoid.c
parent4a24103f1ed459a387e45e407cd5bd606cbd3234 (diff)
downloadgpsd-5fa1d0f507ed636455319ed618d8b27972a302a2.tar.gz
begin squashing negative zeros.
they create incorrect results from atan2() which is used in the ECEF to WGS84 transform. This means regression tests need to be rebuilt...
Diffstat (limited to 'geoid.c')
-rw-r--r--geoid.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/geoid.c b/geoid.c
index 8105a2bf..20e9bdb7 100644
--- a/geoid.c
+++ b/geoid.c
@@ -11,6 +11,8 @@
#include "gpsd_config.h"
#include "gpsd.h"
+static double fix_minuz(double d);
+
static double bilinear(double x1, double y1, double x2, double y2, double x, double y, double z11, double z12, double z21, double z22)
{
double delta;
@@ -112,13 +114,28 @@ void ecef_to_wgs84fix(struct gps_data_t *gpsdata,
veast = -vx*sin(lambda)+vy*cos(lambda);
gpsdata->fix.climb = vx*cos(phi)*cos(lambda)+vy*cos(phi)*sin(lambda)+vz*sin(phi);
gpsdata->fix.speed = sqrt(pow(vnorth,2) + pow(veast,2));
- heading = atan2(veast,vnorth);
+ heading = atan2(fix_minuz(veast), fix_minuz(vnorth));
/*@ +evalorder @*/
if (heading < 0)
heading += 2 * PI;
gpsdata->fix.track = heading * RAD_2_DEG;
}
+/*
+ * Some systems propagate the sign along with zero. This messes up
+ * certain trig functions, like atan2():
+ * atan2(+0, +0) = 0
+ * atan2(+0, -0) = PI
+ * Obviously that will break things. Luckily the "==" operator thinks
+ * that -0 == +0; we will use this to return an unambiguous value.
+ *
+ * I hereby decree that zero is not allowed to have a negative sign!
+ */
+static double fix_minuz(double d)
+{
+ return ((d == 0.0) ? 0.0 : d);
+}
+
#ifdef TESTMAIN
#include <stdio.h>
#include <stdlib.h>