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?

Views: 122

Reply to This

Replies to This Discussion

I got 308.35 meters running the code above. Sounds good!
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;
}
}
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.
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.
Fantastic. Wish there were a few more people your age willing to stay on a project even when it requires thought.

One thing to keep firmly in mind on your "direction" part is to remember if you are looking to find the direction TO your target, or the direction FROM the target.

If your direction answers are bouncy and you want to average a few calculations but get stuck on how to average "almost" north bearings like 358 degrees and 2 degrees (and you know the answer is not 180 degrees), let me know and I'll show you a trick.
here is what i am reading on bearing http://mathforum.org/library/drmath/view/55417.html. First i would want to get my bearing by driving straight a bit and then get the bearing from my current GPS point to my ending point. Then how should i go about getting to the right bearing? the robot would need to turn and drive forward again, but doesnt driving forward change the bearing? Seems like it would be a trial and error code where the robot turns and keeps checking its bearing till it gets it right. But in the process of doing this, it will mess up its previous bearing reading because it will have moved since, right?
OK, bearing vs heading. If you want to go from lat1, lon1 to lat2, lon2 you can calculated the bearing to point 2. But unless you have a compass on board, you don't know your heading. So you need to start moving, then the GPS will tell you your heading (no need to calc it yourself). If the heading is not the same as the bearing, start turning in the shortest direction. Rinse, lather, repeat.

Since you are using a ground vehicle not an aircraft, drift won't be much of an issue. First, learn the vehicle. You can drive the vehicle at different steering settings and find out how much turn you get. That is, 1 second forward at "right 1" turns me right 3 degrees; 1 second forward at "right 2" turns me 7 degrees; 1 second forward at "right 3" turns me 10 degrees.

You can then get a rough idea of what steering input to use whether you want to turn most quickly or more gently to a close bearing/heading match. Then just move forward making small adjustments. Note that the heading won't be very accurate until you've moved on a constant heading for a several seconds.
ok i suppose this is the heading in the GPS code

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

I am still working on the heading. I have tried a few equations and code examples but yet to find one that seems to work.
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.
I've been wondering how you were doing. Worried that maybe you'd given up. Good to hear there is some progress.
yeah i put the project away for a while, but pulled it back out this weekend after watching sparkfun's competition. Now i am trying to decide whether to hack a rc truck or make my own. I am thinking of hacking a rc truck but do not know what to expect inside. I would think that the steering is done with a servo but online i see that it is done with a normal motor. Kinda confusing to me how you could steer with a motor not using differential steering. But i will try and find a vehicle.
I Have not been able to test my heading today outside because it rained all day. But walking around in my house i couldnt really get that good of a heading. Do you know how long it takes to get a heading and how much it could bounce around?

RSS

Social Networking

Contests

Season Two of the Trust Time Trial (T3) Contest has now begun. The fourth round is an accuracy round for multicopters, which requires contestants to fly a cube. The deadline is April 14th.

A list of all T3 contests is here

Groups

Advertisement

© 2013   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service