| |||||||||||||||||||||||||||||||
GPSIt's about time I played a little with GPS as it is going to be very useful on Moana. Ideally we want 50cm accuracy which standard GPS cannot provide but I have a few ideas about that. For now, I need to just get it up and running and familiarize myself with all things GPS. GPS ModulesThere are a large number of GPS modules available these days. After a fair amount of research, I decided to go for the Adafruit Ultimate GPS Breakout which has a 10Hz update rate and also has some internal data logging which may be useful. Another great feature is that it is 5v/3.3v tolerant so there is no need to faff about with logic level conversions.
Out of the box, the GPS module is good to go. You power it up and connect to via a serial port and data comes out on a serial line at 9600 baud. You can use coolterm with an FTDI adaptor or an arduino with a do-nothing sketch (as the arduino has the FTDI adaptor built in). The GPS pushes out several different log-lines (sentences) and there are two that contain useful information about location, the GPRMC and the GPGGA sentences. When I turned on the device it took about 10 minutes to get a fix, but thereafter, the connection was very reliable. $GPRMC,225234.000,A,3853.3783,S,17624.3235,E,2.87,220.04,230319,,,D*7D $GPGGA,225234.000,3853.3783,S,17624.3235,E,2,07,1.13,32.5,M,26.8,M,0000,0000*46 The two key fields here are the Lat (3853.3783,S) and Long (17624.3235, E). These mean: 38 degrees, 53.3783 minutes South, 176 degrees, 24.3235 minutes East. South and West are considered negative so this can be represented -38 53.3783, 176 24.3235. There is a lot of other useful information in there, timestamps, date, number of satellites, altitude etc and either sentence would be useful. However, the GPRMC sentence has a V/A (void/acquired) flag which means it is easy to know if there is valid data in the log line so that is the one I am leaning towards. AccuracyI wanted to get a 'ball-park' idea of how accurate the GPS was. I used Google maps to find a landmark (a telegraph pole) and put the GPS at the base of it. I then grabbed the data that came in over the GPRMC sentence and put it into google maps. (You need to enter it in the format Lat Long: +/- DD MM.xxxx +/- DDD MM.xxxx). I then tried to estimate where that datapoint was on the satellite map (and in the real world!). My accuracy was about 8 metres. On a global scale, this is awesome. On the scale of a lawn mower, this is not so great, I could be mowing my neighbour's lawn. Improving GPS AccuracyHow accurate can we really get for a fixed location? I know the GPS signal is deliberately given a 'wobble' but is this distributed in a guassian around the true value? Namely, by averaging readings over a period of time, is it possible to get much more accurate results? This was one of the reasons I selected this GPS due to the on-board logging. So it was time to set up an experiment to find out. After considering options, I decided not to use the GPS on-board binary logging, but just scrape the output from the arduino serial monitor. I put the GPS and arduino into a sealed box, strapped them to a rail on the deck and brought the USB cable in through a window. I plugged this into a Raspberry Pi that was running the Arduino IDE, and let it run for over 24 hours in changeable weather. I scraped the Serial Monitor window to put everything into a file, then ran it through awk to collect the GPRMC records cat gps.txt |grep GPRMC |grep ",A," |awk -F "," '{print $4, $6}' > latlong.txt
This gave me about 135,000 readings so I averaged the latitude and longitude values, put them into google maps (on satellite view) to see how we faired. The results were: Accuracy with averaging: 20cm. Well, that is awesome. If this can translate to 50cm accuracy on the mower, we are in a very good place. See average.txt in gps folder for details. Home Made Differential GPSAnalysing the data from the the GPS feed, I saw that it can change considerably over time, but over a period of 5 seconds, the lat/long rarely changes more than 3/10000th of a degree. This means that if we had two GPS receivers in relatively close proximity (500m), reading from the same satellites, they would be very likely to have the same small error, thus meaning the two GPS devices would not need to be synced and we would only have a small margin of error. (What I am saying here is that the 'wobble' on the signal is slow). In order to make this work, I need to put a GPS on the mower and have a communication link to my stationary GPS. When the mower makes a GPS reading, it needs to talk to the stationary GPS. The stationary GPS takes it's last reading, subtracts it known location and sends the difference back to the mower. The mower will remove the diff from its own reading and hopefully result in a much more accurate GPS fix. Differential GPS ImplementationIdeally, the communication with the stationary GPS can be over the same wireless (XBee) channel I use for controlling the mower. This will mean reconfiguring the network to be a star-network so the mower can talk to two Xbees. However, to test whether this is even going to work, I will use a separate xbee channel. It also allows me to test this off the mower. So I need to do the following:
The stationary GPS could then be modified to constantly update it's reference using a running average. This will make it even more accurate over time (assuming the wobble on the system is Gaussian around the actual value). I took the opportunity to buy some high power Xbee chips as I believe I will eventually need those in the mower. These give a range of over 1km. GPS MathsSince I'm using an Adafruit GPS, I downloaded their GPS sentence parsing library. This makes fetching the Lat and long values very simple and after some tinkering, I managed to get the values out without the need to display every GPS sentence. There are quite a few ways that earth co-ordinates can be represented and this caused me some confusion at first:
Add to this, that latitude is either North or South of the equator and longitude is East or West of Greenwich and sometimes they are represented as positive or negative values, it can cause some headaches. It is easy enough to convert from one format to another, but you need to know what you are dealing with first. The GPS sentence containing latitude is in the format DD MM.mmmm N|S The GPS sentence containing longitude is in the format DDD MM.mmmm E|W North and East are considered positive After playing with various formats, I decided the easiest format to deal with mathematically was +/-DDD.dddddd which also fits well with google maps. After writing several conversion routines, I found the Adafruit GPS library also provided the fix in this format as well as the more usual DDD MM.mmmm format. So it seems I am following in others footsteps here! I will use this format internally and flip it back to DDD MM.mmmm if I need to display it. To put this in perspective, one degree of latitude (near the equator) is 111km so using fractions of degrees are not intuitive as minutes and we need 6 decimal places to get 10cm accuracy. At my latitude (36 degrees South), we can use: 1 degree of Longitude = cosine (latitude in decimal degrees) * length of degree (km) at equator. => 111 * cos(rad(36)) = 89 km March 2019 | |||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||