Compare commits

...

7 Commits
v1.0 ... master

Author SHA1 Message Date
Will Riley 147b1ae7cf
fix multilib error on emerge (#39)
Fix multilib error.
2024-12-03 12:32:21 +00:00
Daniel Warner 6a448b4850
Misc c++ updates (#30)
* Misc c++ updates

* update trim

Co-authored-by: Dan Warner <info@danrw.com>
2022-11-13 13:22:13 +00:00
Daniel Warner 16f4717840
Create cmake.yml (#29) 2022-11-13 11:59:04 +00:00
Daniel Warner 3db90aae9d
remove travis (#28)
Co-authored-by: Dan Warner <info@danrw.com>
2022-11-13 11:38:21 +00:00
Daniel Warner dd1ced0ce4
pragma once (#27)
Co-authored-by: Dan Warner <info@danrw.com>
2022-11-13 11:33:05 +00:00
srcejon 835e40a5e6
Add DateTime constructor that has a microsecond parameter (#24) 2022-11-13 11:13:43 +00:00
Daniel Warner a43acae9ff
Resolve #19 (#26)
Co-authored-by: Dan Warner <info@danrw.com>
2022-11-13 11:09:27 +00:00
33 changed files with 295 additions and 309 deletions

29
.github/workflows/cmake.yml vendored Normal file
View File

@ -0,0 +1,29 @@
name: CMake
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
env:
BUILD_TYPE: RelWithDebInfo
jobs:
build_matrix:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Test
working-directory: ${{github.workspace}}/build
run: ctest -C ${{env.BUILD_TYPE}}

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build/

View File

@ -1,90 +0,0 @@
sudo: required
dist: trusty
language: cpp
matrix:
include:
# Clang 4.0
- env: COMPILER=clang++-4.0
addons:
apt:
packages:
- clang-4.0
- g++-5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
# Clang 5.0
- env: COMPILER=clang++-5.0
addons:
apt:
packages:
- clang-5.0
- g++-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
# Clang 6.0
- env: COMPILER=clang++-6.0
addons:
apt:
packages:
- clang-6.0
- g++-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-6.0
# Clang 7.0
- env: COMPILER=clang++-7
addons:
apt:
packages:
- clang-7
- g++-7
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-7 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
# GCC 5
- env: COMPILER=g++-5
addons:
apt:
packages: g++-5
sources:
- ubuntu-toolchain-r-test
# GCC 6
- env: COMPILER=g++-6
addons:
apt:
packages: g++-6
sources:
- ubuntu-toolchain-r-test
# GCC 7
- env: COMPILER=g++-7
addons:
apt:
packages: g++-7
sources:
- ubuntu-toolchain-r-test
install:
# Set the ${CXX} variable properly
- export CXX=${COMPILER}
- ${CXX} --version
# Travis machines have 2 cores
- JOBS=2
before_script:
# have CMake generate build files
- cd "${TRAVIS_BUILD_DIR}"
- mkdir build && cd build
- cmake ..
script:
# build
- cmake --build . -- -j${JOBS}

View File

@ -5,7 +5,12 @@ if (POLICY CMP0054)
cmake_policy(SET CMP0054 NEW) cmake_policy(SET CMP0054 NEW)
endif() endif()
set(CMAKE_CXX_STANDARD 11) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "..." FORCE)
endif()
set(CMAKE_INSTALL_LIBDIR "/lib64")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)

View File

@ -1,8 +1,6 @@
SGP4 library SGP4 library
============ ============
[![Build Status](https://travis-ci.org/dnwrnr/sgp4.svg?branch=master)](https://travis-ci.org/dnwrnr/sgp4)
License License
------- -------

View File

@ -38,4 +38,4 @@ set(SRCS
add_library(sgp4 STATIC ${SRCS} ${INCS}) add_library(sgp4 STATIC ${SRCS} ${INCS})
add_library(sgp4s SHARED ${SRCS} ${INCS}) add_library(sgp4s SHARED ${SRCS} ${INCS})
install( TARGETS sgp4s LIBRARY DESTINATION lib ) install( TARGETS sgp4s LIBRARY DESTINATION lib )
install( FILES ${INCS} DESTINATION include/SGP4 ) install( FILES ${INCS} DESTINATION include/libsgp4 )

View File

@ -15,8 +15,7 @@
*/ */
#ifndef COORDGEODETIC_H_ #pragma once
#define COORDGEODETIC_H_
#include "Util.h" #include "Util.h"
@ -24,6 +23,9 @@
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
namespace libsgp4
{
/** /**
* @brief Stores a geodetic location (latitude, longitude, altitude). * @brief Stores a geodetic location (latitude, longitude, altitude).
* *
@ -35,12 +37,7 @@ public:
/** /**
* Default constructor * Default constructor
*/ */
CoordGeodetic() CoordGeodetic() = default;
: latitude(0.0),
longitude(0.0),
altitude(0.0)
{
}
/** /**
* Constructor * Constructor
@ -109,11 +106,11 @@ public:
} }
/** latitude in radians (-PI >= latitude < PI) */ /** latitude in radians (-PI >= latitude < PI) */
double latitude; double latitude{};
/** latitude in radians (-PI/2 >= latitude <= PI/2) */ /** latitude in radians (-PI/2 >= latitude <= PI/2) */
double longitude; double longitude{};
/** altitude in kilometers */ /** altitude in kilometers */
double altitude; double altitude{};
}; };
/** /**
@ -126,4 +123,4 @@ inline std::ostream& operator<<(std::ostream& strm, const CoordGeodetic& g)
return strm << g.ToString(); return strm << g.ToString();
} }
#endif } // namespace libsgp4

View File

@ -15,8 +15,7 @@
*/ */
#ifndef COORDTOPOCENTRIC_H_ #pragma once
#define COORDTOPOCENTRIC_H_
#include "Util.h" #include "Util.h"
@ -24,6 +23,9 @@
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
namespace libsgp4
{
/** /**
* @brief Stores a topocentric location (azimuth, elevation, range and range * @brief Stores a topocentric location (azimuth, elevation, range and range
* rate). * rate).
@ -37,13 +39,7 @@ public:
/** /**
* Default constructor * Default constructor
*/ */
CoordTopocentric() CoordTopocentric() = default;
: azimuth(0.0)
, elevation(0.0)
, range(0.0)
, range_rate(0.0)
{
}
/** /**
* Constructor * Constructor
@ -108,13 +104,13 @@ public:
} }
/** azimuth in radians */ /** azimuth in radians */
double azimuth; double azimuth{};
/** elevations in radians */ /** elevations in radians */
double elevation; double elevation{};
/** range in kilometers */ /** range in kilometers */
double range; double range{};
/** range rate in kilometers per second */ /** range rate in kilometers per second */
double range_rate; double range_rate{};
}; };
@ -123,4 +119,4 @@ inline std::ostream& operator<<(std::ostream& strm, const CoordTopocentric& t)
return strm << t.ToString(); return strm << t.ToString();
} }
#endif } // namespace libsgp4

View File

@ -80,7 +80,7 @@ int main()
std::cout << "F " << dt.Microsecond() << " " << microsecond << std::endl; std::cout << "F " << dt.Microsecond() << " " << microsecond << std::endl;
return 0; return 0;
} }
if (!jd_dmy(dt.Julian() + 0.5, year, month, day)) if (!jd_dmy(dt.Julian() + 0.5, year, month, day))
{ {
std::cout << "julian" << std::endl; std::cout << "julian" << std::endl;
@ -89,7 +89,7 @@ int main()
} }
} }
} }
for (int hour = 1; hour < 24; hour++) for (int hour = 1; hour < 24; hour++)
{ {
std::cout << hour << std::endl; std::cout << hour << std::endl;
@ -127,7 +127,7 @@ int main()
} }
} }
} }
jd_dmy(1721425.5, 0, 0, 0); jd_dmy(1721425.5, 0, 0, 0);
DateTime d1(1000, 1, 1); DateTime d1(1000, 1, 1);
@ -142,7 +142,7 @@ int main()
std::cout << d3.Julian() << std::endl; std::cout << d3.Julian() << std::endl;
std::cout << d4.Julian() << std::endl; std::cout << d4.Julian() << std::endl;
std::cout << d5.Julian() << std::endl; std::cout << d5.Julian() << std::endl;
return 0; return 0;
} }

