From 1ac3e9eb9a73f90a7dbc66e2101cd7cad97c9df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Est=C3=A9vez?= Date: Sat, 20 Mar 2021 10:42:06 +0100 Subject: [PATCH] Add support for SMOG-1 This adds the following changes with respect to SMOG-P: * Longer 48 bit syncword for the RA frames (the AO-40 frames also will have the longer syncword, but gr-satellites detects the distributed syncword) * CRC-16 ARC checking for RA and AO-40 frames * TX signalling frames The telemetry parser is not done yet (cherry picked from commit 1872e70929b6cdd3793b7cf2768b131b4a9c27c8) --- CHANGELOG.md | 1 + docs/source/satyaml.rst | 14 ++ .../satellites_ao40_fec_deframer.block.yml | 8 +- .../satellites_smogp_ra_deframer.block.yml | 11 +- ...llites_smogp_signalling_deframer.block.yml | 11 +- python/check_tt64_crc.py | 13 +- .../components/deframers/ao40_fec_deframer.py | 19 ++- .../components/deframers/smogp_ra_deframer.py | 33 +++- .../deframers/smogp_signalling_deframer.py | 17 +- python/core/gr_satellites_flowgraph.py | 8 + python/satyaml/SMOG-1.yml | 155 ++++++++++++++++++ python/satyaml/satyaml.py | 9 +- python/telemetry/smogp.py | 15 +- 13 files changed, 287 insertions(+), 27 deletions(-) create mode 100644 python/satyaml/SMOG-1.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e59af05..da6a55cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for SPUTNIX satellites: OrbiCraft-Zorkiy, CubeSX-HSE, CubeSX-Sirius-HSE, KSU CubeSat - Support for TAUSAT-1 and TSURU - 2k4 downlink for MEZNSAT +- Support for SMOG-1 ### Fixed - RS basis options swapped in CCSDS Reed-Solomon encoder GRC block diff --git a/docs/source/satyaml.rst b/docs/source/satyaml.rst index 873e915e..be89d973 100644 --- a/docs/source/satyaml.rst +++ b/docs/source/satyaml.rst @@ -130,6 +130,12 @@ The framings allowed in the ``framing`` field are the following: * ``AO-40 FEC short``, AO-40 FEC protocol with short frames, as used by SMOG-P and ATL-1 +* ``AO-40 FEC CRC-16-ARC``, the AO-40 FEC protocol with an CRC-16 ARC, as used by + SMOG-1 + +* ``AO-40 FEC CRC-16-ARC short``, AO-40 FEC protocol with short frames and a + CRC-16 ARC, as used by SMOG-1 + * ``CCSDS Reed-Solomon``, CCSDS Reed-Solomon TM codewords (see :ref:`CCSDS deframers`) * ``CCSDS Concatenated``, CCSDS Concatenated TM codewords (see :ref:`CCSDS deframers`) @@ -186,8 +192,16 @@ The framings allowed in the ``framing`` field are the following: * ``SMOG-P RA``, Repeat-Accumulate FEC as used by SMOG-P and ATL-1 +* ``SMOG-1 RA``, Repeat-Accumulate FEC as used by SMOG-1. The difference with + ``SMOG-P RA`` is a longer 48 bit syncword (instead of 16 bit) and the inclusion + of a CRC-16 ARC to check frame integrity. + * ``SMOG-P Signalling``, custom signalling frames as used by SMOG-P and ATL-1 +* ``SMOG-1 Signalling``, custom signalling frames as used by SMOG-1. The difference + with ``SMOG-P Signalling`` is the addition of a different PRBS to mark transitions + to TX mode. + * ``OPS-SAT``, custom framing used by OPS-SAT, which consists of AX.25 frames with CCSDS Reed-Solomon codewords as payload diff --git a/grc/components/deframers/satellites_ao40_fec_deframer.block.yml b/grc/components/deframers/satellites_ao40_fec_deframer.block.yml index eb98f10d..8cf521c4 100644 --- a/grc/components/deframers/satellites_ao40_fec_deframer.block.yml +++ b/grc/components/deframers/satellites_ao40_fec_deframer.block.yml @@ -12,6 +12,11 @@ parameters: dtype: bool default: 'False' options: ['True', 'False'] +- id: crc + label: Use CRC-16 ARC + dtype: bool + default: 'False' + options: ['True', 'False'] - id: options label: Command line options dtype: string @@ -28,7 +33,7 @@ outputs: templates: imports: import satellites.components.deframers - make: satellites.components.deframers.ao40_fec_deframer(syncword_threshold = ${threshold}, short_frames = ${short_frames}, options=${options}) + make: satellites.components.deframers.ao40_fec_deframer(syncword_threshold = ${threshold}, short_frames = ${short_frames}, crc = ${crc}, options=${options}) documentation: |- Deframes a signal using the AO-40 FEC protocol @@ -42,6 +47,7 @@ documentation: |- Parameters: Syncword threshold: number of bit errors to allow in the detection of the 32 bit syncword Use short frames (SMOG-P): enable usage of short frames, which is a variant employed by SMOG-P and ATL-1 + Use CRC-16 ARC: use CRC-16 ARC (used in SMOG-1) Command line options: options to pass down to the block, following the syntax of the gr_satellites command line tool file_format: 1 diff --git a/grc/components/deframers/satellites_smogp_ra_deframer.block.yml b/grc/components/deframers/satellites_smogp_ra_deframer.block.yml index 80f883f9..2013d940 100644 --- a/grc/components/deframers/satellites_smogp_ra_deframer.block.yml +++ b/grc/components/deframers/satellites_smogp_ra_deframer.block.yml @@ -11,6 +11,12 @@ parameters: label: Syncword threshold dtype: int default: 0 +- id: protocol + label: Protocol + dtype: enum + default: 'False' + options: ['False', 'True'] + option_labels: ['SMOG-P', 'SMOG-1'] - id: options label: Command line options dtype: string @@ -27,10 +33,10 @@ outputs: templates: imports: import satellites.components.deframers - make: satellites.components.deframers.smogp_ra_deframer(frame_size = ${frame_size}, syncword_threshold = ${threshold}, options=${options}) + make: satellites.components.deframers.smogp_ra_deframer(frame_size = ${frame_size}, syncword_threshold = ${threshold}, new_protocol=${protocol}, options=${options}) documentation: |- - Deframes SMOG-P RA FEC frames + Deframes SMOG-P or SMOG-1 RA FEC frames The frames use a Repeat-Accumulate FEC @@ -43,6 +49,7 @@ documentation: |- Parameters: Frame size: size of the decode frame in bytes Syncword threshold: number of bit errors to allow in syncword detection + Protocol: chooses between SMOG-P older protocol and SMOG-1 newer protocol Command line options: options to pass down to the block, following the syntax of the gr_satellites command line tool file_format: 1 diff --git a/grc/components/deframers/satellites_smogp_signalling_deframer.block.yml b/grc/components/deframers/satellites_smogp_signalling_deframer.block.yml index cbff43a5..ad50bc60 100644 --- a/grc/components/deframers/satellites_smogp_signalling_deframer.block.yml +++ b/grc/components/deframers/satellites_smogp_signalling_deframer.block.yml @@ -7,6 +7,12 @@ parameters: label: Syncword threshold dtype: int default: 0 +- id: protocol + label: Protocol + dtype: enum + default: 'False' + options: ['False', 'True'] + option_labels: ['SMOG-P', 'SMOG-1'] - id: options label: Command line options dtype: string @@ -23,10 +29,10 @@ outputs: templates: imports: import satellites.components.deframers - make: satellites.components.deframers.smogp_signalling_deframer(syncword_threshold = ${threshold}, options=${options}) + make: satellites.components.deframers.smogp_signalling_deframer(syncword_threshold = ${threshold}, new_protocol=${protocol}, options=${options}) documentation: |- - Deframes SMOG-P signalling frames + Deframes SMOG-P or SMOG-1 signalling frames Input: A stream of soft symbols containing signalling frames @@ -36,6 +42,7 @@ documentation: |- Parameters: Syncword threshold: number of bit errors to allow in syncword detection + Protocol: chooses between SMOG-P older protocol and SMOG-1 newer protocol Command line options: options to pass down to the block, following the syntax of the gr_satellites command line tool file_format: 1 diff --git a/python/check_tt64_crc.py b/python/check_tt64_crc.py index af830a5b..dfbdff05 100644 --- a/python/check_tt64_crc.py +++ b/python/check_tt64_crc.py @@ -61,13 +61,14 @@ class check_tt64_crc(gr.basic_block): """ docstring for block check_tt64_crc """ - def __init__(self, verbose): + def __init__(self, verbose, packet_len = 48): gr.basic_block.__init__(self, name="check_tt64_crc", in_sig=[], out_sig=[]) self.verbose = verbose + self.packet_len = packet_len self.message_port_register_in(pmt.intern('in')) self.set_msg_handler(pmt.intern('in'), self.handle_msg) @@ -81,14 +82,18 @@ def handle_msg(self, msg_pmt): return packet = bytes(pmt.u8vector_elements(msg)) - if len(packet) < 48: + if self.packet_len is not None: + packet = packet[:self.packet_len] + + if (self.packet_len is not None and len(packet) < self.packet_len) \ + or (self.packet_len is None and len(packet) < 2): if self.verbose: print("Packet too short") return - packet_out = packet[:46] + packet_out = packet[:-2] msg_out = pmt.cons(pmt.PMT_NIL, pmt.init_u8vector(len(packet_out), packet_out)) - if crc16_arc(packet[:48]) == 0: + if crc16_arc(packet) == 0: if self.verbose: print("CRC OK") self.message_port_pub(pmt.intern('ok'), msg_out) diff --git a/python/components/deframers/ao40_fec_deframer.py b/python/components/deframers/ao40_fec_deframer.py index 09015dd6..5f2f617d 100644 --- a/python/components/deframers/ao40_fec_deframer.py +++ b/python/components/deframers/ao40_fec_deframer.py @@ -9,7 +9,8 @@ # from gnuradio import gr, digital, fec, blocks -from ... import distributed_syncframe_soft, matrix_deinterleaver_soft, decode_rs +from ... import distributed_syncframe_soft, matrix_deinterleaver_soft, decode_rs,\ + check_tt64_crc from ...hier.ccsds_descrambler import ccsds_descrambler from ...utils.options_block import options_block @@ -26,9 +27,11 @@ class ao40_fec_deframer(gr.hier_block2, options_block): Args: syncword_threshold: number of bit errors allowed in syncword (int) short_frames: use short frames (used in SMOG-P) (bool) + crc: use CRC-16 ARC (used in SMOG-P) (bool) options: Options from argparse """ - def __init__(self, syncword_threshold = None, short_frames = False, options = None): + def __init__(self, syncword_threshold = None, short_frames = False, + crc = False, options = None): gr.hier_block2.__init__(self, "ao40_fec_deframer", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(0, 0, 0)) @@ -49,12 +52,21 @@ def __init__(self, syncword_threshold = None, short_frames = False, options = No self.scrambler = ccsds_descrambler() self.rs = decode_rs(False, 1 if short_frames else 2) + if crc: + # CRC-16 ARC + self.crc = check_tt64_crc(verbose = self.options.verbose_crc, + packet_len = None) + self.connect(self, self.deframer) self.msg_connect((self.deframer, 'out'), (self.deinterleaver, 'in')) self.msg_connect((self.deinterleaver, 'out'), (self.viterbi_decoder, 'in')) self.msg_connect((self.viterbi_decoder, 'out'), (self.scrambler, 'in')) self.msg_connect((self.scrambler, 'out'), (self.rs, 'in')) - self.msg_connect((self.rs, 'out'), (self, 'out')) + if crc: + self.msg_connect((self.rs, 'out'), (self.crc, 'in')) + self.msg_connect((self.crc, 'ok'), (self, 'out')) + else: + self.msg_connect((self.rs, 'out'), (self, 'out')) _default_sync_threshold = 8 @@ -65,3 +77,4 @@ def add_options(cls, parser): """ parser.add_argument('--syncword_threshold', type = int, default = cls._default_sync_threshold, help = 'Syncword bit errors [default=%(default)r]') parser.add_argument('--verbose_rs', action = 'store_true', help = 'Verbose RS decoder') + parser.add_argument('--verbose_crc', action = 'store_true', help = 'Verbose CRC decoder') diff --git a/python/components/deframers/smogp_ra_deframer.py b/python/components/deframers/smogp_ra_deframer.py index 36258fc1..02b3d2f5 100644 --- a/python/components/deframers/smogp_ra_deframer.py +++ b/python/components/deframers/smogp_ra_deframer.py @@ -9,11 +9,13 @@ # from gnuradio import gr, digital -from ... import decode_ra_code +from ... import decode_ra_code, check_tt64_crc from ...hier.sync_to_pdu_soft import sync_to_pdu_soft from ...utils.options_block import options_block _syncword = '0010110111010100' +_syncword_new = '001011011101010001100011110001010011010110011001' + fec_sizes = {128: 260, 256: 514} class smogp_ra_deframer(gr.hier_block2, options_block): @@ -25,10 +27,12 @@ class smogp_ra_deframer(gr.hier_block2, options_block): Args: frame_size: size of the frame before FEC (int) + new_protocol: enable new protocol used in SMOG-1 (bool) syncword_threshold: number of bit errors allowed in syncword (int) options: Options from argparse """ - def __init__(self, frame_size, syncword_threshold = None, options = None): + def __init__(self, frame_size, new_protocol = False, + syncword_threshold = None, options = None): gr.hier_block2.__init__(self, "smogp_ra_deframer", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(0, 0, 0)) @@ -37,22 +41,37 @@ def __init__(self, frame_size, syncword_threshold = None, options = None): self.message_port_register_hier_out('out') if syncword_threshold is None: - syncword_threshold = self.options.syncword_threshold + syncword_threshold = self.options.ra_syncword_threshold + if syncword_threshold < 0: + syncword_threshold = self._default_sync_threshold_new if new_protocol \ + else self._default_sync_threshold_old + syncword = _syncword_new if new_protocol else _syncword self.deframer = sync_to_pdu_soft(packlen = fec_sizes[frame_size] * 8,\ - sync = _syncword,\ + sync = syncword,\ threshold = syncword_threshold) self.fec = decode_ra_code(frame_size) + if new_protocol: + # CRC-16 ARC + self.crc = check_tt64_crc(verbose = self.options.verbose_crc, + packet_len = None) self.connect(self, self.deframer) self.msg_connect((self.deframer, 'out'), (self.fec, 'in')) - self.msg_connect((self.fec, 'out'), (self, 'out')) + if new_protocol: + self.msg_connect((self.fec, 'out'), (self.crc, 'in')) + self.msg_connect((self.crc, 'ok'), (self, 'out')) + else: + self.msg_connect((self.fec, 'out'), (self, 'out')) - _default_sync_threshold = 0 + _default_sync_threshold = -1 + _default_sync_threshold_old = 0 + _default_sync_threshold_new = 6 @classmethod def add_options(cls, parser): """ Adds SMOG-P RA deframer specific options to the argparse parser """ - parser.add_argument('--syncword_threshold', type = int, default = cls._default_sync_threshold, help = 'Syncword bit errors [default=%(default)r]') + parser.add_argument('--ra_syncword_threshold', type = int, default = cls._default_sync_threshold, help = 'RA syncword bit errors [default=%(default)r]') + parser.add_argument('--verbose_crc', action = 'store_true', help = 'Verbose CRC decoder') diff --git a/python/components/deframers/smogp_signalling_deframer.py b/python/components/deframers/smogp_signalling_deframer.py index 020ec2bf..ea34efeb 100644 --- a/python/components/deframers/smogp_signalling_deframer.py +++ b/python/components/deframers/smogp_signalling_deframer.py @@ -13,6 +13,7 @@ from ...utils.options_block import options_block _syncword = '0010110111010100100101111111110111010011011110110000111100011111' +_syncword_tx = '0010110111010100101000111001111000011010010101010110101111001011' class smogp_signalling_deframer(gr.hier_block2, options_block): """ @@ -22,10 +23,11 @@ class smogp_signalling_deframer(gr.hier_block2, options_block): with signalling frames. Args: + new_protocol: enable new protocol used in SMOG-1 (bool) syncword_threshold: number of bit errors allowed in syncword (int) options: Options from argparse """ - def __init__(self, syncword_threshold = None, options = None): + def __init__(self, new_protocol = False, syncword_threshold = None, options = None): gr.hier_block2.__init__(self, "smogp_signalling_deframer", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(0, 0, 0)) @@ -34,16 +36,23 @@ def __init__(self, syncword_threshold = None, options = None): self.message_port_register_hier_out('out') if syncword_threshold is None: - syncword_threshold = self.options.syncword_threshold + syncword_threshold = self.options.signalling_syncword_threshold self.slicer = digital.binary_slicer_fb() self.deframer = sync_to_pdu_packed(packlen = 64,\ sync = _syncword,\ threshold = syncword_threshold) + if new_protocol: + self.deframer_tx = sync_to_pdu_packed(packlen = 64,\ + sync = _syncword_tx,\ + threshold = syncword_threshold) self.connect(self, self.slicer, self.deframer) self.msg_connect((self.deframer, 'out'), (self, 'out')) - + if new_protocol: + self.connect(self.slicer, self.deframer_tx) + self.msg_connect((self.deframer_tx, 'out'), (self, 'out')) + _default_sync_threshold = 8 @classmethod @@ -51,4 +60,4 @@ def add_options(cls, parser): """ Adds SMOG-P signalling deframer specific options to the argparse parser """ - parser.add_argument('--syncword_threshold', type = int, default = cls._default_sync_threshold, help = 'Syncword bit errors [default=%(default)r]') + parser.add_argument('--signalling_syncword_threshold', type = int, default = cls._default_sync_threshold, help = 'Signalling syncword bit errors [default=%(default)r]') diff --git a/python/core/gr_satellites_flowgraph.py b/python/core/gr_satellites_flowgraph.py index b9063eb5..d062c261 100644 --- a/python/core/gr_satellites_flowgraph.py +++ b/python/core/gr_satellites_flowgraph.py @@ -371,6 +371,11 @@ def add_options(cls, parser, file = None, name = None, norad = None): 'Astrocast FX.25 NRZ' : set_options(deframers.astrocast_fx25_deframer, nrzi = False), 'AO-40 FEC' : deframers.ao40_fec_deframer, 'AO-40 FEC short' : set_options(deframers.ao40_fec_deframer, short_frames = True), + 'AO-40 FEC CRC-16-ARC' : set_options(deframers.ao40_fec_deframer, + crc = True), + 'AO-40 FEC CRC-16-ARC short' : set_options(deframers.ao40_fec_deframer, + short_frames = True, + crc = True), 'AO-40 uncoded' : deframers.ao40_uncoded_deframer, 'TT-64' : deframers.tt64_deframer, 'ESEO' : deframers.eseo_deframer, @@ -388,7 +393,10 @@ def add_options(cls, parser, file = None, name = None, norad = None): 'NGHam' : set_options(deframers.ngham_deframer, decode_rs = True), 'NGHam no Reed Solomon' : set_options(deframers.ngham_deframer, decode_rs = False), 'SMOG-P RA' : deframers.smogp_ra_deframer, + 'SMOG-1 RA' : set_options(deframers.smogp_ra_deframer, new_protocol = True), 'SMOG-P Signalling' : deframers.smogp_signalling_deframer, + 'SMOG-1 Signalling' : set_options(deframers.smogp_signalling_deframer, + new_protocol = True), 'OPS-SAT' : deframers.ops_sat_deframer, 'U482C' : deframers.u482c_deframer, 'UA01' : deframers.ua01_deframer, diff --git a/python/satyaml/SMOG-1.yml b/python/satyaml/SMOG-1.yml new file mode 100644 index 00000000..9f4c0bd1 --- /dev/null +++ b/python/satyaml/SMOG-1.yml @@ -0,0 +1,155 @@ +name: SMOG-1 +norad: 99000 +telemetry_servers: + - BME +data: + &tlm Telemetry: + telemetry: smogp + &signalling Signalling: + telemetry: smogp_signalling + &spectrum Spectrum: + files: smogp +transmitters: + 1k25 FSK long concatenated FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 1250 + framing: AO-40 FEC CRC-16-ARC + data: + - *tlm + - *spectrum + 1k25 FSK short concatenated FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 1250 + framing: AO-40 FEC CRC-16-ARC short + data: + - *tlm + - *spectrum + 1k25 FSK long RA FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 1250 + framing: SMOG-1 RA + frame size: 256 + data: + - *tlm + - *spectrum + 1k25 FSK short RA FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 1250 + framing: SMOG-1 RA + frame size: 128 + data: + - *tlm + - *spectrum + 1k25 FSK signalling: + frequency: 437.345e+6 + modulation: FSK + baudrate: 1250 + framing: SMOG-1 Signalling + data: + - *signalling + 2k5 FSK long concatenated FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 2500 + framing: AO-40 FEC CRC-16-ARC + data: + - *tlm + - *spectrum + 2k5 FSK short concatenated FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 2500 + framing: AO-40 FEC CRC-16-ARC short + data: + - *tlm + - *spectrum + 2k5 FSK long RA FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 2500 + framing: SMOG-1 RA + frame size: 256 + data: + - *tlm + - *spectrum + 2k5 FSK short RA FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 2500 + framing: SMOG-1 RA + frame size: 128 + data: + - *tlm + - *spectrum + 5k FSK long concatenated FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 5000 + framing: AO-40 FEC CRC-16-ARC + data: + - *tlm + - *spectrum + 5k FSK short concatenated FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 5000 + framing: AO-40 FEC CRC-16-ARC short + data: + - *tlm + - *spectrum + 5k FSK long RA FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 5000 + framing: SMOG-1 RA + frame size: 256 + data: + - *tlm + - *spectrum + 5k FSK short RA FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 5000 + framing: SMOG-1 RA + frame size: 128 + data: + - *tlm + - *spectrum + 12k5 FSK long concatenated FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 12500 + framing: AO-40 FEC CRC-16-ARC + data: + - *tlm + - *spectrum + 12k5 FSK short concatenated FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 12500 + framing: AO-40 FEC CRC-16-ARC short + data: + - *tlm + - *spectrum + 12k5 FSK long RA FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 12500 + framing: SMOG-1 RA + frame size: 256 + data: + - *tlm + - *spectrum + 12k5 FSK short RA FEC: + frequency: 437.345e+6 + modulation: FSK + baudrate: 12500 + framing: SMOG-1 RA + frame size: 128 + data: + - *tlm + - *spectrum diff --git a/python/satyaml/satyaml.py b/python/satyaml/satyaml.py index 7c30f44f..e759abe9 100644 --- a/python/satyaml/satyaml.py +++ b/python/satyaml/satyaml.py @@ -28,10 +28,13 @@ def __init__(self, path = _default_path): 'AO-40 FEC', 'AO-40 FEC short', 'AO-40 uncoded', 'TT-64', 'ESEO', 'Lucky-7', 'Reaktor Hello World', 'S-NET', 'Swiatowid', 'NuSat', 'K2SAT', 'CCSDS Reed-Solomon', 'CCSDS Concatenated', - 'LilacSat-1', 'AAUSAT-4', 'NGHam', 'NGHam no Reed Solomon', 'SMOG-P RA', - 'SMOG-P Signalling', 'OPS-SAT', 'U482C', 'UA01', 'SALSAT', + 'LilacSat-1', 'AAUSAT-4', 'NGHam', 'NGHam no Reed Solomon', + 'SMOG-P RA', 'SMOG-1 RA', + 'SMOG-P Signalling', 'SMOG-1 Signalling', + 'OPS-SAT', 'U482C', 'UA01', 'SALSAT', 'Mobitex', 'Mobitex-NX', 'FOSSASAT', 'AISTECHSAT-2', 'AALTO-1', - 'Grizu-263A', 'IDEASSat', 'YUSAT', 'AX5043', 'USP'] + 'Grizu-263A', 'IDEASSat', 'YUSAT', 'AX5043', 'USP', + 'AO-40 FEC CRC-16-ARC', 'AO-40 FEC CRC-16-ARC short'] transports = ['KISS', 'KISS no control byte', 'KISS KS-1Q'] top_level_words = ['name', 'alternative_names', 'norad', 'telemetry_servers', 'data', 'transports', 'transmitters'] diff --git a/python/telemetry/smogp.py b/python/telemetry/smogp.py index b0f17d27..f5a5aab7 100644 --- a/python/telemetry/smogp.py +++ b/python/telemetry/smogp.py @@ -406,6 +406,16 @@ 0x3a, 0xc6, 0x88, 0x90, 0xdb, 0x8c, 0x8c,\ 0x42, 0xf3, 0x51, 0x75, 0x43, 0xa0, 0x83, 0x93], dtype = 'uint8') +signalling_prbs_tx = np.array([0xA3, 0x9E, 0x1A, 0x55, 0x6B, 0xCB, 0x5C, 0x2F, + 0x2A, 0x5C, 0xAD, 0xD5, 0x32, 0xFE, 0x85, 0x1D, + 0xDC, 0xE8, 0xBC, 0xE5, 0x13, 0x7E, 0xBA, 0xBD, + 0x9D, 0x44, 0x31, 0x51, 0x3C, 0x92, 0x26, 0x6C, + 0xF3, 0x68, 0x98, 0xDA, 0xA3, 0xBA, 0x7F, 0x84, + 0x86, 0x32, 0x95, 0xAC, 0x8D, 0x4E, 0x66, 0x8B, + 0x7F, 0x7B, 0xE0, 0x14, 0xE2, 0x3C, 0x49, 0x45, + 0x32, 0xE4, 0x5C, 0x44, 0xF5, 0x6D, 0x2D, 0x0A], + dtype = 'uint8') + downlink_speeds = [500, 1250, 2500, 5000, 12500] codings = ['RX', 'AO-40 short', 'AO-40', 'RA (260, 128)', 'RA (514, 256)'] @@ -418,6 +428,9 @@ def parse(packet): prbs = np.frombuffer(packet[:-6], dtype = 'uint8') ber_prbs = np.sum((np.unpackbits(prbs) ^ np.unpackbits(signalling_prbs[6:])).astype('int')) / (prbs.size * 8) + ber_prbs_tx = np.sum((np.unpackbits(prbs) ^ np.unpackbits(signalling_prbs_tx[6:])).astype('int')) / (prbs.size * 8) + sig_type = 'RX' if ber_prbs < ber_prbs_tx else 'TX' + ber_prbs = min(ber_prbs, ber_prbs_tx) flags = np.unpackbits(np.frombuffer(packet[-6:], dtype = 'uint8')).reshape((-1, 8)) decoded_flags = 1*(np.sum(flags, axis = 1) > 4) @@ -434,4 +447,4 @@ def parse(packet): print(f'Error: invalid coding {decoded_flags[3:]}') return - return f'Signalling packet: BER {ber_prbs:.4f}, rate {downlink_speed} baud, coding {coding}' + return f'Signalling packet: mode {sig_type}, BER {ber_prbs:.4f}, rate {downlink_speed} baud, coding {coding}'