The 1090 Megahertz Riddle (second edition)

A Guide to Decoding Mode S and ADS-B Signals
By: Junzi Sun (junzis.com)

Airborne velocity

Airborne velocities are all transmitted with Type Code 19 (TC=19). The general structure of the message is shown in Table 1.1. Four different subtypes are defined in bits 6–8 of the ME field. All sub-types share a similar overall message structure, with the different definitions from message bits 14 to 35 (or frame bits 46 to 67).

Airborne velocity message structure
FIELD MSG ME BITS
Type Code TC 33–37 1–5 5
  TC=19 [Binary: 10011]
Sub-type ST 38–40 6–8 3
Intent change flag IC 41 9 1
IFR capability flag IFR 42 10 1
Navigation uncertainty category for velocity 43–45 11–13 3
  ADS-B version 0 NUCr
  ADS-B version 1–2 NUCv
Sub-type specific fields 46–67 14–35 22
  Refer to Table 1.2 and Table 1.3
Source bit for vertical rate VrSrc 38 36 1
  0: GNSS, 1: Barometer
Sign bit for vertical rate Svr 69 37 1
  0: Up, 1: Down
Vertical rate VR 70–78 38–46 9
  All zeros: no information
  LSB: 64 ft/min
  VR = 64 x (Decimal value - 1)
Reserved 79–80 47–48 2
Sign bit for GNSS and Baro altitudes difference SDif 81 49 1
  0: GNSS alt above Baro alt
  1: GNSS alt below Baro alt
Difference between GNSS and Baro altitudes dAlt 82–88 50–56 7
  All zeros: no information
  LSB: 25 ft

Subtypes 1 and 2 are used to report ground speeds of aircraft. Subtypes 3 and 4 are used to report aircraft true airspeed or indicated airspeed. Reporting of airspeed in ADS-B only occurs when aircraft position cannot be determined based on the GNSS system. In the real world, subtype 3 messages are very rare.

Sub-type 2 and 4 are designed for supersonic aircraft. Their message structures are identical to subtypes 1 and 3, but with the speed resolution of 4 kt instead of 1 kt. However, since there are no operational supersonic airliners currently, there is no ADS-B airborne velocity message with sub-type 2 and 4 at this moment.1

These messages contain more information than just horizontal and vertical velocity. Two other significant types of information are the navigation uncertainty category for velocity, and the difference between the GNSS height and barometric altitude.

Compared to position messages, the decoding of velocity messages is more straightforward since there is no complicated encoding scheme. We will use two example messages to illustrate the decoding process in the rest of this chapter:

Message A:  8D485020994409940838175B284F (sub-type 1)
Message B:  8DA05F219B06B6AF189400CBC33F (sub-type 3)

Downlink format, ICAO address, ME field, and parity of both messages are as follows:

+-----+----+--------+----------------+--------+
+     | DF | ICAO   | ME             |  PI    |
+-----+----+--------+----------------+--------+
+ A   | 8D | 485020 | 99440994083817 | 5B284F |
+-----+----+--------+----------------+--------+
+ B   | 8D | A05F21 | 9B06B6AF189400 | CBC33F |
+-----+----+--------+----------------+--------+

Next, we can convert two ME fields into binary and decompose the structure further as follows:

Message A (sub-type 1):
+-----+---+--+---+---+-----------+-----+---+---------+----+----+-------+
|TC   |ST |IC|IFR|NUC|           |VrSrc|Svr|VR       |RESV|SDif|DAlt   |
+-----+---+--+---+---+-----------+-----+---+---------+----+----+-------+
|10011|001|0 |1  |000|10000001001|0    |1  |000001110|00  |0   |0010111|
|     |   |  |   |   |10010100000|     |   |         |    |    |       |
+-----+---+--+---+---+-----------+-----+---+---------+----+----+-------+
|19   |1  |0 |1  |0  |           |0    |1  |14       |0   |0   |23     |
+-----+---+--+---+---+-----------+-----+---+---------+----+----+-------+
Message B (sub-type 3):
+-----+---+--+---+---+-----------+-----+---+---------+----+----+-------+
|TC   |ST |IC|IFR|NUC|           |VrSrc|Svr|VR       |RESV|SDif|DAlt   |
+-----+---+--+---+---+-----------+-----+---+---------+----+----+-------+
|10011|011|0 |0  |000|11010110110|1    |1  |000100101|00  |0   |0000000|
|     |   |  |   |   |10101111000|     |   |         |    |    |       | 
+-----+---+--+---+---+-----------+-----+---+---------+----+----+-------+
|5    |3  |0 |0  |0  |           |1    |1  |37       |0   |0   |0      |
+-----+---+--+---+---+-----------+-----+---+---------+----+----+-------+