View File

@ -15,8 +15,7 @@
*/ */
#ifndef DATETIME_H_ #pragma once
#define DATETIME_H_
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
@ -27,6 +26,8 @@
#include "TimeSpan.h" #include "TimeSpan.h"
#include "Util.h" #include "Util.h"
namespace libsgp4
{
namespace namespace
{ {
static int daysInMonth[2][13] = { static int daysInMonth[2][13] = {
@ -60,7 +61,7 @@ public:
* Constructor * Constructor
* @param[in] ticks raw tick value * @param[in] ticks raw tick value
*/ */
DateTime(int64_t ticks) explicit DateTime(int64_t ticks)
: m_encoded(ticks) : m_encoded(ticks)
{ {
} }
@ -111,6 +112,21 @@ public:
* @param[in] second the second * @param[in] second the second
* @param[in] microsecond the microsecond * @param[in] microsecond the microsecond
*/ */
DateTime(int year, int month, int day, int hour, int minute, int second, int microsecond)
{
Initialise(year, month, day, hour, minute, second, microsecond);
}
/**
* Initialise to the given data and time.
* @param[in] year the year
* @param[in] month the month
* @param[in] day the day
* @param[in] hour the hour
* @param[in] minute the minute
* @param[in] second the second
* @param[in] microsecond the microsecond
*/
void Initialise(int year, void Initialise(int year,
int month, int month,
int day, int day,
@ -434,7 +450,7 @@ public:
DateTime AddMicroseconds(const double microseconds) const DateTime AddMicroseconds(const double microseconds) const
{ {
int64_t ticks = static_cast<int64_t>(microseconds * TicksPerMicrosecond); auto ticks = static_cast<int64_t>(microseconds * TicksPerMicrosecond);
return AddTicks(ticks); return AddTicks(ticks);
} }
@ -587,7 +603,7 @@ public:
*/ */
double ToJulian() const double ToJulian() const
{ {
TimeSpan ts = TimeSpan(Ticks()); auto ts = TimeSpan(Ticks());
return ts.TotalDays() + 1721425.5; return ts.TotalDays() + 1721425.5;
} }
@ -649,7 +665,7 @@ public:
} }
private: private:
int64_t m_encoded; int64_t m_encoded{};
}; };
inline std::ostream& operator<<(std::ostream& strm, const DateTime& dt) inline std::ostream& operator<<(std::ostream& strm, const DateTime& dt)
@ -702,4 +718,4 @@ inline bool operator<=(const DateTime& dt1, const DateTime& dt2)
return (dt1.Compare(dt2) <= 0); return (dt1.Compare(dt2) <= 0);
} }
#endif } // namespace libsgp4

View File

@ -15,8 +15,7 @@
*/ */
#ifndef DECAYEDEXCEPTION_H_ #pragma once
#define DECAYEDEXCEPTION_H_
#include "DateTime.h" #include "DateTime.h"
#include "Vector.h" #include "Vector.h"
@ -24,6 +23,9 @@
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
namespace libsgp4
{
/** /**
* @brief The exception that the SGP4 class throws when a satellite decays. * @brief The exception that the SGP4 class throws when a satellite decays.
*/ */
@ -74,4 +76,4 @@ private:
Vector _vel; Vector _vel;
}; };
#endif } // namespace libsgp4

