SatYAML Format

SatYAML files describe satellites to gr-satellites. Each file says how the satellite is named, which transmitters it has, how each one is modulated and framed, and what to do with the decoded data. The gr_satellites tool and the Satellite decoder block read these files to assemble a decoder automatically. This page is the complete reference for the format, including the fields the code reads that the upstream documentation does not mention, and how files are validated.

A First Example

AU03.yml, a satellite with one AFSK transmitter and a telemetry parser:

name: AU03
alternative_names:
  - QB50 AU03
  - i-INSPIRE II
norad: 42731
data:
  &tlm Telemetry:
    telemetry: au03
transmitters:
  4k8 AFSK downlink:
    frequency: 436.330e+6
    modulation: AFSK
    baudrate: 4800
    af_carrier: 3600
    deviation: -1200
    framing: U482C
    data:
    - *tlm

Read it as: "AU03 (also called QB50 AU03 or i-INSPIRE II, NORAD 42731) has one data type, Telemetry, parsed with the au03 telemetry definition. It has one transmitter, 4k8 AFSK downlink: 4800 baud AFSK on a 3600 Hz audio carrier with ±1200 Hz tones, using the GOMspace U482C framing. Its frames go to Telemetry."

Structure

name, alternative_names, norad, telemetry_servers   ← identity
data:          { <data name>: <data sink spec> }    ← what to do with frames
transports:    { <transport name>: <transport spec> }  (optional)
transmitters:  { <transmitter name>: <transmitter spec> }

YAML Anchors

The &name / *name syntax is standard YAML. &tlm Telemetry: attaches the anchor tlm to the key Telemetry, and - *tlm later inserts that same string. So these two are equivalent:

    data:
    - *tlm
    data:
    - Telemetry

Anchors simply avoid typing the name twice. Whatever you use, the transmitter's data (and transports) list must contain keys that exist in the data (and transports) section.

Top-Level Fields

Field Required Type Meaning
name Yes string Main name, used to select the satellite and in --list_satellites.
alternative_names No list of strings (or empty) Other names that select the satellite. An empty value is allowed.
norad Yes integer NORAD catalog number. Used to select the satellite, for sat.cfg, and sent to telemetry servers.
telemetry_servers No list of strings Extra telemetry servers (SatNOGS is always used).
data Yes mapping Data sinks. See below.
transports No mapping Higher-layer protocols. See below.
transmitters Yes mapping Transmitters. See below.

Valid telemetry_servers entries:

Entry Server
FUNcube FUNcube Warehouse
PWSat PW-Sat2 ground station
BME BME telemetry server (only NORAD 44830, 44832, 47964)
BMEWS BME WebSocket server
HIT <port> Harbin Institute of Technology proxy on 127.0.0.1:<port>
SIDS <url> Any SIDS server at <url>

The value after HIT or SIDS is separated by a single space. See Telemetry Submission.

The data Section

Each entry has a name (any string; it appears only in the SatYAML file) and a specification of the data sink to create:

Specification Data sink Example
telemetry: <definition> Telemetry parser using satellites.telemetry.<definition> telemetry: funcube
files: <receiver> File receiver using satellites.filereceiver.<receiver> files: smogp
image: <receiver> Image receiver (file receiver plus feh display) image: by70_1
decoder: <datasink> A custom data sink class from satellites.components.datasinks decoder: codec2_udp_sink
unknown (a bare value, not a mapping) Hex dump of each frame &tlm Telemetry: unknown

Example with several data entries:

data:
  &tlm Telemetry:
    telemetry: by70_1
  &image Image:
    image: by70_1
  &codec2 Codec2:
    decoder: codec2_udp_sink

Notes from the code:

  • The key for file reception is files (plural). The upstream documentation calls it file, but a file: entry is not recognized and silently becomes a hex dump sink.
  • The checks are done in the order decoder, telemetry, files, image; anything else becomes a hex dump.
  • A decoder class is first constructed with options=...; if it does not accept that argument it is constructed with no arguments.
  • With --hexdump, telemetry and unknown entries are not created at all.
  • Telemetry definitions and receivers are looked up by attribute name in the satellites.telemetry and satellites.filereceiver packages, so they must be imported in those packages' __init__.py (see Writing a Telemetry Parser).

Transmitters

A transmitter is one combination of frequency, modulation and coding. Each one gets its own demodulator and deframer, and all of them run in parallel on the same input.

transmitters:
  1k2 FSK downlink:
    frequency: 437.300e+6
    modulation: FSK
    baudrate: 1200
    framing: AX100 ASM+Golay
    data:
    - *tlm
    - *image

Common fields

Field Required Type Meaning
(key) Yes string Transmitter name. Printed by the telemetry parser (-> Packet from <name>) and stored as the transmitter key in each frame's metadata.
frequency Yes number (Hz) Downlink frequency. Informational: shown by --list_satellites, not used for decoding.
modulation Yes string Demodulator to use. See Modulations.
baudrate Yes number Symbol rate in baud (before Manchester coding).
framing Yes string Deframer to use. See Framings.
data One of data/transports list Data entries that receive this transmitter's frames directly.
transports One of data/transports list Transports that receive this transmitter's frames.
additional_data No mapping Extra deframer output ports mapped to data entries (see below).

Note: Write frequencies the way the bundled files do, with a decimal point and a signed exponent (437.300e+6) or as a plain integer (437300000). PyYAML follows YAML 1.1, where 437.3e6 (no sign in the exponent) and 437e6 are read as strings. A string frequency makes --list_satellites fail and is rejected by the checker.

