Skip to content

Commit da18122

Browse files
Feature/convert2tle (#239)
* Add TLE creation method and unit tests for Keplerian elements conversion * Refactor TLE class to rename Line3 to Name and update constructor parameters * Add TLEFitter class for fitting TLE from state vector using Newton-Raphson method; enhance TLE creation method and improve error handling in TLE constructor * Refactor KeplerianElements and TLE conversion; add TLEMeanElementsConverter for improved TLE fitting; implement angle normalization methods and corresponding tests * Add TLE classification and configuration records; refactor TLE creation methods to use new configuration structure * Refactor TLE generation to use StringBuilder for improved performance; replace instance MeanElementsConverter with a static shared instance * Refactor APITest and TLE classes for improved readability; add TLE creation method with detailed documentation * Refactor TLE class to improve validation and parsing; enhance state vector conversion and update tests for accuracy * Refactor TLE class to enhance mean Keplerian elements handling; improve angle normalization methods and update tests for accuracy * Update version numbers and enhance TLE class documentation; add methods for converting TLE to Equinoctial and mean Keplerian elements * Refactor TLE and related classes to streamline state vector conversion; remove unnecessary frame transformations and improve test assertions * Update IO.Astrodynamics.Net/IO.Astrodynamics/OrbitalParameters/TLE/TLE.cs Co-authored-by: Copilot <[email protected]> * Update IO.Astrodynamics.Net/IO.Astrodynamics/OrbitalParameters/TLE/TLE.cs Co-authored-by: Copilot <[email protected]> * Update IO.Astrodynamics.Net/IO.Astrodynamics/OrbitalParameters/TLE/TLE.cs Co-authored-by: Copilot <[email protected]> * Update IO.Astrodynamics.Net/IO.Astrodynamics/OrbitalParameters/TLE/TLE.cs Co-authored-by: Copilot <[email protected]> * Update IO.Astrodynamics.Net/IO.Astrodynamics/OrbitalParameters/TLE/TLE.cs Co-authored-by: Copilot <[email protected]> * Update IO.Astrodynamics.Net/IO.Astrodynamics/OrbitalParameters/TLE/TLE.cs Co-authored-by: Copilot <[email protected]> * Update IO.Astrodynamics.Net/IO.Astrodynamics/OrbitalParameters/TLE/TLE.cs Co-authored-by: Copilot <[email protected]> * Fix typo in TLETests: update BalisticCoefficient to BallisticCoefficient * Update IO.Astrodynamics.Net/IO.Astrodynamics/OrbitalParameters/TLE/TLE.cs Co-authored-by: Copilot <[email protected]> * Update IO.Astrodynamics.Net/IO.Astrodynamics/Math/NewtonRaphson.cs Co-authored-by: Copilot <[email protected]> * Update IO.Astrodynamics.Net/IO.Astrodynamics/Math/SpecialFunctions.cs Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
1 parent 4d67196 commit da18122

28 files changed

+1685
-353
lines changed

IO.Astrodynamics.Net/IO.Astrodynamics.CLI/Helpers.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using IO.Astrodynamics.Frames;
1111
using IO.Astrodynamics.Math;
1212
using IO.Astrodynamics.OrbitalParameters;
13+
using IO.Astrodynamics.OrbitalParameters.TLE;
1314
using IO.Astrodynamics.Physics;
1415
using IO.Astrodynamics.SolarSystemObjects;
1516
using IO.Astrodynamics.Surface;

IO.Astrodynamics.Net/IO.Astrodynamics.CLI/IO.Astrodynamics.CLI.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<FileVersion>0.0.1</FileVersion>
1010
<PackAsTool>true</PackAsTool>
1111
<ToolCommandName>astro</ToolCommandName>
12-
<Version>0.6.5.1</Version>
12+
<Version>0.7.0.0-preview1</Version>
1313
<Title>Astrodynamics command line interface</Title>
1414
<Authors>Sylvain Guillet</Authors>
1515
<Description>This CLI allows end user to exploit IO.Astrodynamics framework </Description>
Binary file not shown.

IO.Astrodynamics.Net/IO.Astrodynamics.Performance/IO.Astrodynamics.Performance.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@
8787
<Content Update="Data\SolarSystem\latest_leapseconds.tls">
8888
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
8989
</Content>
90+
<Content Include="..\..\..\..\Downloads\earth_latest_high_prec.bpc">
91+
<Link>Data/SolarSystem/earth_latest_high_prec.bpc</Link>
92+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
93+
</Content>
9094
</ItemGroup>
9195

9296
<ItemGroup>
@@ -119,9 +123,6 @@
119123
<None Update="Data\SolarSystem\earth_fixed.tf">
120124
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
121125
</None>
122-
<None Update="Data\SolarSystem\earth_latest_high_prec.bpc">
123-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
124-
</None>
125126
<None Update="Data\SolarSystem\earth_topo_201023.tf">
126127
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
127128
</None>

IO.Astrodynamics.Net/IO.Astrodynamics.Performance/VelocityScenario.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public void VVIntegration()
9999
// var res = _integrator.Integrate(sv);
100100
}
101101