View File

@ -20,6 +20,9 @@
#include "Globals.h" #include "Globals.h"
#include "Util.h" #include "Util.h"
namespace libsgp4
{
/** /**
* Converts a DateTime and Geodetic position to Eci coordinates * Converts a DateTime and Geodetic position to Eci coordinates
* @param[in] dt the date * @param[in] dt the date
@ -82,7 +85,7 @@ CoordGeodetic Eci::ToGeodetic() const
const double r = sqrt((m_position.x * m_position.x) const double r = sqrt((m_position.x * m_position.x)
+ (m_position.y * m_position.y)); + (m_position.y * m_position.y));
static const double e2 = kF * (2.0 - kF); static const double e2 = kF * (2.0 - kF);
double lat = Util::AcTan(m_position.z, r); double lat = Util::AcTan(m_position.z, r);
@ -104,3 +107,5 @@ CoordGeodetic Eci::ToGeodetic() const
return CoordGeodetic(lat, lon, alt, true); return CoordGeodetic(lat, lon, alt, true);
} }
} // namespace libsgp4

View File

@ -15,13 +15,15 @@
*/ */
#ifndef ECI_H_ #pragma once
#define ECI_H_
#include "CoordGeodetic.h" #include "CoordGeodetic.h"
#include "Vector.h" #include "Vector.h"
#include "DateTime.h" #include "DateTime.h"
namespace libsgp4
{
/** /**
* @brief Stores an Earth-centered inertial position for a particular time. * @brief Stores an Earth-centered inertial position for a particular time.
*/ */
@ -141,4 +143,4 @@ private:
Vector m_velocity; Vector m_velocity;
}; };
#endif } // namespace libsgp4

View File

@ -15,11 +15,13 @@
*/ */
#ifndef GLOBALS_H_ #pragma once
#define GLOBALS_H_
#include <cmath> #include <cmath>
namespace libsgp4
{
const double kAE = 1.0; const double kAE = 1.0;
const double kQ0 = 120.0; const double kQ0 = 120.0;
const double kS0 = 78.0; const double kS0 = 78.0;
@ -72,5 +74,4 @@ const double kHOURS_PER_DAY = 24.0;
const double kA3OVK2 = -kXJ3 / kCK2 * kAE * kAE * kAE; const double kA3OVK2 = -kXJ3 / kCK2 * kAE * kAE * kAE;
#endif } // namespace libsgp4

View File

@ -16,9 +16,11 @@
#include "Observer.h" #include "Observer.h"
#include "CoordTopocentric.h" #include "CoordTopocentric.h"
namespace libsgp4
{
/* /*
* calculate lookangle between the observer and the passed in Eci object * calculate lookangle between the observer and the passed in Eci object
*/ */
@ -80,3 +82,5 @@ CoordTopocentric Observer::GetLookAngle(const Eci &eci)
range.w, range.w,
rate); rate);
} }
} // namespace libsgp4

View File

