Lucy is a spacecraft that will study the Trojan asteroids, during a twelve year mission. It was launched last Saturday at 9:34 UTC from Cape Canaveral on an Atlas V rocket. Its telemetry downlink is on X-band, at a frequency of 8445.768 MHz.
Iban Cardona EB3FRN made a 30 minute recording of the telemetry downlink at 19:00 UTC on Saturday, as the spacecraft first appeared over Europe after launch. r00t.cz did a brief analysis of this recording overnight, and then published some more details about the telemetry data. On Sunday, at 8:52 UTC, I did a long recording with one of the dishes in the Allen Telescope Array. This recording lasts 3 hours 26 minutes, and ends when the spacecraft set below the 16 degree elevation mask of the ATA. In this post I give a first analysis of the telemetry data in both recordings.
The recording done at ATA can be downloaded from the following datasets in Zenodo:
- Lucy recording with Allen Telescope Array on 2021-10-17: part 1/2, polarization X
- Lucy recording with Allen Telescope Array on 2021-10-17: part 1/2, polarization Y
- Lucy recording with Allen Telescope Array on 2021-10-17: part 2/2, polarization X
- Lucy recording with Allen Telescope Array on 2021-10-17: part 2/2, polarization Y
Iban used a 2.4 metre antenna and RHCP polarization, and the ATA dishes are 6.1 metre and have dual linear polarization. The SNR in both recordings is enough to decode the telemetry, though unfortunately in Iban’s recording there is loss of IQ samples, which makes decoding of many frames fail.
The telemetry downlink is modulated using PCM/PSK/PM with the telemetry on a subcarrier whose frequency is approximately 281.25 kHz. The symbol rate is 60 kbaud, and the coding is CCSDS r=1/6 Turbo code with 8920 bit frames. The data link frames are CCSDS AOS frames with the usual CRC-16 in the frame error control field.
During these two recordings the spacecraft was still using its low gain antenna. As of 2021-10-19 19:55 UTC it has changed to the high gain antenna and doubled the symbol rate to 120 kbaud.
The figure below shows the GNU Radio decoder flowgraph used for the ATA recording. It has an auto-polarization block that combines the two linear polarizations with the appropriate coefficients that maximise the SNR (so RCHP is synthesized taking into account phase offsets and gain offsets). The rest of the decoder is quite similar to other decoders of deep space probes shown in this blog. The flowgraph uses some blocks from gr-satellites and the Turbo decoder from gr-dslwp.
The GNU Radio flowgraph used to decode Iban’s recording is lucy_eb3frn.grc
, and the flowgraph used to decode the ATA recording is lucy_ata.grc
.
The figure below shows the GNU Radio decoder processing Iban’s recording. The top plot shows the symbols in the time domain. The middle plot shows the spectrum at the output of the PLL, with the real part in blue, which contains the residual carrier, and the imaginary part in red, which contains the data sidebands. The bottom plot is the constellation diagram, in which we can see the two BPSK symbols even though the constellation is noisy.
The AOS frames use spacecraft ID 0x31, matching the SANA registry. There are two virtual channels in use: virtual channel 0, which contains telemetry data, and virtual channel 63, which contains Only Idle Data (as it should, since virtual channel 63 is reserved for that purpose).
Interestingly, the frames in virtual channel 63 contain an M_PDU header with the first header pointer value of 2046, indicating that the packet zone contains only idle data. From reading the blue book, I think it is more common not to have an M_PDU header in the frames in the Only Idle Data virtual channel. The packet zone of these idle frames is filled with 0xaa
bytes.
Virtual channel 0 contains CCSDS Space Packets using M_PDU. The Space Packets contain a 5 byte secondary header. The first four bytes are a timestamp given as the seconds elapsed since the J2000 epoch (2000-01-01 12:00 UTC), and the fifth byte probably indicates fractions of a second, but it is difficult to be sure of this.
The figure below shows the APIDs in use in the recording done with ATA. APID 2047 is the APID dedicated to idle packets, which are filled with 0x55
bytes. Most of APIDs have packets of different lengths.
In the recording done earlier by Iban the distribution of the APIDs in use is slightly different, perhaps hinting at some changes in the enabled subsystems between the two recordings. The plot is shown below. Due to the lost IQ samples in Iban’s recording, only about 40% of the AOS frames could be decoded correctly. Even so, the decodes are good enough to get an idea of what was being transmitted. The lack of APIDs 7 and 1032 is interesting. Looking again at the ATA’s data, it seems that APIDs 6 and 7 are mutually exclusive, and that APID 1031 and 1032 are only sent when APID 7 is sent.
Given that we have only one frame from APID 4, it is very difficult to get an idea of what it contains. APID 5 is perhaps the most interesting (or easiest to reverse-engineer). The dump of this APID from the ATA recording is shown below. Each row of the image corresponds to one packet, and shows all the bytes of the packet except for the primary header. Bytes are colour coded using the Viridis colour map (purple is 0x00
and yellow is 0xff
).
As r00t has pointed out, this APID contains fields following a key-value scheme. The keys are two bytes long, and the values can be either 2, 4 or 8 bytes long and have integer or floating point format depending on the key. All the packets in this APID are laid out in exactly the same way, with the same keys in the same positions, so it is not difficult to guess which positions correspond to keys and what are the lengths of their corresponding values.
I have obtained a complete list of the keys and their data types used in APID 5. I have noticed that some of the values that r00t interpreted as int32
make more sense when interpreted as float32
(in fact, for those fields that have values centred on zero the difference can be spotted due to the fact that floats are encoded in sign-magnitude format and ints are encoded in two’s complement). Still, for some fields it is not clear from the data if they should be interpreted as floats or ints, or whether they are signed or unsigned ints.
It is difficult to guess what telemetry value each of these keys is encoding. When plotted, many keys look more or less like Gaussian noise (maybe not completely Gaussian, but Gaussian-like). The most peculiar keys are plotted below.
According to r00t, APID 6 also contains data in key-value format, but it is more difficult to parse because the packets have different lengths and contain the keys in different orders. I haven’t looked at the data in this APID in detail. Here is a plot of its contents in the ATA recording. Since there are frames of different length, here and in the plots below the shorter frames have been zero padded on the right to make them all have the same length.
APIDs 7 and 8 are very similar to APIDs 5 and 6 respectively, so even though I haven’t looked at them in detail it seems that they have the same structure. Here are their contents.
APID 1028 contains mostly static data. APIDs 1029 through 1032 are very interesting. It is not obvious what they contain. At first they might appear to have very high entropy, but when many packets are plotted it is apparent that the data is not uniformly distributed. It seems that APIDs 1029 and 1031 have the same structure, and also APIDs 1030 and 1032 have the same structure.
APID 2047 is not interesting, as it only contains idle packets of different lengths.
The analysis of the frames was done in this Jupyter notebook for Iban’s recording, and in this one for ATA’s recording. The same folder in the repository also contains binary data files with the decoded frames. The frames in these files are stored back-to-back. Each frame has a size of 1113 bytes, since the CRC-16 is removed by the GNU Radio decoder.
Thanks for the great information, Daniel! I will be recording Lucy tonight with a 4.6m dish diameter instrument.