To post comments on this article and find any associated files
and/or downloads, go to www.servomagazine.com/index.php/magazine/issue/2018/01.
The second issue is that we are checking for equality
with two floating point numbers. Because of
the way floating point numbers are
represented in a binary system, this is almost
surely destined to fail us. The common
approach is to see if the numbers are “close”
to some specified precision; say, six decimal
places for crude applications. While we could
implement such a close to or equal to check,
we would still be battling the precision issue.
Okay. Let’s try specifying a tolerance. If
we’re within 0.001 degrees latitude and
longitude of the target point, drop. That
seems reasonable until we look at the
geometry of the globe and lines of latitude
and longitude. Assuming a spherical globe,
there is a distance of 111.2 km between
each line of latitude on the globe. At the equator, one
degree of longitude is 111.2 km. As we follow lines of
longitude to the poles, they converge; meaning that at 89
degrees latitude, the distance covered by one degree of
longitude is only 1.941 km. That means that using our
tolerance of 0.001 degrees makes the drop point location
wiggle room vary from 111 m at the equator to 1.9 m at
89 N latitude! That’s not good because we want to specify
a tolerance that is location invariant.
Figure 2: GPS modules like this are cheaply and easily available, and provide
amazing timing and location accuracy for drone projects.
To effectively solve the equations, each packet contains
the time of transmission (according to atomic clocks on the
satellites), the satellite’s position in space, and a
pseudorandom code used to find the time of arrival.
Satellite position is given as an ephemeris
encoding of the timing is beyond the scope of this article,
but from this information the location and time can be
solved for with surprising accuracy.
Handheld consumer grade GPS receivers that sell for
$15 in single piece quantities can find your position to
within ± 3 meters (Figure 2) with no external information,
Internet, monthly fees, or other limitations. Amazing!
Enter the haversine formula! This formula allows us to
calculate the distance between two coordinates; so, we can
specify a tolerance of 10 meters. Plus, it’s the same distance
everywhere on the spherical Earth.
This brings us to our first problem. Say we want to
drop our payload at 40.234 N, 130.234W. The naïve way to
code this would be:
if (current_lat == target_lat && current_long
The haversine formula is really a specific application of
the law of haversines in the weird world of spherical
trigonometry. If we know the radius of the Earth (r), the
latitudes of the points 1 and 2 (ji), and longitude of the
points (li), we can calculate the distance between them (d)
If you were to try such a snippet, you’d find that the
payload is very likely to never drop at all. This is due to the
precision of the measurement and the fact that equality
checks on floating point values are problematic at best.
j2 — j1 l2 — l1
d = 2 r sin-1 sin2 + cos(j1) cos (j2) sin2 Ö ) ( ( ( ) )
First, the precision issue. If you specify a certain set of
drop coordinates and sit exactly on those coordinates, it is
unlikely that the GPS will show those exact numbers. (How
far down can you trust the position estimate? Three meters
is the best on most non-differential GPS units!) If you leave
the GPS in one position and watch the position estimates,
you can get an idea of what to expect.
While that looks like a ton of “fun” to program and
deal with all of the strange edge cases, luckily there is an
implementation already in the TinyGPS++ library. It’s always
nice to know how things are done, though, so we can
understand the limitations and what to do if they break.
While this may seem “inaccurate,” remember that at
300 million meters per second, the timing of the signals
must be resolved to within about 9 ns to get that precision.
Pretty phenomenal for a network of satellites whizzing
around the Earth and a $15 receiver!
The hardware hookup on this project is relatively simple
and just requires an Arduino Uno, breadboard, GPS
module, pushbutton, and your gripper servo. I chose an
Uno because it’s what wasn’t occupied with other projects
at the moment, but a similar board such as the Wildfire
would work as well.
12 SERVO 01.2018