增加了基于SPG4模型与两行根数的,卫星轨道点生成代码
parent
c55953aa7c
commit
44a5db3168
|
@ -38,6 +38,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RasterMainWidgetGUI", "Rast
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageshowTool", "ImageshowTool\ImageshowTool.vcxproj", "{8C8CA066-A93A-4098-9A46-B855EFEAADF2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPG4Tool", "SPG4Tool\SPG4Tool.vcxproj", "{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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|x86.ActiveCfg = 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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -181,6 +195,7 @@ Global
|
|||
{B8B40C54-F7FE-4809-B6FB-8BC014570D7B} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
||||
{E56B3878-A3DC-41A4-ABF3-B628816D0D64} = {6505E2BA-06A2-447B-BC85-8CF1A81359BC}
|
||||
{8C8CA066-A93A-4098-9A46-B855EFEAADF2} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
||||
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
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