# Telecom Design SDK decode GPS frame

The Telecom Design SDK contains a function to encode GPS coordinates : TD_SENSOR_EncodePositionXY this function from the SDK allow to choose the size of the GPS encoded data and to reduce it. This post explains how this function works and gives a php implementation to decode it.

The encoding function can be call from the GPS loop with the following parameters :

• the fix structure
• the destination buffer
• the size of the encoded data
• a default value to return

A full precision encoding will need 48 bits : 2 will be used for sign of latitude and longitude when the 46 others, split in 23 bits for each are containing longitude and latitude. According to the documentation, this allow a precision of 60 cm in latitude and 119 cm in longitude.

If you want to save 1 byte, the precision will change for 9,52/19,6 meters ; 32 bits encoding will reduce the precision to 152/305 meters.

After asking a question to TD forum, I got the precise answer from the team on the way to decode the positions encoded that way : you can find it here.

So basically to decode a 48bits encoded frame that way :

444444443333333333222222222211111111110000000000
765432109876543210987654321098765432109876543210
X                                                - lng Sign 1=-
X                                               - lat Sign 1=-
XXXXXXXXXXXXXXXXXXXXXXX                        - 23b Latitude
XXXXXXXXXXXXXXXXXXXXXXX - 23b Longitude

Then we have the following  algorithm for 48 bits

if ( encodedLat != 8333333 )
latitude = ( encodedLat * 108 + 53 ) / 10_000_000;
else
latitude = 90.0
latitude = (latSign > 0)?-latitude:latitude;

if ( encodedLng != 8372093 )
longitude = ( encodedLng * 215 + 107 ) / 10_000_000;
else
longitude = 180.0
longitude = (lngSign > 0)?-longitude:longitude;

The way to do this in PHP is assuming \$_gps contains the 48 bits of the encoded location :

\$_lngS = ( (\$_gps & 0x800000000000 ) > 0 ) ? -1 : 1;
\$_latS = ( (\$_gps & 0x400000000000 ) > 0 ) ? -1 : 1;
\$_encLat = (\$_gps & 0x3FFFFF800000 ) >> 23;
\$_encLng = (\$_gps & 0x7FFFFF );

if ( \$_encLat != 8333333 ) {
\$_decLat = \$_latS * ( \$_encLat * 108 + 53) / 10000000;
} else {
\$_decLat = \$_latS * 90.0;
}
if ( \$_encLng != 8372093 ) {
\$_decLng = \$_lngS * ( \$_encLng * 215 + 107) / 10000000;
} else {
\$_decLng = \$_lngS * 180.0;
}

For 40 bits encoding, the algorithm would be :

if ( encodedLat != 524170 )
latitude = ( encodedLat * 1717 + 858 ) / 10_000_000;
else
latitude = 90.0
latitude = (latSign > 0)?-latitude:latitude;

if ( encodedLng != 524170 )
longitude = ( encodedLng * 3434 + 1716 ) / 10_000_000;
else
longitude = 180.0
longitude = (lngSign > 0)?-longitude:longitude;

and the php implementation :

\$_lngS = ( (\$_gps & 0x8000000000 ) > 0 ) ? -1 : 1;
\$_latS = ( (\$_gps & 0x4000000000 ) > 0 ) ? -1 : 1;
\$_encLat = (\$_gps & 0x3FFFF80000 ) >> 23;
\$_encLng = (\$_gps & 0x7FFFF );

if ( \$_encLat != 524170 ) {
\$_decLat = \$_latS * ( \$_encLat * 1717 + 858) / 10000000;
} else {
\$_decLat = \$_latS * 90.0;
}
if ( \$_encLng != 524170 ) {
\$_decLng = \$_lngS * ( \$_encLng * 3434 + 1716) / 10000000;
} else {
\$_decLng = \$_lngS * 180.0;
}

Hope it helps !

This entry was posted in Sigfox and tagged , , . Bookmark the permalink.

### One Response to Telecom Design SDK decode GPS frame

This site uses Akismet to reduce spam. Learn how your comment data is processed.