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!
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....
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.
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.
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.
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));
Replies
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.
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 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;
}
}