@ -15,12 +15,14 @@
*/ */
#ifndef OBSERVER_H_ #pragma once
#define OBSERVER_H_
#include "CoordGeodetic.h" #include "CoordGeodetic.h"
#include "Eci.h" #include "Eci.h"
namespace libsgp4
{
class DateTime; class DateTime;
struct CoordTopocentric; struct CoordTopocentric;
@ -48,7 +50,7 @@ public:
* Constructor * Constructor
* @param[in] geo the observers position * @param[in] geo the observers position
*/ */
Observer(const CoordGeodetic &geo) explicit Observer(const CoordGeodetic &geo)
: m_geo(geo) : m_geo(geo)
, m_eci(DateTime(), geo) , m_eci(DateTime(), geo)
{ {
@ -98,5 +100,4 @@ private:
Eci m_eci; Eci m_eci;
}; };
#endif } // namespace libsgp4

View File

@ -19,6 +19,9 @@
#include "Tle.h" #include "Tle.h"
namespace libsgp4
{
OrbitalElements::OrbitalElements(const Tle& tle) OrbitalElements::OrbitalElements(const Tle& tle)
{ {
/* /*
@ -64,3 +67,4 @@ OrbitalElements::OrbitalElements(const Tle& tle)
period_ = kTWOPI / RecoveredMeanMotion(); period_ = kTWOPI / RecoveredMeanMotion();
} }
} // namespace libsgp4

View File

@ -15,12 +15,14 @@
*/ */
#ifndef ORBITALELEMENTS_H_ #pragma once
#define ORBITALELEMENTS_H_
#include "Util.h" #include "Util.h"
#include "DateTime.h" #include "DateTime.h"
namespace libsgp4
{
class Tle; class Tle;
/** /**
@ -29,7 +31,7 @@ class Tle;
class OrbitalElements class OrbitalElements
{ {
public: public:
OrbitalElements(const Tle& tle); explicit OrbitalElements(const Tle& tle);
/* /*
* XMO * XMO
@ -142,4 +144,4 @@ private:
DateTime epoch_; DateTime epoch_;
}; };
#endif } // namespace libsgp4

View File

@ -26,6 +26,9 @@
#include <iomanip> #include <iomanip>
#include <cstring> #include <cstring>
namespace libsgp4
{
void SGP4::SetTle(const Tle& tle) void SGP4::SetTle(const Tle& tle)
{ {
/* /*
@ -1346,3 +1349,5 @@ void SGP4::Reset()
std::memset(&deepspace_consts_, 0, sizeof(deepspace_consts_)); std::memset(&deepspace_consts_, 0, sizeof(deepspace_consts_));
std::memset(&integrator_params_, 0, sizeof(integrator_params_)); std::memset(&integrator_params_, 0, sizeof(integrator_params_));
} }
} // namespace libsgp4

View File

@ -15,8 +15,7 @@
*/ */
#ifndef SGP4_H_ #pragma once
#define SGP4_H_
#include "Tle.h" #include "Tle.h"
#include "OrbitalElements.h" #include "OrbitalElements.h"
@ -24,6 +23,9 @@
#include "SatelliteException.h" #include "SatelliteException.h"
#include "DecayedException.h" #include "DecayedException.h"
namespace libsgp4
{
/** /**
* @mainpage * @mainpage
* *
@ -36,7 +38,7 @@
class SGP4 class SGP4
{ {
public: public:
SGP4(const Tle& tle) explicit SGP4(const Tle& tle)
: elements_(tle) : elements_(tle)
{ {
Initialise(); Initialise();
@ -255,4 +257,4 @@ private:
bool use_deep_space_; bool use_deep_space_;
}; };
#endif } // namespace libsgp4

View File

@ -15,22 +15,24 @@
*/ */
#ifndef SATELLITEEXCEPTION_H_ #pragma once
#define SATELLITEEXCEPTION_H_
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
namespace libsgp4
{
/** /**
* @brief The exception that the SGP4 class throws upon an error. * @brief The exception that the SGP4 class throws upon an error.
*/ */
class SatelliteException : public std::runtime_error class SatelliteException : public std::runtime_error
{ {
public: public:
SatelliteException(const char* message) explicit SatelliteException(const char* message)
: runtime_error(message) : runtime_error(message)
{ {
} }
}; };
#endif } // namespace libsgp4

View File

@ -22,6 +22,9 @@
#include <cmath> #include <cmath>
namespace libsgp4
{
Eci SolarPosition::FindPosition(const DateTime& dt) Eci SolarPosition::FindPosition(const DateTime& dt)
{ {
const double mjd = dt.ToJ2000(); const double mjd = dt.ToJ2000();
@ -61,3 +64,5 @@ double SolarPosition::Delta_ET(double year) const
return 26.465 + 0.747622 * (year - 1950) + 1.886913 return 26.465 + 0.747622 * (year - 1950) + 1.886913
* sin(kTWOPI * (year - 1975) / 33); * sin(kTWOPI * (year - 1975) / 33);
} }
} // namespace libsgp4

View File

@ -15,21 +15,21 @@
*/ */
#ifndef SOLARPOSITION_H_ #pragma once
#define SOLARPOSITION_H_
#include "DateTime.h" #include "DateTime.h"
#include "Eci.h" #include "Eci.h"
namespace libsgp4
{
/** /**
* @brief Find the position of the sun * @brief Find the position of the sun
*/ */
class SolarPosition class SolarPosition
{ {
public: public:
SolarPosition() SolarPosition() = default;
{
}
Eci FindPosition(const DateTime& dt); Eci FindPosition(const DateTime& dt);
@ -37,4 +37,4 @@ private:
double Delta_ET(double year) const; double Delta_ET(double year) const;
}; };
#endif } // namespace libsgp4

View File

@ -15,14 +15,16 @@
*/ */
#ifndef TIMESPAN_H_ #pragma once
#define TIMESPAN_H_
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include <cmath> #include <cmath>
#include <stdint.h> #include <cstdint>
namespace libsgp4
{
namespace namespace
{ {
@ -51,7 +53,7 @@ namespace
class TimeSpan class TimeSpan
{ {
public: public:
TimeSpan(int64_t ticks) explicit TimeSpan(int64_t ticks)
: m_ticks(ticks) : m_ticks(ticks)
{ {
} }
@ -195,7 +197,7 @@ public:
} }
private: private:
int64_t m_ticks; int64_t m_ticks{};
void CalculateTicks(int days, void CalculateTicks(int days,
int hours, int hours,
@ -204,7 +206,7 @@ private:
int microseconds) int microseconds)
{ {
m_ticks = days * TicksPerDay + m_ticks = days * TicksPerDay +
(hours * 3600LL + minutes * 60LL + seconds) * TicksPerSecond + (hours * 3600LL + minutes * 60LL + seconds) * TicksPerSecond +
microseconds * TicksPerMicrosecond; microseconds * TicksPerMicrosecond;
} }
}; };
@ -254,4 +256,4 @@ inline bool operator<=(const TimeSpan& ts1, const TimeSpan& ts2)
return (ts1.Compare(ts2) <= 0); return (ts1.Compare(ts2) <= 0);
} }
#endif } // namespace libsgp4

View File

@ -17,8 +17,10 @@
#include "Tle.h" #include "Tle.h"
#include <locale> #include <locale>
namespace libsgp4
{
namespace namespace
{ {
static const unsigned int TLE1_COL_NORADNUM = 2; static const unsigned int TLE1_COL_NORADNUM = 2;
@ -144,9 +146,13 @@ void Tle::Initialize()
TLE2_LEN_REVATEPOCH), orbit_number_); TLE2_LEN_REVATEPOCH), orbit_number_);
if (year < 57) if (year < 57)
{
year += 2000; year += 2000;
}
else else
{
year += 1900; year += 1900;
}
epoch_ = DateTime(year, day); epoch_ = DateTime(year, day);
} }
@ -172,18 +178,18 @@ void Tle::ExtractInteger(const std::string& str, unsigned int& val)
bool found_digit = false; bool found_digit = false;
unsigned int temp = 0; unsigned int temp = 0;
for (std::string::const_iterator i = str.begin(); i != str.end(); ++i) for (auto& i : str)
{ {
if (isdigit(*i)) if (isdigit(i))
{ {
found_digit = true; found_digit = true;
temp = (temp * 10) + static_cast<unsigned int>(*i - '0'); temp = (temp * 10) + static_cast<unsigned int>(i - '0');
} }
else if (found_digit) else if (found_digit)
{ {
throw TleException("Unexpected non digit"); throw TleException("Unexpected non digit");
} }
else if (*i != ' ') else if (i != ' ')
{ {
throw TleException("Invalid character"); throw TleException("Invalid character");
} }
@ -366,3 +372,5 @@ void Tle::ExtractExponential(const std::string& str, double& val)
throw TleException("Failed to convert value to double"); throw TleException("Failed to convert value to double");
} }
} }
} // namespace libsgp4

View File

@ -15,13 +15,15 @@
*/ */
#ifndef TLE_H_ #pragma once
#define TLE_H_
#include "Util.h" #include "Util.h"
#include "DateTime.h" #include "DateTime.h"
#include "TleException.h" #include "TleException.h"
namespace libsgp4
{
/** /**
* @brief Processes a two-line element set used to convey OrbitalElements. * @brief Processes a two-line element set used to convey OrbitalElements.
* *
@ -35,10 +37,9 @@ public:
* @param[in] line_one Tle line one * @param[in] line_one Tle line one
* @param[in] line_two Tle line two * @param[in] line_two Tle line two
*/ */
Tle(const std::string& line_one, Tle(std::string line_one, std::string line_two)
const std::string& line_two) : line_one_(std::move(line_one))
: line_one_(line_one) , line_two_(std::move(line_two))
, line_two_(line_two)
{ {
Initialize(); Initialize();
} }
@ -49,12 +50,10 @@ public:
* @param[in] line_one Tle line one * @param[in] line_one Tle line one
* @param[in] line_two Tle line two * @param[in] line_two Tle line two
*/ */
Tle(const std::string& name, Tle(std::string name, std::string line_one, std::string line_two)
const std::string& line_one, : name_(std::move(name))
const std::string& line_two) , line_one_(std::move(line_one))
: name_(name) , line_two_(std::move(line_two))
, line_one_(line_one)
, line_two_(line_two)
{ {
Initialize(); Initialize();
} }
@ -317,17 +316,17 @@ private:
std::string int_designator_; std::string int_designator_;
DateTime epoch_; DateTime epoch_;
double mean_motion_dt2_; double mean_motion_dt2_{};
double mean_motion_ddt6_; double mean_motion_ddt6_{};
double bstar_; double bstar_{};
double inclination_; double inclination_{};
double right_ascending_node_; double right_ascending_node_{};
double eccentricity_; double eccentricity_{};
double argument_perigee_; double argument_perigee_{};
double mean_anomaly_; double mean_anomaly_{};
double mean_motion_; double mean_motion_{};
unsigned int norad_number_; unsigned int norad_number_{};
unsigned int orbit_number_; unsigned int orbit_number_{};
static const unsigned int TLE_LEN_LINE_DATA = 69; static const unsigned int TLE_LEN_LINE_DATA = 69;
static const unsigned int TLE_LEN_LINE_NAME = 22; static const unsigned int TLE_LEN_LINE_NAME = 22;
@ -339,4 +338,4 @@ inline std::ostream& operator<<(std::ostream& strm, const Tle& t)
return strm << t.ToString(); return strm << t.ToString();
} }
#endif } // namespace libsgp4

