Custom packets

This page documents the custom packets used by the Skybrush firmware to transmit drone show related status information to the ground station in a compact fashion.

Most of the custom packets used by the firmware are embedded in a MAVLink DATA16, DATA32, DATA64 or DATA96 message. These packets are used interchangeably; feel free to use the packet which fits the size of the payload that you are trying to send as both the firmware and the ground station will have a common handler registered to all of these packets. From now on, we will refer to these as DATA packets and the appropriate size of the packet is implied.

Some MAVLink packets with unspecified semantics (such as LED_CONTROL) are also used by the Skybrush firmware in a specific manner. These will also be documented here.

Multi-byte values are in little-endian order unless specified otherwise.

Drone to GCS

DATA packets sent from the drone to the ground station have their type field set to 0x5b or 0x5d. Type 0x5b is a standard status packet. For packets with type 0x5d, the real type of the packet is encoded in the first byte of the payload.

Drone show status

This packet is used to convey status information related to the drone show context to the ground station. It is meant to be used in conjunction with standard MAVLink HEARTBEAT, GLOBAL_POSITION_INT, GPS_RAW_INT and SYS_STATUS packets. The packet is emitted when the telemetry profile of the drone (i.e. the SHOW_TEL_PROFILE parameter) is set to "standard".

The packet is a MAVLink DATA16 packet with the type set to 0x5b. The structure of the payload is as follows:

Structure of a DATA16 drone show status packet
Figure 1. Structure of a DATA16 drone show status packet

where:

Start time

The scheduled start time of the show in GPS time-of-week, in seconds, encoded as a 32-bit signed integer; -1 if the start time is not set on the drone yet.

Color

The current color of the LED of the drone, in RGB565 encoding (i.e. 5 bits for the red channel, 6 bits for the green channel, 5 bits for the blue channel), encoded as a 16-bit unsigned integer.

Flags

See below.

Flags 2

See below.

GPS

Most significant 5 bits: number of GPS satellites seen by the drone, capped at 31. Least significant 3 bits: GPS fix status (0 = no GPS connected, 1 = no fix, 2 = 2D fix, 3 = 3D fix, 4 = DGPS, 5 = RTK float, 6 = RTK fixed, 7 = surveyed station).

Flags 3

See below.

Elapsed time

Number of seconds elapsed since the start of the show (negative if waiting for the start time of the show), in seconds, encoded as a 16-bit signed integer.

RTCM counters

Number of RTCM messages received in the last five seconds by the drone plus one, encoded as 8-bit unsigned integers per RTCM channel (first byte: primary channel, second byte: backup channel). Zero means that no RTCM messages have been observed on the telemetry channel since boot.

The flags in the Flags, Flags 2 and Flags 3 bytes have a convoluted encoding due to backward compatibility purposes. From LSB to MSB, the individual bits in Flags are as follows:

  • Fence breached

  • Drone uses GPS time to start the show and the start time is not valid yet

  • Authorization granted (0 = not granted, 1 = granted; superseded by authorization scopes in Flags 3).

  • Fence enabled

  • Show orientation set

  • Show origin set

  • Scheduled start time set

  • Show data loaded successfully

From LSB to MSB, the individual bits in Flags 2 are as follows:

  • Current show execution stage (4 bits, 0 = off, 1 = initializing, 2 = waiting for start time, 3 = taking off, 4 = performing, 5 = returning to launch site, 6 = position hold, 7 = landing, 8 = landed, 9 = error, 10 = testing lights)

  • Next 3 bits unspecified, must be set to 0.

  • MSB is set to 1 if the drone is not at its expected takeoff position, 0 otherwise.

From LSB to MSB, the individual bits in Flags 3 are as follows:

  • Boot count modulo 4, in 2 bits.

  • Authorization scope, in 2 bits.

  • Next 3 bits reserved, must be set to 0.

  • MSB is set to 1 if the drone drifted from its expected position, 0 otherwise.

Extended drone show status

Supported since firmware version 20251017.

This packet is used to convey extended status information related to the drone show context to the ground station. The packet is emitted when the telemetry profile of the drone (i.e. the SHOW_TEL_PROFILE parameter) is set to "compact". In the compact telemetry profile, the GLOBAL_POSITION_INT and GPS_RAW_INT packets are not emitted, and the extended drone show status packet is used to convey the information that is normally extracted from GLOBAL_POSITION_INT and GPS_RAW_INT.

The packet is a MAVLink DATA96 packet with the type set to 0x5b. The structure of the payload is as follows:

Structure of a DATA96 extended drone show status packet
Figure 2. Structure of a DATA96 extended drone show status packet

where the first 14 bytes are identical to the standard drone show status packet. The remaining fields are to be interpreted as follows:

