SatTrack is a command-line utility for tracking satellites and predicting when they will be visible from a given location. It's targeted mainly at the amateur radio and amateur satellite communities.
It has the following features:
- Download TLE data from the Internet
- Display orbital elements for one or more satellites
- Calculate the position of a satellite at a given time
- Calculate look angles (azimuth/elevation/range) for antenna pointing
- Check if a satellite is currently visible from your location
- Real-time satellite tracking with configurable update interval
- Predict upcoming satellite passes
Install dependencies:
sudo apt install build-essential cmake libcurl4-openssl-dev libcurlpp-dev libspdlog-dev libfmt-dev libgtest-devBuild the application:
mkdir build
cd build
cmake ..
make
make testFor a fully static build that runs on embedded ARM systems with older libraries:
Install the musl cross-compiler:
cd /opt
sudo wget https://musl.cc/arm-linux-musleabihf-cross.tgz
sudo tar xzf arm-linux-musleabihf-cross.tgz
sudo rm arm-linux-musleabihf-cross.tgzAdd the compiler to your PATH (add to ~/.bashrc for persistence):
export PATH="/opt/arm-linux-musleabihf-cross/bin:$PATH"Build the ARM sysroot (one-time):
This builds static versions of zlib, OpenSSL, curl, and curlpp for ARM:
TOOLCHAIN_PREFIX=arm-linux-musleabihf SYSROOT=~/arm-sysroot-musl ./scripts/build-arm-sysroot.shBuild for ARM:
mkdir build-arm && cd build-arm
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/arm-linux-musleabihf.cmake -DCMAKE_BUILD_TYPE=Release
makeStrip the binary (optional, reduces size from ~17MB to ~5MB):
arm-linux-musleabihf-strip sattrackThe resulting binary is fully static with no runtime dependencies and will run on any armv7l Linux system regardless of the installed libc version.
SatTrack is a command-line application built using C++20. I wrote it largely as an opportunity to better familiarize myself with the features of C++11, C++14, C++17, and C++20 since I originally learned C++ back in the late 90s.
I used Claude Code to help speed up my implementation of SatTrack by helping me maintain my build scripts, write test cases, update documentation, and perform research on calculations and C++20 features that I wasn't familiar with, but most of the actual code was written by me.
Although I wrote the initial Keplerian propagation code by hand and learned a lot from doing so, when I decided to move to SGP4/SDP4 to improve pass prediction accuracy I had Claude port the SGP4/SDP4 reference implementation published by Celestrak rather than writing it myself. I didn't use an off-the-shelf library because I wanted tighter integration with my other code and with the C++20 standard library.
SatTrack uses CelesTrak as its primary source for TLE data. CelesTrak is a non-profit service that provides satellite information for free. If you feel so inclined, they take donations to help cover their costs.
All configuration options can be provided on the command line, but you can also create a config file to store common options, like the list of satellites you care about. The config file is stored in TOML format and the options available are the same as the command line options. The config file is located at ~/.sattrack.toml by default, but you can also supply a path to the config file using the --config command line option.
Here is an example config file:
# Station Location
lat = 35.58
long = 139.48
alt = 30
info.id = 25544
tle.id = 25544The most common usage pattern looks like this:
# First update our TLE in case it is out of date
$ sattrack update
Loading TLE database from file: /home/andrew/.sattrack.tle
Loading TLE database... done.
Loaded 13526 TLE entries.
Downloading TLE data for group: active... Done.
Saving TLE database to file: /home/andrew/.sattrack.tle
Saving TLE database... done.
Saved 13526 TLE entries.
# Show upcomming passes
$ sattrack passes 25544
Passes for ISS (ZARYA):
Upcoming Passes:
Satellite Start End Duration Starts In Start Az End Az Max Az Max Elev
------------------------- ------------------------- ------------------------- -------------- ------------------ ------------ ------------ ------------ ----------
25544 ISS (ZARYA) 2025-12-03 00:02:09 UTC 2025-12-03 00:06:01 UTC 3m 52s 0h 17m 9s 162.51 SSE 92.23 E 127.40 SE 14.56
25544 ISS (ZARYA) 2025-12-03 01:37:18 UTC 2025-12-03 01:43:52 UTC 6m 33s 1h 52m 18s 245.78 WSW 37.47 NE 322.04 NW 47.48
25544 ISS (ZARYA) 2025-12-03 03:17:46 UTC 2025-12-03 03:18:20 UTC 0m 33s 3h 32m 46s 334.48 NNW 343.97 NNW 339.22 NNW 10.08
25544 ISS (ZARYA) 2025-12-03 08:08:50 UTC 2025-12-03 08:15:20 UTC 6m 30s 8h 23m 50s 323.54 NW 112.49 ESE 37.93 NE 44.74
25544 ISS (ZARYA) 2025-12-03 09:46:33 UTC 2025-12-03 09:50:39 UTC 4m 5s 10h 1m 33s 269.94 W 194.63 SSW 232.24 SW 15.25
25544 ISS (ZARYA) 2025-12-04 00:49:48 UTC 2025-12-04 00:56:25 UTC 6m 37s 25h 4m 48s 213.26 SSW 56.44 ENE 135.35 SE 55.23 SatTrack provides the following commands:
Downloads TLE data from Celestrak and stores it locally. You can specify which satellite groups to download.
# Update with the default "active" group
sattrack update
# Update specific groups
sattrack update amateur visualDisplays orbital elements for satellites from the local TLE database.
sattrack info 25544Displays the raw Two-Line Element set data from the local TLE database.
sattrack tle 25544Calculates the geodetic location (latitude, longitude, altitude) of a satellite at a given time.
sattrack geo 25544 --time "2025-12-01 12:00:00"Calculates the look angles (azimuth, elevation, range) for antenna pointing. Uses TLE data from the local database.
Options:
--time <time>- Time at which to get look angles (format: YYYY-MM-DD HH:MM:SS UTC, default: now)
sattrack --lat 35.58 --long 139.48 look 25544
sattrack --lat 35.58 --long 139.48 look 25544 --time "2025-12-01 12:00:00"Checks if a satellite is currently visible (above the minimum elevation threshold) from your location.
Options:
--elev <n>- Minimum elevation above the horizon in degrees (default 10)--time <time>- Time at which to check visibility (format: YYYY-MM-DD HH:MM:SS UTC, default: now)
sattrack --lat 35.58 --long 139.48 visible 25544
sattrack --lat 35.58 --long 139.48 visible 25544 --elev 5Provides real-time tracking output with configurable update interval and duration.
Options:
--interval <n>- Update interval in seconds (default 1)--duration <n>- Duration to track in seconds (default 60)
sattrack --lat 35.58 --long 139.48 track 25544
sattrack --lat 35.58 --long 139.48 track 25544 --interval 5 --duration 300Predicts upcoming satellite passes using local TLE data. This command calculates passes locally without requiring an API key.
Options:
--days <n>- Number of days to search for passes (default 1)--elev <n>- Filters out passes whose maximum elevation is below this value, in degrees (default 10)--horizon <n>- Passes start and end when the satellite crosses this elevation, in degrees (default 0)
sattrack --lat 35.58 --long 139.48 passes 25544
sattrack --lat 35.58 --long 139.48 passes 25544 --days 2 --elev 20
sattrack --lat 35.58 --long 139.48 passes 25544 --horizon 10 # useful for antenna tracking--config <path>- Path to configuration file (default: ~/.sattrack.toml)--lat <lat>- Latitude of ground station in decimal degrees--long <long>- Longitude of ground station in decimal degrees--alt <alt>- Altitude above sea level in meters-v, --verbose- Display debugging information
There was no need for me to reinvent the wheel, so I used existing libraries wherever it made sense to do so.
SatTrack depends on these libraries:
- CMake is used for the build system.
- RapidJSON is used to parse JSON.
- curlpp wraps libcurl in a C++ interface for making HTTPS requests.
- CLI11 for command-line argument parsing.
- spdlog for fast, header-only logging.
- fmt for modern C++ string formatting (required by spdlog).
- Asio for cross-platform async I/O, signals, timers, and serial ports (standalone, non-Boost version).
- Google Test for unit testing (only needed for running tests).
SatTrack also depends on Howard Hinnant's date library to support C++20 date/time functions that are not yet well supported by most compilers.
Here is the copyright statement for the date library:
// The MIT License (MIT)
//
// Copyright (c) 2015, 2016, 2017 Howard Hinnant
// Copyright (c) 2016 Adrian Colomitchi
// Copyright (c) 2017 Florian Dang
// Copyright (c) 2017 Paul Thompson
// Copyright (c) 2018, 2019 Tomasz Kamiński
// Copyright (c) 2019 Jiangang ZhuangMIT License
Copyright 2025, Andrew C. Young andrew@vaelen.org
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.