Demodulator fields

Field Used by Meaning
af_carrier AFSK (required) Audio frequency in Hz at the centre of the two tones.
deviation AFSK (required), FSK (optional) Tone offset from the centre in Hz. Negative means the low tone is symbol 1. Overrides --deviation.
fm_deviation AFSK (optional) FM deviation in Hz, used to size the IQ input filter. Overrides --fm-deviation (default 3000).

Deframer fields

These fields are passed to the deframer as keyword arguments. Only use them with framings that accept them; otherwise building the decoder fails with a Python TypeError about an unexpected keyword argument.

Field Accepted by Values Default
frame size CCSDS framings, GEOSCAN, the RA framings Bytes after FEC decoding. For RA framings only 126, 128 or 256 are valid. CCSDS 223, GEOSCAN 66, RA required
precoding CCSDS framings differential none
RS basis CCSDS Reed-Solomon, CCSDS Concatenated (required); CCSDS Uncoded conventional, dual dual (constructor)
RS interleaving CCSDS framings integer 1
scrambler CCSDS framings, AX100 ASM+Golay CCSDS, none CCSDS
convolutional CCSDS Concatenated CCSDS, NASA-DSN, CCSDS uninverted, NASA-DSN uninverted CCSDS
callsign Mobitex family callsign string none

For example, BY70-1:

  9k6 BPSK downlink:
    frequency: 436.200e+6
    modulation: BPSK
    baudrate: 9600
    framing: CCSDS Concatenated
    precoding: differential
    RS basis: conventional
    frame size: 114
    transports:
    - *kiss

Differential precoding resolves the 180° phase ambiguity of BPSK. The CCSDS standard specifies the dual basis for Reed-Solomon, but many satellites use the conventional basis.

additional_data

Some deframers have more than one output port. additional_data maps an extra port name to a data entry. LilacSat-1 sends Codec2 voice on the deframer's codec2 port:

    additional_data:
      codec2: *codec2

Frames from additional ports are tagged with the transmitter name like regular frames, but go only to the named data entry, not to KISS output, ZMQ or submission.

Transports

Transports sit between the deframer and the data sinks, for protocols that carry packets inside frames. KS-1Q, for example, sends a KISS stream with a 3-byte header in each frame:

name: KS-1Q
norad: 41847
data:
  &tlm Telemetry:
    telemetry: csp
transports:
  &kiss KISS:
    protocol: KISS KS-1Q
    data:
    - *tlm
transmitters:
  20k FSK downlink:
    frequency: 436.500e+6
    modulation: FSK
    baudrate: 20000
    framing: CCSDS Concatenated
    RS basis: dual
    frame size: 223
    transports:
    - *kiss
Field Required Meaning
(key) Yes Transport name (documentation only).
protocol Yes One of the transport protocols.
data Yes Data entries that receive the transport's output packets.
virtual_channels For TM KISS and TM short KISS List of integer CCSDS virtual channel IDs to extract.

Note: The upstream KS-1Q example shows framing: CCSDS Concatenated dual, which is not a valid framing. The bundled file uses framing: CCSDS Concatenated with RS basis: dual, as above.

Validation

gr_satellites does not validate a SatYAML file before using it. Mistakes show up as Python exceptions while the decoder is built, for example a KeyError with the name of an unknown modulation or framing. A thorough checker exists in satellites.satyaml.yamlfiles.check_yaml() and is run on every bundled file by the qa_satyaml unit test. You can run it on your own file:

python3 -c "from satellites.satyaml import yamlfiles; yamlfiles.check_yaml('my_sat.yml')"

It raises satellites.satyaml.satyaml.YAMLError (whose text is in its message attribute) for problems such as:

Check Message
Unknown top-level key Unknown word <key> in <file>
Missing name, norad, data or transmitters Missing name field in <file> (and similar)
norad not an integer NORAD field does not contain a number in <file>
Unknown telemetry server Unknown telemetry server <server>
Transport without valid protocol Missing protocol field in transport <key> / Unknown protocol field in transport <key>
TM KISS without virtual_channels list of ints virtual_channels field missing in transport <key>
Missing frequency, modulation, baudrate, framing Missing frequency field in <transmitter> in <file> (and similar)
Non-numeric frequency, baudrate, af_carrier, deviation, fm_deviation Frequency field does not contain a float in ... (and similar)
Unknown modulation or framing Unknown modulation in <transmitter> in <file> / Unknown framing in ...
AFSK without af_carrier or deviation Missing af_carrier field for AFSK in ...
CCSDS RS/Concatenated without RS basis, or bad precoding, RS basis, RS interleaving, scrambler, convolutional No RS basis field in ..., Invalid precoding value ..., ...
Transmitter with neither data nor transports No data or transport field in <transmitter> in <file>
Data entry not defined Data entry <name> used in <transmitter> is not defined in data field in <file>
additional_data entry not defined Additional data entry <name> used in ...

Limitations of the checker, visible in the code:

  • References in a transmitter's transports list are not checked against the transports section. The check tests for a key named transport (singular), which never exists. A typo there only fails at runtime with a KeyError.
  • It does not check that deframer fields are accepted by the chosen framing, nor frame size values.
  • The CCSDS Uncoded framing is not subject to the CCSDS field checks.

See Also