Latitude

Latitude of the current position of the drone, in 10-7 degrees, encoded as a signed 32-bit integer.

Longitude

Longitude of the current position of the drone, in 10-7 degrees, encoded as a signed 32-bit integer.

AMSL

Altitude of the drone above mean sea level, in millimeters, encoded as a signed 32-bit integer.

AHL

Altitude of the drone above home level, in millimeters, encoded as a signed 32-bit integer.

N, E and D velocity

Ground velocity components of the drone (North, East and Down), in centimeters per second, encoded as signed 32-bit integers.

Heading

Yaw angle of the drone, in centidegrees, encoded as an unsigned 16-bit integer.

HDOP and VDOP

Horizontal and vertical dilution of precision, scaled by a factor of 100, encoded as unsigned 16-bit integers. (For instance, a value of 155 means 1.55).

Show ID

32-bit opaque unsigned identifier of the show currently uploaded to the drone. Can be used to verify that all drones are prepared to fly the same show by comparing this field across the telemetry packets received from the drones. An identifier consisting of zero bits only means that the show ID is not known.

Trajectory index

16-bit zero-based index of the trajectory within the show that the drone is flying. 0xFFFF means that the index is not known.

Note that an unknown show ID or an unknown trajectory index is not an error; it may simply mean that the GCS is of an older version that did not provide this information at upload time.

Acknowledgment

Implemented with a DATA packet with the type set to 0x5d and the first byte of the payload set to 0x04.

TODO: finish documentation

GCS to drone

DATA packets sent from the ground station to the drone have their type field set to 0x5c. The real type of the packet is encoded in the first byte of the payload.

LED control packet

LED control commands are conveyed in MAVLink LED_CONTROL messages where the instance and the pattern fields are both set to decimal 42. The payload of the message contains the command itself.

The general semantics of the message is primarily decided by the length of the payload.

Payload of length 0

Instructs the drone to flash its LED five times to attract attention.

Payload of length 1

Instructs the drone to flash its LED five times to attract attention if its configured group (in the SHOW_GROUP parameter) matches the group mask in the first byte of the payload. Bit 0 (LSB) of the payload belongs to group 0, bit 1 belongs to group 1 and so on.

Payload of length 3

Set the LED to a specific color for 5 seconds. the desired color is encoded in the payload in RGB order (one byte per channel).

Payload of length 5

Set the LED to a specific color for a given duration. The desired color is encoded in the payload in RGB order (one byte per channel) in the first three bytes, followed by a 16-bit duration in milliseconds as an unsigned integer.

Payload of length 6

Same as a payload of length 5, extended by a byte that encodes an effect with which the light intensity will be modulated (0 = off, 1 = solid, 2 = blinking, 3 = "breathing", i.e. slowly fading in and out).

Payload of length 7

Same as a payload of length 6, extended by a group mask. The drone will execute the command if its configured group (in the SHOW_GROUP parameter) matches the group mask.

Start time configuration

Implemented with a DATA packet with the type set to 0x5c and the first byte of the payload set to 0x01.

Structure of a start time configuration packet payload
Figure 3. Structure of a start time configuration packet payload

where:

Start time

Start time to set on the drone, in GPS time of week (sec), encoded as a 32-bit signed integer. Anything larger than 604799 means not to touch the start time that is currently set. Negative number means that the start time must be cleared.

Auth

The authorization scope. TODO: explain this!

Countdown

Number of milliseconds left until the start of the show, used to implement starting the show with a countdown, encoded as a 32-bit signed integer. Positive numbers mean that there is still some time left until the start of the show. The SHOW_SYNC_MODE parameter must be set to 1 for this argument to take effect, otherwise it is ignored by the drone.

Collective return to launch

This packet is currently unused and might be deprecated in the future.

Implemented with a DATA packet with the type set to 0x5c and the first byte of the payload set to 0x02.

The next two bytes of the payload encode the start time of the collective return-to-launch (RTL) operation, in seconds since the start of the show, encoded as a 16-bit unsigned integer. Zero is a special value, it clears any scheduled collective RTL for the future if the drone has not started the operation yet.

This packet is currently unused as the corresponding feature has not been tested thoroughly yet.

Simple geofence setup

This packet is experimental. We reserve the right to remove or change it in future versions.

Implemented with a DATA packet with the type set to 0x5c and the first byte of the payload set to 0x03.

TODO: finish documentation

Time axis configuration

This packet is experimental. We reserve the right to remove or change it in future versions.

Implemented with a DATA packet with the type set to 0x5c and the first byte of the payload set to 0x04.

Structure of a time axis configuration packet payload
Figure 4. Structure of a time axis configuration packet payload

