For an overview of Quetzal-1, read our profile!
Thanks to the support of the international radio amateur community, and SatNOGS, more than 75,000 telemetry packets were obtained for Quetzal-1, throughout its 211 days of operation from April to November 2020. We have aggregated this data (along with all the pictures 🖼️ sent by the first Guatemalan satellite!) in the quetzal1-telemetry repository.
We will keep this repository as it was when the satellite was operational, for future reference for any and all other CubeSat teams or individuals that may be interested. For further information on our satellite's end of operations, see here.
We are indebted to you, the community.
- With ❤️, the Quetzal-1 CubeSat Team.
Repository | Description |
---|---|
quetzal1-hardware | Contains the hardware design files for Quetzal-1 and its subsystems. |
quetzal1-flight-software | Contains the software for Quetzal-1 and its subsystems. |
quetzal1-telemetry | Contains the telemetry and photos transmitted by Quetzal-1 while in orbit. |
gr-quetzal1 | This repository. |
This repository contains the UHF specifications of Quetzal-1, the GNURadio decoder for the satellite and a Python application for data visualization. We also show a method of installing GNURadio 3.7 on Ubuntu 16.04 LTS, which is the software on which this code was tested.
- Directory Description
- Help us track Quetzal-1!
- Downlink Decoder and Parser
- Transmitter
- Python Scripts for Data Visualization
- GNURadio 3.7 Installation
- How should you cite this repository?
The following files are included in this repository:
- apps: Contains the following software related to the Ground Control Station (GCS):
- apps/desktop: Contains the Python application for data visualization.
- apps/receiver: Contains the GNURadio 3.7 code for the receiver (decoder for both telemetry beacons and images).
- apps/transmitter: Contains the GNURadio 3.7 code for the transmitter (used to command the satellite while in-orbit).
- docs: Contains a spreadsheet detailing the structure for telemetry and image beacons.
- examples: Contains examples produced by the receiver scripts.
- media: Contains miscellaneous images that are used or referenced throughout this repository.
- recordings: Contains
.wav
recordings of telemetry and image beacons that may serve as an example to test the receiver scripts. - TLE: Contains the original TLE for the satellite, when deployed from the ISS.
Thanks to the people at SatNOGS, radio amateurs, Space-Track and Celestrak, Quetzal-1 has beed identified as NORAD ID #45598. Check out the SatNOGS post here. Also, the TLE is currently available in Celestrak here.
Quetzal-1 was deployed from the Kibo module onboard the International Space Station on April 28, 2020 at 15:20 UTC. About 30 minutes after ejection, it began antenna deployment and beacon transmission. For downlink, Quetzal-1 uses a GOMSpace AX100 transceiver, which transmits GMSK-modulated data at 4800 bps at 437.200 MHz (as coordinated by IARU).
Beacons are encapsulated in AX.25 + HDLC frames, with G3RUH scrambling and NRZI encoding. The following image shows the overall beacon format:
The spacecraft’s beacon is sent with a 10 second period. The spreadsheet in docs/Beacon_Package_Data.xlsx
details both the AX.25 + HDLC structure and the beacon data format.
Although it is always sent, we do not use the AX.25 portion of the packet. However, for the sake of being explicit, the data contained in the AX.25 section is always the following (in hexadecimal):
40 40 40 40 40 40 60 40 40 40 40 40 40 61 03 F0
Image packets have the same encapsulation as telemetry packets (beacons). The following image shows the overall format:
gr-satellites was used in this project to develop an AX.25 + HDLC decoder for data at 4800 bps. The flowgraph in apps/ax25_decode.grc
can be opened via gnuradio-companion
.
For reference, the flowgraph is shown below. The Telemetry Forwarder
was used to send decoded beacons to SatNOGS servers for live viewing, and the ZMQ PUB Sink
can be used for Live Beacon Parsing.
The live decoding feature works with GQRX and a compatible SDR. Locally, we use HackRF, but any SDR should work. In order to decode frames from the satellite, GQRX must first demodulate the incoming frames and then pass on this data into ax25_decode.grc
via UDP.
In the GQRX main GUI, several things must be configured:
- In the Input Controls tab:
- Ensure the DC Remove checkbox is checked.
- Adjust RF, IF and BB gains according to your needs. Common values that usually work on HackRF, depending on the noise around the antenna and the strength of the satellite signal are shown below. However, playing around with these values to find the optimal combination of gains is recommended.
- RF: 0 dB, IF: 16 dB, BB: 20 to 32 dB
- RF: 0 dB, IF: 24 dB, BB: 20 to 24 dB
- RF: 14 dB, IF: 16 dB, BB: 20 to 24 dB
- RF: 14 dB, IF: 8 dB, BB: 20 to 32 dB
- In the Receiver Options tab:
- The satellite sends GMSK-modulated data. To demodulate such satellite signals, select Narrow FM as the demodulation mode.
- The filter width can be left to Normal, as this usually gives enough bandwidth for the 4800 bps frames from Quetzal-1.
- In the FFT Settings tab:
- Set the FFT size to 32768. This usually makes the spectrum cleaner.
- You can adjust the zoom on the FFT display to fit your needs.
- Make sure port 7355 is configured for UDP. To do so, click on the ... button next to Rec and select the Network tab. Then configure:
- UDP Host: localhost
- UDP Port: 7355
Once you've correctly configured this (and making sure you're correctly tracking the downlink frequency for the satellite), connect GQRX with the decoder by clicking on the UDP button on the bottom right of the GQRX GUI. Run the decoder and, if all is correct, you should start to see decoded frames printed into the terminal.
These decoded frames are automatically saved into the /home/user/Received Data
directory. The decoder saves both the parsed and raw data under the names raw_beacon_X.dat
and parsed_beacon_X.txt
, where X
is the current datetime of your system.
ℹ️ NOTE
.dat
files can be opened with a Hex editor, such as Bless Hex Editor.
Doppler frequency correction can be achieved by connecting GPredict with GQRX. Guides on how to do this are readily available online, some examples here and here.
Frames can also be decoded once the satellite has passed, assuming you've saved a .wav
file of the demodulated beacons. To record a pass, click on the Rec button next to UDP in the bottom right of GQRX. Then, go into the decoder and comment out the UDP source and Short To Float blocks. Afterwards, uncomment the WAV File Source and Throttle blocks, select the .wav
file that you've recorded and run the flowgraph. Any correctly demodulated data should be decoded, parsed and saved into your home directory.
We have provided a realistic recording of a satellite beacon in example_beacon_quetzal1.wav. If you decode this, you should obtain files equal to those shown in example_beacon_parsed.txt and example_beacon_raw.dat.
We've also added a recording of an actual satellite pass over Guatemala, obtained on April 28 at 18:26 UTC.
A recording of a picture taken and transmitted by our satellite while in our lab is provided in example_image_quetzal1.wav. If you decode this, you should obtain files equal to those in example_image.dat and example_image_metadata.txt, saved into a directory called Received Data/
within your home directory (see write_photo.py for more information on the default directory).
The .dat
file contains the image. To view it in Windows, change the file extension to .jpg
(the converted example image is available here).
The transmitter code was also developed in GNURadio. Just like downlinks, commands are G3RUH-scrambled and NRZI-encoded, but frames are only encapsulated in HDLC, without the AX.25 header.
To the user, the transmitter shows a Python QT GUI developed within GNURadio Companion. A barebones version of this same GUI was developed to simplify the commanding process when taking and downloading photos from the satellite.
The flowgraph is shown below. Each block is commented to explain its purpose. The Generate Command
block contains an embedded Python block, which defines and generates each command.
Credit: Aldo Aguilar
ℹ️ NOTE
As of commit 15ff8d9
, this GUI could only graph data "post-mortem". However, starting from commit 6565bdc
, the GUI can also show live beacons coming from the GNURadio decoder.
A GUI was developed in python3
to visualize beacon data. For the program to run correctly, please make sure you've installed PyQt5
, pyqtgraph
0.10.0 and zmq
. To do so, run:
python3 -m pip install PyQt5
python3 -m pip install pyqtgraph==0.10.0
python3 -m pip install zmq
Once this is done, you can run the script by going into the apps/desktop/
directory, opening a terminal and running:
python3 -m main.py
Upon opening the GUI, you can select a beacon to visualize by clicking on Select Hex and navigating to one of the decoded .dat
files (for example, choose the file in examples/example_beacon_raw.dat
). Once selected, the GUI will automatically start displaying beacons one second at a time (although you can change this by executing the program with the --interval [value in ms]
flag. More information available on python3 main.py --help
). You can also scan through the beacons by clicking on the fast-foward and rewind buttons.
Alicja Musial has developed a Python tool to automatically download decoded data from SatNOGS. Visit her repository for instructions on how to do this. Once the data has been downloaded, it can automatically be put into the Python GUI for visualization.
You can now view decoded data live by clicking on Connect to port, typing localhost
as the IP address and 1502
as the port to connnect to. Once this is done, you can test it out by running the GNURadio decoder with the example beacon recording (examples/example_beacon_quetzal1.wav
). Upon doing this, decoded frames will start to appear in the GUI. When tracking Quetzal-1, you can use this feature to view live data.
Click me
This installation process was written and tested in 2020. It is possible that it may no longer work in its entirety.
The decoder was developed for GNURadio 3.7. We show below a process for installing this GNURadio version and other necessary modules in Ubuntu 16.04 LTS. We mainly use PyBOMBS to install GNURadio.
All the necessary dependencies can be installed by a single command, shown below. More info on this here.
sudo apt-get -y install git-core cmake g++ python-dev swig \
pkg-config libfftw3-dev libboost-all-dev libcppunit-dev libgsl0-dev \
libusb-dev libsdl1.2-dev python-wxgtk3.0 python-numpy \
python-cheetah python-lxml doxygen libxi-dev python-sip \
libqt4-opengl-dev libqwt-dev libfontconfig1-dev libxrender-dev \
python-sip python-sip-dev python-qt4 python-sphinx libusb-1.0-0-dev \
libcomedi-dev libzmq-dev
There are some Python modules necessary for gr-satellites, mainly construct
and requests
. To install, first install and update pip on Python 2.7.
sudo apt-get install python-pip
python2 -m pip install --upgrade pip
Then, install the aforementioned Python modules:
python2 -m pip install construct[extras]
python2 -m pip install requests
PyBOMBS lets us install GNURadio easily (as well as any OOT modules we might want in the future). Install PyBOMBS through pip by running:
python2 -m pip install pybombs
If it hasn't been created yet, create the prefix in which all GNURadio related files will be installed:
mkdir prefix/
Then, install the necessary recipe files by running:
pybombs recipes add gr-recipes git+https://github.com/gnuradio/gr-recipes.git
pybombs recipes add gr-etcetera https://github.com/gnuradio/gr-etcetera.git
Finally, install GNURadio 3.7 with the following command. Note that if typing gnuradio-default
instead of gnuradio-stable
in the command, Pybombs will install GNURadio 3.8. For this guide, we do not want this.
pybombs prefix init -a default prefix/default/ -R gnuradio-stable
As of 2020, the master branch for gr-satellites has been updated to GNURadio 3.8. We must select GNURadio 3.7 for our installation. To do this, navigate to the recipe file, located in ~/.pybombs/recipes/gr-recipes/
. Search for the file gr-satellites.lwr
and open it. Change the gitbranch parameter from master
to maint-3.7
. Save the file and run the commands below.
cd prefix/default
source ./setup_env.sh
pybombs install gr-satellites
cd src/gr-satellites/
chmod +x ./compile_hierarchical.sh
./compile_hierarchical.sh
Once this is all done, you may open the GUI for GNURadio by running:
cd prefix/default
source ./setup_env.sh
gnuradio-companion
-
There was a compatibility issue in the maint-3.7 branch of gr-satellites with construct v2.10 (see this link for more details). This issue was fixed in the v1.8.3 release of the maint-3.7 branch, so now construct v2.10 should work fine. If it happens again, maybe just roll back to construct v2.9 via the following commands:
python2 -m pip uninstall construct[extras] python2 -m pip install construct[extras]==2.9.52
-
When installing PyBOMBS with pip in Python 2.7, we may get an error message saying that
setuptools
requires Python>=3.5. If this happens, roll back to a version of setuptools compatible with Python2, by running:python2 -m pip uninstall setuptools python2 -m pip install setuptools
When running this, we rolled back from setuptools v46.X.X to v20.X.X and then the Pybombs installation went fine.
-
Ubuntu 16.04 LTS only normally updates
cmake
until version 3.5. If ever you are requested to have a newer version ofcmake
, you can do so by following these steps:sudo apt remove --purge --auto-remove cmake wget -qO - https://apt.kitware.com/keys/kitware-archive-latest.asc | sudo apt-key add - sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ xenial main' sudo apt-get update sudo apt-get install cmake
You can then check your
cmake
version by running:cmake --version
This was taken from Liu Hao Cheng's answer in this Stackoverflow thread.
You may cite this repository as shown below. Further information is available in the CITATION.cff file.
Quetzal-1 CubeSat Team. (2022). gr-quetzal1 [Computer software]. https://github.com/danalvarez/gr-quetzal1