Here, the second rows and third rows of the messages are binary and decimal values, respectively.

Vertical rate

The method for decoding vertical rate and its related parameters are the same for different sub-types.

First of all, the vertical rate source bit VrSrc (ME bit 36) indicates the source of the altitude measurements. GNSS altitude is encoded as 0, while 1 encodes the barometric altitude.

The direction of aircraft vertical movement can be read from Svr bit (ME bit 37), with 0 and 1 referring to climb and descent, respectively. The encoded vertical rate value VR can be computed using message ME bits 38 to 46. If the 9-bit block contains all zeros, the vertical rate information is not available.

The final vertical speed (\(\mathrm{VS}\)) is calculated as:

\[\mathrm{VS} = \begin{cases} 64 (V_R - 1), & S_{vr} = 0 \\ -64 (V_R - 1), & S_{vr} = 1 \end{cases}\]

where the final vertical speed has the unit of ft/min.

Based on the example Message A, the vertical speed is calculated as:

\[\mathrm{VS}_A = -64 \times (14 - 1) = -832 ~\text{ft/min}\]

which indicates that the aircraft A is descending with a vertical speed of 832 ft/min.

Based on the example Message B, the vertical speed is calculated as:

\[\mathrm{VS}_B = -64 \times (37 - 1) = -2304 ~\text{ft/min}\]

which indicates that the aircraft B is descending with a vertical speed of 2304 ft/min.

GNSS and barometric altitudes difference

The last eight bits of the ME field contain the difference between the barometric and GNSS altitudes. Of these eight bits, the first bit indicates the sign for the value of the remaining bits. When it is 1, the value is negative. This means the GNSS altitude is below the barometric altitude.

The value is encoded with the increment of 25 feet, and the equation to calculate the altitude difference is:

\[\Delta h = s (n - 1) \times 25\]

where \(s\) is the sign and \(n\) is the decimal value of the encoded altitude difference.

Based on the example Message A, the difference between GNSS and barometric altitude is:

\[\Delta h = 1 (23 - 1) \times 25 = 550 ~\text{ft}\]

When all the bits are zeros (as shown in Message B) or ones, this information is not available.

Sub-type 1 and 2: Ground speed decoding

The velocity information fields of subtype 1 and 2 messages consist of the East-West velocity component and the North-South velocity component, as well as the signs for these two values. The structure of ME bits 14 to 35 is shown in Table 1.2.

Velocity fields of sub-type 1 and 2 (ME bit 14 to 35)
FIELD MSG ME BITS
Direction for E-W velocity component Dew 46 14 1
  0: from West to East
  1: from East to West
East-West velocity component Vew 47–56 15–24 10
  All zeros: no information available
  Sub-type 1: Speed = Decimal value - 1
  Sub-type 2: Speed = 4 x (Decimal value - 1)
  Unit: Knots
Direction for N-S velocity component Dns 57 25 1
  0: from South to North
  1: from North to South
North-South velocity component Vns 58–67 26–35 10
  All zeros: No information available
  Sub-type 1: Speed = Decimal value - 1
  Sub-type 2: Speed = 4 x (Decimal value - 1)
  Unit: Knots

Here, we can see that ME bits 14 and 25 are sign bits indicating the directions of each component. Each 10-bit block following these sign bits encodes a velocity component. It is important to point out that when any of the 10-bit blocks contains only zeros, no velocity information is available. For supersonic velocity (sub-type 2), the final velocity components are multiplied by a factor of 4.

To calculate the velocity, four values are needed, which are Sew, Vew, Sns, and Vns. It is common to consider speed vector’s West-East and South-North component as positive values, which are denoted as \(V_x\) and \(V_y\). The formulas for sub-type 1 (subsonic) and sub-type 2 (supersonic) differ by a factor of 4.

For subsonic speed (sub-type 1), the speed components can be computed as:

\[\begin{aligned} V_x &= \begin{cases} V_{ew} - 1, & S_{ew} = 0 \\ -1(V_{ew} - 1), & S_{ew} = 1 \end{cases} \\ V_y &= \begin{cases} V_{ns} - 1, & S_{ns} = 0 \\ -1(V_{ns} - 1), & S_{ns} = 1 \end{cases}\end{aligned}\]

For supersonic speed (sub-type 2), the speed components can be computed as:

