Simple maths for GPS (Haversine) math.h had appeared very inaccurate LPC1768 (fixed)

Comments

12 comments

  • Avatar
    Michael Johnson

    You'll need put the signature of the function before it is used otherwise the compiler will default the parameter types to be of int.

     

    0
    Comment actions Permalink
  • Avatar
    Mark Boyce

    Thanks Michael, I didn't include the header file here but it is present as you suggested. What do you think?

    0
    Comment actions Permalink
  • Avatar
    Michael Johnson

    You've used haversine before it has been declared.

    You'll need to put

    double haversine(double lat1, double lon1, double lat2, double lon2)

    before

    double test_distance()

    0
    Comment actions Permalink
  • Avatar
    Mark Boyce

    Yes, that's in the header file

    0
    Comment actions Permalink
  • Avatar
    Mark Boyce

    Hi Michael here is a better example with the problem

     

    #include "processing.h"
    #include <math.h>
    #include <stdio.h>

     

    double haversine(double lat1, double lon1, double lat2, double lon2);

    double test_distance()
    {
     //-42.78724667 147.246516667 to -42.7872449999 147.2465333 (1.36m)
     // -42.7872466666, 147.247016667, -42.7872449999, 147.247742 (100m)
     // -42.7872466666, 147.247016667, -42.7872449999, 147.25877  (1000m)
      double result = haversine(-42.7872466666, 147.247016667, -42.7872449999, 147.247742);
    }

    #define M_PI (double)3.14159265358979

    double haversine(double lat1, double lon1, double lat2, double lon2)
    {
     // Convert degrees to radians
     lat1 = lat1 * M_PI / (double)180.0;
     lon1 = lon1 * M_PI / (double)180.0;
     
     lat2 = lat2 * M_PI / (double)180.0;
     lon2 = lon2 * M_PI / (double)180.0;
     


     
     // P
     double dlat = lat2-lat1;
     double dlon = lon2-lon1;
     double sumlat = lat1 + lat2;
     double calc = dlon * cos(sumlat/(double)2.0);
            calc *=calc;
            dlat *=dlat;

            double distance = sqrt(calc + dlat) * (double)6371000.0;

     return distance;
     
    }

    0
    Comment actions Permalink
  • Avatar
    Michael Johnson

    double result = haversine(-42.7872466666, 147.247016667, -42.7872449999, 147.247742);
    debug_printf("result %g\n", result);

    prints 59.1903 building the code with MS CL produces the same result.

    0
    Comment actions Permalink
  • Avatar
    Mark Boyce

    Yes the result should yield 1.3m but I'm getting 59 in firmware and 1.3 in excel and google maps.

    It seems I have to resign to the fact that math.h in both MS and GCC doesn't have the accuracy for gps. I am wondering if there are other libraries out there that can deal with long doubles math.

     

    Thanks for you help

    0
    Comment actions Permalink
  • Avatar
    Mark Boyce

    sorry I meant should yield 100m but I'm getting 59 in firmware and 100 in excel and google maps

    0
    Comment actions Permalink
  • Avatar
    Michael Johnson

    It's fairly common for double precision to be used for GPS calculations.

    Perhaps 59 is the accurate one and excel/maps isn't?

    0
    Comment actions Permalink
  • Avatar
    Mark Boyce

    As you can tell from my co-ords it is way past bedtime. I'll take another look tomorrow. Again I appreciate your help Michael. You may have a point on the excel thing.

    0
    Comment actions Permalink
  • Avatar
    Jon Elliott

    I think 59 meters is correct, I get the same with my own Haversine code and also if I plot the points on Google Earth and measure the distance with the ruler tool.

    Jon

    0
    Comment actions Permalink
  • Avatar
    Mark Boyce

    Thanks guy's hit it again after 5 hours of sleep and the test cases are the same with MS C#. Google, Excel and GCC code. Problem's gone. Please delete thread then divide me by 0.

    Thanks for your support :)

    0
    Comment actions Permalink

Please sign in to leave a comment.