ARK has been developing satellite tracking software based on a fork of predict-g1yyh, which is in turn a patched version of predict. We have long been using predict for TLE-based satellite tracking, but in order to control our radios and antenna rotors, we have also been forced to patch predict with hamlib support. In the end, fueled by annoyances over minor or major bugs often due to a slightly insane codebase, our need for changes outweighted our patience for trying to push patches upstream. We therefore decided to fork into a new software package called flyby.


The goal of flyby has been to improve the original code base of predict, while retaining most of the features and feel of the original application. On the way, we decided that the best way to do this was to split all functionality for satellite calculations into a separate C library, libpredict. This has also enabled us to reuse the pure satellite tracking in other applications in a sensible and easy way.

While some remnants of code dating back to a FORTRAN implementation of SGP4 and SDP4 from the seventies and some associated weirdness are still present under the hood, libpredict defines what we believe is a sensible public API with well-defined data structures for doing satellite calculations and extracting information from TLEs. Among the included features are prediction of both absolute (WGS84) and relative (azimuth, elevation) coordinates, along with other relevant properties for a given TLE at a given time. It can also predict the arrival time (AOS) for a satellite, and the corresponding departure time (LOS), and calculate the doppler shifts throughout a pass. The use of ANSI C makes binary compatibility well-defined. Bindings to other programming languages can also easily be made. Version 1.0 has been released, though flyby currently uses the latest development version planned for release 2.0. This version will be released once we freeze some fluctuating parts of the API. We are also planning to possibly upgrade the internal calculation algorithms to the most recent version of the reference implementation of SGP4, but this will be done in a backwards-compatible way. We have, however, been doing our own cleanups of the C version of the original SGP4/SDP4 code to make it more robust, and the expected improvements in numerical accuracy are probably minor at best.

With libpredict in place, along with numerical tests to check the correctness of its prediction results, we were able to remove a large bulk of code from flyby and replace it with more readable calls to libpredict. Redundant functionality was removed, like the network socket for providing satellite calculations (as this now is available for any application through an inclusion of libpredict), and the TLE-editor, so that you don’t have to destroy your TLEs when accidentally entering the wrong submenu, like shown for the unfortunate user below.
Removing unnecessary code made cleaning up the rest of the application more manageable. We believe we have been able to make the code more robust against accidental errors, race conditions and general weirdness, and made it more readable and easier to add new, advanced features or fix new and old bugs. Some unavoidable insanity still remains, but the larger bulk should hopefully have less insane characteristics.

Most of this, except for the removal of certain features, is generally unnoticable by the end user, however. But we have not only made the code more robust. We have also implemented new features!:-) At first glance on some of the screens, flyby looks very much like predict-g1yyh with a different colour scheme, but it goes deeper than that.

  • Main menu: We have replaced the static main menu with a straight jump to the multitrack view over the current state of all displayed satellites, from where further options can be selected (see screenshot at the start of this post).
  • Multitrack view: We have made it possible to show more satellites than the number of lines available in the terminal :-). Search features and submenus for tracking options are also implemented.
  • The fields in the QTH editor now behave as actual fields, and you don’t have to be afraid of destroying your QTH coordinates when you accidentally enter the editor.
  • Satellites in the TLE database can be disabled/enabled for display, when you have too many TLEs in your TLE database or you are interested in only a few specific satellites.
  • Flyby now follows the XDG base directory standard for its configuration files, TLE files and the transponder database.
  • As a consequence of the above, TLE files are not limited to the single TLE file defined in ~/.predict/predict.tle, but merges all TLE files defined in ~/.local/share/flyby/tles/, /usr/local/share/flyby/tles/ and /usr/share/flyby/tles/. Multiply defined TLEs have a precedence ordering where the user-defined TLEs take precedence over any system-wide TLEs (and/or the most recent TLE). This can be useful for TLE updating and providing defaults, and also makes it easier to compile TLEs from several sources. It is no longer necessary to merge TLE-files manually into a single file. (The ease of adding a lot of TLEs also necessitates the earlier mentioned whitelisting feature :-).)
  • As previously mentioned, flyby supports rotor and rig control through hamlib using rotctld and rigctld in single track mode, which provides an easy way to support a wide range of rigs and rotor controllers.
  • A transponder database editor has been implemented, so that you don’t have to edit its weird format manually anymore.
  • Option parsing is now done using GNU longopts, and the arguments have been revised and (hopefully) better documented in --help.

Formats of all options files and database files are backwards-compatible with the file formats used in predict.

More, minor features will also be added, like improving the whitelisting options for more intuitive ease of use, apply layout improvements and remove the size limit on the number of satellites. Layout-wise, there does not have to be limits on the number of TLEs anymore, whereas original predict was limited to the number of letters in the alphabet due to the shortcuts for selecting TLEs, and also had limitations on the multitrack view.

Finally: Why still use ncurses? Well, why not?:-P While it seems old-fashioned, and sometimes/often is far more horrendous to program than just using a normal GUI toolkit built for the purpose, it is lightweight and doesn’t need the availability of Xorg. This can be nice when running remotely. Some potential for nice visualization of the satellite tracks is lost, but the display can in some ways be made to be as elegant as or more elegant than a normal GUI application. Maneuvering can be more convenient when using only a keyboard and sensible shortcuts, and it’s always handy to just apply CTRL + C to immediately jump out of the program, like for other CLI applications.

We will be publishing a series of blog posts detailing the usage of flyby and libpredict.