增加了基于SPG4模型与两行根数的,卫星轨道点生成代码
parent
c55953aa7c
commit
44a5db3168
|
@ -38,6 +38,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RasterMainWidgetGUI", "Rast
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageshowTool", "ImageshowTool\ImageshowTool.vcxproj", "{8C8CA066-A93A-4098-9A46-B855EFEAADF2}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageshowTool", "ImageshowTool\ImageshowTool.vcxproj", "{8C8CA066-A93A-4098-9A46-B855EFEAADF2}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPG4Tool", "SPG4Tool\SPG4Tool.vcxproj", "{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|ARM = Debug|ARM
|
Debug|ARM = Debug|ARM
|
||||||
|
@ -168,6 +170,18 @@ Global
|
||||||
{8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x64.Build.0 = Release|x64
|
{8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x64.Build.0 = Release|x64
|
||||||
{8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x86.ActiveCfg = Release|x64
|
{8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x86.ActiveCfg = Release|x64
|
||||||
{8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x86.Build.0 = Release|x64
|
{8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x86.Build.0 = Release|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|ARM.ActiveCfg = Debug|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|ARM.Build.0 = Debug|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|x86.Build.0 = Debug|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|ARM.ActiveCfg = Release|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|ARM.Build.0 = Release|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|x64.Build.0 = Release|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|x86.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -181,6 +195,7 @@ Global
|
||||||
{B8B40C54-F7FE-4809-B6FB-8BC014570D7B} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
{B8B40C54-F7FE-4809-B6FB-8BC014570D7B} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
||||||
{E56B3878-A3DC-41A4-ABF3-B628816D0D64} = {6505E2BA-06A2-447B-BC85-8CF1A81359BC}
|
{E56B3878-A3DC-41A4-ABF3-B628816D0D64} = {6505E2BA-06A2-447B-BC85-8CF1A81359BC}
|
||||||
{8C8CA066-A93A-4098-9A46-B855EFEAADF2} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
{8C8CA066-A93A-4098-9A46-B855EFEAADF2} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
||||||
|
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {179F0A62-C631-4667-AD03-3780ADE09F41}
|
SolutionGuid = {179F0A62-C631-4667-AD03-3780ADE09F41}
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
#include "SPG4Function.h"
|
||||||
|
#include <Tle.h>
|
||||||
|
#include <SGP4.h>
|
||||||
|
#include <Observer.h>
|
||||||
|
#include <CoordGeodetic.h>
|
||||||
|
#include <CoordTopocentric.h>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<SatelliteAntPos> RunTle(libsgp4::Tle tle, double start, double end, double inc, bool printfinfoflag)
|
||||||
|
{
|
||||||
|
std::vector<SatelliteAntPos> resultpos(0);
|
||||||
|
double current = start;
|
||||||
|
libsgp4::SGP4 model(tle);
|
||||||
|
bool running = true;
|
||||||
|
bool first_run = true;
|
||||||
|
|
||||||
|
std::cout << std::setprecision(0) << tle.NoradNumber() << " xx"
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
while (running)
|
||||||
|
{
|
||||||
|
bool error = false;
|
||||||
|
libsgp4::Vector position;
|
||||||
|
libsgp4::Vector velocity;
|
||||||
|
double tsince;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (first_run && current != 0.0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* make sure first run is always as zero
|
||||||
|
*/
|
||||||
|
tsince = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* otherwise run as normal
|
||||||
|
*/
|
||||||
|
tsince = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
libsgp4::Eci eci = model.FindPosition(tsince);
|
||||||
|
position = eci.Position();
|
||||||
|
velocity = eci.Velocity();
|
||||||
|
}
|
||||||
|
catch (libsgp4::SatelliteException& e)
|
||||||
|
{
|
||||||
|
std::cerr << e.what() << std::endl;
|
||||||
|
error = true;
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
catch (libsgp4::DecayedException& e)
|
||||||
|
{
|
||||||
|
std::cerr << e.what() << std::endl;
|
||||||
|
|
||||||
|
position = e.Position();
|
||||||
|
velocity = e.Velocity();
|
||||||
|
|
||||||
|
if (!first_run)
|
||||||
|
{
|
||||||
|
// print out position on first run
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
SatelliteAntPos antpos{};
|
||||||
|
antpos.time = tsince;
|
||||||
|
antpos.Px = position.x;
|
||||||
|
antpos.Py = position.y;
|
||||||
|
antpos.Pz = position.z;
|
||||||
|
antpos.Vx = velocity.z;
|
||||||
|
antpos.Vy = velocity.z;
|
||||||
|
antpos.Vz = velocity.z;
|
||||||
|
|
||||||
|
resultpos.push_back(antpos);
|
||||||
|
if (printfinfoflag) {
|
||||||
|
std::cout << std::setprecision(8) << std::fixed;
|
||||||
|
std::cout.width(17);
|
||||||
|
std::cout << tsince << " ";
|
||||||
|
std::cout.width(16);
|
||||||
|
std::cout << position.x << " ";
|
||||||
|
std::cout.width(16);
|
||||||
|
std::cout << position.y << " ";
|
||||||
|
std::cout.width(16);
|
||||||
|
std::cout << position.z << " ";
|
||||||
|
std::cout << std::setprecision(9) << std::fixed;
|
||||||
|
std::cout.width(14);
|
||||||
|
std::cout << velocity.x << " ";
|
||||||
|
std::cout.width(14);
|
||||||
|
std::cout << velocity.y << " ";
|
||||||
|
std::cout.width(14);
|
||||||
|
std::cout << velocity.z << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((first_run && current == 0.0) || !first_run)
|
||||||
|
{
|
||||||
|
if (current == end)
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
else if (current + inc > end)
|
||||||
|
{
|
||||||
|
current = end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current += inc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first_run = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return resultpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef __SPG4FUNCTION__H__
|
||||||
|
#define __SPG4FUNCTION__H__
|
||||||
|
|
||||||
|
#include "Tle.h"
|
||||||
|
#include "SGP4.h"
|
||||||
|
#include "Observer.h"
|
||||||
|
#include "BaseConstVariable.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
//void RunTle(libsgp4::Tle tle, double start, double end, double inc);
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<SatelliteAntPos> RunTle(libsgp4::Tle tle, double start, double end, double inc,bool printfinfoflag=false);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,145 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}</ProjectGuid>
|
||||||
|
<Keyword>QtVS_v304</Keyword>
|
||||||
|
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0</WindowsTargetPlatformVersion>
|
||||||
|
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0</WindowsTargetPlatformVersion>
|
||||||
|
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
|
||||||
|
<Import Project="$(QtMsBuild)\qt_defaults.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
|
||||||
|
<QtInstall>tools_qt5</QtInstall>
|
||||||
|
<QtModules>core</QtModules>
|
||||||
|
<QtBuildConfig>debug</QtBuildConfig>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
|
||||||
|
<QtInstall>tools_qt5</QtInstall>
|
||||||
|
<QtModules>core</QtModules>
|
||||||
|
<QtBuildConfig>release</QtBuildConfig>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
|
||||||
|
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
|
||||||
|
</Target>
|
||||||
|
<ImportGroup Label="ExtensionSettings" />
|
||||||
|
<ImportGroup Label="Shared" />
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(QtMsBuild)\Qt.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(QtMsBuild)\Qt.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<IncludePath>.\libsgp4;..\BaseCommonLibrary\BaseTool;$(IncludePath)</IncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
|
||||||
|
<ClCompile>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
|
||||||
|
<ClCompile>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="libsgp4\CoordGeodetic.cc" />
|
||||||
|
<ClCompile Include="libsgp4\CoordTopocentric.cc" />
|
||||||
|
<ClCompile Include="libsgp4\DateTime.cc" />
|
||||||
|
<ClCompile Include="libsgp4\DecayedException.cc" />
|
||||||
|
<ClCompile Include="libsgp4\Eci.cc" />
|
||||||
|
<ClCompile Include="libsgp4\Globals.cc" />
|
||||||
|
<ClCompile Include="libsgp4\Observer.cc" />
|
||||||
|
<ClCompile Include="libsgp4\OrbitalElements.cc" />
|
||||||
|
<ClCompile Include="libsgp4\SatelliteException.cc" />
|
||||||
|
<ClCompile Include="libsgp4\SGP4.cc" />
|
||||||
|
<ClCompile Include="libsgp4\SolarPosition.cc" />
|
||||||
|
<ClCompile Include="libsgp4\TimeSpan.cc" />
|
||||||
|
<ClCompile Include="libsgp4\Tle.cc" />
|
||||||
|
<ClCompile Include="libsgp4\TleException.cc" />
|
||||||
|
<ClCompile Include="libsgp4\Util.cc" />
|
||||||
|
<ClCompile Include="libsgp4\Vector.cc" />
|
||||||
|
<ClCompile Include="SPG4Toolmain.cpp" />
|
||||||
|
<ClCompile Include="SPG4Function.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="libsgp4\CoordGeodetic.h" />
|
||||||
|
<ClInclude Include="libsgp4\CoordTopocentric.h" />
|
||||||
|
<ClInclude Include="libsgp4\DateTime.h" />
|
||||||
|
<ClInclude Include="libsgp4\DecayedException.h" />
|
||||||
|
<ClInclude Include="libsgp4\Eci.h" />
|
||||||
|
<ClInclude Include="libsgp4\Globals.h" />
|
||||||
|
<ClInclude Include="libsgp4\Observer.h" />
|
||||||
|
<ClInclude Include="libsgp4\OrbitalElements.h" />
|
||||||
|
<ClInclude Include="libsgp4\SatelliteException.h" />
|
||||||
|
<ClInclude Include="libsgp4\SGP4.h" />
|
||||||
|
<ClInclude Include="libsgp4\SolarPosition.h" />
|
||||||
|
<ClInclude Include="libsgp4\TimeSpan.h" />
|
||||||
|
<ClInclude Include="libsgp4\Tle.h" />
|
||||||
|
<ClInclude Include="libsgp4\TleException.h" />
|
||||||
|
<ClInclude Include="libsgp4\Util.h" />
|
||||||
|
<ClInclude Include="libsgp4\Vector.h" />
|
||||||
|
<ClInclude Include="SPG4Function.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\BaseCommonLibrary\BaseCommonLibrary.vcxproj">
|
||||||
|
<Project>{872ecd6f-30e3-4a1b-b17c-15e87d373ff6}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
||||||
|
<Import Project="$(QtMsBuild)\qt.targets" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,137 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Form Files">
|
||||||
|
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
|
||||||
|
<Extensions>ui</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Translation Files">
|
||||||
|
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
|
||||||
|
<Extensions>ts</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="libsgp4">
|
||||||
|
<UniqueIdentifier>{fd21014a-ae49-484d-bbcf-92b5b994c075}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="SPG4Toolmain.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\CoordGeodetic.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\CoordTopocentric.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\DateTime.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\DecayedException.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\Eci.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\Globals.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\Observer.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\OrbitalElements.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\SatelliteException.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\SGP4.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\SolarPosition.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\TimeSpan.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\Tle.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\TleException.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\Util.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libsgp4\Vector.cc">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="SPG4Function.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="libsgp4\CoordGeodetic.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\CoordTopocentric.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\DateTime.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\DecayedException.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\Eci.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\Globals.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\Observer.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\OrbitalElements.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\SatelliteException.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\SGP4.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\SolarPosition.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\TimeSpan.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\Tle.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\TleException.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\Util.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libsgp4\Vector.h">
|
||||||
|
<Filter>libsgp4</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="SPG4Function.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,38 @@
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include "Tle.h"
|
||||||
|
#include "SGP4.h"
|
||||||
|
#include "Observer.h"
|
||||||
|
#include "CoordGeodetic.h"
|
||||||
|
#include "CoordTopocentric.h"
|
||||||
|
#include <string>
|
||||||
|
#include "SPG4Function.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
½̽ËĺÅ01ÐÇÎÀÐǹìµÀ
|
||||||
|
1 57624U 23120A 25064.58152700 -.00000191 00000-0 00000+0 0 9998
|
||||||
|
2 57624 15.4792 205.4597 0004587 123.7538 133.1804 1.00272901 5837
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//int main(int argc, char *argv[])
|
||||||
|
//{
|
||||||
|
//
|
||||||
|
// std::string line1="1 57624U 23120A 25064.58152700 -.00000191 00000-0 00000+0 0 9998";
|
||||||
|
// std::string line2="2 57624 15.4792 205.4597 0004587 123.7538 133.1804 1.00272901 5837";
|
||||||
|
//
|
||||||
|
// libsgp4::Tle tle("GF3", line1, line2);
|
||||||
|
//
|
||||||
|
// double start = 0;
|
||||||
|
// double end = 10;
|
||||||
|
// double inc = 1;
|
||||||
|
//
|
||||||
|
// RunTle(tle, start, end, inc);
|
||||||
|
// //QCoreApplication a(argc, argv);
|
||||||
|
//
|
||||||
|
// //return a.exec();
|
||||||
|
//}
|
|
@ -0,0 +1,41 @@
|
||||||
|
set(SRCS
|
||||||
|
CoordGeodetic.cc
|
||||||
|
CoordTopocentric.cc
|
||||||
|
DateTime.cc
|
||||||
|
DecayedException.cc
|
||||||
|
Eci.cc
|
||||||
|
Globals.cc
|
||||||
|
Observer.cc
|
||||||
|
OrbitalElements.cc
|
||||||
|
SGP4.cc
|
||||||
|
SatelliteException.cc
|
||||||
|
SolarPosition.cc
|
||||||
|
TimeSpan.cc
|
||||||
|
Tle.cc
|
||||||
|
TleException.cc
|
||||||
|
Util.cc
|
||||||
|
Vector.cc)
|
||||||
|
|
||||||
|
set(INCS
|
||||||
|
CoordGeodetic.h
|
||||||
|
CoordTopocentric.h
|
||||||
|
DateTime.h
|
||||||
|
DecayedException.h
|
||||||
|
Eci.h
|
||||||
|
Globals.h
|
||||||
|
Observer.h
|
||||||
|
OrbitalElements.h
|
||||||
|
SatelliteException.h
|
||||||
|
SGP4.h
|
||||||
|
SolarPosition.h
|
||||||
|
TimeSpan.h
|
||||||
|
TleException.h
|
||||||
|
Tle.h
|
||||||
|
Util.h
|
||||||
|
Vector.h
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(sgp4 STATIC ${SRCS} ${INCS})
|
||||||
|
add_library(sgp4s SHARED ${SRCS} ${INCS})
|
||||||
|
install( TARGETS sgp4s LIBRARY DESTINATION lib )
|
||||||
|
install( FILES ${INCS} DESTINATION include/libsgp4 )
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "CoordGeodetic.h"
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stores a geodetic location (latitude, longitude, altitude).
|
||||||
|
*
|
||||||
|
* Internally the values are stored in radians and kilometres.
|
||||||
|
*/
|
||||||
|
struct CoordGeodetic
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
CoordGeodetic() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param[in] lat the latitude (degrees by default)
|
||||||
|
* @param[in] lon the longitude (degrees by default)
|
||||||
|
* @param[in] alt the altitude in kilometers
|
||||||
|
* @param[in] is_radians whether the latitude/longitude is in radians
|
||||||
|
*/
|
||||||
|
CoordGeodetic(
|
||||||
|
double lat,
|
||||||
|
double lon,
|
||||||
|
double alt,
|
||||||
|
bool is_radians = false)
|
||||||
|
{
|
||||||
|
if (is_radians)
|
||||||
|
{
|
||||||
|
latitude = lat;
|
||||||
|
longitude = lon;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
latitude = Util::DegreesToRadians(lat);
|
||||||
|
longitude = Util::DegreesToRadians(lon);
|
||||||
|
}
|
||||||
|
altitude = alt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
* @param[in] geo object to copy from
|
||||||
|
*/
|
||||||
|
CoordGeodetic(const CoordGeodetic& geo)
|
||||||
|
{
|
||||||
|
latitude = geo.latitude;
|
||||||
|
longitude = geo.longitude;
|
||||||
|
altitude = geo.altitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assignment operator
|
||||||
|
* @param[in] geo object to copy from
|
||||||
|
*/
|
||||||
|
CoordGeodetic& operator=(const CoordGeodetic& geo)
|
||||||
|
{
|
||||||
|
if (this != &geo)
|
||||||
|
{
|
||||||
|
latitude = geo.latitude;
|
||||||
|
longitude = geo.longitude;
|
||||||
|
altitude = geo.altitude;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump this object to a string
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
std::string ToString() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::right << std::fixed << std::setprecision(3);
|
||||||
|
ss << "Lat: " << std::setw(8) << Util::RadiansToDegrees(latitude);
|
||||||
|
ss << ", Lon: " << std::setw(8) << Util::RadiansToDegrees(longitude);
|
||||||
|
ss << ", Alt: " << std::setw(10) << altitude;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** latitude in radians (-PI >= latitude < PI) */
|
||||||
|
double latitude{};
|
||||||
|
/** latitude in radians (-PI/2 >= latitude <= PI/2) */
|
||||||
|
double longitude{};
|
||||||
|
/** altitude in kilometers */
|
||||||
|
double altitude{};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump a Coordgeodetic to a stream
|
||||||
|
* @param[in,out] strm stream to output to
|
||||||
|
* @param[in] g the CoordGeodetic to print
|
||||||
|
*/
|
||||||
|
inline std::ostream& operator<<(std::ostream& strm, const CoordGeodetic& g)
|
||||||
|
{
|
||||||
|
return strm << g.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "CoordTopocentric.h"
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stores a topocentric location (azimuth, elevation, range and range
|
||||||
|
* rate).
|
||||||
|
*
|
||||||
|
* Azimuth and elevation are stored in radians. Range in kilometres. Range
|
||||||
|
* rate in kilometres/second.
|
||||||
|
*/
|
||||||
|
struct CoordTopocentric
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
CoordTopocentric() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param[in] az azimuth in radians
|
||||||
|
* @param[in] el elevation in radians
|
||||||
|
* @param[in] rnge range in kilometers
|
||||||
|
* @param[in] rnge_rate range rate in kilometers per second
|
||||||
|
*/
|
||||||
|
CoordTopocentric(
|
||||||
|
double az,
|
||||||
|
double el,
|
||||||
|
double rnge,
|
||||||
|
double rnge_rate)
|
||||||
|
: azimuth(az)
|
||||||
|
, elevation(el)
|
||||||
|
, range(rnge)
|
||||||
|
, range_rate(rnge_rate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
* @param[in] topo object to copy from
|
||||||
|
*/
|
||||||
|
CoordTopocentric(const CoordTopocentric& topo)
|
||||||
|
{
|
||||||
|
azimuth = topo.azimuth;
|
||||||
|
elevation = topo.elevation;
|
||||||
|
range = topo.range;
|
||||||
|
range_rate = topo.range_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assignment operator
|
||||||
|
* @param[in] topo object to copy from
|
||||||
|
*/
|
||||||
|
CoordTopocentric& operator=(const CoordTopocentric& topo)
|
||||||
|
{
|
||||||
|
if (this != &topo)
|
||||||
|
{
|
||||||
|
azimuth = topo.azimuth;
|
||||||
|
elevation = topo.elevation;
|
||||||
|
range = topo.range;
|
||||||
|
range_rate = topo.range_rate;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump this object to a string
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
std::string ToString() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::right << std::fixed << std::setprecision(3);
|
||||||
|
ss << "Az: " << std::setw(8) << Util::RadiansToDegrees(azimuth);
|
||||||
|
ss << ", El: " << std::setw(8) << Util::RadiansToDegrees(elevation);
|
||||||
|
ss << ", Rng: " << std::setw(10) << range;
|
||||||
|
ss << ", Rng Rt: " << std::setw(7) << range_rate;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** azimuth in radians */
|
||||||
|
double azimuth{};
|
||||||
|
/** elevations in radians */
|
||||||
|
double elevation{};
|
||||||
|
/** range in kilometers */
|
||||||
|
double range{};
|
||||||
|
/** range rate in kilometers per second */
|
||||||
|
double range_rate{};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& strm, const CoordTopocentric& t)
|
||||||
|
{
|
||||||
|
return strm << t.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "DateTime.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
bool jd_dmy(int JD, int c_year, int c_month, int c_day)
|
||||||
|
{
|
||||||
|
// For the Gregorian calendar:
|
||||||
|
int a = JD + 32044;
|
||||||
|
int b = (4 * a + 3) / 146097;
|
||||||
|
int c = a - (b * 146097) / 4;
|
||||||
|
|
||||||
|
// Then, for both calendars:
|
||||||
|
int d = (4 * c + 3) / 1461;
|
||||||
|
int e = c - (1461 * d) / 4;
|
||||||
|
int m = (5 * e + 2) / 153;
|
||||||
|
|
||||||
|
int day = e - (153 * m + 2) / 5 + 1;
|
||||||
|
int month = m + 3 - 12 * (m / 10);
|
||||||
|
int year = b * 100 + d - 4800 + m / 10;
|
||||||
|
|
||||||
|
if (c_year != year || c_month != month || c_day != day)
|
||||||
|
{
|
||||||
|
std::cout << year << " " << month << " " << day << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
for (int year = 1; year <= 9999; year++)
|
||||||
|
{
|
||||||
|
for (int month = 1; month <= 12; month++)
|
||||||
|
{
|
||||||
|
for (int day = 1; day <= DateTime::DaysInMonth(year, month); day++)
|
||||||
|
{
|
||||||
|
int hour = 23;
|
||||||
|
int minute = 59;
|
||||||
|
int second = 59;
|
||||||
|
int microsecond = 999999;
|
||||||
|
|
||||||
|
DateTime dt(year, month, day, hour, minute, second, microsecond);
|
||||||
|
|
||||||
|
if (dt.Year() != year ||
|
||||||
|
dt.Month() != month ||
|
||||||
|
dt.Day() != day ||
|
||||||
|
dt.Hour() != hour ||
|
||||||
|
dt.Minute() != minute ||
|
||||||
|
dt.Second() != second ||
|
||||||
|
dt.Microsecond() != microsecond)
|
||||||
|
{
|
||||||
|
std::cout << "failed" << std::endl;
|
||||||
|
std::cout << "Y " << dt.Year() << " " << year << std::endl;
|
||||||
|
std::cout << "M " << dt.Month() << " " << month << std::endl;
|
||||||
|
std::cout << "D " << dt.Day() << " " << day << std::endl;
|
||||||
|
std::cout << "H " << dt.Hour() << " " << hour << std::endl;
|
||||||
|
std::cout << "M " << dt.Minute() << " " << minute << std::endl;
|
||||||
|
std::cout << "S " << dt.Second() << " " << second << std::endl;
|
||||||
|
std::cout << "F " << dt.Microsecond() << " " << microsecond << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!jd_dmy(dt.Julian() + 0.5, year, month, day))
|
||||||
|
{
|
||||||
|
std::cout << "julian" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int hour = 1; hour < 24; hour++)
|
||||||
|
{
|
||||||
|
std::cout << hour << std::endl;
|
||||||
|
for (int minute = 0; minute < 60; minute++)
|
||||||
|
{
|
||||||
|
for (int second = 0; second < 60; second++)
|
||||||
|
{
|
||||||
|
for (int microsecond = 0; microsecond < 1000000; microsecond += 10000)
|
||||||
|
{
|
||||||
|
int year = 1000;
|
||||||
|
int month = 10;
|
||||||
|
int day = 23;
|
||||||
|
|
||||||
|
DateTime dt(year, month, day, hour, minute, second, microsecond);
|
||||||
|
|
||||||
|
if (dt.Year() != year ||
|
||||||
|
dt.Month() != month ||
|
||||||
|
dt.Day() != day ||
|
||||||
|
dt.Hour() != hour ||
|
||||||
|
dt.Minute() != minute ||
|
||||||
|
dt.Second() != second ||
|
||||||
|
dt.Microsecond() != microsecond)
|
||||||
|
{
|
||||||
|
std::cout << "failed" << std::endl;
|
||||||
|
std::cout << "Y " << dt.Year() << " " << year << std::endl;
|
||||||
|
std::cout << "M " << dt.Month() << " " << month << std::endl;
|
||||||
|
std::cout << "D " << dt.Day() << " " << day << std::endl;
|
||||||
|
std::cout << "H " << dt.Hour() << " " << hour << std::endl;
|
||||||
|
std::cout << "M " << dt.Minute() << " " << minute << std::endl;
|
||||||
|
std::cout << "S " << dt.Second() << " " << second << std::endl;
|
||||||
|
std::cout << "F " << dt.Microsecond() << " " << microsecond << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jd_dmy(1721425.5, 0, 0, 0);
|
||||||
|
|
||||||
|
DateTime d1(1000, 1, 1);
|
||||||
|
DateTime d2(2000, 1, 1);
|
||||||
|
DateTime d3(4000, 1, 1);
|
||||||
|
DateTime d4(6000, 1, 1);
|
||||||
|
DateTime d5(8000, 1, 1);
|
||||||
|
|
||||||
|
std::cout << std::setprecision(20);
|
||||||
|
std::cout << d1.Julian() << std::endl;
|
||||||
|
std::cout << d2.Julian() << std::endl;
|
||||||
|
std::cout << d3.Julian() << std::endl;
|
||||||
|
std::cout << d4.Julian() << std::endl;
|
||||||
|
std::cout << d5.Julian() << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,721 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include "TimeSpan.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
static int daysInMonth[2][13] = {
|
||||||
|
// 1 2 3 4 5 6 7 8 9 10 11 12
|
||||||
|
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||||
|
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
||||||
|
};
|
||||||
|
static int cumulDaysInMonth[2][13] = {
|
||||||
|
// 1 2 3 4 5 6 7 8 9 10 11 12
|
||||||
|
{0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
|
||||||
|
{0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents an instance in time.
|
||||||
|
*/
|
||||||
|
class DateTime
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default contructor
|
||||||
|
* Initialise to 0001/01/01 00:00:00.000000
|
||||||
|
*/
|
||||||
|
DateTime()
|
||||||
|
{
|
||||||
|
Initialise(1, 1, 1, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param[in] ticks raw tick value
|
||||||
|
*/
|
||||||
|
explicit DateTime(int64_t ticks)
|
||||||
|
: m_encoded(ticks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param[in] year the year
|
||||||
|
* @param[in] doy the day of the year
|
||||||
|
*/
|
||||||
|
DateTime(unsigned int year, double doy)
|
||||||
|
{
|
||||||
|
m_encoded = TimeSpan(
|
||||||
|
static_cast<int64_t>(AbsoluteDays(year, doy) * TicksPerDay)).Ticks();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param[in] year the year
|
||||||
|
* @param[in] month the month
|
||||||
|
* @param[in] day the day
|
||||||
|
*/
|
||||||
|
DateTime(int year, int month, int day)
|
||||||
|
{
|
||||||
|
Initialise(year, month, day, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
DateTime(int year, int month, int day, int hour, int minute, int second)
|
||||||
|
{
|
||||||
|
Initialise(year, month, day, hour, minute, second, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
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,
|
||||||
|
int month,
|
||||||
|
int day,
|
||||||
|
int hour,
|
||||||
|
int minute,
|
||||||
|
int second,
|
||||||
|
int microsecond)
|
||||||
|
{
|
||||||
|
if (!IsValidYearMonthDay(year, month, day) ||
|
||||||
|
hour < 0 || hour > 23 ||
|
||||||
|
minute < 0 || minute > 59 ||
|
||||||
|
second < 0 || second > 59 ||
|
||||||
|
microsecond < 0 || microsecond > 999999)
|
||||||
|
{
|
||||||
|
assert(false && "Invalid date");
|
||||||
|
}
|
||||||
|
m_encoded = TimeSpan(
|
||||||
|
AbsoluteDays(year, month, day),
|
||||||
|
hour,
|
||||||
|
minute,
|
||||||
|
second,
|
||||||
|
microsecond).Ticks();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current time
|
||||||
|
* @param[in] microseconds whether to set the microsecond component
|
||||||
|
* @returns a DateTime object set to the current date and time
|
||||||
|
*/
|
||||||
|
static DateTime Now(bool useMicroseconds = false)
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
if (useMicroseconds)
|
||||||
|
{
|
||||||
|
return DateTime(UnixEpoch +
|
||||||
|
duration_cast<microseconds>(system_clock::now()
|
||||||
|
.time_since_epoch()).count() * TicksPerMicrosecond);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return DateTime(UnixEpoch +
|
||||||
|
duration_cast<seconds>(system_clock::now()
|
||||||
|
.time_since_epoch()).count() * TicksPerSecond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find whether a year is a leap year
|
||||||
|
* @param[in] year the year to check
|
||||||
|
* @returns whether the year is a leap year
|
||||||
|
*/
|
||||||
|
static bool IsLeapYear(int year)
|
||||||
|
{
|
||||||
|
if (!IsValidYear(year))
|
||||||
|
{
|
||||||
|
assert(false && "Invalid year");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given year is valid
|
||||||
|
* @param[in] year the year to check
|
||||||
|
* @returns whether the year is valid
|
||||||
|
*/
|
||||||
|
static bool IsValidYear(int year)
|
||||||
|
{
|
||||||
|
bool valid = true;
|
||||||
|
if (year < 1 || year > 9999)
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the year/month is valid
|
||||||
|
* @param[in] year the year to check
|
||||||
|
* @param[in] month the month to check
|
||||||
|
* @returns whether the year/month is valid
|
||||||
|
*/
|
||||||
|
static bool IsValidYearMonth(int year, int month)
|
||||||
|
{
|
||||||
|
bool valid = true;
|
||||||
|
if (IsValidYear(year))
|
||||||
|
{
|
||||||
|
if (month < 1 || month > 12)
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the year/month/day is valid
|
||||||
|
* @param[in] year the year to check
|
||||||
|
* @param[in] month the month to check
|
||||||
|
* @param[in] day the day to check
|
||||||
|
* @returns whether the year/month/day is valid
|
||||||
|
*/
|
||||||
|
static bool IsValidYearMonthDay(int year, int month, int day)
|
||||||
|
{
|
||||||
|
bool valid = true;
|
||||||
|
if (IsValidYearMonth(year, month))
|
||||||
|
{
|
||||||
|
if (day < 1 || day > DaysInMonth(year, month))
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the number of days in a month given the year/month
|
||||||
|
* @param[in] year the year
|
||||||
|
* @param[in] month the month
|
||||||
|
* @returns the days in the given month
|
||||||
|
*/
|
||||||
|
static int DaysInMonth(int year, int month)
|
||||||
|
{
|
||||||
|
if (!IsValidYearMonth(year, month))
|
||||||
|
{
|
||||||
|
assert(false && "Invalid year and month");
|
||||||
|
}
|
||||||
|
|
||||||
|
const int* daysInMonthPtr;
|
||||||
|
|
||||||
|
if (IsLeapYear(year))
|
||||||
|
{
|
||||||
|
daysInMonthPtr = daysInMonth[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
daysInMonthPtr = daysInMonth[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return daysInMonthPtr[month];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the day of the year given the year/month/day
|
||||||
|
* @param[in] year the year
|
||||||
|
* @param[in] month the month
|
||||||
|
* @param[in] day the day
|
||||||
|
* @returns the day of the year
|
||||||
|
*/
|
||||||
|
int DayOfYear(int year, int month, int day) const
|
||||||
|
{
|
||||||
|
if (!IsValidYearMonthDay(year, month, day))
|
||||||
|
{
|
||||||
|
assert(false && "Invalid year, month and day");
|
||||||
|
}
|
||||||
|
|
||||||
|
int daysThisYear = day;
|
||||||
|
|
||||||
|
if (IsLeapYear(year))
|
||||||
|
{
|
||||||
|
daysThisYear += cumulDaysInMonth[1][month];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
daysThisYear += cumulDaysInMonth[0][month];
|
||||||
|
}
|
||||||
|
|
||||||
|
return daysThisYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
double AbsoluteDays(unsigned int year, double doy) const
|
||||||
|
{
|
||||||
|
int64_t previousYear = year - 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* + days in previous years ignoring leap days
|
||||||
|
* + Julian leap days before this year
|
||||||
|
* - minus prior century years
|
||||||
|
* + plus prior years divisible by 400 days
|
||||||
|
*/
|
||||||
|
int64_t daysSoFar = 365 * previousYear
|
||||||
|
+ previousYear / 4LL
|
||||||
|
- previousYear / 100LL
|
||||||
|
+ previousYear / 400LL;
|
||||||
|
|
||||||
|
return static_cast<double>(daysSoFar) + doy - 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AbsoluteDays(int year, int month, int day) const
|
||||||
|
{
|
||||||
|
int previousYear = year - 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* days this year (0 - ...)
|
||||||
|
* + days in previous years ignoring leap days
|
||||||
|
* + Julian leap days before this year
|
||||||
|
* - minus prior century years
|
||||||
|
* + plus prior years divisible by 400 days
|
||||||
|
*/
|
||||||
|
int result = DayOfYear(year, month, day) - 1
|
||||||
|
+ 365 * previousYear
|
||||||
|
+ previousYear / 4
|
||||||
|
- previousYear / 100
|
||||||
|
+ previousYear / 400;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeSpan TimeOfDay() const
|
||||||
|
{
|
||||||
|
return TimeSpan(Ticks() % TicksPerDay);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DayOfWeek() const
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The fixed day 1 (January 1, 1 Gregorian) is Monday.
|
||||||
|
* 0 Sunday
|
||||||
|
* 1 Monday
|
||||||
|
* 2 Tuesday
|
||||||
|
* 3 Wednesday
|
||||||
|
* 4 Thursday
|
||||||
|
* 5 Friday
|
||||||
|
* 6 Saturday
|
||||||
|
*/
|
||||||
|
return static_cast<int>(((m_encoded / TicksPerDay) + 1LL) % 7LL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Equals(const DateTime& dt) const
|
||||||
|
{
|
||||||
|
return (m_encoded == dt.m_encoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Compare(const DateTime& dt) const
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (m_encoded < dt.m_encoded)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (m_encoded > dt.m_encoded)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime AddYears(const int years) const
|
||||||
|
{
|
||||||
|
return AddMonths(years * 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime AddMonths(const int months) const
|
||||||
|
{
|
||||||
|
int year;
|
||||||
|
int month;
|
||||||
|
int day;
|
||||||
|
FromTicks(year, month, day);
|
||||||
|
month += months % 12;
|
||||||
|
year += months / 12;
|
||||||
|
|
||||||
|
if (month < 1)
|
||||||
|
{
|
||||||
|
month += 12;
|
||||||
|
--year;
|
||||||
|
}
|
||||||
|
else if (month > 12)
|
||||||
|
{
|
||||||
|
month -= 12;
|
||||||
|
++year;
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxday = DaysInMonth(year, month);
|
||||||
|
day = std::min(day, maxday);
|
||||||
|
|
||||||
|
return DateTime(year, month, day).Add(TimeOfDay());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a TimeSpan to this DateTime
|
||||||
|
* @param[in] t the TimeSpan to add
|
||||||
|
* @returns a DateTime which has the given TimeSpan added
|
||||||
|
*/
|
||||||
|
DateTime Add(const TimeSpan& t) const
|
||||||
|
{
|
||||||
|
return AddTicks(t.Ticks());
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime AddDays(const double days) const
|
||||||
|
{
|
||||||
|
return AddMicroseconds(days * 86400000000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime AddHours(const double hours) const
|
||||||
|
{
|
||||||
|
return AddMicroseconds(hours * 3600000000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime AddMinutes(const double minutes) const
|
||||||
|
{
|
||||||
|
return AddMicroseconds(minutes * 60000000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime AddSeconds(const double seconds) const
|
||||||
|
{
|
||||||
|
return AddMicroseconds(seconds * 1000000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime AddMicroseconds(const double microseconds) const
|
||||||
|
{
|
||||||
|
auto ticks = static_cast<int64_t>(microseconds * TicksPerMicrosecond);
|
||||||
|
return AddTicks(ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime AddTicks(int64_t ticks) const
|
||||||
|
{
|
||||||
|
return DateTime(m_encoded + ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of ticks
|
||||||
|
* @returns the number of ticks
|
||||||
|
*/
|
||||||
|
int64_t Ticks() const
|
||||||
|
{
|
||||||
|
return m_encoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FromTicks(int& year, int& month, int& day) const
|
||||||
|
{
|
||||||
|
int totalDays = static_cast<int>(m_encoded / TicksPerDay);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* number of 400 year cycles
|
||||||
|
*/
|
||||||
|
int num400 = totalDays / 146097;
|
||||||
|
totalDays -= num400 * 146097;
|
||||||
|
/*
|
||||||
|
* number of 100 year cycles
|
||||||
|
*/
|
||||||
|
int num100 = totalDays / 36524;
|
||||||
|
if (num100 == 4)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* last day of the last leap century
|
||||||
|
*/
|
||||||
|
num100 = 3;
|
||||||
|
}
|
||||||
|
totalDays -= num100 * 36524;
|
||||||
|
/*
|
||||||
|
* number of 4 year cycles
|
||||||
|
*/
|
||||||
|
int num4 = totalDays / 1461;
|
||||||
|
totalDays -= num4 * 1461;
|
||||||
|
/*
|
||||||
|
* number of years
|
||||||
|
*/
|
||||||
|
int num1 = totalDays / 365;
|
||||||
|
if (num1 == 4)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* last day of the last leap olympiad
|
||||||
|
*/
|
||||||
|
num1 = 3;
|
||||||
|
}
|
||||||
|
totalDays -= num1 * 365;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find year
|
||||||
|
*/
|
||||||
|
year = (num400 * 400) + (num100 * 100) + (num4 * 4) + num1 + 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert day of year to month/day
|
||||||
|
*/
|
||||||
|
const int* daysInMonthPtr;
|
||||||
|
if (IsLeapYear(year))
|
||||||
|
{
|
||||||
|
daysInMonthPtr = daysInMonth[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
daysInMonthPtr = daysInMonth[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
month = 1;
|
||||||
|
while (totalDays >= daysInMonthPtr[month] && month <= 12)
|
||||||
|
{
|
||||||
|
totalDays -= daysInMonthPtr[month++];
|
||||||
|
}
|
||||||
|
|
||||||
|
day = totalDays + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Year() const
|
||||||
|
{
|
||||||
|
int year;
|
||||||
|
int month;
|
||||||
|
int day;
|
||||||
|
FromTicks(year, month, day);
|
||||||
|
return year;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Month() const
|
||||||
|
{
|
||||||
|
int year;
|
||||||
|
int month;
|
||||||
|
int day;
|
||||||
|
FromTicks(year, month, day);
|
||||||
|
return month;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Day() const
|
||||||
|
{
|
||||||
|
int year;
|
||||||
|
int month;
|
||||||
|
int day;
|
||||||
|
FromTicks(year, month, day);
|
||||||
|
return day;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hour component
|
||||||
|
* @returns the hour component
|
||||||
|
*/
|
||||||
|
int Hour() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_encoded % TicksPerDay / TicksPerHour);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minute component
|
||||||
|
* @returns the minute component
|
||||||
|
*/
|
||||||
|
int Minute() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_encoded % TicksPerHour / TicksPerMinute);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Second component
|
||||||
|
* @returns the Second component
|
||||||
|
*/
|
||||||
|
int Second() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_encoded % TicksPerMinute / TicksPerSecond);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Microsecond component
|
||||||
|
* @returns the microsecond component
|
||||||
|
*/
|
||||||
|
int Microsecond() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_encoded % TicksPerSecond / TicksPerMicrosecond);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to a julian date
|
||||||
|
* @returns the julian date
|
||||||
|
*/
|
||||||
|
double ToJulian() const
|
||||||
|
{
|
||||||
|
auto ts = TimeSpan(Ticks());
|
||||||
|
return ts.TotalDays() + 1721425.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to greenwich sidereal time
|
||||||
|
* @returns the greenwich sidereal time
|
||||||
|
*/
|
||||||
|
double ToGreenwichSiderealTime() const
|
||||||
|
{
|
||||||
|
// julian date of previous midnight
|
||||||
|
double jd0 = floor(ToJulian() + 0.5) - 0.5;
|
||||||
|
// julian centuries since epoch
|
||||||
|
double t = (jd0 - 2451545.0) / 36525.0;
|
||||||
|
double jdf = ToJulian() - jd0;
|
||||||
|
|
||||||
|
double gt = 24110.54841 + t * (8640184.812866 + t * (0.093104 - t * 6.2E-6));
|
||||||
|
gt += jdf * 1.00273790935 * 86400.0;
|
||||||
|
|
||||||
|
// 360.0 / 86400.0 = 1.0 / 240.0
|
||||||
|
return Util::WrapTwoPI(Util::DegreesToRadians(gt / 240.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the modified julian date since the j2000 epoch
|
||||||
|
* January 1, 2000, at 12:00 TT
|
||||||
|
* @returns the modified julian date
|
||||||
|
*/
|
||||||
|
double ToJ2000() const
|
||||||
|
{
|
||||||
|
return ToJulian() - 2415020.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to local mean sidereal time (GMST plus the observer's longitude)
|
||||||
|
* @param[in] lon observers longitude
|
||||||
|
* @returns the local mean sidereal time
|
||||||
|
*/
|
||||||
|
double ToLocalMeanSiderealTime(const double lon) const
|
||||||
|
{
|
||||||
|
return Util::WrapTwoPI(ToGreenwichSiderealTime() + lon);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToString() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
int year;
|
||||||
|
int month;
|
||||||
|
int day;
|
||||||
|
FromTicks(year, month, day);
|
||||||
|
ss << std::right << std::setfill('0');
|
||||||
|
ss << std::setw(4) << year << "-";
|
||||||
|
ss << std::setw(2) << month << "-";
|
||||||
|
ss << std::setw(2) << day << " ";
|
||||||
|
ss << std::setw(2) << Hour() << ":";
|
||||||
|
ss << std::setw(2) << Minute() << ":";
|
||||||
|
ss << std::setw(2) << Second() << ".";
|
||||||
|
ss << std::setw(6) << Microsecond() << " UTC";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int64_t m_encoded{};
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& strm, const DateTime& dt)
|
||||||
|
{
|
||||||
|
return strm << dt.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline DateTime operator+(const DateTime& dt, TimeSpan ts)
|
||||||
|
{
|
||||||
|
return DateTime(dt.Ticks() + ts.Ticks());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline DateTime operator-(const DateTime& dt, const TimeSpan& ts)
|
||||||
|
{
|
||||||
|
return DateTime(dt.Ticks() - ts.Ticks());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline TimeSpan operator-(const DateTime& dt1, const DateTime& dt2)
|
||||||
|
{
|
||||||
|
return TimeSpan(dt1.Ticks() - dt2.Ticks());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const DateTime& dt1, const DateTime& dt2)
|
||||||
|
{
|
||||||
|
return dt1.Equals(dt2);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator>(const DateTime& dt1, const DateTime& dt2)
|
||||||
|
{
|
||||||
|
return (dt1.Compare(dt2) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator>=(const DateTime& dt1, const DateTime& dt2)
|
||||||
|
{
|
||||||
|
return (dt1.Compare(dt2) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const DateTime& dt1, const DateTime& dt2)
|
||||||
|
{
|
||||||
|
return !dt1.Equals(dt2);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<(const DateTime& dt1, const DateTime& dt2)
|
||||||
|
{
|
||||||
|
return (dt1.Compare(dt2) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<=(const DateTime& dt1, const DateTime& dt2)
|
||||||
|
{
|
||||||
|
return (dt1.Compare(dt2) <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1 @@
|
||||||
|
#include "DecayedException.h"
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DateTime.h"
|
||||||
|
#include "Vector.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The exception that the SGP4 class throws when a satellite decays.
|
||||||
|
*/
|
||||||
|
class DecayedException : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param[in] dt time of the event
|
||||||
|
* @param[in] pos position of the satellite at dt
|
||||||
|
* @param[in] vel velocity of the satellite at dt
|
||||||
|
*/
|
||||||
|
DecayedException(const DateTime& dt, const Vector& pos, const Vector& vel)
|
||||||
|
: runtime_error("Satellite decayed")
|
||||||
|
, _dt(dt)
|
||||||
|
, _pos(pos)
|
||||||
|
, _vel(vel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the date
|
||||||
|
*/
|
||||||
|
DateTime Decayed() const
|
||||||
|
{
|
||||||
|
return _dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the position
|
||||||
|
*/
|
||||||
|
Vector Position() const
|
||||||
|
{
|
||||||
|
return _pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the velocity
|
||||||
|
*/
|
||||||
|
Vector Velocity() const
|
||||||
|
{
|
||||||
|
return _vel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DateTime _dt;
|
||||||
|
Vector _pos;
|
||||||
|
Vector _vel;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Eci.h"
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a DateTime and Geodetic position to Eci coordinates
|
||||||
|
* @param[in] dt the date
|
||||||
|
* @param[in] geo the geodetic position
|
||||||
|
*/
|
||||||
|
void Eci::ToEci(const DateTime& dt, const CoordGeodetic &geo)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* set date
|
||||||
|
*/
|
||||||
|
m_dt = dt;
|
||||||
|
|
||||||
|
static const double mfactor = kTWOPI * (kOMEGA_E / kSECONDS_PER_DAY);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate Local Mean Sidereal Time for observers longitude
|
||||||
|
*/
|
||||||
|
const double theta = m_dt.ToLocalMeanSiderealTime(geo.longitude);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* take into account earth flattening
|
||||||
|
*/
|
||||||
|
const double c = 1.0
|
||||||
|
/ sqrt(1.0 + kF * (kF - 2.0) * pow(sin(geo.latitude), 2.0));
|
||||||
|
const double s = pow(1.0 - kF, 2.0) * c;
|
||||||
|
const double achcp = (kXKMPER * c + geo.altitude) * cos(geo.latitude);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* X position in km
|
||||||
|
* Y position in km
|
||||||
|
* Z position in km
|
||||||
|
* W magnitude in km
|
||||||
|
*/
|
||||||
|
m_position.x = achcp * cos(theta);
|
||||||
|
m_position.y = achcp * sin(theta);
|
||||||
|
m_position.z = (kXKMPER * s + geo.altitude) * sin(geo.latitude);
|
||||||
|
m_position.w = m_position.Magnitude();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* X velocity in km/s
|
||||||
|
* Y velocity in km/s
|
||||||
|
* Z velocity in km/s
|
||||||
|
* W magnitude in km/s
|
||||||
|
*/
|
||||||
|
m_velocity.x = -mfactor * m_position.y;
|
||||||
|
m_velocity.y = mfactor * m_position.x;
|
||||||
|
m_velocity.z = 0.0;
|
||||||
|
m_velocity.w = m_velocity.Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the position in geodetic form
|
||||||
|
*/
|
||||||
|
CoordGeodetic Eci::ToGeodetic() const
|
||||||
|
{
|
||||||
|
const double theta = Util::AcTan(m_position.y, m_position.x);
|
||||||
|
|
||||||
|
const double lon = Util::WrapNegPosPI(theta
|
||||||
|
- m_dt.ToGreenwichSiderealTime());
|
||||||
|
|
||||||
|
const double r = sqrt((m_position.x * m_position.x)
|
||||||
|
+ (m_position.y * m_position.y));
|
||||||
|
|
||||||
|
static const double e2 = kF * (2.0 - kF);
|
||||||
|
|
||||||
|
double lat = Util::AcTan(m_position.z, r);
|
||||||
|
double phi = 0.0;
|
||||||
|
double c = 0.0;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
phi = lat;
|
||||||
|
const double sinphi = sin(phi);
|
||||||
|
c = 1.0 / sqrt(1.0 - e2 * sinphi * sinphi);
|
||||||
|
lat = Util::AcTan(m_position.z + kXKMPER * c * e2 * sinphi, r);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
while (fabs(lat - phi) >= 1e-10 && cnt < 10);
|
||||||
|
|
||||||
|
const double alt = r / cos(lat) - kXKMPER * c;
|
||||||
|
|
||||||
|
return CoordGeodetic(lat, lon, alt, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoordGeodetic.h"
|
||||||
|
#include "Vector.h"
|
||||||
|
#include "DateTime.h"
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stores an Earth-centered inertial position for a particular time.
|
||||||
|
*/
|
||||||
|
class Eci
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param[in] dt the date to be used for this position
|
||||||
|
* @param[in] latitude the latitude in degrees
|
||||||
|
* @param[in] longitude the longitude in degrees
|
||||||
|
* @param[in] altitude the altitude in kilometers
|
||||||
|
*/
|
||||||
|
Eci(const DateTime& dt,
|
||||||
|
const double latitude,
|
||||||
|
const double longitude,
|
||||||
|
const double altitude)
|
||||||
|
{
|
||||||
|
ToEci(dt, CoordGeodetic(latitude, longitude, altitude));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param[in] dt the date to be used for this position
|
||||||
|
* @param[in] geo the position
|
||||||
|
*/
|
||||||
|
Eci(const DateTime& dt, const CoordGeodetic& geo)
|
||||||
|
{
|
||||||
|
ToEci(dt, geo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param[in] dt the date to be used for this position
|
||||||
|
* @param[in] position the position
|
||||||
|
*/
|
||||||
|
Eci(const DateTime &dt, const Vector &position)
|
||||||
|
: m_dt(dt)
|
||||||
|
, m_position(position)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param[in] dt the date to be used for this position
|
||||||
|
* @param[in] position the position
|
||||||
|
* @param[in] velocity the velocity
|
||||||
|
*/
|
||||||
|
Eci(const DateTime &dt, const Vector &position, const Vector &velocity)
|
||||||
|
: m_dt(dt)
|
||||||
|
, m_position(position)
|
||||||
|
, m_velocity(velocity)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equality operator
|
||||||
|
* @param dt the date to compare
|
||||||
|
* @returns true if the object matches
|
||||||
|
*/
|
||||||
|
bool operator==(const DateTime& dt) const
|
||||||
|
{
|
||||||
|
return m_dt == dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inequality operator
|
||||||
|
* @param dt the date to compare
|
||||||
|
* @returns true if the object doesn't match
|
||||||
|
*/
|
||||||
|
bool operator!=(const DateTime& dt) const
|
||||||
|
{
|
||||||
|
return m_dt != dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update this object with a new date and geodetic position
|
||||||
|
* @param dt new date
|
||||||
|
* @param geo new geodetic position
|
||||||
|
*/
|
||||||
|
void Update(const DateTime& dt, const CoordGeodetic& geo)
|
||||||
|
{
|
||||||
|
ToEci(dt, geo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the position
|
||||||
|
*/
|
||||||
|
Vector Position() const
|
||||||
|
{
|
||||||
|
return m_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the velocity
|
||||||
|
*/
|
||||||
|
Vector Velocity() const
|
||||||
|
{
|
||||||
|
return m_velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the date
|
||||||
|
*/
|
||||||
|
DateTime GetDateTime() const
|
||||||
|
{
|
||||||
|
return m_dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the position in geodetic form
|
||||||
|
*/
|
||||||
|
CoordGeodetic ToGeodetic() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ToEci(const DateTime& dt, const CoordGeodetic& geo);
|
||||||
|
|
||||||
|
DateTime m_dt;
|
||||||
|
Vector m_position;
|
||||||
|
Vector m_velocity;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Globals.h"
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
const double kAE = 1.0;
|
||||||
|
const double kQ0 = 120.0;
|
||||||
|
const double kS0 = 78.0;
|
||||||
|
const double kMU = 398600.8;
|
||||||
|
const double kXKMPER = 6378.135;
|
||||||
|
const double kXJ2 = 1.082616e-3;
|
||||||
|
const double kXJ3 = -2.53881e-6;
|
||||||
|
const double kXJ4 = -1.65597e-6;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* alternative XKE
|
||||||
|
* affects final results
|
||||||
|
* aiaa-2006-6573
|
||||||
|
* const double kXKE = 60.0 / sqrt(kXKMPER * kXKMPER * kXKMPER / kMU);
|
||||||
|
* dundee
|
||||||
|
* const double kXKE = 7.43669161331734132e-2;
|
||||||
|
*/
|
||||||
|
const double kXKE = 60.0 / sqrt(kXKMPER * kXKMPER * kXKMPER / kMU);
|
||||||
|
const double kCK2 = 0.5 * kXJ2 * kAE * kAE;
|
||||||
|
const double kCK4 = -0.375 * kXJ4 * kAE * kAE * kAE * kAE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* alternative QOMS2T
|
||||||
|
* affects final results
|
||||||
|
* aiaa-2006-6573
|
||||||
|
* #define QOMS2T (pow(((Q0 - S0) / XKMPER), 4.0))
|
||||||
|
* dundee
|
||||||
|
* #define QOMS2T (1.880279159015270643865e-9)
|
||||||
|
*/
|
||||||
|
const double kQOMS2T = pow(((kQ0 - kS0) / kXKMPER), 4.0);
|
||||||
|
|
||||||
|
const double kS = kAE * (1.0 + kS0 / kXKMPER);
|
||||||
|
const double kPI = 3.14159265358979323846264338327950288419716939937510582;
|
||||||
|
const double kTWOPI = 2.0 * kPI;
|
||||||
|
const double kTWOTHIRD = 2.0 / 3.0;
|
||||||
|
const double kTHDT = 4.37526908801129966e-3;
|
||||||
|
/*
|
||||||
|
* earth flattening
|
||||||
|
*/
|
||||||
|
const double kF = 1.0 / 298.26;
|
||||||
|
/*
|
||||||
|
* earth rotation per sideral day
|
||||||
|
*/
|
||||||
|
const double kOMEGA_E = 1.00273790934;
|
||||||
|
const double kAU = 1.49597870691e8;
|
||||||
|
|
||||||
|
const double kSECONDS_PER_DAY = 86400.0;
|
||||||
|
const double kMINUTES_PER_DAY = 1440.0;
|
||||||
|
const double kHOURS_PER_DAY = 24.0;
|
||||||
|
|
||||||
|
const double kA3OVK2 = -kXJ3 / kCK2 * kAE * kAE * kAE;
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Observer.h"
|
||||||
|
#include "CoordTopocentric.h"
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculate lookangle between the observer and the passed in Eci object
|
||||||
|
*/
|
||||||
|
CoordTopocentric Observer::GetLookAngle(const Eci &eci)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* update the observers Eci to match the time of the Eci passed in
|
||||||
|
* if necessary
|
||||||
|
*/
|
||||||
|
Update(eci.GetDateTime());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculate differences
|
||||||
|
*/
|
||||||
|
Vector range_rate = eci.Velocity() - m_eci.Velocity();
|
||||||
|
Vector range = eci.Position() - m_eci.Position();
|
||||||
|
|
||||||
|
range.w = range.Magnitude();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate Local Mean Sidereal Time for observers longitude
|
||||||
|
*/
|
||||||
|
double theta = eci.GetDateTime().ToLocalMeanSiderealTime(m_geo.longitude);
|
||||||
|
|
||||||
|
double sin_lat = sin(m_geo.latitude);
|
||||||
|
double cos_lat = cos(m_geo.latitude);
|
||||||
|
double sin_theta = sin(theta);
|
||||||
|
double cos_theta = cos(theta);
|
||||||
|
|
||||||
|
double top_s = sin_lat * cos_theta * range.x
|
||||||
|
+ sin_lat * sin_theta * range.y - cos_lat * range.z;
|
||||||
|
double top_e = -sin_theta * range.x
|
||||||
|
+ cos_theta * range.y;
|
||||||
|
double top_z = cos_lat * cos_theta * range.x
|
||||||
|
+ cos_lat * sin_theta * range.y + sin_lat * range.z;
|
||||||
|
double az = atan(-top_e / top_s);
|
||||||
|
|
||||||
|
if (top_s > 0.0)
|
||||||
|
{
|
||||||
|
az += kPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (az < 0.0)
|
||||||
|
{
|
||||||
|
az += 2.0 * kPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
double el = asin(top_z / range.w);
|
||||||
|
double rate = range.Dot(range_rate) / range.w;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* azimuth in radians
|
||||||
|
* elevation in radians
|
||||||
|
* range in km
|
||||||
|
* range rate in km/s
|
||||||
|
*/
|
||||||
|
return CoordTopocentric(az,
|
||||||
|
el,
|
||||||
|
range.w,
|
||||||
|
rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoordGeodetic.h"
|
||||||
|
#include "Eci.h"
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
class DateTime;
|
||||||
|
struct CoordTopocentric;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stores an observers location in Eci coordinates.
|
||||||
|
*/
|
||||||
|
class Observer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param[in] latitude observers latitude in degrees
|
||||||
|
* @param[in] longitude observers longitude in degrees
|
||||||
|
* @param[in] altitude observers altitude in kilometers
|
||||||
|
*/
|
||||||
|
Observer(const double latitude,
|
||||||
|
const double longitude,
|
||||||
|
const double altitude)
|
||||||
|
: m_geo(latitude, longitude, altitude)
|
||||||
|
, m_eci(DateTime(), m_geo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param[in] geo the observers position
|
||||||
|
*/
|
||||||
|
explicit Observer(const CoordGeodetic &geo)
|
||||||
|
: m_geo(geo)
|
||||||
|
, m_eci(DateTime(), geo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the observers location
|
||||||
|
* @param[in] geo the observers position
|
||||||
|
*/
|
||||||
|
void SetLocation(const CoordGeodetic& geo)
|
||||||
|
{
|
||||||
|
m_geo = geo;
|
||||||
|
m_eci.Update(m_eci.GetDateTime(), m_geo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the observers location
|
||||||
|
* @returns the observers position
|
||||||
|
*/
|
||||||
|
CoordGeodetic GetLocation() const
|
||||||
|
{
|
||||||
|
return m_geo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the look angle for the observers position to the object
|
||||||
|
* @param[in] eci the object to find the look angle to
|
||||||
|
* @returns the lookup angle
|
||||||
|
*/
|
||||||
|
CoordTopocentric GetLookAngle(const Eci &eci);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @param[in] dt the date to update the observers position for
|
||||||
|
*/
|
||||||
|
void Update(const DateTime &dt)
|
||||||
|
{
|
||||||
|
if (m_eci != dt)
|
||||||
|
{
|
||||||
|
m_eci.Update(dt, m_geo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** the observers position */
|
||||||
|
CoordGeodetic m_geo;
|
||||||
|
/** the observers Eci for a particular time */
|
||||||
|
Eci m_eci;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "OrbitalElements.h"
|
||||||
|
|
||||||
|
#include "Tle.h"
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
OrbitalElements::OrbitalElements(const Tle& tle)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* extract and format tle data
|
||||||
|
*/
|
||||||
|
mean_anomoly_ = tle.MeanAnomaly(false);
|
||||||
|
ascending_node_ = tle.RightAscendingNode(false);
|
||||||
|
argument_perigee_ = tle.ArgumentPerigee(false);
|
||||||
|
eccentricity_ = tle.Eccentricity();
|
||||||
|
inclination_ = tle.Inclination(false);
|
||||||
|
mean_motion_ = tle.MeanMotion() * kTWOPI / kMINUTES_PER_DAY;
|
||||||
|
bstar_ = tle.BStar();
|
||||||
|
epoch_ = tle.Epoch();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* recover original mean motion (xnodp) and semimajor axis (aodp)
|
||||||
|
* from input elements
|
||||||
|
*/
|
||||||
|
const double a1 = pow(kXKE / MeanMotion(), kTWOTHIRD);
|
||||||
|
const double cosio = cos(Inclination());
|
||||||
|
const double theta2 = cosio * cosio;
|
||||||
|
const double x3thm1 = 3.0 * theta2 - 1.0;
|
||||||
|
const double eosq = Eccentricity() * Eccentricity();
|
||||||
|
const double betao2 = 1.0 - eosq;
|
||||||
|
const double betao = sqrt(betao2);
|
||||||
|
const double temp = (1.5 * kCK2) * x3thm1 / (betao * betao2);
|
||||||
|
const double del1 = temp / (a1 * a1);
|
||||||
|
const double a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0)));
|
||||||
|
const double del0 = temp / (a0 * a0);
|
||||||
|
|
||||||
|
recovered_mean_motion_ = MeanMotion() / (1.0 + del0);
|
||||||
|
/*
|
||||||
|
* alternative way to calculate
|
||||||
|
* doesnt affect final results
|
||||||
|
* recovered_semi_major_axis_ = pow(XKE / RecoveredMeanMotion(), TWOTHIRD);
|
||||||
|
*/
|
||||||
|
recovered_semi_major_axis_ = a0 / (1.0 - del0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find perigee and period
|
||||||
|
*/
|
||||||
|
perigee_ = (RecoveredSemiMajorAxis() * (1.0 - Eccentricity()) - kAE) * kXKMPER;
|
||||||
|
period_ = kTWOPI / RecoveredMeanMotion();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Util.h"
|
||||||
|
#include "DateTime.h"
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
class Tle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The extracted orbital elements used by the SGP4 propagator.
|
||||||
|
*/
|
||||||
|
class OrbitalElements
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit OrbitalElements(const Tle& tle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XMO
|
||||||
|
*/
|
||||||
|
double MeanAnomoly() const
|
||||||
|
{
|
||||||
|
return mean_anomoly_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XNODEO
|
||||||
|
*/
|
||||||
|
double AscendingNode() const
|
||||||
|
{
|
||||||
|
return ascending_node_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OMEGAO
|
||||||
|
*/
|
||||||
|
double ArgumentPerigee() const
|
||||||
|
{
|
||||||
|
return argument_perigee_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EO
|
||||||
|
*/
|
||||||
|
double Eccentricity() const
|
||||||
|
{
|
||||||
|
return eccentricity_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XINCL
|
||||||
|
*/
|
||||||
|
double Inclination() const
|
||||||
|
{
|
||||||
|
return inclination_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XNO
|
||||||
|
*/
|
||||||
|
double MeanMotion() const
|
||||||
|
{
|
||||||
|
return mean_motion_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BSTAR
|
||||||
|
*/
|
||||||
|
double BStar() const
|
||||||
|
{
|
||||||
|
return bstar_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AODP
|
||||||
|
*/
|
||||||
|
double RecoveredSemiMajorAxis() const
|
||||||
|
{
|
||||||
|
return recovered_semi_major_axis_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XNODP
|
||||||
|
*/
|
||||||
|
double RecoveredMeanMotion() const
|
||||||
|
{
|
||||||
|
return recovered_mean_motion_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PERIGE
|
||||||
|
*/
|
||||||
|
double Perigee() const
|
||||||
|
{
|
||||||
|
return perigee_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Period in minutes
|
||||||
|
*/
|
||||||
|
double Period() const
|
||||||
|
{
|
||||||
|
return period_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EPOCH
|
||||||
|
*/
|
||||||
|
DateTime Epoch() const
|
||||||
|
{
|
||||||
|
return epoch_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
double mean_anomoly_;
|
||||||
|
double ascending_node_;
|
||||||
|
double argument_perigee_;
|
||||||
|
double eccentricity_;
|
||||||
|
double inclination_;
|
||||||
|
double mean_motion_;
|
||||||
|
double bstar_;
|
||||||
|
double recovered_semi_major_axis_;
|
||||||
|
double recovered_mean_motion_;
|
||||||
|
double perigee_;
|
||||||
|
double period_;
|
||||||
|
DateTime epoch_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,260 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Tle.h"
|
||||||
|
#include "OrbitalElements.h"
|
||||||
|
#include "Eci.h"
|
||||||
|
#include "SatelliteException.h"
|
||||||
|
#include "DecayedException.h"
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @mainpage
|
||||||
|
*
|
||||||
|
* This documents the SGP4 tracking library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The simplified perturbations model 4 propagater.
|
||||||
|
*/
|
||||||
|
class SGP4
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit SGP4(const Tle& tle)
|
||||||
|
: elements_(tle)
|
||||||
|
{
|
||||||
|
Initialise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetTle(const Tle& tle);
|
||||||
|
Eci FindPosition(double tsince) const;
|
||||||
|
Eci FindPosition(const DateTime& date) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct CommonConstants
|
||||||
|
{
|
||||||
|
double cosio;
|
||||||
|
double sinio;
|
||||||
|
double eta;
|
||||||
|
double t2cof;
|
||||||
|
double x1mth2;
|
||||||
|
double x3thm1;
|
||||||
|
double x7thm1;
|
||||||
|
double aycof;
|
||||||
|
double xlcof;
|
||||||
|
double xnodcf;
|
||||||
|
double c1;
|
||||||
|
double c4;
|
||||||
|
double omgdot; // secular rate of omega (radians/sec)
|
||||||
|
double xnodot; // secular rate of xnode (radians/sec)
|
||||||
|
double xmdot; // secular rate of xmo (radians/sec)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NearSpaceConstants
|
||||||
|
{
|
||||||
|
double c5;
|
||||||
|
double omgcof;
|
||||||
|
double xmcof;
|
||||||
|
double delmo;
|
||||||
|
double sinmo;
|
||||||
|
double d2;
|
||||||
|
double d3;
|
||||||
|
double d4;
|
||||||
|
double t3cof;
|
||||||
|
double t4cof;
|
||||||
|
double t5cof;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeepSpaceConstants
|
||||||
|
{
|
||||||
|
double gsto;
|
||||||
|
double zmol;
|
||||||
|
double zmos;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lunar / solar constants for epoch
|
||||||
|
* applied during DeepSpaceSecular()
|
||||||
|
*/
|
||||||
|
double sse;
|
||||||
|
double ssi;
|
||||||
|
double ssl;
|
||||||
|
double ssg;
|
||||||
|
double ssh;
|
||||||
|
/*
|
||||||
|
* lunar / solar constants
|
||||||
|
* used during DeepSpaceCalculateLunarSolarTerms()
|
||||||
|
*/
|
||||||
|
double se2;
|
||||||
|
double si2;
|
||||||
|
double sl2;
|
||||||
|
double sgh2;
|
||||||
|
double sh2;
|
||||||
|
double se3;
|
||||||
|
double si3;
|
||||||
|
double sl3;
|
||||||
|
double sgh3;
|
||||||
|
double sh3;
|
||||||
|
double sl4;
|
||||||
|
double sgh4;
|
||||||
|
double ee2;
|
||||||
|
double e3;
|
||||||
|
double xi2;
|
||||||
|
double xi3;
|
||||||
|
double xl2;
|
||||||
|
double xl3;
|
||||||
|
double xl4;
|
||||||
|
double xgh2;
|
||||||
|
double xgh3;
|
||||||
|
double xgh4;
|
||||||
|
double xh2;
|
||||||
|
double xh3;
|
||||||
|
/*
|
||||||
|
* used during DeepSpaceCalcDotTerms()
|
||||||
|
*/
|
||||||
|
double d2201;
|
||||||
|
double d2211;
|
||||||
|
double d3210;
|
||||||
|
double d3222;
|
||||||
|
double d4410;
|
||||||
|
double d4422;
|
||||||
|
double d5220;
|
||||||
|
double d5232;
|
||||||
|
double d5421;
|
||||||
|
double d5433;
|
||||||
|
double del1;
|
||||||
|
double del2;
|
||||||
|
double del3;
|
||||||
|
/*
|
||||||
|
* integrator constants
|
||||||
|
*/
|
||||||
|
double xfact;
|
||||||
|
double xlamo;
|
||||||
|
|
||||||
|
enum TOrbitShape
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
RESONANCE,
|
||||||
|
SYNCHRONOUS
|
||||||
|
} shape;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IntegratorParams
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* integrator values
|
||||||
|
*/
|
||||||
|
double xli;
|
||||||
|
double xni;
|
||||||
|
double atime;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Initialise();
|
||||||
|
static void RecomputeConstants(const double xinc,
|
||||||
|
double& sinio,
|
||||||
|
double& cosio,
|
||||||
|
double& x3thm1,
|
||||||
|
double& x1mth2,
|
||||||
|
double& x7thm1,
|
||||||
|
double& xlcof,
|
||||||
|
double& aycof);
|
||||||
|
Eci FindPositionSDP4(const double tsince) const;
|
||||||
|
Eci FindPositionSGP4(double tsince) const;
|
||||||
|
static Eci CalculateFinalPositionVelocity(
|
||||||
|
const DateTime& date,
|
||||||
|
const double e,
|
||||||
|
const double a,
|
||||||
|
const double omega,
|
||||||
|
const double xl,
|
||||||
|
const double xnode,
|
||||||
|
const double xinc,
|
||||||
|
const double xlcof,
|
||||||
|
const double aycof,
|
||||||
|
const double x3thm1,
|
||||||
|
const double x1mth2,
|
||||||
|
const double x7thm1,
|
||||||
|
const double cosio,
|
||||||
|
const double sinio);
|
||||||
|
/**
|
||||||
|
* Deep space initialisation
|
||||||
|
*/
|
||||||
|
void DeepSpaceInitialise(
|
||||||
|
const double eosq,
|
||||||
|
const double sinio,
|
||||||
|
const double cosio,
|
||||||
|
const double betao,
|
||||||
|
const double theta2,
|
||||||
|
const double betao2,
|
||||||
|
const double xmdot,
|
||||||
|
const double omgdot,
|
||||||
|
const double xnodot);
|
||||||
|
/**
|
||||||
|
* Calculate lunar / solar periodics and apply
|
||||||
|
*/
|
||||||
|
static void DeepSpacePeriodics(
|
||||||
|
const double tsince,
|
||||||
|
const DeepSpaceConstants& ds_constants,
|
||||||
|
double& em,
|
||||||
|
double& xinc,
|
||||||
|
double& omgasm,
|
||||||
|
double& xnodes,
|
||||||
|
double& xll);
|
||||||
|
/**
|
||||||
|
* Deep space secular effects
|
||||||
|
*/
|
||||||
|
static void DeepSpaceSecular(
|
||||||
|
const double tsince,
|
||||||
|
const OrbitalElements& elements,
|
||||||
|
const CommonConstants& c_constants,
|
||||||
|
const DeepSpaceConstants& ds_constants,
|
||||||
|
IntegratorParams& integ_params,
|
||||||
|
double& xll,
|
||||||
|
double& omgasm,
|
||||||
|
double& xnodes,
|
||||||
|
double& em,
|
||||||
|
double& xinc,
|
||||||
|
double& xn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset
|
||||||
|
*/
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the constants used
|
||||||
|
*/
|
||||||
|
struct CommonConstants common_consts_;
|
||||||
|
struct NearSpaceConstants nearspace_consts_;
|
||||||
|
struct DeepSpaceConstants deepspace_consts_;
|
||||||
|
mutable struct IntegratorParams integrator_params_;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the orbit data
|
||||||
|
*/
|
||||||
|
OrbitalElements elements_;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flags
|
||||||
|
*/
|
||||||
|
bool use_simple_model_;
|
||||||
|
bool use_deep_space_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1 @@
|
||||||
|
#include "SatelliteException.h"
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The exception that the SGP4 class throws upon an error.
|
||||||
|
*/
|
||||||
|
class SatelliteException : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit SatelliteException(const char* message)
|
||||||
|
: runtime_error(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "SolarPosition.h"
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
Eci SolarPosition::FindPosition(const DateTime& dt)
|
||||||
|
{
|
||||||
|
const double mjd = dt.ToJ2000();
|
||||||
|
const double year = 1900 + mjd / 365.25;
|
||||||
|
const double T = (mjd + Delta_ET(year) / kSECONDS_PER_DAY) / 36525.0;
|
||||||
|
const double M = Util::DegreesToRadians(Util::Wrap360(358.47583
|
||||||
|
+ Util::Wrap360(35999.04975 * T)
|
||||||
|
- (0.000150 + 0.0000033 * T) * T * T));
|
||||||
|
const double L = Util::DegreesToRadians(Util::Wrap360(279.69668
|
||||||
|
+ Util::Wrap360(36000.76892 * T)
|
||||||
|
+ 0.0003025 * T*T));
|
||||||
|
const double e = 0.01675104 - (0.0000418 + 0.000000126 * T) * T;
|
||||||
|
const double C = Util::DegreesToRadians((1.919460
|
||||||
|
- (0.004789 + 0.000014 * T) * T) * sin(M)
|
||||||
|
+ (0.020094 - 0.000100 * T) * sin(2 * M)
|
||||||
|
+ 0.000293 * sin(3 * M));
|
||||||
|
const double O = Util::DegreesToRadians(
|
||||||
|
Util::Wrap360(259.18 - 1934.142 * T));
|
||||||
|
const double Lsa = Util::WrapTwoPI(L + C
|
||||||
|
- Util::DegreesToRadians(0.00569 - 0.00479 * sin(O)));
|
||||||
|
const double nu = Util::WrapTwoPI(M + C);
|
||||||
|
double R = 1.0000002 * (1 - e * e) / (1 + e * cos(nu));
|
||||||
|
const double eps = Util::DegreesToRadians(23.452294 - (0.0130125
|
||||||
|
+ (0.00000164 - 0.000000503 * T) * T) * T + 0.00256 * cos(O));
|
||||||
|
R = R * kAU;
|
||||||
|
|
||||||
|
Vector solar_position(R * cos(Lsa),
|
||||||
|
R * sin(Lsa) * cos(eps),
|
||||||
|
R * sin(Lsa) * sin(eps),
|
||||||
|
R);
|
||||||
|
|
||||||
|
return Eci(dt, solar_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
double SolarPosition::Delta_ET(double year) const
|
||||||
|
{
|
||||||
|
return 26.465 + 0.747622 * (year - 1950) + 1.886913
|
||||||
|
* sin(kTWOPI * (year - 1975) / 33);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DateTime.h"
|
||||||
|
#include "Eci.h"
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the position of the sun
|
||||||
|
*/
|
||||||
|
class SolarPosition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SolarPosition() = default;
|
||||||
|
|
||||||
|
Eci FindPosition(const DateTime& dt);
|
||||||
|
|
||||||
|
private:
|
||||||
|
double Delta_ET(double year) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "TimeSpan.h"
|
|
@ -0,0 +1,259 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
static const int64_t TicksPerDay = 86400000000LL;
|
||||||
|
static const int64_t TicksPerHour = 3600000000LL;
|
||||||
|
static const int64_t TicksPerMinute = 60000000LL;
|
||||||
|
static const int64_t TicksPerSecond = 1000000LL;
|
||||||
|
static const int64_t TicksPerMillisecond = 1000LL;
|
||||||
|
static const int64_t TicksPerMicrosecond = 1LL;
|
||||||
|
|
||||||
|
static const int64_t UnixEpoch = 62135596800000000LL;
|
||||||
|
|
||||||
|
static const int64_t MaxValueTicks = 315537897599999999LL;
|
||||||
|
|
||||||
|
// 1582-Oct-15
|
||||||
|
static const int64_t GregorianStart = 49916304000000000LL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a time interval.
|
||||||
|
*
|
||||||
|
* Represents a time interval (duration/elapsed) that is measured as a positive
|
||||||
|
* or negative number of days, hours, minutes, seconds, and fractions
|
||||||
|
* of a second.
|
||||||
|
*/
|
||||||
|
class TimeSpan
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit TimeSpan(int64_t ticks)
|
||||||
|
: m_ticks(ticks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeSpan(int hours, int minutes, int seconds)
|
||||||
|
{
|
||||||
|
CalculateTicks(0, hours, minutes, seconds, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeSpan(int days, int hours, int minutes, int seconds)
|
||||||
|
{
|
||||||
|
CalculateTicks(days, hours, minutes, seconds, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeSpan(int days, int hours, int minutes, int seconds, int microseconds)
|
||||||
|
{
|
||||||
|
CalculateTicks(days, hours, minutes, seconds, microseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeSpan Add(const TimeSpan& ts) const
|
||||||
|
{
|
||||||
|
return TimeSpan(m_ticks + ts.m_ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeSpan Subtract(const TimeSpan& ts) const
|
||||||
|
{
|
||||||
|
return TimeSpan(m_ticks - ts.m_ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Compare(const TimeSpan& ts) const
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (m_ticks < ts.m_ticks)
|
||||||
|
{
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
if (m_ticks > ts.m_ticks)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Equals(const TimeSpan& ts) const
|
||||||
|
{
|
||||||
|
return m_ticks == ts.m_ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Days() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_ticks / TicksPerDay);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Hours() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_ticks % TicksPerDay / TicksPerHour);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Minutes() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_ticks % TicksPerHour / TicksPerMinute);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Seconds() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_ticks % TicksPerMinute / TicksPerSecond);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Milliseconds() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_ticks % TicksPerSecond / TicksPerMillisecond);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Microseconds() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_ticks % TicksPerSecond / TicksPerMicrosecond);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t Ticks() const
|
||||||
|
{
|
||||||
|
return m_ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TotalDays() const
|
||||||
|
{
|
||||||
|
return static_cast<double>(m_ticks) / TicksPerDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TotalHours() const
|
||||||
|
{
|
||||||
|
return static_cast<double>(m_ticks) / TicksPerHour;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TotalMinutes() const
|
||||||
|
{
|
||||||
|
return static_cast<double>(m_ticks) / TicksPerMinute;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TotalSeconds() const
|
||||||
|
{
|
||||||
|
return static_cast<double>(m_ticks) / TicksPerSecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TotalMilliseconds() const
|
||||||
|
{
|
||||||
|
return static_cast<double>(m_ticks) / TicksPerMillisecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TotalMicroseconds() const
|
||||||
|
{
|
||||||
|
return static_cast<double>(m_ticks) / TicksPerMicrosecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToString() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << std::right << std::setfill('0');
|
||||||
|
|
||||||
|
if (m_ticks < 0)
|
||||||
|
{
|
||||||
|
ss << '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Days() != 0)
|
||||||
|
{
|
||||||
|
ss << std::setw(2) << std::abs(Days()) << '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << std::setw(2) << std::abs(Hours()) << ':';
|
||||||
|
ss << std::setw(2) << std::abs(Minutes()) << ':';
|
||||||
|
ss << std::setw(2) << std::abs(Seconds());
|
||||||
|
|
||||||
|
if (Microseconds() != 0)
|
||||||
|
{
|
||||||
|
ss << '.' << std::setw(6) << std::abs(Microseconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int64_t m_ticks{};
|
||||||
|
|
||||||
|
void CalculateTicks(int days,
|
||||||
|
int hours,
|
||||||
|
int minutes,
|
||||||
|
int seconds,
|
||||||
|
int microseconds)
|
||||||
|
{
|
||||||
|
m_ticks = days * TicksPerDay +
|
||||||
|
(hours * 3600LL + minutes * 60LL + seconds) * TicksPerSecond +
|
||||||
|
microseconds * TicksPerMicrosecond;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& strm, const TimeSpan& t)
|
||||||
|
{
|
||||||
|
return strm << t.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline TimeSpan operator+(const TimeSpan& ts1, const TimeSpan& ts2)
|
||||||
|
{
|
||||||
|
return ts1.Add(ts2);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline TimeSpan operator-(const TimeSpan& ts1, const TimeSpan& ts2)
|
||||||
|
{
|
||||||
|
return ts1.Subtract(ts2);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const TimeSpan& ts1, TimeSpan& ts2)
|
||||||
|
{
|
||||||
|
return ts1.Equals(ts2);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator>(const TimeSpan& ts1, const TimeSpan& ts2)
|
||||||
|
{
|
||||||
|
return (ts1.Compare(ts2) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator>=(const TimeSpan& ts1, const TimeSpan& ts2)
|
||||||
|
{
|
||||||
|
return (ts1.Compare(ts2) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const TimeSpan& ts1, const TimeSpan& ts2)
|
||||||
|
{
|
||||||
|
return !ts1.Equals(ts2);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<(const TimeSpan& ts1, const TimeSpan& ts2)
|
||||||
|
{
|
||||||
|
return (ts1.Compare(ts2) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<=(const TimeSpan& ts1, const TimeSpan& ts2)
|
||||||
|
{
|
||||||
|
return (ts1.Compare(ts2) <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,376 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Tle.h"
|
||||||
|
|
||||||
|
#include <locale>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
static const unsigned int TLE1_COL_NORADNUM = 2;
|
||||||
|
static const unsigned int TLE1_LEN_NORADNUM = 5;
|
||||||
|
static const unsigned int TLE1_COL_INTLDESC_A = 9;
|
||||||
|
static const unsigned int TLE1_LEN_INTLDESC_A = 2;
|
||||||
|
// static const unsigned int TLE1_COL_INTLDESC_B = 11;
|
||||||
|
static const unsigned int TLE1_LEN_INTLDESC_B = 3;
|
||||||
|
// static const unsigned int TLE1_COL_INTLDESC_C = 14;
|
||||||
|
static const unsigned int TLE1_LEN_INTLDESC_C = 3;
|
||||||
|
static const unsigned int TLE1_COL_EPOCH_A = 18;
|
||||||
|
static const unsigned int TLE1_LEN_EPOCH_A = 2;
|
||||||
|
static const unsigned int TLE1_COL_EPOCH_B = 20;
|
||||||
|
static const unsigned int TLE1_LEN_EPOCH_B = 12;
|
||||||
|
static const unsigned int TLE1_COL_MEANMOTIONDT2 = 33;
|
||||||
|
static const unsigned int TLE1_LEN_MEANMOTIONDT2 = 10;
|
||||||
|
static const unsigned int TLE1_COL_MEANMOTIONDDT6 = 44;
|
||||||
|
static const unsigned int TLE1_LEN_MEANMOTIONDDT6 = 8;
|
||||||
|
static const unsigned int TLE1_COL_BSTAR = 53;
|
||||||
|
static const unsigned int TLE1_LEN_BSTAR = 8;
|
||||||
|
// static const unsigned int TLE1_COL_EPHEMTYPE = 62;
|
||||||
|
// static const unsigned int TLE1_LEN_EPHEMTYPE = 1;
|
||||||
|
// static const unsigned int TLE1_COL_ELNUM = 64;
|
||||||
|
// static const unsigned int TLE1_LEN_ELNUM = 4;
|
||||||
|
|
||||||
|
static const unsigned int TLE2_COL_NORADNUM = 2;
|
||||||
|
static const unsigned int TLE2_LEN_NORADNUM = 5;
|
||||||
|
static const unsigned int TLE2_COL_INCLINATION = 8;
|
||||||
|
static const unsigned int TLE2_LEN_INCLINATION = 8;
|
||||||
|
static const unsigned int TLE2_COL_RAASCENDNODE = 17;
|
||||||
|
static const unsigned int TLE2_LEN_RAASCENDNODE = 8;
|
||||||
|
static const unsigned int TLE2_COL_ECCENTRICITY = 26;
|
||||||
|
static const unsigned int TLE2_LEN_ECCENTRICITY = 7;
|
||||||
|
static const unsigned int TLE2_COL_ARGPERIGEE = 34;
|
||||||
|
static const unsigned int TLE2_LEN_ARGPERIGEE = 8;
|
||||||
|
static const unsigned int TLE2_COL_MEANANOMALY = 43;
|
||||||
|
static const unsigned int TLE2_LEN_MEANANOMALY = 8;
|
||||||
|
static const unsigned int TLE2_COL_MEANMOTION = 52;
|
||||||
|
static const unsigned int TLE2_LEN_MEANMOTION = 11;
|
||||||
|
static const unsigned int TLE2_COL_REVATEPOCH = 63;
|
||||||
|
static const unsigned int TLE2_LEN_REVATEPOCH = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the tle object.
|
||||||
|
* @exception TleException
|
||||||
|
*/
|
||||||
|
void Tle::Initialize()
|
||||||
|
{
|
||||||
|
if (!IsValidLineLength(line_one_))
|
||||||
|
{
|
||||||
|
throw TleException("Invalid length for line one");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsValidLineLength(line_two_))
|
||||||
|
{
|
||||||
|
throw TleException("Invalid length for line two");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line_one_[0] != '1')
|
||||||
|
{
|
||||||
|
throw TleException("Invalid line beginning for line one");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line_two_[0] != '2')
|
||||||
|
{
|
||||||
|
throw TleException("Invalid line beginning for line two");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int sat_number_1;
|
||||||
|
unsigned int sat_number_2;
|
||||||
|
|
||||||
|
ExtractInteger(line_one_.substr(TLE1_COL_NORADNUM,
|
||||||
|
TLE1_LEN_NORADNUM), sat_number_1);
|
||||||
|
ExtractInteger(line_two_.substr(TLE2_COL_NORADNUM,
|
||||||
|
TLE2_LEN_NORADNUM), sat_number_2);
|
||||||
|
|
||||||
|
if (sat_number_1 != sat_number_2)
|
||||||
|
{
|
||||||
|
throw TleException("Satellite numbers do not match");
|
||||||
|
}
|
||||||
|
|
||||||
|
norad_number_ = sat_number_1;
|
||||||
|
|
||||||
|
if (name_.empty())
|
||||||
|
{
|
||||||
|
name_ = line_one_.substr(TLE1_COL_NORADNUM, TLE1_LEN_NORADNUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
int_designator_ = line_one_.substr(TLE1_COL_INTLDESC_A,
|
||||||
|
TLE1_LEN_INTLDESC_A + TLE1_LEN_INTLDESC_B + TLE1_LEN_INTLDESC_C);
|
||||||
|
|
||||||
|
unsigned int year = 0;
|
||||||
|
double day = 0.0;
|
||||||
|
|
||||||
|
ExtractInteger(line_one_.substr(TLE1_COL_EPOCH_A,
|
||||||
|
TLE1_LEN_EPOCH_A), year);
|
||||||
|
ExtractDouble(line_one_.substr(TLE1_COL_EPOCH_B,
|
||||||
|
TLE1_LEN_EPOCH_B), 4, day);
|
||||||
|
ExtractDouble(line_one_.substr(TLE1_COL_MEANMOTIONDT2,
|
||||||
|
TLE1_LEN_MEANMOTIONDT2), 2, mean_motion_dt2_);
|
||||||
|
ExtractExponential(line_one_.substr(TLE1_COL_MEANMOTIONDDT6,
|
||||||
|
TLE1_LEN_MEANMOTIONDDT6), mean_motion_ddt6_);
|
||||||
|
ExtractExponential(line_one_.substr(TLE1_COL_BSTAR,
|
||||||
|
TLE1_LEN_BSTAR), bstar_);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* line 2
|
||||||
|
*/
|
||||||
|
ExtractDouble(line_two_.substr(TLE2_COL_INCLINATION,
|
||||||
|
TLE2_LEN_INCLINATION), 4, inclination_);
|
||||||
|
ExtractDouble(line_two_.substr(TLE2_COL_RAASCENDNODE,
|
||||||
|
TLE2_LEN_RAASCENDNODE), 4, right_ascending_node_);
|
||||||
|
ExtractDouble(line_two_.substr(TLE2_COL_ECCENTRICITY,
|
||||||
|
TLE2_LEN_ECCENTRICITY), -1, eccentricity_);
|
||||||
|
ExtractDouble(line_two_.substr(TLE2_COL_ARGPERIGEE,
|
||||||
|
TLE2_LEN_ARGPERIGEE), 4, argument_perigee_);
|
||||||
|
ExtractDouble(line_two_.substr(TLE2_COL_MEANANOMALY,
|
||||||
|
TLE2_LEN_MEANANOMALY), 4, mean_anomaly_);
|
||||||
|
ExtractDouble(line_two_.substr(TLE2_COL_MEANMOTION,
|
||||||
|
TLE2_LEN_MEANMOTION), 3, mean_motion_);
|
||||||
|
ExtractInteger(line_two_.substr(TLE2_COL_REVATEPOCH,
|
||||||
|
TLE2_LEN_REVATEPOCH), orbit_number_);
|
||||||
|
|
||||||
|
if (year < 57)
|
||||||
|
{
|
||||||
|
year += 2000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
year += 1900;
|
||||||
|
}
|
||||||
|
|
||||||
|
epoch_ = DateTime(year, day);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check
|
||||||
|
* @param str The string to check
|
||||||
|
* @returns Whether true of the string has a valid length
|
||||||
|
*/
|
||||||
|
bool Tle::IsValidLineLength(const std::string& str)
|
||||||
|
{
|
||||||
|
return str.length() == LineLength() ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a string containing an integer
|
||||||
|
* @param[in] str The string to convert
|
||||||
|
* @param[out] val The result
|
||||||
|
* @exception TleException on conversion error
|
||||||
|
*/
|
||||||
|
void Tle::ExtractInteger(const std::string& str, unsigned int& val)
|
||||||
|
{
|
||||||
|
bool found_digit = false;
|
||||||
|
unsigned int temp = 0;
|
||||||
|
|
||||||
|
for (auto& i : str)
|
||||||
|
{
|
||||||
|
if (isdigit(i))
|
||||||
|
{
|
||||||
|
found_digit = true;
|
||||||
|
temp = (temp * 10) + static_cast<unsigned int>(i - '0');
|
||||||
|
}
|
||||||
|
else if (found_digit)
|
||||||
|
{
|
||||||
|
throw TleException("Unexpected non digit");
|
||||||
|
}
|
||||||
|
else if (i != ' ')
|
||||||
|
{
|
||||||
|
throw TleException("Invalid character");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_digit)
|
||||||
|
{
|
||||||
|
val = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a string containing an double
|
||||||
|
* @param[in] str The string to convert
|
||||||
|
* @param[in] point_pos The position of the decimal point. (-1 if none)
|
||||||
|
* @param[out] val The result
|
||||||
|
* @exception TleException on conversion error
|
||||||
|
*/
|
||||||
|
void Tle::ExtractDouble(const std::string& str, int point_pos, double& val)
|
||||||
|
{
|
||||||
|
std::string temp;
|
||||||
|
bool found_digit = false;
|
||||||
|
|
||||||
|
for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* integer part
|
||||||
|
*/
|
||||||
|
if (point_pos >= 0 && i < str.begin() + point_pos - 1)
|
||||||
|
{
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
if (i == str.begin())
|
||||||
|
{
|
||||||
|
if(*i == '-' || *i == '+')
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* first character could be signed
|
||||||
|
*/
|
||||||
|
temp += *i;
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done)
|
||||||
|
{
|
||||||
|
if (isdigit(*i))
|
||||||
|
{
|
||||||
|
found_digit = true;
|
||||||
|
temp += *i;
|
||||||
|
}
|
||||||
|
else if (found_digit)
|
||||||
|
{
|
||||||
|
throw TleException("Unexpected non digit");
|
||||||
|
}
|
||||||
|
else if (*i != ' ')
|
||||||
|
{
|
||||||
|
throw TleException("Invalid character");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* decimal point
|
||||||
|
*/
|
||||||
|
else if (point_pos >= 0 && i == str.begin() + point_pos - 1)
|
||||||
|
{
|
||||||
|
if (temp.length() == 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* integer part is blank, so add a '0'
|
||||||
|
*/
|
||||||
|
temp += '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*i == '.')
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* decimal point found
|
||||||
|
*/
|
||||||
|
temp += *i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw TleException("Failed to find decimal point");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* fraction part
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i == str.begin() && point_pos == -1)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* no decimal point expected, add 0. beginning
|
||||||
|
*/
|
||||||
|
temp += '0';
|
||||||
|
temp += '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* should be a digit
|
||||||
|
*/
|
||||||
|
if (isdigit(*i))
|
||||||
|
{
|
||||||
|
temp += *i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw TleException("Invalid digit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Util::FromString<double>(temp, val))
|
||||||
|
{
|
||||||
|
throw TleException("Failed to convert value to double");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a string containing an exponential
|
||||||
|
* @param[in] str The string to convert
|
||||||
|
* @param[out] val The result
|
||||||
|
* @exception TleException on conversion error
|
||||||
|
*/
|
||||||
|
void Tle::ExtractExponential(const std::string& str, double& val)
|
||||||
|
{
|
||||||
|
std::string temp;
|
||||||
|
|
||||||
|
for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
|
||||||
|
{
|
||||||
|
if (i == str.begin())
|
||||||
|
{
|
||||||
|
if (*i == '-' || *i == '+' || *i == ' ')
|
||||||
|
{
|
||||||
|
if (*i == '-')
|
||||||
|
{
|
||||||
|
temp += *i;
|
||||||
|
}
|
||||||
|
temp += '0';
|
||||||
|
temp += '.';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw TleException("Invalid sign");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (i == str.end() - 2)
|
||||||
|
{
|
||||||
|
if (*i == '-' || *i == '+')
|
||||||
|
{
|
||||||
|
temp += 'e';
|
||||||
|
temp += *i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw TleException("Invalid exponential sign");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isdigit(*i))
|
||||||
|
{
|
||||||
|
temp += *i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw TleException("Invalid digit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Util::FromString<double>(temp, val))
|
||||||
|
{
|
||||||
|
throw TleException("Failed to convert value to double");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,341 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Util.h"
|
||||||
|
#include "DateTime.h"
|
||||||
|
#include "TleException.h"
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Processes a two-line element set used to convey OrbitalElements.
|
||||||
|
*
|
||||||
|
* Used to extract the various raw fields from a two-line element set.
|
||||||
|
*/
|
||||||
|
class Tle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @details Initialise given the two lines of a tle
|
||||||
|
* @param[in] line_one Tle line one
|
||||||
|
* @param[in] line_two Tle line two
|
||||||
|
*/
|
||||||
|
Tle(std::string line_one, std::string line_two)
|
||||||
|
: line_one_(std::move(line_one))
|
||||||
|
, line_two_(std::move(line_two))
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @details Initialise given the satellite name and the two lines of a tle
|
||||||
|
* @param[in] name Satellite name
|
||||||
|
* @param[in] line_one Tle line one
|
||||||
|
* @param[in] line_two Tle line two
|
||||||
|
*/
|
||||||
|
Tle(std::string name, std::string line_one, std::string line_two)
|
||||||
|
: name_(std::move(name))
|
||||||
|
, line_one_(std::move(line_one))
|
||||||
|
, line_two_(std::move(line_two))
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
* @param[in] tle Tle object to copy from
|
||||||
|
*/
|
||||||
|
Tle(const Tle& tle)
|
||||||
|
{
|
||||||
|
name_ = tle.name_;
|
||||||
|
line_one_ = tle.line_one_;
|
||||||
|
line_two_ = tle.line_two_;
|
||||||
|
|
||||||
|
norad_number_ = tle.norad_number_;
|
||||||
|
int_designator_ = tle.int_designator_;
|
||||||
|
epoch_ = tle.epoch_;
|
||||||
|
mean_motion_dt2_ = tle.mean_motion_dt2_;
|
||||||
|
mean_motion_ddt6_ = tle.mean_motion_ddt6_;
|
||||||
|
bstar_ = tle.bstar_;
|
||||||
|
inclination_ = tle.inclination_;
|
||||||
|
right_ascending_node_ = tle.right_ascending_node_;
|
||||||
|
eccentricity_ = tle.eccentricity_;
|
||||||
|
argument_perigee_ = tle.argument_perigee_;
|
||||||
|
mean_anomaly_ = tle.mean_anomaly_;
|
||||||
|
mean_motion_ = tle.mean_motion_;
|
||||||
|
orbit_number_ = tle.orbit_number_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the satellite name
|
||||||
|
* @returns the satellite name
|
||||||
|
*/
|
||||||
|
std::string Name() const
|
||||||
|
{
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first line of the tle
|
||||||
|
* @returns the first line of the tle
|
||||||
|
*/
|
||||||
|
std::string Line1() const
|
||||||
|
{
|
||||||
|
return line_one_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the second line of the tle
|
||||||
|
* @returns the second line of the tle
|
||||||
|
*/
|
||||||
|
std::string Line2() const
|
||||||
|
{
|
||||||
|
return line_two_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the norad number
|
||||||
|
* @returns the norad number
|
||||||
|
*/
|
||||||
|
unsigned int NoradNumber() const
|
||||||
|
{
|
||||||
|
return norad_number_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the international designator
|
||||||
|
* @returns the international designator
|
||||||
|
*/
|
||||||
|
std::string IntDesignator() const
|
||||||
|
{
|
||||||
|
return int_designator_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the tle epoch
|
||||||
|
* @returns the tle epoch
|
||||||
|
*/
|
||||||
|
DateTime Epoch() const
|
||||||
|
{
|
||||||
|
return epoch_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first time derivative of the mean motion divided by two
|
||||||
|
* @returns the first time derivative of the mean motion divided by two
|
||||||
|
*/
|
||||||
|
double MeanMotionDt2() const
|
||||||
|
{
|
||||||
|
return mean_motion_dt2_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the second time derivative of mean motion divided by six
|
||||||
|
* @returns the second time derivative of mean motion divided by six
|
||||||
|
*/
|
||||||
|
double MeanMotionDdt6() const
|
||||||
|
{
|
||||||
|
return mean_motion_ddt6_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the BSTAR drag term
|
||||||
|
* @returns the BSTAR drag term
|
||||||
|
*/
|
||||||
|
double BStar() const
|
||||||
|
{
|
||||||
|
return bstar_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the inclination
|
||||||
|
* @param in_degrees Whether to return the value in degrees or radians
|
||||||
|
* @returns the inclination
|
||||||
|
*/
|
||||||
|
double Inclination(bool in_degrees) const
|
||||||
|
{
|
||||||
|
if (in_degrees)
|
||||||
|
{
|
||||||
|
return inclination_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Util::DegreesToRadians(inclination_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the right ascension of the ascending node
|
||||||
|
* @param in_degrees Whether to return the value in degrees or radians
|
||||||
|
* @returns the right ascension of the ascending node
|
||||||
|
*/
|
||||||
|
double RightAscendingNode(const bool in_degrees) const
|
||||||
|
{
|
||||||
|
if (in_degrees)
|
||||||
|
{
|
||||||
|
return right_ascending_node_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Util::DegreesToRadians(right_ascending_node_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the eccentricity
|
||||||
|
* @returns the eccentricity
|
||||||
|
*/
|
||||||
|
double Eccentricity() const
|
||||||
|
{
|
||||||
|
return eccentricity_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the argument of perigee
|
||||||
|
* @param in_degrees Whether to return the value in degrees or radians
|
||||||
|
* @returns the argument of perigee
|
||||||
|
*/
|
||||||
|
double ArgumentPerigee(const bool in_degrees) const
|
||||||
|
{
|
||||||
|
if (in_degrees)
|
||||||
|
{
|
||||||
|
return argument_perigee_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Util::DegreesToRadians(argument_perigee_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mean anomaly
|
||||||
|
* @param in_degrees Whether to return the value in degrees or radians
|
||||||
|
* @returns the mean anomaly
|
||||||
|
*/
|
||||||
|
double MeanAnomaly(const bool in_degrees) const
|
||||||
|
{
|
||||||
|
if (in_degrees)
|
||||||
|
{
|
||||||
|
return mean_anomaly_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Util::DegreesToRadians(mean_anomaly_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mean motion
|
||||||
|
* @returns the mean motion (revolutions per day)
|
||||||
|
*/
|
||||||
|
double MeanMotion() const
|
||||||
|
{
|
||||||
|
return mean_motion_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the orbit number
|
||||||
|
* @returns the orbit number
|
||||||
|
*/
|
||||||
|
unsigned int OrbitNumber() const
|
||||||
|
{
|
||||||
|
return orbit_number_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the expected tle line length
|
||||||
|
* @returns the tle line length
|
||||||
|
*/
|
||||||
|
static unsigned int LineLength()
|
||||||
|
{
|
||||||
|
return TLE_LEN_LINE_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump this object to a string
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
std::string ToString() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::right << std::fixed;
|
||||||
|
ss << "Norad Number: " << NoradNumber() << std::endl;
|
||||||
|
ss << "Int. Designator: " << IntDesignator() << std::endl;
|
||||||
|
ss << "Epoch: " << Epoch() << std::endl;
|
||||||
|
ss << "Orbit Number: " << OrbitNumber() << std::endl;
|
||||||
|
ss << std::setprecision(8);
|
||||||
|
ss << "Mean Motion Dt2: ";
|
||||||
|
ss << std::setw(12) << MeanMotionDt2() << std::endl;
|
||||||
|
ss << "Mean Motion Ddt6: ";
|
||||||
|
ss << std::setw(12) << MeanMotionDdt6() << std::endl;
|
||||||
|
ss << "Eccentricity: ";
|
||||||
|
ss << std::setw(12) << Eccentricity() << std::endl;
|
||||||
|
ss << "BStar: ";
|
||||||
|
ss << std::setw(12) << BStar() << std::endl;
|
||||||
|
ss << "Inclination: ";
|
||||||
|
ss << std::setw(12) << Inclination(true) << std::endl;
|
||||||
|
ss << "Right Ascending Node: ";
|
||||||
|
ss << std::setw(12) << RightAscendingNode(true) << std::endl;
|
||||||
|
ss << "Argument Perigee: ";
|
||||||
|
ss << std::setw(12) << ArgumentPerigee(true) << std::endl;
|
||||||
|
ss << "Mean Anomaly: ";
|
||||||
|
ss << std::setw(12) << MeanAnomaly(true) << std::endl;
|
||||||
|
ss << "Mean Motion: ";
|
||||||
|
ss << std::setw(12) << MeanMotion() << std::endl;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Initialize();
|
||||||
|
static bool IsValidLineLength(const std::string& str);
|
||||||
|
void ExtractInteger(const std::string& str, unsigned int& val);
|
||||||
|
void ExtractDouble(const std::string& str, int point_pos, double& val);
|
||||||
|
void ExtractExponential(const std::string& str, double& val);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name_;
|
||||||
|
std::string line_one_;
|
||||||
|
std::string line_two_;
|
||||||
|
|
||||||
|
std::string int_designator_;
|
||||||
|
DateTime epoch_;
|
||||||
|
double mean_motion_dt2_{};
|
||||||
|
double mean_motion_ddt6_{};
|
||||||
|
double bstar_{};
|
||||||
|
double inclination_{};
|
||||||
|
double right_ascending_node_{};
|
||||||
|
double eccentricity_{};
|
||||||
|
double argument_perigee_{};
|
||||||
|
double mean_anomaly_{};
|
||||||
|
double mean_motion_{};
|
||||||
|
unsigned int norad_number_{};
|
||||||
|
unsigned int orbit_number_{};
|
||||||
|
|
||||||
|
static const unsigned int TLE_LEN_LINE_DATA = 69;
|
||||||
|
static const unsigned int TLE_LEN_LINE_NAME = 22;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& strm, const Tle& t)
|
||||||
|
{
|
||||||
|
return strm << t.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1 @@
|
||||||
|
#include "TleException.h"
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The exception that the Tle class throws on an error.
|
||||||
|
*
|
||||||
|
* The exception that the Tle decoder will throw on an error.
|
||||||
|
*/
|
||||||
|
class TleException : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param message Exception message
|
||||||
|
*/
|
||||||
|
explicit TleException(const char* message)
|
||||||
|
: runtime_error(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <locale>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
namespace Util {
|
||||||
|
void TrimLeft(std::string& s)
|
||||||
|
{
|
||||||
|
s.erase(s.begin(),
|
||||||
|
std::find_if(s.begin(), s.end(), [](unsigned char c) { return std::isgraph(c) != 0; }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrimRight(std::string& s)
|
||||||
|
{
|
||||||
|
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char c) { return std::isgraph(c) != 0; }).base(),
|
||||||
|
s.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Trim(std::string& s)
|
||||||
|
{
|
||||||
|
TrimLeft(s);
|
||||||
|
TrimRight(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace libsgp4::Util
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
namespace Util
|
||||||
|
{
|
||||||
|
template
|
||||||
|
<typename T>
|
||||||
|
bool FromString(const std::string& str, T& val)
|
||||||
|
{
|
||||||
|
std::stringstream ss(str);
|
||||||
|
return !(ss >> val).fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* always positive result
|
||||||
|
* Mod(-3,4)= 1 fmod(-3,4)= -3
|
||||||
|
*/
|
||||||
|
inline double Mod(const double x, const double y)
|
||||||
|
{
|
||||||
|
if (y == 0.0)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x - y * floor(x / y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double WrapNegPosPI(const double a)
|
||||||
|
{
|
||||||
|
return Mod(a + kPI, kTWOPI) - kPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double WrapTwoPI(const double a)
|
||||||
|
{
|
||||||
|
return Mod(a, kTWOPI);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double WrapNegPos180(const double a)
|
||||||
|
{
|
||||||
|
return Mod(a + 180.0, 360.0) - 180.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double Wrap360(const double a)
|
||||||
|
{
|
||||||
|
return Mod(a, 360.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double DegreesToRadians(const double degrees)
|
||||||
|
{
|
||||||
|
return degrees * kPI / 180.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double RadiansToDegrees(const double radians)
|
||||||
|
{
|
||||||
|
return radians * 180.0 / kPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double AcTan(const double sinx, const double cosx)
|
||||||
|
{
|
||||||
|
if (cosx == 0.0)
|
||||||
|
{
|
||||||
|
if (sinx > 0.0)
|
||||||
|
{
|
||||||
|
return kPI / 2.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 3.0 * kPI / 2.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cosx > 0.0)
|
||||||
|
{
|
||||||
|
return atan(sinx / cosx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return kPI + atan(sinx / cosx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrimLeft(std::string& s);
|
||||||
|
void TrimRight(std::string& s);
|
||||||
|
void Trim(std::string& s);
|
||||||
|
|
||||||
|
} // namespace Util
|
||||||
|
} // namespace libsgp4
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Vector.h"
|
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Daniel Warner <contact@danrw.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
namespace libsgp4
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generic vector
|
||||||
|
*
|
||||||
|
* Stores x, y, z, w
|
||||||
|
*/
|
||||||
|
struct Vector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
Vector() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param arg_x x value
|
||||||
|
* @param arg_y y value
|
||||||
|
* @param arg_z z value
|
||||||
|
*/
|
||||||
|
Vector(const double arg_x,
|
||||||
|
const double arg_y,
|
||||||
|
const double arg_z)
|
||||||
|
: x(arg_x), y(arg_y), z(arg_z)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param arg_x x value
|
||||||
|
* @param arg_y y value
|
||||||
|
* @param arg_z z value
|
||||||
|
* @param arg_w w value
|
||||||
|
*/
|
||||||
|
Vector(const double arg_x,
|
||||||
|
const double arg_y,
|
||||||
|
const double arg_z,
|
||||||
|
const double arg_w)
|
||||||
|
: x(arg_x), y(arg_y), z(arg_z), w(arg_w)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
* @param v value to copy from
|
||||||
|
*/
|
||||||
|
Vector(const Vector& v)
|
||||||
|
{
|
||||||
|
x = v.x;
|
||||||
|
y = v.y;
|
||||||
|
z = v.z;
|
||||||
|
w = v.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assignment operator
|
||||||
|
* @param v value to copy from
|
||||||
|
*/
|
||||||
|
Vector& operator=(const Vector& v)
|
||||||
|
{
|
||||||
|
if (this != &v)
|
||||||
|
{
|
||||||
|
x = v.x;
|
||||||
|
y = v.y;
|
||||||
|
z = v.z;
|
||||||
|
w = v.w;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract operator
|
||||||
|
* @param v value to suctract from
|
||||||
|
*/
|
||||||
|
Vector operator-(const Vector& v)
|
||||||
|
{
|
||||||
|
return Vector(x - v.x,
|
||||||
|
y - v.y,
|
||||||
|
z - v.z,
|
||||||
|
0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the magnitude of the vector
|
||||||
|
* @returns magnitude of the vector
|
||||||
|
*/
|
||||||
|
double Magnitude() const
|
||||||
|
{
|
||||||
|
return sqrt(x * x + y * y + z * z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the dot product
|
||||||
|
* @returns dot product
|
||||||
|
*/
|
||||||
|
double Dot(const Vector& vec) const
|
||||||
|
{
|
||||||
|
return (x * vec.x) +
|
||||||
|
(y * vec.y) +
|
||||||
|
(z * vec.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts this vector to a string
|
||||||
|
* @returns this vector as a string
|
||||||
|
*/
|
||||||
|
std::string ToString() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::right << std::fixed << std::setprecision(3);
|
||||||
|
ss << "X: " << std::setw(9) << x;
|
||||||
|
ss << ", Y: " << std::setw(9) << y;
|
||||||
|
ss << ", Z: " << std::setw(9) << z;
|
||||||
|
ss << ", W: " << std::setw(9) << w;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** x value */
|
||||||
|
double x{};
|
||||||
|
/** y value */
|
||||||
|
double y{};
|
||||||
|
/** z value */
|
||||||
|
double z{};
|
||||||
|
/** w value */
|
||||||
|
double w{};
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& strm, const Vector& v)
|
||||||
|
{
|
||||||
|
return strm << v.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libsgp4
|
Loading…
Reference in New Issue