View File

@ -15,12 +15,14 @@
*/ */
#ifndef TLEEXCEPTION_H_ #pragma once
#define TLEEXCEPTION_H_
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
namespace libsgp4
{
/** /**
* @brief The exception that the Tle class throws on an error. * @brief The exception that the Tle class throws on an error.
* *
@ -33,10 +35,10 @@ public:
* Constructor * Constructor
* @param message Exception message * @param message Exception message
*/ */
TleException(const char* message) explicit TleException(const char* message)
: runtime_error(message) : runtime_error(message)
{ {
} }
}; };
#endif } // namespace libsgp4

View File

@ -21,28 +21,17 @@
#include <locale> #include <locale>
#include <functional> #include <functional>
namespace Util namespace libsgp4::Util
{ {
namespace
{
struct IsDigit: std::unary_function<char, bool>
{
bool operator()(char c) const
{
return std::isdigit(c, std::locale::classic()) == 0;
}
};
}
void TrimLeft(std::string& s) void TrimLeft(std::string& s)
{ {
s.erase(s.begin(), s.erase(s.begin(),
std::find_if(s.begin(), s.end(), std::not1(IsDigit()))); std::find_if(s.begin(), s.end(), [](unsigned char c){ return std::isgraph(c) != 0; }));
} }
void TrimRight(std::string& s) void TrimRight(std::string& s)
{ {
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(IsDigit())).base(), s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char c){ return std::isgraph(c) != 0; }).base(),
s.end()); s.end());
} }
@ -51,4 +40,4 @@ namespace Util
TrimLeft(s); TrimLeft(s);
TrimRight(s); TrimRight(s);
} }
} } // namespace libsgp4::Util

View File

