"Garbage" data from GPS receiver
skatj
Posts: 88
I'm testing the initialization part of my program, which waits until the GPS receiver locks onto four satellites, and then drives the servos to go forward. This isn't working though, since, according to my debug terminal, it has 0 satellites until about 15 seconds later, when it acquires anywhere from 20-200 satellites and begins moving forward prematurely (the red LED is still blinking).
This is the code snippet I am working with:
Any ideas? I noticed that, in the GPS demo code too, I got a lot of garbage data. Is this because of smart mode? Should I switch to raw NMEA strings?
(Also, I am testing this indoors by holding it out to the window and waiting for the wheels to turn , it eventually can get a signal but I'm not sure if this will mess up the data somehow)
edit: I've added a 2500 millisecond pause to this loop so the data feed is slower, and it fixed the problem. Can someone explain to me why this would fix the problem? Would switching to raw mode let me get the information faster?
Post Edited (skatj) : 2/10/2008 11:19:22 PM GMT
This is the code snippet I am working with:
Initialize: GOSUB Fpu_Reset 'resets the FPU hardware DO SEROUT Sio, Baud, [noparse][[/noparse]"!GPS", GetSats] SERIN Sio, Baud, 3000, No_Response, [noparse][[/noparse]sats] IF sats >= 4 THEN DEBUG DEC ? sats, CR EXIT ELSEIF sats < 4 THEN DEBUG DEC ? sats, CR ENDIF LOOP 'Once four or more satellites have been acquired, the drive servos are set into motion 'and the program goes into autonomous GPS navigation. 'Sets both servos to foward position ServoPos1 = 1250 SEROUT Sdat, Bauds+$8000,[noparse][[/noparse]"!SC", 5, 1, servoPos1.LOWBYTE, servoPos1.HIGHBYTE, CR] ServoPos2 = 500 SEROUT Sdat, Bauds+$8000,[noparse][[/noparse]"!SC", 13, 1, servoPos2.LOWBYTE, servoPos2.HIGHBYTE, CR]
Any ideas? I noticed that, in the GPS demo code too, I got a lot of garbage data. Is this because of smart mode? Should I switch to raw NMEA strings?
(Also, I am testing this indoors by holding it out to the window and waiting for the wheels to turn , it eventually can get a signal but I'm not sure if this will mess up the data somehow)
edit: I've added a 2500 millisecond pause to this loop so the data feed is slower, and it fixed the problem. Can someone explain to me why this would fix the problem? Would switching to raw mode let me get the information faster?
Post Edited (skatj) : 2/10/2008 11:19:22 PM GMT
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Stephen
The documentation says +-5 meters accuracy, which is fine for my application.
With 5 satellites however, I am getting GPS data that is WAY off the mark.
For example, I am supposed to be getting around 21 degrees, 19.044 minutes N and 157 degrees, 51.186 minutes west according to Google Earth, but my GPS receiver is telling me 21 degrees, 19.495 minutes west, and 157 degrees, 51.1879 degrees north.
That's over a mile off for latitude, but for some reason longitude is working fine. Also, both latitude and longitude grow consistently larger as my program runs. The fractional minutes for latitude is now 603 and growing, while my longitude is now 1935. I haven't moved the receiver an inch.
Any ideas as to why I am getting this data?
I've uploaded my program, if that helps any.
edit: I now have 11 satellites, and the data is still off..
Post Edited (skatj) : 2/11/2008 12:29:59 AM GMT
When I use the GPS demo code, it's correct.
When I use my code, it's way off.
I don't understand why, the only difference is that, in the demo code, the coordinate data is output in degrees, minutes, seconds format, while my data is output in degrees, minutes, fractional minutes.
Either my data is being displayed incorrectly, or Google Earth's degrees/minutes/fractional minutes data is off (which I highly doubt).
Can someone take a look at both programs and see what can be causing this discrepancy?
I'm not sure which u-FPU you're using, but that may not make a difference in what I'm about to suggest. Unless I'm mistaken, the following u-FPU instructions don't seem to do what the comments say they are doing:
(extracted from your program)
'loads the minutes and fractional minutes into the FPU for calculation (degrees omitted)
· SHIFTOUT FpuOut, FpuClk, MSBFIRST, [noparse][[/noparse]IntMinutes, LOADBYTE, minutes, FSET]
· SHIFTOUT FpuOut, FpuClk, MSBFIRST, [noparse][[/noparse]FracMin, LOADWORD, minutesD, FSET]
'convert from degrees/minutes/fractional minutes to decimal degrees
· SHIFTOUT FpuOut, FpuClk, MSBFIRST, [noparse][[/noparse]IntMinutes, LOADWORD, 1000, FMUL] 'multiply minutes by 1,000
· SHIFTOUT FpuOut, FpuClk, MSBFIRST, [noparse][[/noparse]IntMinutes, LOADBYTE, 6, FDIV]··· 'divide it by 6
In the first comment you say "... (degrees omitted)", yet in the next comment you say "convert from degrees/minutes/fractional minutes to decimal degrees". Are degrees omitted, or not?
Certainly incorrect comments aren't going to cause a problem, but you've got me pretty well confused as to what is actually going on there in those calculations.
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Genius is one percent inspiration and ninety-nine percent perspiration."
Thomas Alva Edison
My problem comes before that however, since the raw data being debugged is way off according to what it should be in Google Earth.
I wrote a program combining code from the GPS demo (which worked correctly for me) and my own program which displayed raw data (which was not working), and the results I got were mind-boggling.
The demo code ran as expected (though it was quite a bit more than 5 meters off, about 4-5 houses over).
The raw data, when inputted into Google Earth was still, VERY off.
After spending an hour analyzing this data in Google Earth and using an online GPS coordinate converter, I found out a few things.
1. Longitude is fine (raw data is correct)
2. Latitude, when I input the coordinate data in Google Earth in degrees/minutes/fractional minutes, is off.
3. Latitude, when I convert to decimal degrees, is off.
4. Latitude, in the example below, when I convert to degrees/minutes/seconds, the Stamp actually displays this data incorrectly. It displays the seconds as 2.7, when using an online converter (http://www.cosports.com/tools/gps_coords.htm), should be 27 seconds.
5. However, when the conversion is incorrect, my position on Google Earth is where it is supposed to be. With the online converter, it is wrong.
6. The decimal degrees conversion given by the debug terminal is also correct, but when using the raw data (degrees/minutes/fractional minutes) in the online converter, the data is off (in the same position as the other "off" data).
7. I trust this converter over my code, which means that the raw data is wrong (it is wrong in degrees/minutes/fractional minutes anyway).
Conclusions
1. The raw data of the latitude is wrong.
2. The conversion done in the program, is done incorrectly, but somehow outputs the correct position.
I don't understand how this can happen
Any ideas?
Here's an example of my debug terminal screen, I've attached the test program.
The data is organized like this:
Raw data display (latitude)
Raw data display (longitude)
Raw data display (latitude)
Converted data display from demo code (latitude)
Raw data display (longitude)
Converted data display from demo code (longitude)
Thanks,
skatj
In this case, the code is correct but the error crept in when trying
to use an online coordinate converter.
My guess is that when he entered the latitude he used
21 deg 19.453 minutes
where he should have entered
21 deg 19.0453 minutes
Doing both the Longitude and Latitude calculations by hand:
Longitude raw data for minutesD.HIGHBYTE = 7
This is really 7x256 = 1792
Longitude raw data for minutesD.LOWBYTE = 172
Adding these we get 1792 + 172 = 1964
minutes.D has a maximum value of 9999 <<<
or 0.9999 in 'real' numbers
This is supposed to be the decimal part of the minutes
so it has to be less than 1:
1964/10000 = 0.1964 for the decimal part.of the minutes
Raw data for minutes = 51
Therefore the actual minutes = 51.1964 minutes.
Since there are 60 seconds/minute we multiply 60 x 0.1964
and get 11.78 seconds for the Longitude.
Therefore the Longitude is 157 deg 51 min 11.78 sec
So far, so good.
Doing the same for the Raw Latitude GPS numbers, will expose
the problem.
Latitude raw data for minutesD.HIGHBYTE = 1
This is really 1x256 = 256
Latitude raw data for minutesD.LOWBYTE = 197
Adding these we get 256 + 197 = 453
To convert this into the 'real' decimal part of the minutes,
we have to divide by 10,000 just as we did for the Longitude.
453/10000 = 0.0453
Here is where the factor of 10 error came from.
I suspect that 0.453.was used, instead of 0.0453
Raw data for minutes = 19
Therefore the actual minutes = 19.0453 minutes
Converting 0.0453 minutes to seconds
0.0453 x 60 = 2.72 seconds.
and the Latitude is 21 deg 19 min 2.72 sec
The whole problem is that the decimal part of the minutes
is a four digit number, even if the leading digit is ZERO.
phil
How would I account for this when writing the actual program?
If you want to work strictly with integer numbers (all that a Stamp really
understands) you have to represent all values in terms of minuteD units
To add the minuteD number to minutes, multiply minutes by 10,000 then
add minuteD.
Let New_minute be:
New_minute = minute * 10,000 + minuteD
New_Degrees = 60 * New_Minute
How you program the FPU depends a lot on how many digits it can
handle. The maximum Latitude degree value is 180.
Convert 180 degrees into equivalent minuteD counts as follows
1 New_Degree = 60 minutes * 10,000 = 600,000 minuteD counts
180 * 600,000 = 108,000,000 minuteD counts for maximum latitude.
Four bytes can hold values up to 4,294,967,295. Therefore, each
newly calculated Latitude and Longitude will need 4 bytes, or 8 bytes
total if stored as a Stamp variable. The destination Longitude and
Latitude will also need 8 bytes of memory.
High precision math can chew up memory very quickly.
Worst case calculations will involve 9 digit numbers. Can the FPU
give this precision without overflow?
I've only shown one way to do this. Others may have different
solutions which don't require such high precision. It all depends
on how accurately you want to calculate the locations you are trying
to navigate to.
If you really do need this precision and the FPU can't handle 9 digit
calculations, you can use multi precision arithmetic. Tracy Allen
has an excellent discussion of this technique on his website at:
http://www.emesys.com/BS2math6.htm#top
phil
Post Edited (phil kenny) : 2/13/2008 2:17:24 AM GMT