GPS library-ish code

They have GPS libraries for Arduino which are fun to play with but not too easy for some one like me to try and make a UGV with. I think it would be a cool idea for diy drones to have code that would just give like distance to your next GPS point and heading needed. You know, a code without all the sensors and outputs but with just the part in figuring out what is needed to get to the next GPS point. I do not know if i am the only one who would like this but there might be others. Or is there is  simple mod for some of the current code that could do this?

You need to be a member of diydrones to add comments!

Join diydrones

Email me when people reply –

Replies

  • to answer your original post; I know of one library that does exactly what you are asking, the NMEA library, by Maarten Lamers, can be found here. I know it says it's for wiring, and might not work on arduino, but i had it running smoothly on arduino IDE 0015, along with a 328 duemilanove. It doesn't work right now under IDE 0018, but it would be nice....
  • Hey Patrick,

    Do you live near the Florida Pan-handle? I ask because that's where I live, and I am just finishing up my own UGV, SAGAR.

    IMG_2546-150x150.jpg


    More here: http://www.billporter.info/?cat=11

    To answer you last question, yes, you need a magnetic compass. You will also need at least a PD control system
    Feel free to send me a message and I'll send you an email if you want some further help on your project.
  • Here is some info on the AGV i am making and a test video of it going to its first GPS waypoint. http://letsmakerobots.com/node/18922
  • Here is some info on the AGV i am making and a test video of it going to its first GPS waypoint. http://letsmakerobots.com/node/18922
  • I noticed online that almost all the vehicles in the AUV contest had a compass module, is this really needed? I guess it is hard to turn from one waypoint to another with out it?
  • Tried the code today outside by walking. It was able to guide me to the waypoint by serial printing to turn left or right and how far i was to the point. Still not accurate or reliable enough to guide a robot. The distance measures started to get messed up when i got close to the waypoint and stayed still.
  • Its been a while. I switched to the tinygps library because it tells me my heading. I also have a bearing formula working to tell me the bearing from my current location to another gps point. Distance also works. I then made some code to tell me if it is quicker to turn left or right to get on the bearing i need to be on. So i feel almost ready to make a UGV. Since almost all the code is done, the next thing would be to use multiple waypoints and switching in between them. This does not seem to hard once i get a vehicle built. Lastly i would need to figure out a smooth way of steering the vehicle to the waypoint because right now i picture a very jittery and a zigzag movement happening much like a rough line following code would do.
  • Got it all working now. :D. I have it showing the distance from my current location using the GPS to my mailbox. Now time for heading.
  • Ok so i know the problem now. The GPS points from the GPS is in minutes. Well at least the decimal part is. It says my latitude is at 28.194378 but that is not in degrees format. So that is the problem but i do now know how to change that to degrees.
  • so it is normal for it to print to the first 2 decimal places of a float so the rest is there just not being printed. http://www.arduino.cc/en/Serial/Print. But this does not explain why using the gps points from the gps and my code, i get over 17,000m as a distance for a point only 300m away.

    here is the code all together.

    // A simple sketch to read GPS data and parse the $GPRMC string
    // see http://www.ladyada.net/make/gpsshield for more info

    #include

    NewSoftSerial mySerial = NewSoftSerial(0, 1);
    #define powerpin 4

    #define GPSRATE 4800
    //#define GPSRATE 38400


    // GPS parser for 406a
    #define BUFFSIZ 90 // plenty big
    char buffer[BUFFSIZ];
    char *parseptr;
    char buffidx;
    uint8_t hour, minute, second, year, month, date;
    uint32_t latitude, longitude;
    uint8_t groundspeed, trackangle;
    char latdir, longdir;
    char status;

    void setup()
    {
    if (powerpin) {
    pinMode(powerpin, OUTPUT);
    }
    pinMode(13, OUTPUT);
    Serial.begin(GPSRATE);
    mySerial.begin(GPSRATE);

    // prints title with ending line break
    Serial.println("GPS parser");

    digitalWrite(powerpin, LOW); // pull low to turn on!
    }


    void loop()
    {
    uint32_t tmp;

    Serial.print("\n\rread: ");
    readline();

    // check if $GPRMC (global positioning fixed data)
    if (strncmp(buffer, "$GPRMC",6) == 0) {

    // hhmmss time data
    parseptr = buffer+7;
    tmp = parsedecimal(parseptr);
    hour = tmp / 10000;
    minute = (tmp / 100) % 100;
    second = tmp % 100;

    parseptr = strchr(parseptr, ',') + 1;
    status = parseptr[0];
    parseptr += 2;

    // grab latitude & long data
    // latitude
    latitude = parsedecimal(parseptr);

    if (latitude != 0) {
    latitude *= 10000;

    parseptr = strchr(parseptr, '.')+1;

    latitude += parsedecimal(parseptr);

    }
    parseptr = strchr(parseptr, ',') + 1;
    // read latitude N/S data
    if (parseptr[0] != ',') {
    latdir = parseptr[0];
    }

    //Serial.println(latdir);

    // longitude
    parseptr = strchr(parseptr, ',')+1;
    longitude = parsedecimal(parseptr);
    if (longitude != 0) {
    longitude *= 10000;
    parseptr = strchr(parseptr, '.')+1;
    longitude += parsedecimal(parseptr);
    }
    parseptr = strchr(parseptr, ',')+1;
    // read longitude E/W data
    if (parseptr[0] != ',') {
    longdir = parseptr[0];
    }


    // groundspeed
    parseptr = strchr(parseptr, ',')+1;
    groundspeed = parsedecimal(parseptr);

    // track angle
    parseptr = strchr(parseptr, ',')+1;
    trackangle = parsedecimal(parseptr);


    // date
    parseptr = strchr(parseptr, ',')+1;
    tmp = parsedecimal(parseptr);
    date = tmp / 10000;
    month = (tmp / 100) % 100;
    year = tmp % 100;

    Serial.print("\nTime: ");
    Serial.print(hour, DEC); Serial.print(':');
    Serial.print(minute, DEC); Serial.print(':');
    Serial.println(second, DEC);
    Serial.print("Date: ");
    Serial.print(month, DEC); Serial.print('/');
    Serial.print(date, DEC); Serial.print('/');
    Serial.println(year, DEC);

    Serial.print("Lat: ");
    if (latdir == 'N')
    Serial.print('+');
    else if (latdir == 'S')
    Serial.print('-');

    Serial.print(latitude/10000000, DEC); Serial.print('\°', BYTE); Serial.print(' ');
    Serial.print((latitude/10000)%100, DEC); Serial.print('\''); Serial.print(' ');
    Serial.print((latitude%10000)*6/1000, DEC); Serial.print('.');
    Serial.print(((latitude%10000)*6/10)%100, DEC); Serial.println('"');

    float flat1;
    Serial.println(flat1);

    Serial.print("Long: ");
    if (longdir == 'E')
    Serial.print('+');
    else if (longdir == 'W')
    Serial.print('-');
    Serial.print(longitude/10000000, DEC); Serial.print('\°', BYTE); Serial.print(' ');
    Serial.print((longitude/10000)%100, DEC); Serial.print('\''); Serial.print(' ');
    Serial.print((longitude%10000)*6/1000, DEC); Serial.print('.');
    Serial.print(((longitude%10000)*6/10)%100, DEC); Serial.println('"');

    float flon1;


    flat1=latitude*10E-7; //move the decimal
    float flat2=28.323805;
    flon1=longitude*10E-7; // move the decimal
    flon1=flon1*-1; //make longitude negative for my area
    Serial.println(flon1);
    float flon2=-82.267417;
    float dist_calc=0;
    float dist_calc2=0;
    float diflat=0;
    float diflon=0;

    //I've to spplit all the calculation in several steps. If i try to do it in a si
    //ngle line the arduino will explode.
    diflat=radians(flat2-flat1);
    flat1=radians(flat1);
    flat2=radians(flat2);
    diflon=radians((flon2)-(flon1));

    dist_calc = (sin(diflat/2.0)*sin(diflat/2.0));
    dist_calc2= cos(flat1);
    dist_calc2*=cos(flat2);
    dist_calc2*=sin(diflon/2.0);
    dist_calc2*=sin(diflon/2.0);
    dist_calc +=dist_calc2;

    dist_calc=(2*atan2(sqrt(dist_calc),sqrt(1.0-dist_calc)));

    dist_calc*=6371000.0; //Converting to meters

    Serial.println(dist_calc); // this gets some crazy big number for a point close to me
    delay(500);




    }
    //Serial.println(buffer);
    }

    uint32_t parsedecimal(char *str) {
    uint32_t d = 0;

    while (str[0] != 0) {
    if ((str[0] > '9') || (str[0] < '0'))
    return d;
    d *= 10;
    d += str[0] - '0';
    str++;
    }
    return d;
    }

    void readline(void) {
    char c;

    buffidx = 0; // start at begninning
    while (1) {
    c=mySerial.read();
    if (c == -1)
    continue;
    Serial.print(c);
    if (c == '\n')
    continue;
    if ((buffidx == BUFFSIZ-1) || (c == '\r')) {
    buffer[buffidx] = 0;
    return;
    }
    buffer[buffidx++]= c;
    }
    }
This reply was deleted.

Activity