102-
[Benchmark(Description = "SpacecraftPropagator per orbit (GeoPotentials // Moon and sun perturbation // Atmospheric drag // Solar radiation) ")]
102+
// [Benchmark(Description = "SpacecraftPropagator per orbit (GeoPotentials // Moon and sun perturbation // Atmospheric drag // Solar radiation) ")]
103103
public void Propagator()
104104
{
105105
_spacecraftPropagator.Propagate();
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using BenchmarkDotNet.Attributes;
2+
using IO.Astrodynamics.Body;
3+
using IO.Astrodynamics.Math;
4+
using IO.Astrodynamics.OrbitalParameters;
5+
using IO.Astrodynamics.OrbitalParameters.TLE;
6+
using IO.Astrodynamics.TimeSystem;
7+
8+
namespace IO.Astrodynamics.Performance;
9+
10+
[MemoryDiagnoser]
11+
public class VelocityTLE
12+
{
13+
private Time _epoch;
14+
private StateVector _sv;
15+
16+
public VelocityTLE()
17+
{
18+
API.Instance.LoadKernels(new DirectoryInfo("Data"));
19+
_epoch = new TimeSystem.Time(new DateTime(2024, 1, 1), TimeFrame.UTCFrame);
20+
_sv = new StateVector(new Vector3(6800000.0, 0.0, 0.0), new Vector3(0.0, 8000.0, 0.0), CelestialItem.Create(399), _epoch, Frames.Frame.ICRF);
21+
}
22+
23+
[Benchmark(Description = "Convert StateVector to TLE")]
24+
public void ComputeTLE()
25+
{
26+
var tle = _sv.ToTLE(new OrbitalParameters.TLE.Configuration(25666, "TestSatellite", "98067A"));
27+
}
28+
}

IO.Astrodynamics.Net/IO.Astrodynamics.Tests/APITest.cs

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public void FindWindowsOnDistanceConstraintProxy()
108108
RelationnalOperator.Greater, 400000000, Aberration.None,
109109
TimeSpan.FromSeconds(86400.0)));
110110
}
111-
111+
112112
[Fact]
113113
public void FindWindowsOnDistanceConstraintFromIdsProxy()
114114
{
@@ -165,7 +165,7 @@ public void FindWindowsOnOccultationConstraint()
165165
ShapeType.Ellipsoid, null, ShapeType.Ellipsoid, OccultationType.Any, Aberration.LT,
166166
TimeSpan.FromSeconds(3600.0)));
167167
}
168-
168+
169169
[Fact]
170170
public void FindWindowsOnOccultationConstraintFromIDs()
171171
{
@@ -245,6 +245,7 @@ public void FindWindowsOnIlluminationConstraint()
245245
System.Math.PI * 0.5 - (-0.8 * IO.Astrodynamics.Constants.Deg2Rad), 0.0, Aberration.CNS,
246246
TimeSpan.FromHours(4.5), null));
247247
}
248+
248249
[Fact]
249250
public void FindWindowsOnCoordinateConstraint()
250251
{
@@ -257,7 +258,7 @@ public void FindWindowsOnCoordinateConstraint()
257258
TestHelpers.MoonAtJ2000, site.Frame, CoordinateSystem.Rectangular, Coordinate.Z,
258259
RelationnalOperator.Greater,
259260
0.0, 0.0, Aberration.None, TimeSpan.FromSeconds(60.0));
260-
261+
261262
var windows = res as Window[] ?? res.ToArray();
262263
Assert.Single(windows);
263264
Assert.Equal("2023-02-19T14:33:08.9179878 TDB", windows[0].StartDate.ToString());
@@ -275,7 +276,7 @@ public void FindWindowsOnCoordinateConstraint()
275276
TestHelpers.MoonAtJ2000, null, CoordinateSystem.Rectangular, Coordinate.Z,
276277
RelationnalOperator.Greater, 0.0, 0.0, Aberration.None, TimeSpan.FromSeconds(60.0)));
277278
}
278-
279+
279280
[Fact]
280281
public void FindWindowsOnCoordinateConstraintFromIds()
281282
{
@@ -287,7 +288,7 @@ public void FindWindowsOnCoordinateConstraintFromIds()
287288
new Window(TimeSystem.Time.CreateTDB(730036800.0), TimeSystem.Time.CreateTDB(730123200)), site.NaifId,
288289
TestHelpers.MoonAtJ2000.NaifId, site.Frame, CoordinateSystem.Rectangular, Coordinate.Z,
289290
RelationnalOperator.Greater, 0.0, 0.0, Aberration.None, TimeSpan.FromSeconds(60.0));
290-
291+
291292
var windows = res as Window[] ?? res.ToArray();
292293
Assert.Single(windows);
293294
Assert.Equal("2023-02-19T14:33:08.9179878 TDB", windows[0].StartDate.ToString());
@@ -305,6 +306,7 @@ public void FindWindowsOnCoordinateConstraintFromIds()
305306
TestHelpers.MoonAtJ2000, null, CoordinateSystem.Rectangular, Coordinate.Z,
306307
RelationnalOperator.Greater, 0.0, 0.0, Aberration.None, TimeSpan.FromSeconds(60.0)));
307308
}
309+
308310
[Fact]
309311
public void FromIDs()
310312
{
@@ -392,20 +394,20 @@ public void ReadEphemeris()
392394
TestHelpers.EarthAtJ2000, TestHelpers.MoonAtJ2000,
393395
null, Aberration.LT));
394396
}
395-
396-
[Fact]
397+
398+
[Fact]
397399
public void ReadEphemerisUTC()
398400
{
399401
var searchWindow = new Window(TimeSystem.Time.CreateUTC(0.0), TimeSystem.Time.CreateUTC(100.0));
400402
var res = API.Instance.ReadEphemeris(searchWindow, TestHelpers.EarthAtJ2000, TestHelpers.MoonAtJ2000,
401403
Frames.Frame.ICRF, Aberration.LT, TimeSpan.FromSeconds(10.0)).Select(x => x.ToStateVector());
402404

403405
var stateVectors = res as StateVector[] ?? res.ToArray();
404-
Assert.Equal(new Vector3(-291527956.4143643,-266751935.53610146,-76118494.37190592), stateVectors[0].Position,TestHelpers.VectorComparer);
405-
Assert.Equal(new Vector3(643.6475664431179,-665.9766990302671,-301.2930723673155), stateVectors[0].Velocity,TestHelpers.VectorComparer);
406+
Assert.Equal(new Vector3(-291527956.4143643, -266751935.53610146, -76118494.37190592), stateVectors[0].Position, TestHelpers.VectorComparer);
407+
Assert.Equal(new Vector3(643.6475664431179, -665.9766990302671, -301.2930723673155), stateVectors[0].Velocity, TestHelpers.VectorComparer);
406408
Assert.Equal(PlanetsAndMoons.EARTH.NaifId, stateVectors[0].Observer.NaifId);
407409
Assert.Equal(Frames.Frame.ICRF, stateVectors[0].Frame);
408-
Assert.Equal(0, stateVectors[0].Epoch.TimeSpanFromJ2000().TotalSeconds,6);
410+
Assert.Equal(0, stateVectors[0].Epoch.TimeSpanFromJ2000().TotalSeconds, 6);
409411

410412
Assert.Throws<ArgumentNullException>(() => API.Instance.ReadEphemeris(searchWindow, null,
411413
TestHelpers.MoonAtJ2000,
@@ -484,16 +486,16 @@ public async Task ReadOrientation()
484486

485487
//Execute scenario
486488
var root = Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name).CreateSubdirectory("Spacecrafts");
487-
await scenario.SimulateAsync( false, false, TimeSpan.FromSeconds(1.0));
489+
await scenario.SimulateAsync(false, false, TimeSpan.FromSeconds(1.0));
488490
var ckFile = new FileInfo(root + "/OrientationTestFile.ck");
489491
var clckFile = new FileInfo(root + "/ClckTestFile.tsc");
490492
await spacecraft.Clock.WriteAsync(clckFile);
491493
API.Instance.LoadKernels(clckFile);
492-
494+
493495
spacecraft.WriteOrientation(ckFile);
494496
API.Instance.LoadKernels(ckFile);
495497
//Read spacecraft orientation
496-
498+
497499
var res = API.Instance.ReadOrientation(window, spacecraft, TimeSpan.FromSeconds(10.0), Frames.Frame.ICRF,
498500
TimeSpan.FromSeconds(10.0)).ToArray();
499501
var resICRF = spacecraft.Frame.GetStateOrientationsToICRF().ElementAt(1).RelativeToICRF();
@@ -666,7 +668,7 @@ void GetCelestialBodyInformationWithoutJ()
666668
void TransformFrame()
667669
{
668670
//Get the quaternion to transform
669-
var res = API.Instance.TransformFrame(TimeSystem.Time.J2000TDB,Frames.Frame.ICRF, new Frames.Frame(PlanetsAndMoons.EARTH.Frame));
671+
var res = API.Instance.TransformFrame(TimeSystem.Time.J2000TDB, Frames.Frame.ICRF, new Frames.Frame(PlanetsAndMoons.EARTH.Frame));
670672
Assert.Equal(0.76713121207787449, res.Rotation.W, 6);
671673
Assert.Equal(-1.8618836714990174E-05, res.Rotation.VectorPart.X, 6);
672674
Assert.Equal(8.4688405480964646E-07, res.Rotation.VectorPart.Y, 6);
@@ -675,12 +677,13 @@ void TransformFrame()
675677
Assert.Equal(-2.0389347198634933E-09, res.AngularVelocity.Y, 6);
676678
Assert.Equal(7.2921150643333896E-05, res.AngularVelocity.Z, 6);
677679
}
678-
680+
679681
[Fact]
680682
void TransformFrameWindows()
681683
{
682684
//Get the quaternion to transform
683-
var res = API.Instance.TransformFrame(new TimeSystem.Window(TimeSystem.Time.J2000TDB,TimeSystem.Time.J2000TDB.AddDays(1.0)),Frames.Frame.ICRF, new Frames.Frame(PlanetsAndMoons.EARTH.Frame),TimeSpan.FromDays(1.0));
685+
var res = API.Instance.TransformFrame(new TimeSystem.Window(TimeSystem.Time.J2000TDB, TimeSystem.Time.J2000TDB.AddDays(1.0)), Frames.Frame.ICRF,
686+
new Frames.Frame(PlanetsAndMoons.EARTH.Frame), TimeSpan.FromDays(1.0));
684687
Assert.Equal(0.76713121207787449, res.First().Rotation.W, 6);
685688
Assert.Equal(-1.8618836714990174E-05, res.First().Rotation.VectorPart.X, 6);
686689
Assert.Equal(8.4688405480964646E-07, res.First().Rotation.VectorPart.Y, 6);
@@ -695,9 +698,9 @@ void TransformFrameExceptions()
695698
{
696699
//Get the quaternion to transform
697700
Assert.Throws<ArgumentNullException>(() =>
698-
API.Instance.TransformFrame(TimeSystem.Time.J2000TDB,Frames.Frame.ICRF, null));
701+
API.Instance.TransformFrame(TimeSystem.Time.J2000TDB, Frames.Frame.ICRF, null));
699702
Assert.Throws<ArgumentNullException>(() =>
700-
API.Instance.TransformFrame(TimeSystem.Time.J2000TDB,null, new Frames.Frame(PlanetsAndMoons.EARTH.Frame)));
703+
API.Instance.TransformFrame(TimeSystem.Time.J2000TDB, null, new Frames.Frame(PlanetsAndMoons.EARTH.Frame)));
701704
}
702705

703706
[Fact]
@@ -740,52 +743,44 @@ void LoadKernelException()
740743
[Fact]
741744
void UnloadKernels()
742745
{
743-
744-
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Sites/MySite/Ephemeris/MySite.spk"));
745-
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Ephemeris/DRAGONFLY32.spk"));
746-
API.Instance.LoadKernels(new DirectoryInfo(@"Data/UserDataTest/scn100"));
747-
API.Instance.UnloadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Ephemeris/DRAGONFLY32.spk"));
748-
var kernels = API.Instance.GetLoadedKernels().ToArray();
749-
Assert.Equal(1, @kernels.Count(x => x.FullName.Contains("scn100")));
750-
746+
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Sites/MySite/Ephemeris/MySite.spk"));
747+
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Ephemeris/DRAGONFLY32.spk"));
748+
API.Instance.LoadKernels(new DirectoryInfo(@"Data/UserDataTest/scn100"));
749+
API.Instance.UnloadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Ephemeris/DRAGONFLY32.spk"));
750+
var kernels = API.Instance.GetLoadedKernels().ToArray();
751+
Assert.Equal(1, @kernels.Count(x => x.FullName.Contains("scn100")));
751752
}
752753

753754
[Fact]
754755
void UnloadKernels2()
755756
{
756-
757-
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Clocks/DRAGONFLY32.tsc"));
757+
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Clocks/DRAGONFLY32.tsc"));
758758

759-
API.Instance.UnloadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Clocks/DRAGONFLY32.tsc"));
760-
var kernels = API.Instance.GetLoadedKernels().ToArray();
761-
Assert.Equal(0, kernels.Count(x => x.FullName.Contains("DRAGONFLY32.tsc")));
762-
759+
API.Instance.UnloadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Clocks/DRAGONFLY32.tsc"));
760+
var kernels = API.Instance.GetLoadedKernels().ToArray();
761+
Assert.Equal(0, kernels.Count(x => x.FullName.Contains("DRAGONFLY32.tsc")));
763762
}
764763

765764
[Fact]
766765
void LoadKernels()
767766
{
768-
769-
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Sites/MySite/Ephemeris/MySite.spk"));
770-
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Ephemeris/DRAGONFLY32.spk"));
771-
API.Instance.LoadKernels(new DirectoryInfo(@"Data/UserDataTest/scn100"));
767+
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Sites/MySite/Ephemeris/MySite.spk"));
768+
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Ephemeris/DRAGONFLY32.spk"));
769+
API.Instance.LoadKernels(new DirectoryInfo(@"Data/UserDataTest/scn100"));
772770

773-
var kernels = API.Instance.GetLoadedKernels().ToArray();
774-
Assert.Equal(1, @kernels.Count(x => x.FullName.Contains("scn100")));
775-
771+
var kernels = API.Instance.GetLoadedKernels().ToArray();
772+
Assert.Equal(1, @kernels.Count(x => x.FullName.Contains("scn100")));
776773
}
777774

778775
[Fact]
779776
void LoadKernels2()
780777
{
781-
782-
API.Instance.LoadKernels(new DirectoryInfo(@"Data/UserDataTest/scn100"));
783-
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Ephemeris/DRAGONFLY32.spk"));
784-
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Sites/MySite/Ephemeris/MySite.spk"));
778+
API.Instance.LoadKernels(new DirectoryInfo(@"Data/UserDataTest/scn100"));
779+
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Spacecrafts/DRAGONFLY32/Ephemeris/DRAGONFLY32.spk"));
780+
API.Instance.LoadKernels(new FileInfo(@"Data/UserDataTest/scn100/Sites/MySite/Ephemeris/MySite.spk"));
785781

786-
var kernels = API.Instance.GetLoadedKernels().ToArray();
787-
Assert.Equal(1, @kernels.Count(x => x.FullName.Contains("scn100")));
788-
782+
var kernels = API.Instance.GetLoadedKernels().ToArray();
783+
Assert.Equal(1, @kernels.Count(x => x.FullName.Contains("scn100")));
789784
}
790785

791786
[Fact]
@@ -821,6 +816,15 @@ void TLEElements()
821816
Assert.Equal(10, tle.M);
822817
}
823818

819+
[Fact]
820+
void ConvertTLE()
821+
{
822+
var res = API.Instance.ConvertTleToStateVector("ISS",
823+
"1 25544U 98067A 24001.00000000 .00016717 00000-0 10270-3 0 9054",
824+
"2 25544 51.6423 353.0312 0000493 320.8755 39.2360 15.49309423 25703", new TimeSystem.Time(2024, 1, 1, frame: TimeFrame.UTCFrame));
825+
826+
}
827+
824828
[Fact]
825829
void ConvertConicToState()
826830
{

0 commit comments

Comments
 (0)