After a long period of development, we are quite proud to announce that we have finally released a stable version of libpredict 2.0.

Libpredict is a C library for TLE-based satellite tracking (see the general introduction in an earlier post for more details). We started development of the library back in 2013, by forking Predict and starting the long haul towards separating the pure satellite prediction code from the user interface, and collecting the functions into a coherent API. In august 2015, we thought libpredict was ready for its first stable release, and released version 1.0.

Later that year, however, we realized that we had defined the numbers extracted from a TLE no less than three different places :-). Our structure fields were not very coherently named. The object associated with the fixed set of satellite parameters was also the same object used for outputting time-varying properties. Lots of fodder for our inner, undiagnosed OCD.

We follow semantic versioning for the library. Our measures to rectify for these issues resulted in backwards-incompatible changes that already required a major version bump from 1.0 to 2.0. And still, it turns out we weren’t finished.

The separation of satellite prediction functions into a separate library was a stepping stone towards multiple, larger goals. At the same time as we created libpredict, we also created Flyby, a more direct fork of the user interface parts of Predict. After having separated the satellite calculation code into libpredict, we wanted to back-substitute the satellite calculations in Flyby by calls to libpredict, while cleaning up the code and then do further development in the directions we wanted. Seeing all parts of libpredict in action in Flyby led us to realize that while some of our design choices were good, others were also not that good, resulting in further changes to the API. Insertion in Flyby also made missing features and bugs more apparent. We therefore decided to wait with the release of libpredict 2.0 until we were satisfied that there were no major change requirements lurking beneath the surface, so that we did not have to rapidly release version 3.0 straight after having released version 2.0.

Stock photo of generic ARK member doing generic programming stuff.

Finally, this year we were more or less satisfied. After almost 2.5 years, we could release version 2.0 of libpredict. This comes at great satisfaction, as we finally actually can recommend the general public to try out the latest stable version, and not the latest development version. We can also make Flyby use version 2.0 of libpredict instead of requiring the latest development version, which should make us able to finally release version 1.0 of Flyby too.

The release of libpredict 2.0 was duly celebrated by consuming Kvikklunsj (a Norwegian imitation of Kit-Kat) and Coca-Cola at ARK. During the release party for version 1.0, we celebrated using Solo (a Norwegian orange soda) and general candy. This was a horrible, nauseatingly sweet experience we’d rather not repeat, which might also serve to explain why it took 2.5 years between version 1.0 and version 2.0.

Rough summary of the changes – for more details, see the list of issues in the 2.0 milestone:

API changes:

  • Separate predict_orbit_t into an input structure (predict_orbital_elements_t) and an output structure (struct predict_position)
  • Replace the multiple occurrences of TLE parameters by a single instance
  • Clean up TLE parameter names and other fields
  • Change from predict_is_geostationary to predict_is_geosynchronous and change the definitions appropriately
  • Return predict_observation in predict_next_aos and predict_next_los
  • Change the arguments for predict_doppler_shift to use a predict_observation instead of a predict_position
  • Input the TLE lines as separate strings instead of an two-element array of strings

New features:

  • Calculate phase and orbit number
  • Calculate satellite visibility status
  • Calculate satellite footprint
  • Calculate GHA, right ascension and declination for the sun and the moon
  • Calculation of max elevation of a pass


  • Add more examples on libpredict usage
  • Upper-casify and/or rename all constants and document them properly according to SGP4 publications

Bug fixes:

  • Set the international designator properly
  • Rectify the sign for the calculated doppler shift
  • Rectify a path error for our pkgconfig file
  • Remove the last global variable within the library, so that libpredict becomes truly threadsafe.

Other changes:

  • Replace all home-grown math functions by calls to functions from math.h.

The release notes and corresponding sources can be found at, and doxygen documentation at Debian packages can be found at Check out the examples and the README file for introduction to how libpredict can be used, or otherwise see this earlier blog post (updated for recent API changes).

We anticipate that we might have to do some more API-incompatible changes in the future and be forced to release libpredict 3.0. In the meantime, we are aiming for a 2.1 release with added features for Venus and Jupiter tracking and improvements to AOS and LOS calculations.