diff --git a/CMakeLists.txt b/CMakeLists.txt index 98e3492..168a22e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,11 +12,11 @@ project( VERSION 1.0.0 DESCRIPTION "A modern C++ wrapper for SGP4 orbit propagation" HOMEPAGE_URL "https://github.com/gunvirranu/perturb" - LANGUAGES CXX + LANGUAGES C ) option(perturb_DISABLE_IO "Disable I/O and string functionality" OFF) -option(perturb_EXPORT_C_INTERFACE "Provide a C ABI interface" OFF) +option(perturb_ENABLE_CPP_INTERFACE "Expose a small C++ wrapper interface" OFF) # For CMake 3.21+, variable is set by default by project() if(CMAKE_VERSION VERSION_LESS 3.21.0) @@ -56,7 +56,7 @@ endif() add_library( perturb - src/perturb.cpp src/tle.cpp src/sgp4.cpp src/perturb_c.cpp + src/perturb.c ) target_include_directories( @@ -65,14 +65,15 @@ target_include_directories( $ ) -target_compile_features(perturb PUBLIC cxx_std_11) +target_compile_features(perturb PUBLIC c_std_99) +# target_compile_features(perturb PUBLIC cxx_std_11) if(perturb_DISABLE_IO) target_compile_definitions(perturb PUBLIC PERTURB_DISABLE_IO) endif() -if(perturb_EXPORT_C_INTERFACE) - target_compile_definitions(perturb PUBLIC PERTURB_EXPORT_C_INTERFACE) +if(perturb_ENABLE_CPP_INTERFACE) + target_compile_definitions(perturb PUBLIC PERTURB_ENABLE_CPP_INTERFACE) endif() # ---- Install rules ---- diff --git a/CMakePresets.json b/CMakePresets.json index 54f02f4..a09eac0 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -27,7 +27,7 @@ "inherits": "cmake-pedantic", "cacheVariables": { "perturb_DEVELOPER_MODE": "ON", - "perturb_EXPORT_C_INTERFACE": "ON" + "perturb_ENABLE_CPP_INTERFACE": "ON" } }, { @@ -49,8 +49,11 @@ "description": "This preset makes sure perturb actually builds with C++11", "hidden": true, "cacheVariables": { - "CMAKE_CXX_EXTENSIONS": "OFF", + "CMAKE_C_STANDARD": "99", + "CMAKE_C_EXTENSIONS": "OFF", + "CMAKE_C_STANDARD_REQUIRED": "ON", "CMAKE_CXX_STANDARD": "11", + "CMAKE_CXX_EXTENSIONS": "OFF", "CMAKE_CXX_STANDARD_REQUIRED": "ON" } }, @@ -58,6 +61,7 @@ "name": "flags-unix", "hidden": true, "cacheVariables": { + "CMAKE_C_FLAGS": "-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wcast-qual -Wcast-align -Wshadow -Wformat=2 -Wundef -Wdouble-promotion -Wstrict-overflow=5 -Wno-unused-result -Wpointer-arith -Wstrict-prototypes -Wwrite-strings -Wswitch-default -Wswitch-enum -Wunreachable-code", "CMAKE_CXX_FLAGS": "-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wcast-qual -Wcast-align -Wshadow -Wformat=2 -Wformat-overflow -Wformat-truncation -Wundef -Wdouble-promotion -Wstrict-overflow=5 -Wno-maybe-uninitialized -Wno-unused-result" } }, @@ -65,6 +69,7 @@ "name": "flags-windows", "hidden": true, "cacheVariables": { + "CMAKE_C_FLAGS": "/W4 /permissive- /utf-8 /volatile:iso", "CMAKE_CXX_FLAGS": "/W4 /permissive- /utf-8 /volatile:iso /EHsc /Zc:__cplusplus /Zc:throwingNew" } }, diff --git a/include/perturb/perturb.h b/include/perturb/perturb.h index c890b53..3c9b64e 100644 --- a/include/perturb/perturb.h +++ b/include/perturb/perturb.h @@ -6,11 +6,10 @@ * Licensed under the MIT License . * SPDX-License-Identifier: MIT * -* Copyright (c) 2024 Gunvir Ranu +* Copyright (c) 2024 Gunvir Singh Ranu */ -//! @file -//! Exported C interface header for the C++ perturb library +//! @file Primary C header for the perturb library //! @author Gunvir Singh Ranu //! @version 1.0.0 //! @copyright Gunvir Singh Ranu, MIT License @@ -18,79 +17,148 @@ #ifndef PERTURB_PERTURB_H #define PERTURB_PERTURB_H -// Sanity checks on if you're including this header correctly -// `perturb.hpp` is the primary C++ header for this library, perturb. -// This header, `perturb.h`, is intended only for C ABI consumers. -#ifndef PERTURB_EXPORT_C_INTERFACE -# if __cplusplus -# error "Seems like you're using C++. Use the perturb.hpp header." -# else -# error "Seems like you're using C. Enable the PERTURB_EXPORT_C_INTERFACE option." -# endif -#endif -#ifdef PERTURB_EXPORT_C_INTERFACE - #include #include #include -#define PERTURB_TLE_LINE_LEN 69U +// Define `PERTURB_SGP4_ENABLE_DEBUG` to enable Vallado's verification mode. +// Generally, this is unwanted. Only enabled for tests. +#if (defined(PERTURB_SGP4_ENABLE_DEBUG) && defined(PERTURB_DISABLE_IO)) +# error "Cannot enable SGP4 debug without I/O functionality" +#endif + +#ifdef __cplusplus +extern "C" { // Support header inclusion from C++ -// Support header inclusion from C++ -#if __cplusplus -extern "C" { +# ifdef PERTURB_ENABLE_CPP_INTERFACE +namespace perturb { +/// Namespace to shove C interface into to not pollute globals +namespace c_internal { +# endif +#endif // __cplusplus + +#if !(defined(__cplusplus) && defined(PERTURB_ENABLE_CPP_INTERFACE)) +/// Both lines of a TLE **must** be this length, for TLE constructors. +/// +/// It is assumed that this memory can be safely accessed. +/// Lines can be longer for verification mode, but that's for internal testing +/// purposes only and doesn't pertain to general usage. +/// Macro definition is excluded in C++ cases to not pollute globals. +# define PERTURB_TLE_LINE_LEN 69U #endif -typedef double perturb_real_t; +/// Alias to allow possibility of supporting 32-bit and 64-bit floating point +typedef double perturb_real_t; // TODO: Support float32_t and float64_t extern const size_t PERTURB_C_SATELLITE_ALLOC_SIZE; extern const size_t PERTURB_C_TLE_ALLOC_SIZE; -struct perturb_satellite { - void * p_satellite; -}; - -struct perturb_tle { - void * p_tle; +/// A basic and human readable representation of a point in time. +/// +/// The primary purpose of this type is to be constructed manually via +/// aggregate initialization and the converted to a `JulianDate`. +/// +/// @warning +/// This type doesn't enforce a valid date and time upon construction; there +/// are no checks. Additionally, the conversion to `JulianDate` values are only +/// valid from years 1900 to 2100. +/// +/// The question of what this time point represents gets complicated. In the +/// "Revisiting Spacetrack Report #3" paper from Celestrak, it is discussed +/// what this time represents. While UTC would make sense, the method +/// `perturb::sgp4::gstime_SGP4` requires UT1 time to calculate GMST. This +/// library makes the same assumption that the paper concludes: +/// +/// @par +/// "The error associated with approximating UT1 with UTC is within the +/// theoretical uncertainty of the SGP4 theory itself. Except for the GMST +/// calculation, this paper and code assumes time to be realized as UTC." +struct perturb_date_time { + uint16_t year; ///< [year] from 1900 to 2100 + uint8_t month; ///< [month] from 1 to 12 + uint8_t day; ///< [day] from 1 to {28, 29, 30, 31} (depending on month) + uint8_t hour; ///< [hour] from 0 to 23 + uint8_t min; ///< [minute] from 0 to 59 + perturb_real_t sec; ///< Fractional [sec] from 0.0 to 59.999... }; +/// Represents a specific point in time on the Julian calendar. +/// +/// Generally not constructed manually, but instead converted from a `DateTime` +/// or from `Satellite::epoch`. Supports some basic manipulation operations. +/// For a human readable representation, can be converted back to `DateTime`. +/// As for what time point this represents, see the comment on `DateTime`. +/// +/// Internally, this is represented as the "theoretical" sum of two double +/// precision floats. This is to preserve as much time accuracy as possible, +/// since many bits are lost due to storing the number of the day. The smaller +/// value is used to represent a more accurate time offset from that day. The +/// "normalized" value restricts the larger value to entire days and the +/// smaller to a [0.0, 1.0) time offset. struct perturb_julian_date { - perturb_real_t jd; - perturb_real_t jd_frac; + perturb_real_t jd; /// Fractional # of [day] since the epoch (4713 B.C.) + perturb_real_t jd_frac; /// Smaller fractional number of [day], *usually* between 0 and 1 }; +/// Represents the output prediction from SGP4. +/// +/// Generated by `Satellite::propagate` method. The vectors are represented in +/// the TEME (True Equator Mean Equinox) reference frame. Can be converted to +/// classical orbital elements with the `ClassicalOrbitalElements` type. struct perturb_state_vector { - struct perturb_julian_date epoch; - perturb_real_t position[3]; - perturb_real_t velocity[3]; + struct perturb_julian_date epoch; /// Time-stamp of the state vector + perturb_real_t position[3]; /// Position in the TEME frame in [km] + perturb_real_t velocity[3]; /// Velocity in the TEME frame in [km/s] }; -struct perturb_julian_date perturb_datetime_to_julian( - uint8_t year, - uint8_t month, - uint8_t day, - uint8_t hour, - uint8_t min, - perturb_real_t sec -); +/// Classical Keplerian orbital elements. +/// +/// Names and values are from the underlying SGP4 implementation. Can be +/// generated from a `StateVector` via the constructor. +struct perturb_classical_orbital_elements { + perturb_real_t semilatus_rectum; ///< Samilatus rectum in [km] + perturb_real_t semimajor_axis; ///< Semimajor axis in [km] + perturb_real_t eccentricity; ///< Eccentricity (unitless) + perturb_real_t inclination; ///< Inlination in [rad] + perturb_real_t raan; ///< Right ascension of ascending node in [rad] + perturb_real_t arg_of_perigee; ///< Argument of perigee in [rad] + perturb_real_t true_anomaly; ///< True anomaly in [rad] + perturb_real_t mean_anomaly; ///< Mean anomaly in [rad] + perturb_real_t arg_of_latitude; ///< Argument of latitude in [rad] + perturb_real_t true_longitude; ///< True longitude in [rad] + perturb_real_t longitude_of_periapsis; ///< Longitude of periapsis in [rad] +}; + +struct perturb_satellite; // Forward declare, defined in `sgp4.h` +struct perturb_tle; // Forward declare, defined in `tle.h` + +struct perturb_julian_date perturb_datetime_to_julian(struct perturb_date_time t); struct perturb_julian_date perturb_add_days_to_julian( - struct perturb_julian_date t, - perturb_real_t days + struct perturb_julian_date t, perturb_real_t days ); struct perturb_julian_date perturb_epoch(struct perturb_satellite sat); bool perturb_init_sat_from_tle(struct perturb_satellite sat, struct perturb_tle tle); -bool perturb_parse_tle(char * line_1, char * line_2, struct perturb_tle tle); -bool perturb_parse_tle_and_init_sat(char * line_1, char * line_2, struct perturb_satellite sat); +bool perturb_parse_tle(char *line_1, char *line_2, struct perturb_tle tle); +bool perturb_parse_tle_and_init_sat( + char *line_1, char *line_2, struct perturb_satellite sat +); -struct perturb_state_vector perturb_propagate_days(struct perturb_satellite sat, perturb_real_t days); -struct perturb_state_vector perturb_propagate(struct perturb_satellite sat, struct perturb_julian_date t); +struct perturb_state_vector perturb_propagate_days( + struct perturb_satellite sat, perturb_real_t days +); +struct perturb_state_vector perturb_propagate( + struct perturb_satellite sat, struct perturb_julian_date t +); -#if __cplusplus -} +#ifdef __cplusplus +# ifdef PERTURB_ENABLE_CPP_INTERFACE +} // namespace c_internal +} // namespace perturb +# endif +} // extern "C" #endif -#endif // PERTURB_EXPORT_C_INTERFACE #endif // PERTURB_PERTURB_H diff --git a/include/perturb/perturb.hpp b/include/perturb/perturb.hpp index 4c45553..11cd3c9 100644 --- a/include/perturb/perturb.hpp +++ b/include/perturb/perturb.hpp @@ -9,8 +9,7 @@ * Copyright (c) 2022 Gunvir Ranu */ -//! @file -//! Primary header file for the perturb library +//! @file Primary C++ header for the perturb library //! @author Gunvir Ranu //! @version 1.0.0 //! @copyright Gunvir Ranu, MIT License @@ -18,122 +17,59 @@ #ifndef PERTURB_PERTURB_HPP #define PERTURB_PERTURB_HPP -#include "perturb/sgp4.hpp" -#include "perturb/tle.hpp" +#ifndef __cplusplus +# error "This header is intended for C++, use for C" +#endif + +#ifndef PERTURB_ENABLE_CPP_INTERFACE +# error "Set the PERTURB_ENABLE_CPP_INTERFACE feature flag to support the C++ interface" +#endif + +#include "perturb/perturb.h" #include +#include #ifndef PERTURB_DISABLE_IO # include #endif -/// Primary namespace for the perturb library, everything is in here. +/// Primary namespace for the perturb C++ library wrapper, everything is in here. /// /// See README for a brief intro to the main library types and basic usage. +/// The C library interface is hidden in the `perturb::c_internal` namespace. namespace perturb { -/// Alias for representing position and velocity vectors -using Vec3 = std::array; +/// Alias for general floating-point type (may be 32-bit or 64-bit) +using real_t = c_internal::perturb_real_t; -/// Possible issues during SGP4 propagation or even TLE parsing. -/// -/// This is important in two places: -/// 1. After construction of a `Satellite`, check `Satellite::last_error` -/// for any issues with TLE parsing or SGP4 initialization. -/// 2. Calling `Satellite::propagate` returns a `perturb::Sgp4Error`, -/// indicating any possible issues with propagation. -/// -/// If everything is all good, the value should be `Sgp4Error::NONE`. -/// The errors `Sgp4Error::MEAN_ELEMENTS` to `SGP4Error::DECAYED` directly -/// correlate to errors in the underlying SGP4 impl, from the comments of -/// `perturb::sgp4::sgp4`. The additional `Sgp4Error::INVALID_TLE` is for issues -/// with reading the TLE strings. -enum class Sgp4Error : int { - NONE = 0, - MEAN_ELEMENTS, - MEAN_MOTION, - PERT_ELEMENTS, - SEMI_LATUS_RECTUM, - EPOCH_ELEMENTS_SUB_ORBITAL, - DECAYED, - INVALID_TLE, // Not from base impl, added in - UNKNOWN -}; +/// Alias for representing 3D position and velocity vectors in [km] +using Vec3 = std::array; -/// Choice of gravity model / constants for the underlying SGP4 impl. +/// Both lines of a TLE **must** be this length, for TLE constructors. /// -/// Corresponds to the `gravconsttype` type in `perturb::sgp4`. -/// Generally, WGS72 is the standard choice, despite WGS84 being the newer and -/// more accurate model. What is most important is that this is the exact same -/// as the gravity model used to generate the TLE ephemeris. This can be -/// confirmed from the source of your TLE data. -enum class GravModel { - WGS72_OLD, - WGS72, - WGS84 -}; +/// It is assumed that this memory can be safely accessed. +/// Lines can be longer for verification mode, but that's for internal testing +/// purposes only and doesn't pertain to general usage. +constexpr std::size_t TLE_LINE_LEN = 69; -/// A basic and human readable representation of a point in time. -/// -/// The primary purpose of this type is to be constructed manually via -/// aggregate initialization and the converted to a `JulianDate`. -/// -/// @warning -/// This type doesn't enforce a valid date and time upon construction; there -/// are no checks. Additionally, the conversion to `JulianDate` values are only -/// valid from years 1900 to 2100. -/// -/// The question of what this time point represents gets complicated. In the -/// "Revisiting Spacetrack Report #3" paper from Celestrak, it is discussed -/// what this time represents. While UTC would make sense, the method -/// `perturb::sgp4::gstime_SGP4` requires UT1 time to calculate GMST. This -/// library makes the same assumption that the paper concludes: -/// -/// @par -/// "The error associated with approximating UT1 with UTC is within the -/// theoretical uncertainty of the SGP4 theory itself. Except for the GMST -/// calculation, this paper and code assumes time to be realized as UTC." struct DateTime { - int year; ///< Year from 1900 to 2100 - int month; ///< Month from 1 to 12 - int day; ///< Day from 1 to {28, 29, 30, 31} (depending on month) - int hour; ///< Hour from 0 to 23 - int min; ///< Minute from 0 to 59 - double sec; ///< Fractional seconds from 0.0 to 59.999... + c_internal::perturb_date_time internal; /// Internal C data }; -/// Represents a specific point in time on the Julian calendar. -/// -/// Generally not constructed manually, but instead converted from a `DateTime` -/// or from `Satellite::epoch`. Supports some basic manipulation operations. -/// For a human readable representation, can be converted back to `DateTime`. -/// As for what time point this represents, see the comment on `DateTime`. -/// -/// Internally, this is represented as the "theoretical" sum of two double -/// precision floats. This is to preserve as much time accuracy as possible, -/// since many bits are lost due to storing the number of the day. The smaller -/// value is used to represent a more accurate time offset from that day. The -/// "normalized" value restricts the larger value to entire days and the -/// smaller to a [0.0, 1.0) time offset. struct JulianDate { - /// Fractional number of days since the epoch (4713 B.C.) - double jd; - /// Smaller fractional number of days - double jd_frac; + c_internal::perturb_julian_date internal; /// Internal C data - /// Construct an empty julian date initialized to 0 - JulianDate(); - - /// Construct from a Julian number of days since epoch (4713 B.C.) - explicit JulianDate(double jd); + /// Construct from a Julian number of days since epoch + explicit JulianDate(real_t jd); /// Construct from a Julian day number and fractional day. /// /// The "true" Julian date value is the sum of the two. The motivation for /// separating into two parts is to preserve floating-point precision. /// - /// @param jd Larger Julian day value since epoch - /// @param jd_frac Smaller fractional Julian day value - explicit JulianDate(double jd, double jd_frac); + /// @param jd Larger Julian [day] value since epoch + /// @param jd_frac Smaller fractional Julian [day] value + explicit JulianDate(real_t jd, real_t jd_frac); /// Construct from a `DateTime` time point. /// @@ -148,19 +84,15 @@ struct JulianDate { /// @return Same time point converted to a human readable representation DateTime to_datetime() const; - /// Normalizes a Julian date representation to a canonical representation. + /// Get a normalized / canonical julian date representation /// - /// Modifies the two julian day values to restrict the larger value to whole - /// days and the smaller value to a [0.0, 1.0) time offset. This is *not* - /// needed for the conversions as they will automatically normalize, but - /// you may want to do this for other reasons. - void normalize(); - - /// Get a normalized copy of a julian date + /// Larger value is restricted to a whole number of days and the smaller + /// value to a [0.0, 1.0) time offset. This is *not* generally needed for + /// conversions; they will automatically normalize. JulianDate normalized() const; /// Returns the difference/delta in times as a fractional number of days - double operator-(const JulianDate &rhs) const; + real_t operator-(const JulianDate &rhs) const; /// Returns another time point offset by a number of days. /// @@ -170,15 +102,15 @@ struct JulianDate { /// accordingly, but I defaulted to the former method for performance. If /// you think this wasn't the right move, lemme know. /// - /// @param delta_jd Number of fractional days to add + /// @param delta_jd Number of fractional [day] to add /// @return Sum of a time point and offset, *not* normalized - JulianDate operator+(const double &delta_jd) const; + JulianDate operator+(const real_t &delta_jd) const; /// Add a delta number of days offset to this time point - JulianDate &operator+=(const double &delta_jd); + JulianDate &operator+=(const real_t &delta_jd); /// Returns another time point offset backwards by a number of days - JulianDate operator-(const double &delta_jd) const; + JulianDate operator-(const real_t &delta_jd) const; /// Subtracts a delta number of days offset to this time point - JulianDate &operator-=(const double &delta_jd); + JulianDate &operator-=(const real_t &delta_jd); /// Compare if chronologically earlier than another time point bool operator<(const JulianDate &rhs) const; @@ -190,63 +122,28 @@ struct JulianDate { bool operator>=(const JulianDate &rhs) const; }; -/// Represents the output prediction from SGP4. -/// -/// Generated by `Satellite::propagate` method. The vectors are represented in -/// the TEME (True Equator Mean Equinox) reference frame. Can be converted to -/// classical orbital elements with the `ClassicalOrbitalElements` type. struct StateVector { - /// Time-stamp of the state vector - JulianDate epoch; - /// Position in the TEME frame in [km] - Vec3 position; - /// Velocity in the TEME frame in [km/s] - Vec3 velocity; + c_internal::perturb_state_vector internal; /// Internal C data }; -/// Classical Keplerian orbital elements. -/// -/// Names and values are from the underlying SGP4 implementation. Can be -/// generated from a `StateVector` via the constructor. struct ClassicalOrbitalElements { - double semilatus_rectum; ///< Samilatus rectum in [km] - double semimajor_axis; ///< Semimajor axis in [km] - double eccentricity; ///< Eccentricity (unitless) - double inclination; ///< Inlination in [rad] - double raan; ///< Right ascension of ascending node in [rad] - double arg_of_perigee; ///< Argument of perigee in [rad] - double true_anomaly; ///< True anomaly in [rad] - double mean_anomaly; ///< Mean anomaly in [rad] - double arg_of_latitude; ///< Argument of latitude in [rad] - double true_longitude; ///< True longitude in [rad] - double longitude_of_periapsis; ///< Longitude of periapsis in [rad] + c_internal::perturb_classical_orbital_elements internal; /// Internal C data /// Construct from a `StateVector` position and velocity in TEME. /// /// @param sv A position-velocity state vector generated via SGP4 - /// @param grav_model Gravity model used in SGP4 (default `GravModel::WGS72`) - explicit ClassicalOrbitalElements( - StateVector sv, GravModel grav_model = GravModel::WGS72 - ); + /// TODO: param grav_model Gravity model used in SGP4 (default `GravModel::WGS72`) + explicit ClassicalOrbitalElements(StateVector sv); }; -/// Represents a specific orbital ephemeris for an Earth-centered trajectory. -/// -/// This is the primary type in this library. Wraps the internal SGP4 record -/// type `perturb::sgp4::elsetrec`. Generally constructed via TLEs through -/// `Satellite::from_tle` constructors. Of particular importance is the -/// `Satellite::last_error` method which you can check to determine if there -/// were any issues with TLE initialization or propagation. The primary method -/// of running the SGP4 algorithm is the `Satellite::propagate` method. class Satellite { public: - /// Internal SGP4 type - sgp4::elsetrec sat_rec; + c_internal::perturb_satellite internal; /// Internal C data /// Construct from a raw SGP4 orbital record. /// - /// @param sat_rec Pre-initialized SGP4 orbital record - explicit Satellite(sgp4::elsetrec sat_rec); + /// @param sat Pre-initialized SGP4 orbital record + explicit Satellite(c_internal::perturb_satellite sat); /// Construct and initialize from a pre-parsed TLE record. /// @@ -266,7 +163,7 @@ class Satellite { /// @pre The TLE must be valid and contain valid values. /// /// @param tle Parsed and valid TLE - /// @param grav_model Gravity constants to use (default `GravModel::WGS72`) + /// TODO: param grav_model Gravity constants to use (default `GravModel::WGS72`) explicit Satellite( const TwoLineElement &tle, GravModel grav_model = GravModel::WGS72 ); diff --git a/include/perturb/sgp4.hpp b/include/perturb/sgp4.hpp deleted file mode 100644 index 175c3d8..0000000 --- a/include/perturb/sgp4.hpp +++ /dev/null @@ -1,262 +0,0 @@ -#ifndef PERTURB_SGP4_HPP -#define PERTURB_SGP4_HPP -// clang-format off -/* ---------------------------------------------------------------- -* -* SGP4.h -* -* this file contains the sgp4 procedures for analytical propagation -* of a satellite. the code was originally released in the 1980 and 1986 -* spacetrack papers. a detailed discussion of the theory and history -* may be found in the 2006 aiaa paper by vallado, crawford, hujsak, -* and kelso. -* -* current : -* 12 mar 20 david vallado -* chg satnum to string for alpha 5 or 9-digit -* changes : -* 7 dec 15 david vallado -* fix jd, jdfrac -* 3 nov 14 david vallado -* update to msvs2013 c++ -* 30 Dec 11 david vallado -* consolidate updated code version -* 30 Aug 10 david vallado -* delete unused variables in initl -* replace pow inetger 2, 3 with multiplies for speed -* 3 Nov 08 david vallado -* put returns in for error codes -* 29 sep 08 david vallado -* fix atime for faster operation in dspace -* add operationmode for afspc (a) or improved (i) -* performance mode -* 20 apr 07 david vallado -* misc fixes for constants -* 11 aug 06 david vallado -* chg lyddane choice back to strn3, constants, misc doc -* 15 dec 05 david vallado -* misc fixes -* 26 jul 05 david vallado -* fixes for paper -* note that each fix is preceded by a -* comment with "sgp4fix" and an explanation of -* what was changed -* 10 aug 04 david vallado -* 2nd printing baseline working -* 14 may 01 david vallado -* 2nd edition baseline -* 80 norad -* original baseline -* ---------------------------------------------------------------- */ - -//! @file -//! Header for the internal SGP4 impl from Vallado -//! @author David Vallado -//! @author Gunvir Ranu -//! @version SGP4 Version 2020-07-13 -//! @date 2022-07-13 - -// Define `PERTURB_SGP4_ENABLE_DEBUG` to enable Vallado's verification mode. -// Generally, this is unwanted. Only enabled for tests. -#if (defined(PERTURB_SGP4_ENABLE_DEBUG) && defined(PERTURB_DISABLE_IO)) -#error "Cannot enable SGP4 debug without I/O functionality" -#endif - -// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers -// NOLINTBEGIN(readability-avoid-const-params-in-decls) - -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define PERTURB_SGP4_SGP4Version "SGP4 Version 2020-07-13" - -namespace perturb { - -/// An internal namespace containing the underlying SGP4 implementation. -/// -/// If you need some deeper functionality, feel free to dig into this. However, -/// the whole goal of this library is to avoid the need to do that. If you find -/// yourself needing some functionality that perturb's interface doesn't offer, -/// please open an issue as others may have similar thoughts / needs. -namespace sgp4 { - -// -------------------------- structure declarations ---------------------------- -typedef enum // NOLINT(modernize-use-using) -{ - wgs72old, - wgs72, - wgs84 -} gravconsttype; - -typedef struct elsetrec // NOLINT(modernize-use-using,altera-struct-pack-align) -{ - char satnum[6]; - int epochyr, epochtynumrev; - int error; - char operationmode; - char init, method; - - /* Near Earth */ - int isimp; - double aycof , con41 , cc1 , cc4 , cc5 , d2 , d3 , d4 , - delmo , eta , argpdot, omgcof , sinmao , t , t2cof, t3cof , - t4cof , t5cof , x1mth2 , x7thm1 , mdot , nodedot, xlcof , xmcof , - nodecf; - - /* Deep Space */ - int irez; - double d2201 , d2211 , d3210 , d3222 , d4410 , d4422 , d5220 , d5232 , - d5421 , d5433 , dedt , del1 , del2 , del3 , didt , dmdt , - dnodt , domdt , e3 , ee2 , peo , pgho , pho , pinco , - plo , se2 , se3 , sgh2 , sgh3 , sgh4 , sh2 , sh3 , - si2 , si3 , sl2 , sl3 , sl4 , gsto , xfact , xgh2 , - xgh3 , xgh4 , xh2 , xh3 , xi2 , xi3 , xl2 , xl3 , - xl4 , xlamo , zmol , zmos , atime , xli , xni; - - double a, altp, alta, epochdays, jdsatepoch, jdsatepochF, nddot, ndot, - bstar, rcse, inclo, nodeo, ecco, argpo, mo, no_kozai; - // sgp4fix add new variables from tle - char classification, intldesg[11]; - int ephtype; - long elnum , revnum; - // sgp4fix add unkozai'd variable - double no_unkozai; - // sgp4fix add singly averaged variables - double am , em , im , Om , om , mm , nm; - // sgp4fix add constant parameters to eliminate mutliple calls during execution - double tumin, mus, radiusearthkm, xke, j2, j3, j4, j3oj2; - - // Additional elements to capture relevant TLE and object information: - long dia_mm; // RSO dia in mm - double period_sec; // Period in seconds - unsigned char active; // "Active S/C" flag (0=n, 1=y) - unsigned char not_orbital; // "Orbiting S/C" flag (0=n, 1=y) - double rcs_m2; // "RCS (m^2)" storage - -} elsetrec; - - -// namespace SGP4Funcs -// { - - // public class SGP4Class - // { - - bool sgp4init - ( - gravconsttype whichconst, char opsmode, const char satn[5], const double epoch, - const double xbstar, const double xndot, const double xnddot, const double xecco, const double xargpo, - const double xinclo, const double xmo, const double xno, - const double xnodeo, elsetrec& satrec - ); - - bool sgp4 - ( - // no longer need gravconsttype whichconst, all data contained in satrec - elsetrec& satrec, double tsince, - double r[3], double v[3] - ); - - void getgravconst - ( - gravconsttype whichconst, - double& tumin, - double& mus, - double& radiusearthkm, - double& xke, - double& j2, - double& j3, - double& j4, - double& j3oj2 - ); - -#ifndef PERTURB_DISABLE_IO - // older sgp4io methods - void twoline2rv - ( - char longstr1[130], char longstr2[130], - char typerun, char typeinput, char opsmode, - gravconsttype whichconst, - double& startmfe, double& stopmfe, double& deltamin, - elsetrec& satrec - ); -#endif // PERTURB_DISABLE_IO - - // older sgp4ext methods - double gstime_SGP4 - ( - double jdut1 - ); - - double sgn_SGP4 - ( - double x - ); - - double mag_SGP4 - ( - double x[3] - ); - - void cross_SGP4 - ( - double vec1[3], double vec2[3], double outvec[3] - ); - - double dot_SGP4 - ( - double x[3], double y[3] - ); - - double angle_SGP4 - ( - double vec1[3], - double vec2[3] - ); - - void newtonnu_SGP4 - ( - double ecc, double nu, - double& e0, double& m - ); - - double asinh_SGP4 - ( - double xval - ); - - void rv2coe_SGP4 - ( - double r[3], double v[3], double mus, - double& p, double& a, double& ecc, double& incl, double& omega, double& argp, - double& nu, double& m, double& arglat, double& truelon, double& lonper - ); - - void jday_SGP4 - ( - int year, int mon, int day, int hr, int minute, double sec, - double& jd, double& jdFrac - ); - - void days2mdhms_SGP4 - ( - int year, double days, - int& mon, int& day, int& hr, int& minute, double& sec - ); - - void invjday_SGP4 - ( - double jd, double jdFrac, - int& year, int& mon, int& day, - int& hr, int& minute, double& sec - ); - - -// } // namespace - -} // namespace sgp4 -} // namespace perturb - -// NOLINTEND(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers -// NOLINTEND(readability-avoid-const-params-in-decls) -// clang-format on - -#endif // PERTURB_SGP4_HPP diff --git a/include/perturb/tle.hpp b/include/perturb/tle.hpp index 784bc27..2b5a33b 100644 --- a/include/perturb/tle.hpp +++ b/include/perturb/tle.hpp @@ -25,13 +25,6 @@ namespace perturb { -/// Both lines of a TLE **must** be this length, for TLE constructors. -/// -/// The memory can and is accessed. -/// Lines can be longer for verification mode, but that's for internal testing -/// purposes only and doesn't pertain to general usage. -constexpr std::size_t TLE_LINE_LEN = 69; - /// Possible errors when parsing a TLE. /// /// Returned by `TwoLineElement::parse` after processing a TLE record string. diff --git a/src/perturb_c.cpp b/src/perturb.c similarity index 52% rename from src/perturb_c.cpp rename to src/perturb.c index 44b8b4a..c4d3233 100644 --- a/src/perturb_c.cpp +++ b/src/perturb.c @@ -10,17 +10,7 @@ */ #include "perturb/perturb.h" -#include "perturb/perturb.hpp" -#ifdef PERTURB_EXPORT_C_INTERFACE - -using namespace perturb; - -extern "C" { - -const size_t PERTURB_C_SATELLITE_ALLOC_SIZE = sizeof(Satellite); -const size_t PERTURB_C_TLE_ALLOC_SIZE = sizeof(TwoLineElement); - -} - -#endif // PERTURB_EXPORT_C_INTERFACE +#ifdef __cplusplus +# error "Okay someone messed up haha" +#endif