If you are lucky, your receiver outputs navigation message data, such as almanac- and ephemeris parameters, in engineering units. Other receivers may output the navigation message in binary form as received, or in a hexadecimal presentation format (examples are given below). This pages gives a short introduction and some guidelines for the conversion to engineering units.
For clarity, please download the GPS Signal Specification (about 50 pages). This document has been used as guideline for producing this page.
Navigation message structure.
The navigation message is composed of five 'subframes'. Each subframe contains
10 words of 30 bits (see figure below).
Word 1 of each subframe is the 'telemetry word' (T), word 2 the 'handover
word' (H). Within the framework of this page they contain no relevant
information. Word 3 to 10 contain the relevant information.
Subframe 1 contains the GPS week number, SV acc. and health, and the clock
correction parameters (C).
Subframe 2 and 3 contain the ephemeris parameters (E).
Your receiver should add for which SV number the subframes 1, 2 and 3 apply.
Subframe 4 and 5 contain 25 subcommutated pages with info on all SV's, such
as almanac parameters, health, etc. Important for us is subframe 4 page 18:
here (a.o.) the ionosphere correction parameters (I) are given, and the
parameters relating GPS time to UTC (U).
| word subfr |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 1 | T | H | C | C | C | C | ||||
| 2 | T | H | E | E | E | E | E | E | E | E |
| 3 | T | H | E | E | E | E | E | E | E | E |
| 4 p 18 | T | H | I | I | I | U | U | U | ||
| 5 | T | H |
The blank words in the table contain no relevant information for this page.
Conversion.
The following steps have to be made to convert from the original navigation message to parameters in engineering units:
A. Strip subframe's.
Each 30 bit word contains 24 databits and 6 parity bits. I assume, that the
receiver s/w has carried out consistency checks on the data, thus I strip
all telemetry words, handover words and parity bits from the data (if not
already stripped by the receiver). What remains is for each subframe 8 words
with 24 bits, or 8 words with 3 bytes (1 byte = 8 bits), or 24 bytes per
stripped subframe.
B. Convert hex- to byte value (if your receiver outputs byte values, this step can be skipped).
C. Join multiple byte parameters into one unsigned integer (this integer must allow up to 4 bytes !) by shift-left-byte (multiply by 256) and add-byte operations.
D. Convert to 'signed'.
Some parameters are presented in the navigation message as unsigned integers,
others as signed 2's complement integers. The latter require an additional
conversion operation: subtract 2^n from the 'joined' value if the joined
value > 2^(n-1) - 1, with n the number of bits in the joined value. For
example if the joined value of an 8-bit parameter > 127, then subtract
256 from the joined value.
E. Scale to engineering unit.
Multiply the integer value by the LSB value to obtain engineering units.
In the following table all relevant parameters are listed with their place in the navigation message and the conversion operations to engineering units.
| Abbr. | SF | from word -byte |
to word -byte |
join | subtract | multiply by |
eff range |
eng. unit |
remark |
| Tgd | 1 | 7-3 | 2^8 | 2^-31 | sec | ||||
| IODC | 1 | 8-1 | unity | (1) | |||||
| Toc | 1 | 8-2 | 8-3 | b1*2^8+b2 | 2^4 | 604784 | sec | ||
| af2 | 1 | 9-1 | 2^8 | 2^-55 | sec/sec^2 | ||||
| af1 | 1 | 9-2 | 9-3 | b1*2^8+b2 | 2^16 | 2^-43 | sec/sec | ||
| af0 | 1 | 10-1 | 10-3 | (b1*2^16+ b2*2^8+b3) div(2^2) |
2^22 | 2^-31 | sec | (2) | |
| IODE2 | 2 | 3-1 | unity | ||||||
| Crs | 2 | 3-2 | 3-3 | b1*2^8+b2 | 2^16 | 2^-5 | m | ||
| dn | 2 | 4-1 | 4-2 | b1*2^8+b2 | 2^16 | 2^-43 | sc/sec | (3) | |
| M0 | 2 | 4-3 | 5-3 | b1*2^24+b2*2^16 +b3*2^8+b4 |
2^32 | 2^-31 | sc | (3) | |
| Cuc | 2 | 6-1 | 6-2 | b1*2^8+b2 | 2^16 | 2^-29 | rad | ||
| ec | 2 | 6-3 | 7-3 | b1*2^24+b2*2^16 +b3*2^8+b4 |
2^-33 | 0.03 | unity | ||
| Cus | 2 | 8-1 | 8-2 | b1*2^8+b2 | 2^16 | 2^-29 | rad | ||
| rootA | 2 | 8-3 | 9-3 | b1*2^24+b2*2^16 +b3*2^8+b4 |
2^-19 | m^0.5 | |||
| Toe | 2 | 10-1 | 10-2 | b1*2^8+b2 | 2^4 | 604784 | sec | ||
| Cic | 3 | 3-1 | 3-2 | b1*2^8+b2 | 2^16 | 2^-29 | rad | ||
| W0 | 3 | 3-3 | 4-3 | b1*2^24+b2*2^16 +b3*2^8+b4 |
2^32 | 2^-31 | sc | (3) | |
| Cis | 3 | 5-1 | 5-2 | b1*2^8+b2 | 2^16 | 2^-29 | rad | ||
| i0 | 3 | 5-3 | 6-3 | b1*2^24+b2*2^16 +b3*2^8+b4 |
2^32 | 2^-31 | sc | (3) | |
| Crc | 3 | 7-1 | 7-2 | b1*2^8+b2 | 2^16 | 2^-5 | m | ||
| w | 3 | 7-3 | 8-3 | b1*2^24+b2*2^16 +b3*2^8+b4 |
2^32 | 2^-31 | sc | (3) | |
| Wdot | 3 | 9-1 | 9-3 | b1*2^16+b2*2^8 +b3 |
2^24 | 2^-43 | sc/sec | (3) | |
| IODE3 | 3 | 10-1 | unity | ||||||
| idot | 3 | 10-2 | 10-3 | (b1*2^8+b2) div(2^2) |
2^14 | 2^-43 | sc/sec | (2) | |
| pageID | 4/18 | 3-1 | b1 mod 2^6 | unity | (4), (5) | ||||
| a0 | 4/18 | 3-2 | 2^8 | 2^-30 | sec | ||||
| a1 | 4/18 | 3-3 | 2^8 | 2^-27 | sec/sc | ||||
| a2 | 4/18 | 4-1 | 2^8 | 2^-24 | sec/sc^2 | ||||
| a3 | 4/18 | 4-2 | 2^8 | 2^-24 | sec/sc^3 | ||||
| b0 | 4/18 | 4-3 | 2^8 | 2^11 | sec | ||||
| b1 | 4/18 | 5-1 | 2^8 | 2^14 | sec/sc | ||||
| b2 | 4/18 | 5-2 | 2^8 | 2^16 | sec/sc^2 | ||||
| b3 | 4/18 | 5-3 | 2^8 | 2^16 | sec/sc^3 | ||||
| leap | 4/18 | 9-1 | sec | (6) | |||||
| Abbr. | SF | from | to | join | subtract | multiply | range | eng unit | remark |
Use of the table:
Remarks:
Example subframe 1 - clock parameters.
In week 926 at GPS time 586920 I downloaded the following subframe 1 string
from my receiver for SV prn 30:
8B 0E 78 BF 11 26 E7 97 01 07 DF D4 15 9D 8F A0 E8 09 45 46 07 0E 90 24 00
FF EC FF 85 20.
Since this string contains 30 hex values, the Telemetry word and Handover
word are still in, and can be stripped, resulting in the 24 hex values:
E7 97 01 - 07 DF D4 - 15 9D 8F - A0 E8 09 - 45 46 07 - 0E 90 24 - 00 FF EC
- FF 85 20.
For clarity I added a dash between every three hex values, thus indicating
the subframe words 3 to 10.
Since the info I'm interested in, is in words 7, 8, 9 and 10 only, I'll forget
about word 3, 4, 5 and 6.
In the table below I list the hex values of word 7 - 10 in the first column,
give the decimal value in the second column and proceed in the following
columns according the algorithm of the table above.
| word byte |
hex | dec | abbrev | join | subtr | mul | unit |
| 7-1 7-2 |
45 46 |
69 70 |
|||||
| 7-3 | 07 | 7 | Tgd | 7 | 7 | 3.259629E-9 | sec |
| 8-1 | 0E | 14 | IODC | 14 | 14 | 14 | unity |
| 8-2 8-3 |
90 24 |
144 36 |
Toc | 36900 | 36900 | 590400 | sec |
| 9-1 | 00 | 0 | af2 | 0 | 0 | 0 | sec/sec^2 |
| 9-2 9-3 |
FF EC |
255 236 |
af1 | 65516 | -20 | -2.273736E-12 | sec/sec |
| 10-1 10-2 10-3 |
FF 85 20 |
255 133 32 |
af0 | 4186440 | -7864 | -3.66196E-6 | sec |
The last parameter contains nearly all operations - let's go step-by-step through the calculation. The joined value is: (255*256*256 + 133*256 + 32) div 4 = 16745760 div 4 = 4186440. This value is greater than 2097151 (2^21 - 1), thus 4194304 (2^22) has to be subtracted from it : 4186440 - 4194304 = -7864. Finally, this value has to be multiplied by the LSB value for this parameter, giving the value in engineering units : -7864 * 2^-31 = -7864 * 4.656612E-10 = -3.66196E-6 [sec].
Example subframe 2, 3 - ephemeris parameters.
My receiver gave me the following subframe 2 and -3 strings:
8B 0E 78 BF 11 AB OE FD 44 38 47 CB 73 82 C3 FD 72 02 8F 2F 39 0C F5 A1 0D
77 9B 90 24 7C, and:
8B 0E 78 BF 0F AE FF E1 B5 77 C3 0A 00 2F 26 BD 50 3D 1F A2 42 03 51 82 FF
A3 1A 0E E8 10.
Again I stripped word 1 and 2 from both subframes, and put the remainder in the following table, which by now should be evident.
| word byte |
hex | dec | abbr | join | subtr | mul | unit |
| 3-1 | 0E | 14 | IODE2 | 14 | 14 | 14 | unity |
| 3-2 3-3 |
FD 44 |
253 68 |
Crs | 64836 | -700 | -2.1875E+1 | m |
| 4-1 4-2 |
38 47 |
56 71 |
dn | 14407 | 14407 | 1.637886E-9 | sc/sec |
| 4-3 5-1 5-2 5-3 |
CB 73 82 C3 |
203 115 130 195 |
M0 | 3413344963 | -881622333 | -4.105373E-1 | sc |
| 6-1 6-2 |
FD 72 |
253 114 |
Cuc | 64882 | -654 | -1.218169E-6 | rad |
| 6-3 7-1 7-2 7-3 |
02 8F 2F 39 |
2 143 47 57 |
ec | 42938169 | 42938169 | 4.99866E-3 | unity |
| 8-1 8-2 |
0C F5 |
12 245 |
Cus | 3317 | 3317 | 6.178394E-6 | rad |
| 8-3 9-1 9-2 9-3 |
A1 0D 77 9B |
161 13 119 155 |
rootA | 2702014363 | 2702014363 | 5.153683E+3 | m^0.5 |
| 10-1 10-2 |
90 24 |
144 36 |
Toe | 36900 | 36900 | 590400 | sec |
| 3-1 3-2 |
FF E1 |
255 225 |
Cic | 65505 | -31 | -5.7742E-8 | rad |
| 3-3 4-1 4-2 4-3 |
B5 77 C3 0A |
181 119 195 10 |
W0 | 3044524810 | -1250442486 | -5.822826E-1 | sc |
| 5-1 5-2 |
00 2F |
0 47 |
Cis | 47 | 47 | 8.754432E-8 | rad |
| 5-3 6-1 6-2 6-3 |
26 BD 50 3D |
38 189 80 61 |
i0 | 649941053 | 649941053 | 3.026523E-1 | sc |
| 7-1 7-2 |
1F A2 |
31 162 |
Crc | 8098 | 8098 | 2.530625E+2 | m |
| 7-3 8-1 8-2 8-3 |
42 03 51 82 |
66 3 81 130 |
w | 1107513730 | 1107513730 | 5.157262E-1 | sc |
| 9-1 9-2 9-3 |
FF A3 1A |
255 163 26 |
Wdot | 16753434 | -23782 | -2.7037E-9 | sc/sec |
| 10-1 | 0E | 14 | IODE3 | 14 | 14 | 14 | unity |
| 10-2 10-3 |
E8 10 |
232 16 |
idot | 14852 | -1532 | -1.741682E-10 | sc/sec |
Example subframe 4 page 18 - iono and UTC parameters.
In week 926 at GPS time 588480 I downloaded the following subframe 4 page
18 string from my receiver:
8B 0E 78 BF 94 B1 78 0C 00 FF 00 2C 00 FD 00 00 00 08 00 00 00 00 24 9F 0C
90 02 0C AA AA.
I strip the first 2 words, or 6 hex values from these 30 hex values and enter
the remaining 24 hex values in the table below, which shows the subsequent
steps to engineering units.
| word byte |
hex val |
dec val |
Abbr | join | subtr | mult | unit |
| 3-1 | 78 | 120 | pageID | 56 | 56 | 56 | unity |
| 3-2 | 0C | 12 | a0 | 12 | 12 | 1.117587E-8 | sec |
| 3-3 | 00 | 0 | a1 | 0 | 0 | 0 | sec/sc |
| 4-1 | FF | 255 | a2 | 255 | -1 | -5.960464E-8 | sec/sc^2 |
| 4-2 | 00 | 0 | a3 | 0 | 0 | 0 | sec/sc^3 |
| 4-3 | 2C | 44 | b0 | 44 | 44 | 9.0112E+4 | sec |
| 5-1 | 00 | 0 | b1 | 0 | 0 | 0 | sec/sc |
| 5-2 | FD | 253 | b2 | 253 | -3 | -1.96608E+5 | sec/sc^2 |
| 5-3 | 00 | 0 | b3 | 0 | 0 | 0 | sec/sc^3 |
| 6-1 6-2 6-3 7-1 7-2 7-3 8-1 8-2 8-3 |
00 00 08 00 00 00 00 24 95 |
||||||
| 9-1 | 0C | 12 | leap | 12 | 12 | 12 | sec |
| 9-2 9-3 10-1 10-2 10-3 |
90 02 0C AA AA |
Remarks: