Go Down

Topic: Navigation Calculations for Arduino GPS (Read 3 times) previous topic - next topic

Johnny D

This is an example I made of calculating out distance to destination and angle or azimuth to destination with a GPS.  This takes a destination set of GPS coordinates (entered by the user), and calculates out the distance and angle based on your current GPS position.  It displays the information through the serial channel right now.

It also displays the usual GPS information: latitude, longitude, time, date, velocity, heading.

For the example, I used Dexter Industries GPS shield:  http://dexterindustries.com/Arduino-GPS_Shield.html

I've pasted the code below and attached in a zip file too.

Code: [Select]


#include "string.h"
#include "ctype.h"
#include "SoftwareSerial.h"
#include "dGPS.h"

// Software serial TX & RX Pins for the GPS module
// Initiate the software serial connection

int ledPin = 13;                  // LED test pin
float desLat=0;                   //Destination Latitude filled by user in Serial Monitor Box
float desLon=0;                   //Destination Longitude filled by user in Serial Monitor Box
char fla[2];                      //flag (Y/N) whether to print checksum or not. Filled by user in Serial Monitor Box
dGPS dgps = dGPS();               // Construct dGPS class

float getdestcoord()
 // function to get the coordinates of the destination from user
 { float result;
   while (Serial.available()==0)
   {;}// do nothing until something comes into the serial buffer

   if (Serial.available()>0)
   {
    result=Serial.parseFloat(); //read a float value from serial monitor box, correct upto 2 decimal places
    delay(10); // the processor needs a moment to process
   }
   return result;
 }
 
void getflag(char *str)
  // function to read the flag character from the user
 {  
   while (Serial.available()==0)
   {;}
   int index=0;
   if (Serial.available()>0)
   { if (index<2){
     str[index]=Serial.read();
     index++;
    }
     else str[index]='\0';
     delay(10);
   }  
 }

void setup() {
 pinMode(ledPin, OUTPUT);       // Initialize LED pin
 Serial.end();                  // Close any previously established connections
 Serial.begin(9600);            // Serial output back to computer.  On.
 dgps.init();                   // Run initialization routine for dGPS.
 delay(1000);  
 Serial.print("Do you want to display checksum (Y/N): ");
 delay(3000);
 getflag(fla);
 Serial.println(*fla);
 Serial.print("Enter Destination Latitude (in degrees): ");
 delay(3000);
 desLat=getdestcoord();
 Serial.println(desLat);
 Serial.print("Enter Destination Longitude (in degrees): ");
 delay(3000);
 desLon=getdestcoord();
 Serial.println(desLon);
}

void loop() {
 
 dgps.update(desLat, desLon);                  // Calling this updates the GPS data.  The data in dGPS variables stays the same unless
                                 // this function is called.  When this function is called, the data is updated.
 Serial.print("UTC Time: ");
 Serial.println(dgps.Time());    // .Time returns the UTC time (GMT) in HHMMSS, 24 huor format (H-Hour; M-Minute; S-Second)
 Serial.print("Status: ");
 Serial.println(dgps.Status());  // A - Satellites acquired and a valid signal.  V - No sats and not a valid signal.
 Serial.print("Latitude: ");
 Serial.println(dgps.Lat(), 6);  // Lattitude - in DD.MMSSSS format (decimal-degrees format)  (D-Degree; M-Minute; S-Second)
 Serial.print("Longitude: ");
 Serial.println(dgps.Lon(), 6);  // Longitude - in DD.MMSSSS format (decimal-degrees format)  (D-Degree; M-Minute; S-Second)
 Serial.print("Velocity: ");
 Serial.println(dgps.Vel(), 6);  // Velocity, in knots.
 Serial.print("Heading: ");
 Serial.println(dgps.Head(), 6);  // Heading, in degrees
 Serial.print("UTC Date: ");
 Serial.println(dgps.Date());  // UTC date.  Date is in format:  DDMMYY (D - Day; M - Month; Y-Year)
 Serial.print("Distance to destination: ");
 Serial.println(dgps.Dist());    // The distance to the destination in kilometers. Correct upto 2 decimal points. Radius of Earth taken as 6,378.1 kilometers
 Serial.print("Azimuth to destination: ");
 Serial.println(dgps.Azim());     //Azimuth of the destination coordinates from the current location in degrees. Correct upto 2 decimal points
 Serial.print("Mode Indicator: ");
 Serial.println(dgps.Mode());     //Azimuth of the destination coordinates from the current location in degrees. Correct upto 2 decimal points
   switch(*fla){ //SWITCH CASE TO CHECK IF THE USER WANTS CHECKSUM OR NOT
    case 'Y':
    case 'y':
      Serial.print("CheckSum: ");
      Serial.println(dgps.Checks());
      break;
    case 'N':
    case 'n':
      Serial.print("");
      break;
    default: Serial.print(""); }
Serial.println("");
}



