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:
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:
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.
0xFFFFmeans 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.
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_GROUPparameter) 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_GROUPparameter) 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.
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_MODEparameter 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.
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: 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: 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:
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