Here is a description of the data protocol between the Rocket and the Ground Station for the Mjollnir project.
This protocol defines how Telecommands and Telemetry are transmitted between the Ground Station, the Engine Computer, and the Flight Controller.
The following repositories follow this data protocol:
- aesirkth/flight-controller
- aesirkth/ground-control
- engine computer repository
The diagrams in this document can be edited using the online tool diagrams.net. Just import the .xml files. Export the diagrams to .png and to .xml (compressed) and save them back here after modification.
The HTML tables in this document can be edited using the online tool tablesgenerator.com. Simply click "File / Paste table data" and paste the table. Make sure to check "Do not generate CSS" and uncheck "Compact mode".
Overview of the data buses between the Ground Station and the Rocket
The source file can be found in doc/diagrams/data-buses.xml and edited using diagrams.net [desktop]
The Gateway is connected to the Control computer through the USB connector of the Flight Controller
The RFD900+ on the Ground Station side is connected to the Dashboard computer through an FTDI USB cable.
The Flight Controller on the Ground Station 'Gateway' is a preliminary solution to have the Control computer talk to the Rocket's Flight Controller during the first static fire.
The work on this data protocol is still preliminary. The development will be iterative and the first milestone is the static fire planned for the end of the beginning of 2021. The protocol will be refined later on to better allocate the telemetry sent back to the Ground Station.
Drivers:
- Send commands to the Rocket and have the relevant ones forwarded to the Engine Computer
- Send back Telemetry to the Ground Station, mainly comprised of measurement samples from the Engine Computer
- No logic on the Flight Controller for the Telemetry packets, the packets are simply forwarded to the Ground Station. We will try to store the telemetry on the FC memory as well, so we can have data with higher sampling rates even if it is offline, as well as a backup.
Drivers:
- Maximize the amount of data downlinked from the Rocket, by optimizing how the data packets are processed by the Flight Controller and maybe also the Ground Station.
- Be more resilient to loss of frames.
All serial links share the same configuration. The baud rate is 57600 (might need to be changed to 115200). The airspeed between the RFD900+ modems is 64kbps.
A frame on the serial links looks like this:
| Byte number | Description |
|---|---|
| 0 | Frame separator: 0x0A |
| 1 | Frame separator: 0x0D |
| 2 | Frame ID |
| 3 | Data byte 0 |
| 4 | Data byte 1 |
| [...] | [...] |
| N+3 | Data byte N |
The length of the data field is variable
Note: the CAN bus between the Engine Computer and the Flight Controller can be extended to additional boards in future developments.
CAN bus: CAN2.0 (FlexCAN) @1Mbit/s with termination 120Ω resistors on the Flight Controller side and on the Engine Computer side.
Base frame format (11 identifier bits)
Note: The Time Sync of the Engine Computer will be handled by the Flight Controller. The EC will send a request package and the FC will answer it using its currently configured system time (this can be the time set by the Ground Station or the time received through GNSS).
The term ID is used below to denote identifier field of the CAN Bus and byte 2 (Frame ID) of a frame over the serial links.
The identifier field is an 11 bits field but only the 8 lower bits are used to make the data on the CAN Bus as similar as possible to the data on the serial buses. The remaining ID values 100 - 7FF are available for data transfer between on-board systems over the CAN Bus only, and cannot be sent to ground.
Each message on the Telecommand TC link and the Telemetry TM link has a unique ID.
| ID | Frame Type | From | To | Unique IDs |
|---|---|---|---|---|
| 0x00 - 0x0F | TC | Ground Station | Flight Controller | 16 |
| 0x10 - 0x1F | TC | Flight Controller | Ground Station | 16 |
| 0x20 - 0x2F | TC | Ground Station | Engine Computer | 16 |
| 0x30 - 0x3F | TC | Engine Computer | Ground Station | 16 |
| 0x40 - 0x7F | TM | Flight Controller | Ground Station | 64 |
| 0x80 - 0xFF | TM | Engine Computer | Ground Station | 128 |
The Telecommand link is a low data rate radio link over LoRa at 433 MHz. The communication will work on a request-response basis where the Ground Station sends a command and the Flight Controller or Engine Computer replies back, but at the same time some data will be streamed from the FC at a low rate.
Command sequence to the Rocket. Command addressed to the Flight Controller
The source file can be found in doc/diagrams/command-sequence.xml and edited using diagrams.net [desktop]
Command sequence to the Rocket. Command addressed to the Engine Controller
The source file can be found in doc/diagrams/command-sequence.xml and edited using diagrams.net [desktop]
ALL DATA MUST BE LITTLE-ENDIAN
Commands sent from the Ground Station to the Flight Controller
| ID | Description | Data size | Data | Comment | Rate |
|---|---|---|---|---|---|
| 0x00 | Time Sync | 4 | system_time | uint32_t, hhmmss.sss | |
| 0x01 | Set Power Mode | 1 | TBD | ||
| 0x02 | Set Radio Equipment | 1 | bit0: is_fpv_en bit1: is_tm_en |
Default state is 0 | |
| 0x03 | Set Parachute Output | 1 | bit0: is_parachute_armed bit1: is_parachute1_en bit2: is_parachute2_en |
Default state is 0 Must set is_armed to 1 before a parachute can be enabled |
|
| 0x04 | Set Data Logging | 1 | bit0: is_logging_en | enables data logging to SD-card and/or flash-chip | |
| 0x05 | Dump flash chip | 1 | bit0: dump_sd bit1: dump_usb |
Replies sent from the Flight Controller to the Ground Station and stremed data
| ID | Description | Data size | Data | Comment | Rate |
|---|---|---|---|---|---|
| 0x10 | Return Time Sync | N/A | |||
| 0x11 | Return Power Mode | 1 | TBD | ||
| 0x12 | Return Radio Equipment | 1 | bit0: is_fpv_en bit1: is_tm_en |
||
| 0x13 | Return Parachute Output | 1 | bit0: is_parachute_armed bit1: is_parachute1_en bit2: is_parachute2_en |
||
| 0x14 | Onboard Battery Voltage | 4 | battery_1 | uint16_t, in 0.01V | 0.2 |
| battery_2 | uint16_t, in 0.01V | ||||
| 0x15 | GNSS data | 14 | gnss_time | uint32_t, in hhmmss.sss | 0.2 |
| latitude | int32_t, in ddmm.mmmm | ||||
| longitude | int32_t, in dddmm.mmmm | ||||
| h_dop | uint16_t, in 0.01 | ||||
| 0x16 | Flight Controller Status | 3 | HW_state | uint8_t | 0.2 |
| SW_state | uint8_t | ||||
| mision_state | uint8_t, enum | ||||
| 0x17 | Return Data Logging | 1 | bit0: is_logging_en | ||
| 0x18 | Return dump flash | 1 | bit0: dump_sd bit1: dump_usb |
||
| 0x19 | Return Handshake | 0 |
The Telemetry link is a high data rate radio link over FHSS at 868 MHz. It is technically bi-directional but only the downlink capability is used.
Telemetry sequence from the Rocket. Telemetry from the Flight Controller
The source file can be found in doc/diagrams/telemetry-sequence.xml and edited using diagrams.net [desktop]
Telemetry sequence from the Rocket. Telemetry from the Engine Controller
The source file can be found in doc/diagrams/telemetry-sequence.xml and edited using diagrams.net [desktop]
ALL DATA MUST BE LITTLE-ENDIAN
| ID | Description | Data size | Data | Comment | Tx Rate | Sampling Rate |
|---|---|---|---|---|---|---|
| 0x40 | Time since boot - millis | 4 | ms_since_boot | uint32_t | ||
| 0x41 | Time since boot - micros | 8 | us_since_boot | uint64_t | ||
| 0x42 | Current time | 4 | current_time | uint32_t, in hhmmss.sss interpolated from gps time |
||
| 0x43 | GNSS Data 1 | 12 | gnss_time | uint32_t, in hhmmss.sss | 2 | 2 |
| latitude | int32_t, in ddmm.mmmm | |||||
| longitude | int32_t, in dddmm.mmmm | |||||
| 0x44 | GNSS Data 2 | 12 | altitude | int32_t, in 0.1 meters | 2 | 2 |
| heading | int16_t, in degrees | |||||
| horiz_speed | int16_t, in 0.1 km/h | |||||
| fix_status | uint8_t, {0 = No Fix, 1 = 2D, 2 = 3D} | |||||
| n_satellites | uint8_t | |||||
| h_dop | uint16_t, in 0.1 | |||||
| 0x45 | Inside Static Temperature | 8 | temperature_1 | int32_t, in 0.01 ºC | 2 | TBD |
| temperature_2 | int32_t, in 0.01 ºC | |||||
| 0x46 | Inside Static Pressure | 8 | pressure_1 | int32_t, in 0.01 mbar | 20 | TBD |
| pressure_2 | int32_t, in 0.01 mbar | |||||
| 0x47 | IMU 1 | 18 | accel_x | int16_t | 20 | TBD |
| accel_y | int16_t | |||||
| accel_z | int16_t | |||||
| gyro_x | int16_t | |||||
| gyro_y | int16_t | |||||
| gyro_z | int16_t | |||||
| magnet_x | int16_t | |||||
| magnet_y | int16_t | |||||
| magnet_z | int16_t | |||||
| 0x48 | IMU 2 | 18 | accel_x | int16_t | 20 | TBD |
| accel_y | int16_t | |||||
| accel_z | int16_t | |||||
| gyro_x | int16_t | |||||
| gyro_y | int16_t | |||||
| gyro_z | int16_t | |||||
| magnet_x | int16_t | |||||
| magnet_y | int16_t | |||||
| magnet_z | int16_t | |||||
| 0x49 | External Temperature | 4 | temp_1 | int16_t | 10 | TBD |
| temp_2 | int16_t | |||||
| 0x4A | Air Speed | 4 | pitot | int16_t | 20 | TBD |
| calculated | int16_t | |||||
| 0x4B | Onboard Battery Voltage | 4 | battery_1 | uint16_t, in 0.01V | 2 | 10 |
| battery_2 | uint16_t, in 0.01V | |||||
| 0x4C | Flight Controller Status | 3 | HW_state | uint8_t bit0: is_parachute_armed bit1: is_parachute_1_en bit2: is_parachute_2_en bit3: is_fpv_en bit4: is_telemetry_en |
10 | 10 |
| SW_state | uint8_t | |||||
| mision_state | uint8_t, enum |
The data acquisition process is the following:
- Save all acquired data to a buffer
- Sync the internal clock to GPS time and interpolate it
- At a regular interval send the current time and the stored buffer
- Every few seconds record the delays in the CAN-system
- If needed use the delays to reconstruct the actual time on the ground station
This allows to reduce the overhead on the Telemetry link by only sending one time stamp for all the data acquired in one loop. The error in acquisition time is acceptable as the sampling loop is assumed to be short with respect to the measured phenomena. All the sensors may not be sampled in every loop or may be sampled without sending the samples to the ground. The sensors that require low sampling rates can simply be sampled and sent every X loop
Some cases might exist where the time frame is not received on the Ground Station.
On Sigmundr launch (2019), the telemetry frames were ~100 bytes long. It was noticed that when a failure occured, the whole frame was lost instead of just small bits at the beginning or so. This has to do with how the RFD900+ modems handle the data transmission and should be further investigated.
Possible mitigations for early uses of this protocol can be:
- Time stamp all packets at reception time and compare this time with the time frame.
- Assume no packet loss. (realistic at close range, < 1km with line of sight)
- Group the frames in a big packet (wait and send all at once) like was done on Sigmundr and hope for a pass / fail for one hole sampling loop.