\[\begin{aligned} V_x &= \begin{cases} 4(V_{ew} - 1), & S_{ew} = 0 \\ -4(V_{ew} - 1), & S_{ew} = 1 \end{cases} \\ V_y &= \begin{cases} 4(V_{ns} - 1), & S_{ns} = 0 \\ -4((V_{ns} - 1), & S_{ns} = 1 \end{cases}\end{aligned}\]

The final ground speed (\(V\)) of aircraft is:

\[V = \sqrt{V_x^2 + V_y^2}\]

With these two speed components, the ground track angle (\(\lambda\)) of the aircraft can also be calculated conveniently as:

\[\begin{aligned} \lambda &= arctan2 \left( V_x, V_y \right) \cdot \frac{360}{2\pi} \\ \lambda &= mod(\lambda, 360) \label{eq:ground_track_mod_360}\end{aligned}\]

where Equation [eq:ground_track_mod_360] ensures the track angle range of [0, 360) degree, with North at 0 degrees, which is the case for most aviation applications and studies.

Based on the example message A given earlier:

Message A, ME bit 14-35
+-----+------------+-----+------------+-------+
| Sew | Vew        | Sns | Vns        | VrSrc |
+-----+------------+-----+------------+-------+
| 1   | 0000001001 | 1   | 0010100000 | 0     |
+-----+------------+-----+------------+-------+
| 1   | 9          | 1   | 160        | 0     |
+-----+------------+-----+------------+-------+

the final aircraft speed and track angle are calculated as:

\[\begin{aligned} V_x &= -1 (9 - 1) = -8 \\ V_y &= -1 (160 - 1) = -159 \\ V &= \sqrt{(-9)^2+ (-160)^2} = 159.20 \\ \lambda &= arctan2(-9, -160) \times \frac{360}{2\pi} = 182.88\end{aligned}\]

where the aircraft speed is 159.20 kt and the track angle is 182.88 degrees.

Sub-type 3 and 4: Airspeed decoding

ADS-B velocity messages with sub-type 3 or 4 are broadcast when the ground speed of the aircraft is not known. This could happen when, for example, aircraft positions cannot be obtained due to the low availability of GNSS satellites. Furthermore, instead of West/East and South/North components, speed and heading are encoded directly. Table 1.3 lists the details of message fields.

Velocity fields of sub-type 3 and 4 (ME bit 14 to 35)
FIELD MSG ME BITS
Status bit for magnetic heading SH 46 14 1
  0: not available
  1: available
Magnetic heading HDG 47–56 15–24 10
  LSB: 360/1024 degrees
  Heading = Decimal value \(\times 360 / 1024\)
Airspeed type T 57 25 1
  0: Indicated airspeed (IAS)
  1: True airspeed (TAS)
Airspeed AS 58–67 26–35 10
  All zeros: no information available
  Sub-type 1: Speed = Decimal value - 1
  Sub-type 2: Speed = 4 x (Decimal value - 1)
  Unit: knots

The magnetic heading (\(\phi\)) of the aircraft is calculated as:

\[\phi = \mathrm{HDG} \cdot \frac{360}{1024} \quad \text{degrees}\]

The speed calculations also differ between sub-type 3 and 4:

\[V_{as} = \begin{cases} \mathrm{AS} - 1 & \text{sub-type 3} \\ 4 \cdot (\mathrm{AS} - 1) & \text{sub-type 4} \end{cases}\]

Note that the airspeed type bit T represents whether the value is the indicated airspeed (IAS, T=0) or true airspeed (TAS, T=1).

Now, we can apply the decoding process to the previous example Message B:

Message B, ME bit 14-35
+----+------------+---+------------+
| SH | HDG        | T | AS         |
+----+------------+---+------------+
| 1  | 1010110110 | 1 | 0101111000 |
+----+------------+---+------------+
| 1  | 694        | 1 | 376        |
+----+------------+---+------------+

With heading status SH=1, we know that the magnetic heading information is available. Thus, the heading and airspeed can be derived as:

\[\begin{aligned} \phi &= 694 \times \frac{360}{1024} = 243.98 \\ V_{as} &= 376 - 1 = 375\end{aligned}\]

With airspeed type T=1, we can also determine that the speed refers to the true airspeed of the aircraft.

Try it out Using pyModeS, we can perform the decoding the airborne velocities messages as follows:

import pyModeS as pms

msgA = "8D485020994409940838175B284F"
msgB = "8DA05F219B06B6AF189400CBC33F"

vA = pms.adsb.velocity(msgA)
vB = pms.adsb.velocity(msgB)

We have the following decoded values.

vA: (159, 182.88, -832, 'GS')
vB: (375, 243.98, -2304, 'TAS')

Note that the parameters returned by the velocity() function are speed, track angle (or heading), vertical speed, and speed type.


  1. It is possible that with strong tail wind, the ground speed of an aircraft may appear to be “supersonic” during the flight.↩︎

© Copyright 2021 Junzi Sun. Build with LaTeX, Pandoc, and GitHub