april

Looks good
I have a question
This gps has an accuracy of ~2.5 meters according to their web site
I saw a road grader with a device mounted atop a pole attached to the blade.
What device would they be using that gives height accuracy to I suppose half an inch?

Johnny D

Not sure.  Could it be Differential GPS:  http://en.wikipedia.org/wiki/Differential_GPS

It could also be a positioning device off of survey equipment.  Something like a laser based location device for higher accuracy.

Chagrin

I saw a road grader with a device mounted atop a pole attached to the blade.
What device would they be using that gives height accuracy to I suppose half an inch?


They add a laser when they want that accuracy.

http://www.topconpositioning.com/products/machine-control/3d/3d-millimeter-gps

cyberteque

after a "few" beers I had a go at driving the quad, at night, with my android tablet and the navigation app.
without cell tower assistance I kept "bumping" the verge, with, it was "slightly" better.
not something I'd recommend at speed or if you wanted accuracy.

working out levels for contours in the paddocks seemed to be better, the altitude is way more accurate than position, as is speed.

side by side comparison with the tablet and an EM-406 on an Arduino was interesting, after logging kml files, then plotting them in google earth showed some weird effects of the non-military gps units.

kg4wsv

Quote
the altitude is way more accurate than position


Eh?   Altitude is position - the third dimension.

Typical commercial GPS receivers are known to provide poor altitude measurement, especially when the receiver is moving.  The satellites are nearly always low to the horizon, so the errors are a larger percentage of the actual angle being measured.

If you thought you were getting good altitude data, it either wasn't GPS (barometric pressure, etc), the receiver had special firmware, or maybe something was lying to you to make you think the altitude was good.  Or maybe it was the beer.

-j

cyberteque

I was using a topographic map and went to a local trig point, that's government survey data.
But, when I compared barometric altitude, a Freescale MPL115A1, it was pretty close to what the EM-406 read.
To calibrate the MPL115A1, I went over to the Kuitpo AWS, went online, checked the current barometric pressure.
Standing next to the AWS the barometric altitude read the same as the map, as did the EM-406.

I mainly went to that effort because the MPL115A1's temperature reading was and still is, way off.

With my Android tablet, the altitude was spot on, but that uses cell towers to get better data.

Both the Android tablet and EM-406 speed readings are pretty good, I used a straight bit of road and a stopwatch between "mile" posts to check that.


kg4wsv

Quote
Standing next to the AWS the barometric altitude read the same as the map, as did the EM-406.


Standing isn't moving.  A typical GPS does seem to settle down to a decent altitude measurement if you aren't moving, or are moving at a relatively constant speed.

Too bad barometric pressure altitude is weather dependent.  One project in my "when I get time" pile is a rocket tracker that uses an initial GPS measurement to determine MSL and uses that data to adjust baro for a more accurate altitude reading for a rocket tracker.

-j

Go Up