@ -15,13 +15,14 @@
*/ */
#ifndef UTIL_H_ #pragma once
#define UTIL_H_
#include "Globals.h" #include "Globals.h"
#include <sstream> #include <sstream>
namespace libsgp4
{
namespace Util namespace Util
{ {
template template
@ -50,7 +51,7 @@ namespace Util
{ {
return Mod(a + kPI, kTWOPI) - kPI; return Mod(a + kPI, kTWOPI) - kPI;
} }
inline double WrapTwoPI(const double a) inline double WrapTwoPI(const double a)
{ {
return Mod(a, kTWOPI); return Mod(a, kTWOPI);
@ -101,10 +102,10 @@ namespace Util
} }
} }
} }
void TrimLeft(std::string& s); void TrimLeft(std::string& s);
void TrimRight(std::string& s); void TrimRight(std::string& s);
void Trim(std::string& s); void Trim(std::string& s);
}
#endif } // namespace Util
} // namespace libsgp4

View File

@ -15,14 +15,16 @@
*/ */
#ifndef VECTOR_H_ #pragma once
#define VECTOR_H_
#include <cmath> #include <cmath>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
namespace libsgp4
{
/** /**
* @brief Generic vector * @brief Generic vector
* *
@ -35,10 +37,7 @@ public:
/** /**
* Default constructor * Default constructor
*/ */
Vector() Vector() = default;
: x(0.0), y(0.0), z(0.0), w(0.0)
{
}
/** /**
* Constructor * Constructor
@ -49,7 +48,7 @@ public:
Vector(const double arg_x, Vector(const double arg_x,
const double arg_y, const double arg_y,
const double arg_z) const double arg_z)
: x(arg_x), y(arg_y), z(arg_z), w(0.0) : x(arg_x), y(arg_y), z(arg_z)
{ {
} }
@ -67,7 +66,7 @@ public:
: x(arg_x), y(arg_y), z(arg_z), w(arg_w) : x(arg_x), y(arg_y), z(arg_z), w(arg_w)
{ {
} }
/** /**
* Copy constructor * Copy constructor
* @param v value to copy from * @param v value to copy from
@ -144,13 +143,13 @@ public:
} }
/** x value */ /** x value */
double x; double x{};
/** y value */ /** y value */
double y; double y{};
/** z value */ /** z value */
double z; double z{};
/** w value */ /** w value */
double w; double w{};
}; };
inline std::ostream& operator<<(std::ostream& strm, const Vector& v) inline std::ostream& operator<<(std::ostream& strm, const Vector& v)
@ -158,4 +157,4 @@ inline std::ostream& operator<<(std::ostream& strm, const Vector& v)
return strm << v.ToString(); return strm << v.ToString();
} }
#endif } // namespace libsgp4

View File