This packet allows the GCS to reconfigure how "wall clock time" (i.e. number of seconds elapsed since the start time of the show, which is broadcast in the start time configuration packet) is mapped to "show time", making it possible to slow down the playback of the slow gradually or to resume the show from a suspended state.

The time axis of the show is modelled as a sequence of segments with finite durations (in wall clock time), except the last segment whose duration is infinite. Each segment has a corresponding initial and final rate of time. The rate defines how "fast" the show clock runs compared to the wall clock time within that segment. A rate of 1 means that the show clock runs exactly as fast as wall clock time, i.e. one second elapsed in wall clock time corresponds to one second in the show. A rate of 0.5 means that the show clock runs at half speed, i.e. one second in wall clock time corresponds to half a second in the show. Similarly, a rate of 2 means that the show clock runs at double speed, although it is unlikely that one would use rates above 1 because of safety reasons. A rate of zero means that the time on the show clock stands still for the duration of that segment while wall clock time goes on at a normal rate.

You will see later that right now the packet format does not allow rates above 1 at all. This is intentional; nevertheless, all the data structures in our firmware support rates larger than 1 so the explanation above is still valid. It just happens to be the case that the specific encoding we chose prevents the user from setting the rate above 1.

The initial and final rate of a segment may be equal, in which case time flows at a constant rate during that segment (but the rate may be different from real-time). If the rates are different, it means that the rate of time itself changes linearly during that segment; in other words, time gradually slows down or speeds up in that segment along a quadratic curve. For instance, a segment with a duration of 5 seconds, an initial rate of 1 and a final rate of 0 means that time slows down from real-time to a standstill in 5 seconds (wall clock time), during which the show time advances by only 2.5 seconds (calculated from the duration in wall clock time, multipled by the "average" rate of time in the segment).

The final segment in the time axis always has an infinite duration, and the rate is assumed to be equal to its initial rate for the entire duration.

The packet consists of the following fields:

Seq no.

A sequence number that starts from zero and must be incremented by 1 every time the GCS changes the configuration of the time axis.

N-1

The number of segments in the packet minus one (i.e. N is the number of segments and the stored value is one less than that).

Unused

Unused, reserved for future expansion, must be zero.

Origin

Number of milliseconds on the show clock that corresponds to the start time broadcast in the start time configuration packet. Can be negative. Stored as a 32-bit signed integer.

Initial rate X

Initial rate of time for segment X, between 0 (standstill) and 1 (real-time), multiplied by 65535 and rounded to the nearest integer, stored as an unsigned 16-bit integer.

Final rate X

Final rate of time for segment X, between 0 (standstill) and 1 (real-time), multiplied by 65535 and rounded to the nearest integer, stored as an unsigned 16-bit integer. Note that the N-th segment does not have a final rate as it is assumed to be a constant-rate segment.

Duration X

Duration of segment X. Note that the N-th segment does not have a duration as it is assumed to be infinite.

Example: real-time playback, used as a default

The following packet configures wall clock time to map directly to show time. This is used as the default until the GCS starts broadcasting time axis configuration packets.

Example: real-time playback
Figure 5. Example: real-time playback

Example: slowdown from real-time to standstill at 2 minutes

The following packet configures the show to slow down to a standstill at the 2 minute mark in the show. The duration of the slowdown is 10 seconds in wall clock time, which corresponds to 5 seconds in the show. Note that the sequence number is increased to 1 because it was 0 in the previous example.

Example: slowdown from real-time to standstill in 5 seconds at 2 minutes
Figure 6. Example: slowdown from real-time to standstill in 5 seconds at 2 minutes

Example: resuming from standstill to real-time

The following packet configures the show to speed up from a standstill to real-time with the following parameters:

  • wall clock time since start of the show when we start broadcasting the packet: 2 minutes 30 seconds.

  • wall clock time since start of the show when the transition starts: 3 minutes

  • show clock when resuming: 2 minutes 5 seconds (same as the time on the show clock at the end of the previous example)

  • duration of the speedup: 10 seconds (wall clock time)

Note that the sequence number is increased to 2 because it was 1 in the previous example.

The easiest is to just extend the timeline in the previous example:

Example: resuming from standstill to real-time in 10 seconds at 3 minutes
Figure 7. Example: resuming from standstill to real-time in 10 seconds at 3 minutes

However, note that since we broadcast this packet from 2 minutes 30 seconds wall clock time, it does not matter how the timeline would look like for any time instant that is before 2 minutes 30 seconds wall clock time. This allows us to simplify the packet by pretending that the show started later and it happened to have been stopped abruptly at 2 minutes 30 seconds wall clock time such that the show clock was at 2 minutes 5 seconds:

TODO