...fairly precise GPS coordinate distance calculation
As JRemington notes, the Haversine distance calculation with single-precision float is fairly accurate... about 1 meter or so. This is more accurate than the GPS device is reporting, so it's probably good enough. Are you using longer time periods or expensive GPS devices to get sub-meter accuracy in your coordinates?
I also second his suggestion about treating the lat/lon as planar coordinate (i.e., equirectangular), not spherical. It is ok for small distances, and it changes the Haversine calculation (expensive trig functions) to plain, old pythagorean distance calculations (one square root). Degrees of latitude are (fairly) constant, but degrees of longitude are smaller at the poles, requiring one trig function call to scale them, based on your latitude.
Of course, I have to pitch my NeoGPS library as possible solution. It handles the GPS coordinates as integer degrees x 107. They will retain about 10 significant digits, while single-precision float is only about 6. So the instant you switch to float
, you will lose about 4 significant digits. Again, that will get you down to 1 meter or so. Is that good enough?
One advantage of NeoGPS is its more-robust examples. As you try to extend the examples from other libraries, you will eventually run into problems. If you stick with TinyGPS, I would suggest looking at the NeoGPS examples as a pattern for your own sketch.
Another advantage to NeoGPS is the amount of RAM and CPU time you could save. If you find yourself needing a 100 bytes to 1000 bytes of RAM, or a little more CPU time, you might take a look. NeoGPS is 40% to 70% faster, and uses 70% to 95% less RAM than other libraries. Even the program space can be smaller, depending on how many sentences and fields you really need.
jremington:
To my knowledge, no one has implemented great circle calculations in integer units on the Arduino.
Bahahaha! I'm actually working on that now. It just seems a shame to pull in the floating-point libraries (add, subtract, multiply, sine, cosine, arctangent) just to get the distance. So yes, there is a "clever workaround." Printing lat/lon is another reason people convert the integers to float
s, and I'm working on methods for that, too. Real Soon Now.
Cheers,
/dev