@ -27,25 +27,25 @@
struct PassDetails struct PassDetails
{ {
DateTime aos; libsgp4::DateTime aos;
DateTime los; libsgp4::DateTime los;
double max_elevation; double max_elevation;
}; };
double FindMaxElevation( double FindMaxElevation(
const CoordGeodetic& user_geo, const libsgp4::CoordGeodetic& user_geo,
SGP4& sgp4, libsgp4::SGP4& sgp4,
const DateTime& aos, const libsgp4::DateTime& aos,
const DateTime& los) const libsgp4::DateTime& los)
{ {
Observer obs(user_geo); libsgp4::Observer obs(user_geo);
bool running; bool running;
double time_step = (los - aos).TotalSeconds() / 9.0; double time_step = (los - aos).TotalSeconds() / 9.0;
DateTime current_time(aos); //! current time libsgp4::DateTime current_time(aos); //! current time
DateTime time1(aos); //! start time of search period libsgp4::DateTime time1(aos); //! start time of search period
DateTime time2(los); //! end time of search period libsgp4::DateTime time2(los); //! end time of search period
double max_elevation; //! max elevation double max_elevation; //! max elevation
running = true; running = true;
@ -59,8 +59,8 @@ double FindMaxElevation(
/* /*
* find position * find position
*/ */
Eci eci = sgp4.FindPosition(current_time); libsgp4::Eci eci = sgp4.FindPosition(current_time);
CoordTopocentric topo = obs.GetLookAngle(eci); libsgp4::CoordTopocentric topo = obs.GetLookAngle(eci);
if (topo.elevation > max_elevation) if (topo.elevation > max_elevation)
{ {
@ -111,21 +111,21 @@ double FindMaxElevation(
return max_elevation; return max_elevation;
} }
DateTime FindCrossingPoint( libsgp4::DateTime FindCrossingPoint(
const CoordGeodetic& user_geo, const libsgp4::CoordGeodetic& user_geo,
SGP4& sgp4, libsgp4::SGP4& sgp4,
const DateTime& initial_time1, const libsgp4::DateTime& initial_time1,
const DateTime& initial_time2, const libsgp4::DateTime& initial_time2,
bool finding_aos) bool finding_aos)
{ {
Observer obs(user_geo); libsgp4::Observer obs(user_geo);
bool running; bool running;
int cnt; int cnt;
DateTime time1(initial_time1); libsgp4::DateTime time1(initial_time1);
DateTime time2(initial_time2); libsgp4::DateTime time2(initial_time2);
DateTime middle_time; libsgp4::DateTime middle_time;
running = true; running = true;
cnt = 0; cnt = 0;
@ -135,8 +135,8 @@ DateTime FindCrossingPoint(
/* /*
* calculate satellite position * calculate satellite position
*/ */
Eci eci = sgp4.FindPosition(middle_time); libsgp4::Eci eci = sgp4.FindPosition(middle_time);
CoordTopocentric topo = obs.GetLookAngle(eci); libsgp4::CoordTopocentric topo = obs.GetLookAngle(eci);
if (topo.elevation > 0.0) if (topo.elevation > 0.0)
{ {
@ -189,8 +189,8 @@ DateTime FindCrossingPoint(
cnt = 0; cnt = 0;
while (running && cnt++ < 6) while (running && cnt++ < 6)
{ {
Eci eci = sgp4.FindPosition(middle_time); libsgp4::Eci eci = sgp4.FindPosition(middle_time);
CoordTopocentric topo = obs.GetLookAngle(eci); libsgp4::CoordTopocentric topo = obs.GetLookAngle(eci);
if (topo.elevation > 0) if (topo.elevation > 0)
{ {
middle_time = middle_time.AddSeconds(finding_aos ? -1 : 1); middle_time = middle_time.AddSeconds(finding_aos ? -1 : 1);
@ -205,23 +205,23 @@ DateTime FindCrossingPoint(
} }
std::list<struct PassDetails> GeneratePassList( std::list<struct PassDetails> GeneratePassList(
const CoordGeodetic& user_geo, const libsgp4::CoordGeodetic& user_geo,
SGP4& sgp4, libsgp4::SGP4& sgp4,
const DateTime& start_time, const libsgp4::DateTime& start_time,
const DateTime& end_time, const libsgp4::DateTime& end_time,
const int time_step) const int time_step)
{ {
std::list<struct PassDetails> pass_list; std::list<struct PassDetails> pass_list;
Observer obs(user_geo); libsgp4::Observer obs(user_geo);
DateTime aos_time; libsgp4::DateTime aos_time;
DateTime los_time; libsgp4::DateTime los_time;
bool found_aos = false; bool found_aos = false;
DateTime previous_time(start_time); libsgp4::DateTime previous_time(start_time);
DateTime current_time(start_time); libsgp4::DateTime current_time(start_time);
while (current_time < end_time) while (current_time < end_time)
{ {
@ -230,8 +230,8 @@ std::list<struct PassDetails> GeneratePassList(
/* /*
* calculate satellite position * calculate satellite position
*/ */
Eci eci = sgp4.FindPosition(current_time); libsgp4::Eci eci = sgp4.FindPosition(current_time);
CoordTopocentric topo = obs.GetLookAngle(eci); libsgp4::CoordTopocentric topo = obs.GetLookAngle(eci);
if (!found_aos && topo.elevation > 0.0) if (!found_aos && topo.elevation > 0.0)
{ {
@ -301,14 +301,14 @@ std::list<struct PassDetails> GeneratePassList(
/* /*
* at the end of the pass move the time along by 30mins * at the end of the pass move the time along by 30mins
*/ */
current_time = current_time + TimeSpan(0, 30, 0); current_time = current_time + libsgp4::TimeSpan(0, 30, 0);
} }
else else
{ {
/* /*
* move the time along by the time step value * move the time along by the time step value
*/ */
current_time = current_time + TimeSpan(0, 0, time_step); current_time = current_time + libsgp4::TimeSpan(0, 0, time_step);
} }
if (current_time > end_time) if (current_time > end_time)
@ -330,7 +330,6 @@ std::list<struct PassDetails> GeneratePassList(
pd.aos = aos_time; pd.aos = aos_time;
pd.los = end_time; pd.los = end_time;
pd.max_elevation = FindMaxElevation(user_geo, sgp4, aos_time, end_time); pd.max_elevation = FindMaxElevation(user_geo, sgp4, aos_time, end_time);
pass_list.push_back(pd); pass_list.push_back(pd);
} }
@ -339,19 +338,19 @@ std::list<struct PassDetails> GeneratePassList(
int main() int main()
{ {
CoordGeodetic geo(51.507406923983446, -0.12773752212524414, 0.05); libsgp4::CoordGeodetic geo(51.507406923983446, -0.12773752212524414, 0.05);
Tle tle("GALILEO-PFM (GSAT0101) ", libsgp4::Tle tle("GALILEO-PFM (GSAT0101) ",
"1 37846U 11060A 12293.53312491 .00000049 00000-0 00000-0 0 1435", "1 37846U 11060A 12293.53312491 .00000049 00000-0 00000-0 0 1435",
"2 37846 54.7963 119.5777 0000994 319.0618 40.9779 1.70474628 6204"); "2 37846 54.7963 119.5777 0000994 319.0618 40.9779 1.70474628 6204");
SGP4 sgp4(tle); libsgp4::SGP4 sgp4(tle);
std::cout << tle << std::endl; std::cout << tle << std::endl;
/* /*
* generate 7 day schedule * generate 7 day schedule
*/ */
DateTime start_date = DateTime::Now(true); libsgp4::DateTime start_date = libsgp4::DateTime::Now(true);
DateTime end_date(start_date.AddDays(7.0)); libsgp4::DateTime end_date(start_date.AddDays(7.0));
std::list<struct PassDetails> pass_list; std::list<struct PassDetails> pass_list;
@ -378,7 +377,7 @@ int main()
{ {
ss << "AOS: " << itr->aos ss << "AOS: " << itr->aos
<< ", LOS: " << itr->los << ", LOS: " << itr->los
<< ", Max El: " << std::setw(4) << Util::RadiansToDegrees(itr->max_elevation) << ", Max El: " << std::setw(4) << libsgp4::Util::RadiansToDegrees(itr->max_elevation)
<< ", Duration: " << (itr->los - itr->aos) << ", Duration: " << (itr->los - itr->aos)
<< std::endl; << std::endl;
} }

View File

@ -29,10 +29,10 @@
#include <vector> #include <vector>
#include <cstdlib> #include <cstdlib>
void RunTle(Tle tle, double start, double end, double inc) void RunTle(libsgp4::Tle tle, double start, double end, double inc)
{ {
double current = start; double current = start;
SGP4 model(tle); libsgp4::SGP4 model(tle);
bool running = true; bool running = true;
bool first_run = true; bool first_run = true;
@ -42,13 +42,13 @@ void RunTle(Tle tle, double start, double end, double inc)
while (running) while (running)
{ {
bool error = false; bool error = false;
Vector position; libsgp4::Vector position;
Vector velocity; libsgp4::Vector velocity;
double tsince; double tsince;
try try
{ {
if (first_run && current != 0.0) if (first_run && current != 0.0)
{ {
/* /*
* make sure first run is always as zero * make sure first run is always as zero
@ -63,17 +63,17 @@ void RunTle(Tle tle, double start, double end, double inc)
tsince = current; tsince = current;
} }
Eci eci = model.FindPosition(tsince); libsgp4::Eci eci = model.FindPosition(tsince);
position = eci.Position(); position = eci.Position();
velocity = eci.Velocity(); velocity = eci.Velocity();
} }
catch (SatelliteException& e) catch (libsgp4::SatelliteException& e)
{ {
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
error = true; error = true;
running = false; running = false;
} }
catch (DecayedException& e) catch (libsgp4::DecayedException& e)
{ {
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
@ -181,7 +181,7 @@ void RunTest(const char* infile)
std::string line; std::string line;
std::getline(file, line); std::getline(file, line);
Util::Trim(line); libsgp4::Util::Trim(line);
/* /*
* skip blank lines or lines starting with # * skip blank lines or lines starting with #
@ -199,7 +199,7 @@ void RunTest(const char* infile)
{ {
try try
{ {
if (line.length() >= Tle::LineLength()) if (line.length() >= libsgp4::Tle::LineLength())
{ {
//Tle::IsValidLine(line.substr(0, Tle::LineLength()), 1); //Tle::IsValidLine(line.substr(0, Tle::LineLength()), 1);
/* /*
@ -209,7 +209,7 @@ void RunTest(const char* infile)
line1 = line; line1 = line;
} }
} }
catch (TleException& e) catch (libsgp4::TleException& e)
{ {
std::cerr << "Error: " << e.what() << std::endl; std::cerr << "Error: " << e.what() << std::endl;
std::cerr << line << std::endl; std::cerr << line << std::endl;
@ -225,15 +225,15 @@ void RunTest(const char* infile)
* split line, first 69 is the second line of the tle * split line, first 69 is the second line of the tle
* the rest is the test parameters, if there is any * the rest is the test parameters, if there is any
*/ */
line2 = line.substr(0, Tle::LineLength()); line2 = line.substr(0, libsgp4::Tle::LineLength());
double start = 0.0; double start = 0.0;
double end = 1440.0; double end = 1440.0;
double inc = 120.0; double inc = 120.0;
if (line.length() > 69) if (line.length() > 69)
{ {
std::vector<std::string> tokens; std::vector<std::string> tokens;
parameters = line.substr(Tle::LineLength() + 1, parameters = line.substr(libsgp4::Tle::LineLength() + 1,
line.length() - Tle::LineLength()); line.length() - libsgp4::Tle::LineLength());
tokenize(parameters, tokens); tokenize(parameters, tokens);
if (tokens.size() >= 3) if (tokens.size() >= 3)
{ {
@ -248,14 +248,14 @@ void RunTest(const char* infile)
*/ */
try try
{ {
if (line.length() >= Tle::LineLength()) if (line.length() >= libsgp4::Tle::LineLength())
{ {
//Tle::IsValidLine(line.substr(0, Tle::LineLength()), 2); //Tle::IsValidLine(line.substr(0, Tle::LineLength()), 2);
Tle tle("Test", line1, line2); libsgp4::Tle tle("Test", line1, line2);
RunTle(tle, start, end, inc); RunTle(tle, start, end, inc);
} }
} }
catch (TleException& e) catch (libsgp4::TleException& e)
{ {
std::cerr << "Error: " << e.what() << std::endl; std::cerr << "Error: " << e.what() << std::endl;
std::cerr << line << std::endl; std::cerr << line << std::endl;

View File

@ -24,29 +24,29 @@
int main() int main()
{ {
Observer obs(51.507406923983446, -0.12773752212524414, 0.05); libsgp4::Observer obs(51.507406923983446, -0.12773752212524414, 0.05);
Tle tle = Tle("UK-DMC 2 ", libsgp4::Tle tle = libsgp4::Tle("UK-DMC 2 ",
"1 35683U 09041C 12289.23158813 .00000484 00000-0 89219-4 0 5863", "1 35683U 09041C 12289.23158813 .00000484 00000-0 89219-4 0 5863",
"2 35683 98.0221 185.3682 0001499 100.5295 259.6088 14.69819587172294"); "2 35683 98.0221 185.3682 0001499 100.5295 259.6088 14.69819587172294");
SGP4 sgp4(tle); libsgp4::SGP4 sgp4(tle);
std::cout << tle << std::endl; std::cout << tle << std::endl;
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
{ {
DateTime dt = tle.Epoch().AddMinutes(i * 10); libsgp4::DateTime dt = tle.Epoch().AddMinutes(i * 10);
/* /*
* calculate satellite position * calculate satellite position
*/ */
Eci eci = sgp4.FindPosition(dt); libsgp4::Eci eci = sgp4.FindPosition(dt);
/* /*
* get look angle for observer to satellite * get look angle for observer to satellite
*/ */
CoordTopocentric topo = obs.GetLookAngle(eci); libsgp4::CoordTopocentric topo = obs.GetLookAngle(eci);
/* /*
* convert satellite position to geodetic coordinates * convert satellite position to geodetic coordinates
*/ */
CoordGeodetic geo = eci.ToGeodetic(); libsgp4::CoordGeodetic geo = eci.ToGeodetic();
std::cout << dt << " " << topo << " " << geo << std::endl; std::cout << dt << " " << topo << " " << geo << std::endl;
}; };