PicSat is a recently launched cubesat from the Observatoire de Paris. It is designed to observe the Beta Pictoris star system, using a telescope based on an optical fibre. It transmits telemetry in the 70cm Amateur satellite band and it also carries a V/U FM Amateur transponder as a secondary payload. In my previous post, I decoded the 1k2 BPSK + G3RUH AX.25 packets from PicSat, and added a decoder to gr-satellites. Now I have added a telemetry parser to the gr-satellites decoder.
The PicSat team has written up a very nice description of the packet formats used by PicSat. PicSat's packets are based on the CCSDS Space Packet Protocol. The Space Packet Protocol is very general, so other than the primary header, the packet format is all specific to PicSat. The PicSat webpage allows sending received packets to their server, for inclusion in their database. The webpage also shows the decoded telemetry from the packets, so I've been able to use this feature to check that my telemetry parser is producing the correct results.
This is the same packet as this one, decoded with gr-satellites:
Container: primary_header = Container: ccsds_version = 0 packet_type = False secondary_header_flag = True process_id = 2 level_flag = False payload_flag = False packet_category = 1 sequence_flag = 3 packet_id = 4822 data_length = 108 secondary_header = 2030-01-01 04:53:40.676000 beacon = Container: solar_panel_error_flags = ListContainer: False False False False False i_adcs_get_attitude_error = False i_adcs_get_status_register_error = False fram_enable_error_flag = False ants_error_flag = ListContainer: False False trxvu_tx_error_flag = False trxvu_rx_error_flag = False obc_supervisor_error_flag = False gom_eps_error_flag = False ant1_status_b = Container: undeployed = False timeout = False deploying = False ant2_status_b = Container: undeployed = False timeout = False deploying = False ignore_flag_ants_b_status = False ant3_status_b = Container: undeployed = False timeout = False deploying = False ant4_status_b = Container: undeployed = False timeout = False deploying = False armed_ants_b_status = False ant1_status_a = Container: undeployed = False timeout = False deploying = False ant2_status_a = Container: undeployed = False timeout = False deploying = False ignore_flag_ants_a_status = False ant3_status_a = Container: undeployed = False timeout = False deploying = False ant4_status_a = Container: undeployed = False timeout = False deploying = False armed_ants_a_status = False solar_panel_temps = ListContainer: 0 0 0 2 30210 ants_temperature = ListContainer: 30472 49926 tx_trxvu_hk_current = 33029 tx_trxvu_hk_forwardpower = 5389 tx_trxvu_tx_reflectedpower = 1029 tx_trxvu_hk_pa_temp = 30473 rx_trxvu_hk_pa_temp = 49152 rx_trxvu_hk_board_temp = 768 eps_hk_temp_batts = 771 eps_hk_batt_mode = 32 eps_h_kv_batt = 33 eps_hk_boot_cause = 3 n_reboots_eps = 131864 n_reboots_obc = 0 quaternions = ListContainer: 0.0 0.0 0.0 0.0 angular_rates = ListContainer: 0.00333024328575 -0.0162032786757 0.110771499574 adcs_stat_flag_hl_op_tgt_cap = False adcs_stat_flag_hl_op_tgt_track_fix_wgs84 = False adcs_stat_flag_hl_op_tgt_track_nadir = False adcs_stat_flag_hl_op_tgt_track = False adcs_stat_flag_hl_op_tgt_track_const_v = False adcs_stat_flag_hl_op_spin = False adcs_stat_flag_hl_op_sunp = False adcs_stat_flag_hl_op_detumbling = False adcs_stat_flag_hl_op_measure = False adcs_stat_flag_datetime_valid = False adcs_stat_flag_hl_op_safe = False adcs_stat_flag_hl_op_idle = False up_time = 104017 last_fram_log_fun_err_code = 0 last_fram_log_line_code = 381 last_fram_log_file_crc_code = 1366333782 last_fram_log_counter = 64 average_photon_count = 0 sat_mode = 0 tc_sequence_count = 10768
When implementing the telemetry parser, I've encountered a few small pitfalls with the documentation. The first is that the primary header seems to be 6 byte long, rather than 8 bytes as stated. The beacon data doesn't start immediately after the 6 byte secondary telemetry header. There are 3 bytes of padding between them. This isn't mentioned anywhere in the docs. Finally, I don't know how to decide if the secondary header is for telemetry or for telecommand. This might be mentioned somewhere, so perhaps I need to read the documentation more closely.
As I final remark, it seems that the timestamp in the secondary header was invalid in all the packets of the pass I recorded in my previous post. The interesting thing is that my parser shows 2030-01-01 04:53:40, while the webpage shows 2000-01-02 04:53:40. Note that both agree that the number of days since 2000-01-01 is 10958, so my calculation is actually the correct one.