Reputation: 163
I have some gps sensor data which uses signed 24 bits to represent latitude and longitude each. I want to convert this data in more readable degrees, minutes and seconds format.
I have searched a lot but no algorithm is working for me. I would like to do this in python.
The spec sheet tells the following
Byte [8] > Value: MSB of the UP501 received Latitude
Byte [9] > Value: CSB of the UP501 received Latitude
Byte [10] > Value: LSB of the UP501 received Latitude
Byte 8, 9 and 10 represent the latitude. The north-south latitude is encoded using a signed 24 bit word where -2^23 corresponds to 90° south (the South Pole) and 2^23- 1 corresponds to 90° north (the North Pole). The equator corresponds to 0.
Byte [11] > Value: MSB of the UP501 received Longitude
Byte [12] > Value: CSB of the UP501 received Longitude
Byte [13] > Value: LSB of the UP501 received Longitude
Byte 11, 12 and 13 represent the longitude. The east-west longitude is encoded using a signed 24 bit word where -2^23 corresponds to 180° west and 2^23 -1 corresponds to 180° east. The Greenwich meridian corresponds to 0.
Example data (from 8-13 bytes)
1E 55 9C 1C 69 5A
should give 21°19′44″N, 39°57′13″E
EDIT: After the first comment, here is the problem Every where I have seen is the 32 bit representation of the coordinates. Those methods are not working for me as I do not get what I expect. Not even close.
Is there a better way for this conversion?
Upvotes: 2
Views: 2730
Reputation: 532053
It's a little tricky, since there are several scales involved. First, divide your signed value by 2**23 - 1 to see what "fraction" of the hemisphere it represents.
>>> 0x1e559c / (2.**23 - 1)
0.2369876190409206
So, what is 23.69...% of 90 degrees?
>>> 0x1e559c / (2.**23 - 1) * 90
21.328885713682855
21.something degrees; we're on the right track. Instead, note that there are 90*3600 seconds of latitude between the equator and a pole. Let's see what fraction of that we have:
>>> 0x1e559c / (2.**23 - 1) * 90 * 3600
76783.98856925828
So the given value is ~76784 seconds north of the equator; converting that to degrees/minutes/seconds:
# seconds to minutes and seconds
>>> divmod(76784, 60)
(1279, 44)
# minutes to degrees and minutes
>>> divmod(1279, 60)
(21, 19)
And there's your 21 degrees, 19 minutes, 44 seconds. Now, we know to divide by 2**23 - 1
because we knew the value was less than 0x7fffff and so in the northern hemisphere. (If the value were in the southern hemisphere, we would need to divide by 2**23
, because the scaling is asymmetrical.)
For longitude, you would multiply by 180*3600
seconds per hemisphere instead of 90*3600
, then proceed in the same fashion.
One caveat; I didn't include an example for the southern/western hemisphere, because I wasn't sure if 90S was 0x800000 (two's complement) or 0xffffff (signed magnitude).
Upvotes: 3