Adding a Satellite
If a satellite uses a modulation and framing that gr-satellites already supports, adding it only takes a SatYAML file, with no code. This page walks through the whole process: identifying the protocol, writing and testing the file locally, validating it, adding a telemetry parser, and contributing it upstream.
When a SatYAML File Is Enough
Check the satellite's published radio parameters (or a recording) against the supported lists:
- the modulations: FSK, AFSK, BPSK, DBPSK, Manchester variants, subaudio FSK;
- the framings: AX.25, AX100, U482C, CCSDS, AO-40, NGHam, USP, OpenLST, ...
Many CubeSats use standard modems (GOMspace AX100, AX.25 TNCs, CCSDS-based radios), so a new satellite is often only a new combination of existing building blocks. If the framing is new, a new deframer component must be written in Python (see python/components/deframers/ for examples) and registered in gr_satellites_flowgraph._deframer_hooks and in SatYAML.framings in python/satyaml/satyaml.py.
Where SatYAML Files Live
| Location | Path |
|---|---|
| Source tree | python/satyaml/*.yml |
| Installed | the satellites/satyaml/ directory of the installed Python package |
Find the installed directory with:
python3 -c "import satellites.satyaml, os; print(os.path.dirname(satellites.satyaml.__file__))"
Lookups by name and NORAD ID scan every *.yml file in that directory. A file copied there becomes selectable by name immediately; a file anywhere else can always be used by path.
Step 1: Write the File
Start from a bundled satellite with the same radio. For a satellite with a 9k6 FSK AX.25 G3RUH downlink whose telemetry format you do not know yet:
name: MY-SAT
alternative_names:
- MYSAT-1
norad: 99999
data:
&tlm Telemetry:
unknown
transmitters:
9k6 FSK downlink:
frequency: 437.500e+6
modulation: FSK
baudrate: 9600
framing: AX.25 G3RUH
data:
- *tlm
unknown prints every frame in hex, which is what you want until a parser exists. Remember:
noradmust be an integer.- Write the frequency with a signed exponent (
437.500e+6), or YAML reads it as a string. - Transmitter names appear in the output and in frame metadata; use descriptive names like
9k6 FSK downlink. - Add one entry under
transmittersfor each distinct baud rate or mode the satellite uses. They all run in parallel.
See the SatYAML Format reference for every field.
Step 2: Test with a Recording
Run it by path (the name must end in .yml):
gr_satellites ./MY-SAT.yml --wavfile my_sat_pass.wav
If nothing decodes, work through the tuning workflow: real vs IQ input, polarity (--input_gain -1), --clk_bw, and the verbose options of the deframer.
Step 3: Validate
Run the same checks as the project's unit test:
python3 -c "from satellites.satyaml import yamlfiles; yamlfiles.check_yaml('MY-SAT.yml')"
No output means the file passed. A YAMLError names the problem (see Validation for the messages and the checker's blind spots). The checker does not test whether the chosen framing accepts the deframer fields you used (frame size, scrambler, ...). That is only checked when the decoder is built, so the run from step 2 is the real test: a TypeError about an unexpected keyword argument means a field does not belong to that framing. gr_satellites ./MY-SAT.yml --help is a quick check that the file loads and that the options you expect are registered, but it exits before building the decoder.
Step 4: Add a Telemetry Parser
Once you know the frame layout, write a construct definition (see Writing a Telemetry Parser) and point the data entry at it:
data:
&tlm Telemetry:
telemetry: my_sat
If the satellite sends files or images, add a files: or image: entry with a file receiver.
Step 5: Contribute It
gr-satellites aims to support every satellite transmitting in the Amateur bands, so contributions are welcome:
- Add the
.ymlfile topython/satyaml/.python/satyaml/CMakeLists.txtinstalls all*.ymlfiles with a glob, so no CMake change is needed, but re-runcmakein your build directory so the new file is picked up bymake install. - Add any new telemetry parser to
python/telemetry/__init__.pyandpython/telemetry/CMakeLists.txt(and any new file receiver to the corresponding files inpython/filereceiver/). - Run
make test; theqa_satyamltest runscheck_yaml()on every bundled file. - Follow the contributing guidelines (PEP 8 checked by pycodestyle, commit message rules, the LLM usage policy) and open a pull request against
main.
The list of supported satellites in the upstream Sphinx documentation (docs/source/supported_satellites.rst) is generated from the SatYAML files by docs/generate_supported_satellites.py.
Policies to be aware of
- Satellite teams planning to use gr-satellites for their own ground station are encouraged to upstream support for their satellite rather than keep a fork, and to introduce themselves in the GitHub discussions "Satellite teams" category. See satellite_teams.md.
- Commercial satellites: contributions specifically for receiving a commercial satellite are only accepted if the operator endorses or acknowledges them. Generic blocks are always accepted. See commercial_satellites.md.