diff --git a/IO.Astrodynamics.Performance/IO.Astrodynamics.Performance.csproj b/IO.Astrodynamics.Performance/IO.Astrodynamics.Performance.csproj
new file mode 100644
index 0000000..822d18a
--- /dev/null
+++ b/IO.Astrodynamics.Performance/IO.Astrodynamics.Performance.csproj
@@ -0,0 +1,60 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
+
+
+
+
diff --git a/IO.Astrodynamics.Performance/Program.cs b/IO.Astrodynamics.Performance/Program.cs
new file mode 100644
index 0000000..f8d369e
--- /dev/null
+++ b/IO.Astrodynamics.Performance/Program.cs
@@ -0,0 +1,11 @@
+using BenchmarkDotNet.Running;
+
+namespace IO.Astrodynamics.Performance;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ var summary = BenchmarkRunner.Run(typeof(Program).Assembly);
+ }
+}
\ No newline at end of file
diff --git a/IO.Astrodynamics.Performance/Scenario.cs b/IO.Astrodynamics.Performance/Scenario.cs
new file mode 100644
index 0000000..e87452f
--- /dev/null
+++ b/IO.Astrodynamics.Performance/Scenario.cs
@@ -0,0 +1,21 @@
+// Copyright 2023. Sylvain Guillet (sylvain.guillet@tutamail.com)
+
+using BenchmarkDotNet.Attributes;
+
+namespace IO.Astrodynamics.Performance;
+
+[MarkdownExporterAttribute.GitHub]
+[MemoryDiagnoser]
+[SkewnessColumn]
+[KurtosisColumn]
+[StatisticalTestColumn]
+[ShortRunJob]
+public class Scenario
+{
+ [Benchmark(Description = "Spacecraft propagator")]
+ public void Propagate()
+ {
+ var scenario = new IO.Astrodynamics.Tests.Mission.ScenarioTests();
+ scenario.Propagate();
+ }
+}
\ No newline at end of file
diff --git a/IO.Astrodynamics.Tests/APITest.cs b/IO.Astrodynamics.Tests/APITest.cs
index 8c7ff53..ad5b01c 100644
--- a/IO.Astrodynamics.Tests/APITest.cs
+++ b/IO.Astrodynamics.Tests/APITest.cs
@@ -157,45 +157,45 @@ public void PropagateScenario()
// Read maneuver results
var maneuver = spacecraft.StandbyManeuver;
- Assert.Equal("2021-03-04T00:32:49.8175394 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T00:32:58.2100803 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
- Assert.Equal("2021-03-04T00:32:49.8175394 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T00:32:58.2100803 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
- Assert.Equal(8.3925409000000002, maneuver.ThrustWindow.Length.TotalSeconds, 3);
- Assert.Equal(new Vector3(-97.0714098295484, 107.8305292474044, -119.8974902969949), ((ImpulseManeuver)maneuver).DeltaV);
+ Assert.Equal("2021-03-04T00:32:53.8146003 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T00:33:02.2130194 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T00:32:53.8146003 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T00:33:02.2130194 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
+ Assert.Equal(8.3984190999999999, maneuver.ThrustWindow.Length.TotalSeconds, 3);
+ Assert.Equal(new Vector3(-97.1412202651915, 107.90256552680627, -119.98761196522472), ((ImpulseManeuver)maneuver).DeltaV);
- Assert.Equal(419.62704377403645, maneuver.FuelBurned);
+ Assert.Equal(419.92095543527711, maneuver.FuelBurned);
maneuver = maneuver.NextManeuver;
- Assert.Equal("2021-03-04T01:15:39.8402441 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:16:02.1873755 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:15:39.8402441 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:16:02.1873755 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
- Assert.Equal(22.347131399999999, maneuver.ThrustWindow.Length.TotalSeconds, 3);
- Assert.Equal(new Vector3(-462.3769514474425, -165.79592575424203, 234.3310697732304), ((ImpulseManeuver)maneuver).DeltaV);
- Assert.Equal(1117.3565715207112, maneuver.FuelBurned);
+ Assert.Equal("2021-03-04T01:15:39.8407123 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:16:02.1869075 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:15:39.8407123 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:16:02.1869075 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
+ Assert.Equal(22.3461952, maneuver.ThrustWindow.Length.TotalSeconds, 3);
+ Assert.Equal(new Vector3(-462.1414550058744, -166.03947455552907, 234.6077171916677), ((ImpulseManeuver)maneuver).DeltaV);
+ Assert.Equal(1117.3097601570541, maneuver.FuelBurned);
maneuver = maneuver.NextManeuver;
- Assert.Equal("2021-03-04T01:16:13.2426029 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T04:59:20.7658396 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:16:13.2426029 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:16:22.7850168 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:16:13.2426462 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T04:59:20.8256783 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:16:13.2426462 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:16:22.7849736 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
Assert.Equal(9.5424138999999997, maneuver.ThrustWindow.Length.TotalSeconds, 3);
- Assert.Equal(new Vector3(-139.4951793647351, 85.72332642451474, 194.88236993709975), ((ImpulseManeuver)maneuver).DeltaV);
- Assert.Equal(477.12069491886507, maneuver.FuelBurned);
+ Assert.Equal(new Vector3(-139.49753871704854, 85.72527093628567, 194.88665767803553), ((ImpulseManeuver)maneuver).DeltaV);
+ Assert.Equal(477.11637079604111, maneuver.FuelBurned);
maneuver = maneuver.NextManeuver;
- Assert.Equal("2021-03-04T05:23:58.7294586 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T05:24:07.2981610 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
- Assert.Equal("2021-03-04T05:23:58.7294586 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T05:24:07.2981610 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T05:23:58.7294805 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T05:24:07.2981393 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T05:23:58.7294805 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T05:24:07.2981393 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
Assert.Equal(8.5687023999999994, maneuver.ThrustWindow.Length.TotalSeconds, 3);
- Assert.Equal(new Vector3(134.22795291868337, -81.45016347177679, -183.86968653289438), ((ImpulseManeuver)maneuver).DeltaV);
- Assert.Equal(428.43511797710403, maneuver.FuelBurned);
+ Assert.Equal(new Vector3(134.21948840073748, -81.46563131619929, -183.87722556440008), ((ImpulseManeuver)maneuver).DeltaV);
+ Assert.Equal(428.43294038256437, maneuver.FuelBurned);
}
[Fact]
@@ -214,9 +214,6 @@ public void PropagateScenario2()
//Define parking orbit
KeplerianElements parkingOrbit = new KeplerianElements(10000000.0, 0.5, 1.0, 0.0, 0.0, 0.0, earth, DateTimeExtension.J2000, Frames.Frame.ICRF);
- //Define target orbit
- KeplerianElements targetOrbit = new KeplerianElements(10000000.0, 0.5, 1.0, 0.0, 0.0, 0.0, earth, DateTimeExtension.J2000, Frames.Frame.ICRF);
-
//Create and configure spacecraft
Clock clock = new Clock("clk1", System.Math.Pow(2.0, 16.0));
Spacecraft spacecraft =
@@ -243,25 +240,25 @@ public void PropagateScenario2()
// Read maneuver results
var maneuver = spacecraft.StandbyManeuver;
- Assert.Equal("2021-03-04T01:33:26.9842661 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:33:29.0433537 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:33:26.9842661 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:33:29.0433537 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
- Assert.Equal(2.0590875999999998, maneuver.ThrustWindow.Length.TotalSeconds, 3);
- Assert.Equal(new Vector3(6.06672064664599, 42.796832837817874, -14.017587297211776), ((ImpulseManeuver)maneuver).DeltaV);
+ Assert.Equal("2021-03-04T01:33:26.9902501 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:33:29.0373698 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:33:26.9902501 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:33:29.0373698 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
+ Assert.Equal(2.0470000000000002, maneuver.ThrustWindow.Length.TotalSeconds, 3);
+ Assert.Equal(new Vector3(0.27283642892594173, 42.940862925320744, -14.02921217988478), ((ImpulseManeuver)maneuver).DeltaV);
- Assert.Equal(102.95438080009254, maneuver.FuelBurned);
+ Assert.Equal(102.35598515078391, maneuver.FuelBurned, 6);
maneuver = maneuver.NextManeuver;
- Assert.Equal("2021-03-04T04:18:00.5620061 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T04:18:01.4656137 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
- Assert.Equal("2021-03-04T04:18:00.5620061 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T04:18:01.4656137 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
- Assert.Equal(0.90360759999999996, maneuver.ThrustWindow.Length.TotalSeconds, 3);
- Assert.Equal(new Vector3(0.6113331463337078, 10.731242700644234, 16.97261190194155), ((ImpulseManeuver)maneuver).DeltaV);
- Assert.Equal(45.180377988723926, maneuver.FuelBurned);
+ Assert.Equal("2021-03-04T04:18:07.5605585 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T04:18:08.4670611 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T04:18:07.5605585 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T04:18:08.4670611 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
+ Assert.Equal(0.90650260000000005, maneuver.ThrustWindow.Length.TotalSeconds, 3);
+ Assert.Equal(new Vector3(0.5763904852327267, 10.765407583564869, 17.027153112523376), ((ImpulseManeuver)maneuver).DeltaV);
+ Assert.Equal(45.325132147428718, maneuver.FuelBurned);
}
[Fact]
@@ -667,7 +664,7 @@ void GetCelestialBodyInformation()
Assert.Equal(-2.5388099999999996E-06, res.J3);
Assert.Equal(-1.6559699999999999E-06, res.J4);
}
-
+
[Fact]
void GetCelestialBodyInformationWithoutJ()
{
diff --git a/IO.Astrodynamics.Tests/IO.Astrodynamics.Tests.csproj b/IO.Astrodynamics.Tests/IO.Astrodynamics.Tests.csproj
index a187c6f..2303bd2 100644
--- a/IO.Astrodynamics.Tests/IO.Astrodynamics.Tests.csproj
+++ b/IO.Astrodynamics.Tests/IO.Astrodynamics.Tests.csproj
@@ -10,6 +10,7 @@
+
diff --git a/IO.Astrodynamics.Tests/Math/Vector3Test.cs b/IO.Astrodynamics.Tests/Math/Vector3Test.cs
index 4dcc3a1..aba5910 100644
--- a/IO.Astrodynamics.Tests/Math/Vector3Test.cs
+++ b/IO.Astrodynamics.Tests/Math/Vector3Test.cs
@@ -82,6 +82,51 @@ public void Angle()
Assert.Equal(System.Math.PI / 2.0, angle);
}
+ [Fact]
+ public void Angle2()
+ {
+ Vector3 m1 = new Vector3(1, 0, 0);
+ Vector3 m2 = new Vector3(0, 1, 0);
+ double angle = m2.Angle(m1, Plane.Z);
+ Assert.Equal(-System.Math.PI / 2.0, angle);
+ }
+
+ [Fact]
+ public void Angle3()
+ {
+ Vector3 m1 = new Vector3(1, -1, 0);
+ Vector3 m2 = new Vector3(0, 1, 0);
+ double angle = m2.Angle(m1, new Plane(new Vector3(0.0,0.0,10.0),0.0));
+ Assert.Equal(-2.3561944901923448, angle, 6);
+ }
+
+ [Fact]
+ public void Angle4()
+ {
+ Vector3 m1 = new Vector3(0, -1, 0);
+ Vector3 m2 = new Vector3(0, 1, 0);
+ double angle = m2.Angle(m1, Plane.Z);
+ Assert.Equal(3.1415929999999999, angle, 6);
+ }
+
+ [Fact]
+ public void Angle5()
+ {
+ Vector3 m1 = new Vector3(-1, -1, 0);
+ Vector3 m2 = new Vector3(0, 1, 0);
+ double angle = m2.Angle(m1, Plane.Z);
+ Assert.Equal(2.3561939999999999, angle, 6);
+ }
+
+ [Fact]
+ public void Angle6()
+ {
+ Vector3 m1 = new Vector3(-1, 0, 0);
+ Vector3 m2 = new Vector3(0, 1, 0);
+ double angle = m2.Angle(m1);
+ Assert.Equal(1.5707960000000001, angle, 6);
+ }
+
[Fact]
public void To()
{
@@ -93,7 +138,7 @@ public void To()
Assert.Equal(0.0, q.VectorPart.Y);
Assert.Equal(-0.7071067811865475, q.VectorPart.Z);
}
-
+
[Fact]
public void To2()
{
diff --git a/IO.Astrodynamics.Tests/Mission/ScenarioTests.cs b/IO.Astrodynamics.Tests/Mission/ScenarioTests.cs
index dba33c4..61dbcee 100644
--- a/IO.Astrodynamics.Tests/Mission/ScenarioTests.cs
+++ b/IO.Astrodynamics.Tests/Mission/ScenarioTests.cs
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
+using BenchmarkDotNet.Attributes;
using IO.Astrodynamics.Body;
using IO.Astrodynamics.Body.Spacecraft;
using IO.Astrodynamics.Maneuver;
@@ -56,6 +57,7 @@ public void AddAdditionalCelestialBody()
}
[Fact]
+ [Benchmark]
public void Propagate()
{
DateTime start = DateTimeExtension.CreateUTC(667915269.18539762).ToTDB();
@@ -110,56 +112,56 @@ public void Propagate()
// Read maneuver results
var maneuver = spacecraft.StandbyManeuver;
- Assert.Equal("2021-03-04T00:32:49.8175394 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T00:32:58.2100803 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
- Assert.Equal("2021-03-04T00:32:49.8175394 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T00:32:58.2100803 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
- Assert.Equal(8.3925409000000002, maneuver.ThrustWindow.Length.TotalSeconds, 3);
- Assert.Equal(new Vector3(-97.0714098295484, 107.8305292474044, -119.8974902969949), ((ImpulseManeuver)maneuver).DeltaV);
+ Assert.Equal("2021-03-04T00:32:53.8146003 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T00:33:02.2130194 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T00:32:53.8146003 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T00:33:02.2130194 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
+ Assert.Equal(8.3984190999999999, maneuver.ThrustWindow.Length.TotalSeconds, 3);
+ Assert.Equal(new Vector3(-97.1412202651915, 107.90256552680627, -119.98761196522472), ((ImpulseManeuver)maneuver).DeltaV);
- Assert.Equal(419.62704377403645, maneuver.FuelBurned);
+ Assert.Equal(419.92095543527711, maneuver.FuelBurned);
maneuver = maneuver.NextManeuver;
- Assert.Equal("2021-03-04T01:15:39.8402441 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:16:02.1873755 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:15:39.8402441 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:16:02.1873755 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
- Assert.Equal(22.347131399999999, maneuver.ThrustWindow.Length.TotalSeconds, 3);
- Assert.Equal(new Vector3(-462.3769514474425, -165.79592575424203, 234.3310697732304), ((ImpulseManeuver)maneuver).DeltaV);
- Assert.Equal(1117.3565715207112, maneuver.FuelBurned, 3);
+ Assert.Equal("2021-03-04T01:15:39.8407123 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:16:02.1869075 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:15:39.8407123 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:16:02.1869075 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
+ Assert.Equal(22.3461952, maneuver.ThrustWindow.Length.TotalSeconds, 3);
+ Assert.Equal(new Vector3(-462.1414550058744, -166.03947455552907, 234.6077171916677), ((ImpulseManeuver)maneuver).DeltaV);
+ Assert.Equal(1117.3097601570541, maneuver.FuelBurned, 3);
maneuver = maneuver.NextManeuver;
- Assert.Equal("2021-03-04T01:16:13.2426029 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T04:59:20.7658396 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:16:13.2426029 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T01:16:22.7850168 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:16:13.2426462 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T04:59:20.8256783 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:16:13.2426462 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T01:16:22.7849736 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
Assert.Equal(9.5424138999999997, maneuver.ThrustWindow.Length.TotalSeconds, 3);
- Assert.Equal(new Vector3(-139.4951793647351, 85.72332642451474, 194.88236993709975), ((ImpulseManeuver)maneuver).DeltaV);
- Assert.Equal(477.12069491886507, maneuver.FuelBurned, 3);
+ Assert.Equal(new Vector3(-139.49753871704854, 85.72527093628567, 194.88665767803553), ((ImpulseManeuver)maneuver).DeltaV);
+ Assert.Equal(477.11637079604111, maneuver.FuelBurned, 3);
maneuver = maneuver.NextManeuver;
- Assert.Equal("2021-03-04T05:23:58.7294586 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T05:24:07.2981610 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
- Assert.Equal("2021-03-04T05:23:58.7294586 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
- Assert.Equal("2021-03-04T05:24:07.2981610 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T05:23:58.7294805 (TDB)", maneuver.ManeuverWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T05:24:07.2981393 (TDB)", maneuver.ManeuverWindow.EndDate.ToFormattedString());
+ Assert.Equal("2021-03-04T05:23:58.7294805 (TDB)", maneuver.ThrustWindow.StartDate.ToFormattedString());
+ Assert.Equal("2021-03-04T05:24:07.2981393 (TDB)", maneuver.ThrustWindow.EndDate.ToFormattedString());
Assert.Equal(8.5687023999999994, maneuver.ThrustWindow.Length.TotalSeconds, 3);
- Assert.Equal(new Vector3(134.22795291868337, -81.45016347177679, -183.86968653289438), ((ImpulseManeuver)maneuver).DeltaV);
- Assert.Equal(428.43511797710403, maneuver.FuelBurned, 3);
+ Assert.Equal(new Vector3(134.21948840073748, -81.46563131619929, -183.87722556440008), ((ImpulseManeuver)maneuver).DeltaV);
+ Assert.Equal(428.43294038256437, maneuver.FuelBurned, 3);
Assert.Equal(scenario.Window, summary.Window);
Assert.Single(summary.SpacecraftSummaries);
var maneuverWindow = summary.SpacecraftSummaries.First().ManeuverWindow;
if (maneuverWindow != null)
{
- Assert.Equal(new DateTime(2021, 3, 4, 0, 32, 49, 818, DateTimeKind.Unspecified), maneuverWindow.Value.StartDate, TimeSpan.FromMilliseconds(1));
+ Assert.Equal(new DateTime(2021, 3, 4, 0, 32, 53, 814, DateTimeKind.Unspecified), maneuverWindow.Value.StartDate, TimeSpan.FromMilliseconds(1));
Assert.Equal(new DateTime(2021, 3, 4, 5, 27, 13, 014, DateTimeKind.Unspecified), maneuverWindow.Value.EndDate, TimeSpan.FromMilliseconds(1));
}
- Assert.Equal(2442.5394281907165, summary.SpacecraftSummaries.First().FuelConsumption, 3);
+ Assert.Equal(2442.7800000000002, summary.SpacecraftSummaries.First().FuelConsumption, 3);
}
[Fact]
diff --git a/IO.Astrodynamics.sln b/IO.Astrodynamics.sln
index f4a1938..8956183 100644
--- a/IO.Astrodynamics.sln
+++ b/IO.Astrodynamics.sln
@@ -4,6 +4,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IO.Astrodynamics", "IO.Astr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IO.Astrodynamics.Tests", "IO.Astrodynamics.Tests\IO.Astrodynamics.Tests.csproj", "{7D17CAA6-C53A-447D-B6EC-FD71654EB56F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IO.Astrodynamics.Performance", "IO.Astrodynamics.Performance\IO.Astrodynamics.Performance.csproj", "{7ADFCA3F-5B86-4149-B4C8-99195C4E677F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -18,5 +20,9 @@ Global
{7D17CAA6-C53A-447D-B6EC-FD71654EB56F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D17CAA6-C53A-447D-B6EC-FD71654EB56F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D17CAA6-C53A-447D-B6EC-FD71654EB56F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7ADFCA3F-5B86-4149-B4C8-99195C4E677F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7ADFCA3F-5B86-4149-B4C8-99195C4E677F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7ADFCA3F-5B86-4149-B4C8-99195C4E677F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7ADFCA3F-5B86-4149-B4C8-99195C4E677F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/IO.Astrodynamics/IO.Astrodynamics.nuspec b/IO.Astrodynamics/IO.Astrodynamics.nuspec
index 71e7f32..1f6d569 100644
--- a/IO.Astrodynamics/IO.Astrodynamics.nuspec
+++ b/IO.Astrodynamics/IO.Astrodynamics.nuspec
@@ -4,7 +4,7 @@
IO.Astrodynamics
Sylvain Guillet
Sylvain Guillet
- 1.9.1
+ 1.9.2
Astrodynamics framework
images\dragonfly-dark-trans.png
docs\README.md
diff --git a/IO.Astrodynamics/Maneuver/ApogeeHeightManeuver.cs b/IO.Astrodynamics/Maneuver/ApogeeHeightManeuver.cs
index 7dec4eb..7b361f9 100644
--- a/IO.Astrodynamics/Maneuver/ApogeeHeightManeuver.cs
+++ b/IO.Astrodynamics/Maneuver/ApogeeHeightManeuver.cs
@@ -1,5 +1,7 @@
using System;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver
{
diff --git a/IO.Astrodynamics/Maneuver/ApsidalAlignmentManeuver.cs b/IO.Astrodynamics/Maneuver/ApsidalAlignmentManeuver.cs
index f32b080..7730315 100644
--- a/IO.Astrodynamics/Maneuver/ApsidalAlignmentManeuver.cs
+++ b/IO.Astrodynamics/Maneuver/ApsidalAlignmentManeuver.cs
@@ -1,5 +1,7 @@
using System;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver
diff --git a/IO.Astrodynamics/Maneuver/CombinedManeuver.cs b/IO.Astrodynamics/Maneuver/CombinedManeuver.cs
index e395b30..445af6e 100644
--- a/IO.Astrodynamics/Maneuver/CombinedManeuver.cs
+++ b/IO.Astrodynamics/Maneuver/CombinedManeuver.cs
@@ -1,5 +1,7 @@
using System;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver
{
diff --git a/IO.Astrodynamics/Maneuver/ImpulseManeuver.cs b/IO.Astrodynamics/Maneuver/ImpulseManeuver.cs
index 36073ef..3d6a8b9 100644
--- a/IO.Astrodynamics/Maneuver/ImpulseManeuver.cs
+++ b/IO.Astrodynamics/Maneuver/ImpulseManeuver.cs
@@ -1,6 +1,8 @@
using System;
+using System.Threading.Tasks;
using IO.Astrodynamics.Body.Spacecraft;
using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver
{
diff --git a/IO.Astrodynamics/Maneuver/InstrumentPointingToAttitude.cs b/IO.Astrodynamics/Maneuver/InstrumentPointingToAttitude.cs
index bbaf55f..03cf0f6 100644
--- a/IO.Astrodynamics/Maneuver/InstrumentPointingToAttitude.cs
+++ b/IO.Astrodynamics/Maneuver/InstrumentPointingToAttitude.cs
@@ -3,6 +3,8 @@
using System;
using IO.Astrodynamics.Body;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver;
diff --git a/IO.Astrodynamics/Maneuver/Maneuver.cs b/IO.Astrodynamics/Maneuver/Maneuver.cs
index 5b003ba..657fb43 100644
--- a/IO.Astrodynamics/Maneuver/Maneuver.cs
+++ b/IO.Astrodynamics/Maneuver/Maneuver.cs
@@ -1,25 +1,82 @@
using System;
using System.Collections.Generic;
+using System.Threading.Tasks;
using IO.Astrodynamics.Body.Spacecraft;
-
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
using IO.Astrodynamics.Time;
namespace IO.Astrodynamics.Maneuver
{
public abstract class Maneuver
{
+ ///
+ /// Gets or sets the ThrustWindow instance.
+ ///
+ ///
+ /// The ThrustWindow instance.
+ ///
public Window ThrustWindow { get; internal set; }
+
+ ///
+ /// The AttitudeWindow property represents the window object used to display attitude-related information.
+ ///
+ ///
+ /// Gets or sets the AttitudeWindow property.
+ ///
public Window AttitudeWindow { get; internal set; }
+
+ ///
+ /// Gets or sets the ManeuverWindow object that represents the window for controlling maneuvering tasks.
+ ///
+ ///
+ /// The ManeuverWindow object for controlling maneuvering tasks.
+ ///
public Window ManeuverWindow { get; internal set; }
+
+ ///
+ /// Gets the minimum epoch value.
+ ///
+ ///
+ /// The minimum epoch value represents the earliest date and time when the maneuver can be executed
+ ///
+ ///
+ /// The minimum epoch value.
+ ///
public DateTime MinimumEpoch { get; }
+
+ ///
+ /// Gets the duration for which a maneuver should be held.
+ ///
+ ///
+ /// This property represents the duration as a TimeSpan object.
+ ///
+ /// The maneuver hold duration as a TimeSpan.
public TimeSpan ManeuverHoldDuration { get; }
+
+ ///
+ /// Represents a collection of engine objects.
+ ///
+ /// A read-only collection of objects.
public IReadOnlyCollection Engines { get; }
+
+ ///
+ /// Gets or sets the next maneuver.
+ ///
public Maneuver NextManeuver { get; protected set; }
+ ///
+ /// Gets the target orbital parameters.
+ ///
+ /// The target orbital parameters.
public OrbitalParameters.OrbitalParameters TargetOrbit { get; }
+ ///
+ /// Gets or sets the amount of fuel burned.
+ ///
public double FuelBurned { get; internal set; }
+
protected Maneuver(DateTime minimumEpoch, TimeSpan maneuverHoldDuration, OrbitalParameters.OrbitalParameters targetOrbit,
params Engine[] engines)
{
@@ -52,17 +109,17 @@ public Maneuver SetNextManeuver(Maneuver maneuver)
public static double ComputeDeltaV(double isp, double initialMass, double finalMass)
{
- return isp *Constants.g0 * System.Math.Log(initialMass / finalMass) * 1E-03;
+ return isp * Constants.g0 * System.Math.Log(initialMass / finalMass) * 1E-03;
}
public static TimeSpan ComputeDeltaT(double isp, double initialMass, double fuelFlow, double deltaV)
{
- return TimeSpan.FromSeconds(initialMass / fuelFlow * (1 - System.Math.Exp(-deltaV * 1E03 / (isp *Constants.g0))));
+ return TimeSpan.FromSeconds(initialMass / fuelFlow * (1 - System.Math.Exp(-deltaV * 1E03 / (isp * Constants.g0))));
}
public static double ComputeDeltaM(double isp, double initialMass, double deltaV)
{
- return initialMass * (1 - System.Math.Exp(-deltaV * 1E03 / (isp *Constants.g0)));
+ return initialMass * (1 - System.Math.Exp(-deltaV * 1E03 / (isp * Constants.g0)));
}
}
}
\ No newline at end of file
diff --git a/IO.Astrodynamics/Maneuver/NadirAttitude.cs b/IO.Astrodynamics/Maneuver/NadirAttitude.cs
index c427502..70414d7 100644
--- a/IO.Astrodynamics/Maneuver/NadirAttitude.cs
+++ b/IO.Astrodynamics/Maneuver/NadirAttitude.cs
@@ -2,6 +2,8 @@
using System;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver;
diff --git a/IO.Astrodynamics/Maneuver/PerigeeHeightManeuver.cs b/IO.Astrodynamics/Maneuver/PerigeeHeightManeuver.cs
index 1e2409c..9ff8729 100644
--- a/IO.Astrodynamics/Maneuver/PerigeeHeightManeuver.cs
+++ b/IO.Astrodynamics/Maneuver/PerigeeHeightManeuver.cs
@@ -1,5 +1,7 @@
using System;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver
{
diff --git a/IO.Astrodynamics/Maneuver/PhasingManeuver.cs b/IO.Astrodynamics/Maneuver/PhasingManeuver.cs
index fad02ac..dcab975 100644
--- a/IO.Astrodynamics/Maneuver/PhasingManeuver.cs
+++ b/IO.Astrodynamics/Maneuver/PhasingManeuver.cs
@@ -1,5 +1,7 @@
using System;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver
{
diff --git a/IO.Astrodynamics/Maneuver/PlaneAlignmentManeuver.cs b/IO.Astrodynamics/Maneuver/PlaneAlignmentManeuver.cs
index 76e1953..8b3b6b8 100644
--- a/IO.Astrodynamics/Maneuver/PlaneAlignmentManeuver.cs
+++ b/IO.Astrodynamics/Maneuver/PlaneAlignmentManeuver.cs
@@ -1,5 +1,7 @@
using System;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver
{
diff --git a/IO.Astrodynamics/Maneuver/ProgradeAttitude.cs b/IO.Astrodynamics/Maneuver/ProgradeAttitude.cs
index d2c093c..115b660 100644
--- a/IO.Astrodynamics/Maneuver/ProgradeAttitude.cs
+++ b/IO.Astrodynamics/Maneuver/ProgradeAttitude.cs
@@ -2,6 +2,8 @@
using System;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver;
diff --git a/IO.Astrodynamics/Maneuver/RetrogradeAttitude.cs b/IO.Astrodynamics/Maneuver/RetrogradeAttitude.cs
index af0d61c..b5ad732 100644
--- a/IO.Astrodynamics/Maneuver/RetrogradeAttitude.cs
+++ b/IO.Astrodynamics/Maneuver/RetrogradeAttitude.cs
@@ -2,6 +2,8 @@
using System;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver;
diff --git a/IO.Astrodynamics/Maneuver/ZenithAttitude.cs b/IO.Astrodynamics/Maneuver/ZenithAttitude.cs
index 1ba346b..c1286c5 100644
--- a/IO.Astrodynamics/Maneuver/ZenithAttitude.cs
+++ b/IO.Astrodynamics/Maneuver/ZenithAttitude.cs
@@ -2,6 +2,8 @@
using System;
using IO.Astrodynamics.Body.Spacecraft;
+using IO.Astrodynamics.Math;
+using IO.Astrodynamics.OrbitalParameters;
namespace IO.Astrodynamics.Maneuver;
diff --git a/IO.Astrodynamics/Math/Plane.cs b/IO.Astrodynamics/Math/Plane.cs
index 89bff80..247b726 100644
--- a/IO.Astrodynamics/Math/Plane.cs
+++ b/IO.Astrodynamics/Math/Plane.cs
@@ -5,6 +5,10 @@ public class Plane
public Vector3 Normal { get; }
public double Distance { get; }
+ public static Plane X { get; } = new Plane(Vector3.VectorX);
+ public static Plane Y { get; } = new Plane(Vector3.VectorY);
+ public static Plane Z { get; } = new Plane(Vector3.VectorZ);
+
public Plane(Vector3 normal) : this(normal, 0.0)
{
}
diff --git a/IO.Astrodynamics/Math/Vector3.cs b/IO.Astrodynamics/Math/Vector3.cs
index 74a79d3..b709d6a 100644
--- a/IO.Astrodynamics/Math/Vector3.cs
+++ b/IO.Astrodynamics/Math/Vector3.cs
@@ -1,4 +1,3 @@
-
namespace IO.Astrodynamics.Math
{
public readonly record struct Vector3
@@ -39,6 +38,11 @@ public double Angle(Vector3 vector)
return System.Math.Acos(this * vector / (Magnitude() * vector.Magnitude()));
}
+ public double Angle(Vector3 vector, Plane plane)
+ {
+ return double.Atan2(this.Cross(vector) * plane.Normal.Normalize(), this * vector);
+ }
+
public Vector3 Inverse()
{
return this * -1.0;
diff --git a/IO.Astrodynamics/Mission/Scenario.cs b/IO.Astrodynamics/Mission/Scenario.cs
index f092467..b5a72f5 100644
--- a/IO.Astrodynamics/Mission/Scenario.cs
+++ b/IO.Astrodynamics/Mission/Scenario.cs
@@ -92,14 +92,10 @@ public ScenarioSummary Simulate(DirectoryInfo outputDirectory)
{
throw new InvalidOperationException("There is nothing to simulate");
}
-
-
var rootDirectory = outputDirectory.CreateSubdirectory(this.Mission.Name).CreateSubdirectory(this.Name);
var spacecraftDirectory = rootDirectory.CreateSubdirectory("Spacecrafts");
var siteDirectory = rootDirectory.CreateSubdirectory("Sites");
-
-
API.Instance.PropagateScenario(this, siteDirectory, spacecraftDirectory);
diff --git a/IO.Astrodynamics/OrbitalParameters/EquinoctialElements.cs b/IO.Astrodynamics/OrbitalParameters/EquinoctialElements.cs
index 4d60e14..7143538 100644
--- a/IO.Astrodynamics/OrbitalParameters/EquinoctialElements.cs
+++ b/IO.Astrodynamics/OrbitalParameters/EquinoctialElements.cs
@@ -6,7 +6,15 @@ namespace IO.Astrodynamics.OrbitalParameters
{
public class EquinoctialElements : OrbitalParameters, IEquatable
{
-
+ private double? _argumentOfPeriapsis;
+ private double? _ascendingNode;
+ private double? _eccentricAnomaly;
+ private double? _eccentricity;
+ private double? _inclination;
+ private double? _meanAnomaly;
+ private double? _semisMajorAxis;
+ private double? _trueAnomaly;
+
///
/// Constructor
@@ -41,51 +49,64 @@ public EquinoctialElements(double p, double f, double g, double h, double k, dou
public override double ArgumentOfPeriapsis()
{
- return System.Math.Atan2(G * H - F * K, F * H + G * K);
+ _argumentOfPeriapsis ??= System.Math.Atan2(G * H - F * K, F * H + G * K);
+ return _argumentOfPeriapsis.Value;
}
public override double AscendingNode()
{
- return System.Math.Atan(K / H);
+ _ascendingNode ??= System.Math.Atan(K / H);
+ return _ascendingNode.Value;
}
public override double EccentricAnomaly()
{
+ if (_eccentricAnomaly.HasValue)
+ {
+ return _eccentricAnomaly.Value;
+ }
+
double v = TrueAnomaly();
double e = Eccentricity();
- return 2 * System.Math.Atan((System.Math.Tan(v / 2.0)) / System.Math.Sqrt((1 + e) / (1 - e)));
+ _eccentricAnomaly = 2 * System.Math.Atan((System.Math.Tan(v / 2.0)) / System.Math.Sqrt((1 + e) / (1 - e)));
+ return _eccentricAnomaly.Value;
}
public override double Eccentricity()
{
- return System.Math.Sqrt(F * F + G * G);
+ _eccentricity ??= System.Math.Sqrt(F * F + G * G);
+ return _eccentricity.Value;
}
public override double Inclination()
{
- return System.Math.Atan2(2 * System.Math.Sqrt(H * H + K * K), 1 - H * H - K * K);
+ _inclination ??= System.Math.Atan2(2 * System.Math.Sqrt(H * H + K * K), 1 - H * H - K * K);
+ return _inclination.Value;
}
public override double MeanAnomaly()
{
- return EccentricAnomaly() - Eccentricity() * System.Math.Sin(EccentricAnomaly());
+ _meanAnomaly ??= EccentricAnomaly() - Eccentricity() * System.Math.Sin(EccentricAnomaly());
+ return _meanAnomaly.Value;
}
public override double SemiMajorAxis()
{
- return P / (1 - F * F - G * G);
+ _semisMajorAxis ??= P / (1 - F * F - G * G);
+ return _semisMajorAxis.Value;
}
public override double TrueAnomaly()
{
- return L0 - (AscendingNode() + ArgumentOfPeriapsis());
+ _trueAnomaly ??= L0 - (AscendingNode() + ArgumentOfPeriapsis());
+ return _trueAnomaly.Value;
}
public override EquinoctialElements ToEquinoctial()
{
return this;
}
-
+
public bool Equals(EquinoctialElements other)
{
if (ReferenceEquals(null, other)) return false;
diff --git a/IO.Astrodynamics/OrbitalParameters/KeplerianElements.cs b/IO.Astrodynamics/OrbitalParameters/KeplerianElements.cs
index 5c3a6de..b4f52e2 100644
--- a/IO.Astrodynamics/OrbitalParameters/KeplerianElements.cs
+++ b/IO.Astrodynamics/OrbitalParameters/KeplerianElements.cs
@@ -7,7 +7,9 @@ namespace IO.Astrodynamics.OrbitalParameters
{
public class KeplerianElements : OrbitalParameters, IEquatable
{
-
+ private double? _eccentricAnomaly;
+ private double? _trueAnomaly;
+
///
/// Constructor
@@ -82,16 +84,21 @@ public override double AscendingNode()
public override double EccentricAnomaly()
{
+ if (_eccentricAnomaly.HasValue)
+ {
+ return _eccentricAnomaly.Value;
+ }
+
double tmpEA = M;
- double EA = 0.0;
+ _eccentricAnomaly = 0.0;
- while (System.Math.Abs(tmpEA - EA) > 1E-09)
+ while (System.Math.Abs(tmpEA - _eccentricAnomaly.Value) > 1E-09)
{
- EA = tmpEA;
- tmpEA = M + E * System.Math.Sin(EA);
+ _eccentricAnomaly = tmpEA;
+ tmpEA = M + E * System.Math.Sin(_eccentricAnomaly.Value);
}
- return EA;
+ return _eccentricAnomaly.Value;
}
public override double Eccentricity()
@@ -111,14 +118,19 @@ public override double SemiMajorAxis()
public override double TrueAnomaly()
{
+ if (_trueAnomaly.HasValue)
+ {
+ return _trueAnomaly.Value;
+ }
double EA = EccentricAnomaly();
- double v = System.Math.Atan2(System.Math.Sqrt(1 - E * E) * System.Math.Sin(EA), System.Math.Cos(EA) - E);
- if (v < 0.0)
+ _trueAnomaly = System.Math.Atan2(System.Math.Sqrt(1 - E * E) * System.Math.Sin(EA), System.Math.Cos(EA) - E);
+ if (_trueAnomaly < 0.0)
{
- v += Constants._2PI;
+ _trueAnomaly += Constants._2PI;
}
- return v % Constants._2PI;
+ _trueAnomaly %= Constants._2PI;
+ return _trueAnomaly.Value;
}
public override double MeanAnomaly()
@@ -130,7 +142,7 @@ public override KeplerianElements ToKeplerianElements()
{
return this;
}
-
+
public bool Equals(KeplerianElements other)
{
if (ReferenceEquals(null, other)) return false;
diff --git a/IO.Astrodynamics/OrbitalParameters/OrbitalParameters.cs b/IO.Astrodynamics/OrbitalParameters/OrbitalParameters.cs
index 27db536..d6c3672 100644
--- a/IO.Astrodynamics/OrbitalParameters/OrbitalParameters.cs
+++ b/IO.Astrodynamics/OrbitalParameters/OrbitalParameters.cs
@@ -15,6 +15,26 @@ public abstract class OrbitalParameters : IEquatable
public DateTime Epoch { get; }
public Frame Frame { get; }
+ protected Vector3? _eccentricVector;
+ protected Vector3? _specificAngularMomentum;
+ protected double? _specificOrbitalEnergy;
+ protected Vector3? _ascendingNodeVector;
+ protected Vector3? _decendingNodeVector;
+ protected TimeSpan? _period;
+ protected double? _meanMotion;
+ protected StateVector _stateVector;
+ protected EquinoctialElements _equinoctial;
+ protected Vector3? _perigeevector;
+ protected Vector3? _apogeeVector;
+ protected double? _trueLongitude;
+ protected double? _meanLongitude;
+ protected bool? _isCircular;
+ protected bool? _isParabolic;
+ protected bool? _isHyperbolic;
+ protected KeplerianElements _keplerianElements;
+ protected Equatorial? _equatorial;
+ protected double? _perigeeVelocity;
+ protected double? _apogeeVelocity;
///
/// Constructor
@@ -35,7 +55,9 @@ protected OrbitalParameters(ILocalizable observer, DateTime epoch, Frame frame)
///
public virtual Vector3 EccentricityVector()
{
- return ToStateVector().EccentricityVector();
+ _eccentricVector ??= ToStateVector().EccentricityVector();
+
+ return _eccentricVector.Value;
}
///
@@ -50,7 +72,8 @@ public virtual Vector3 EccentricityVector()
///
public virtual Vector3 SpecificAngularMomentum()
{
- return ToStateVector().SpecificAngularMomentum();
+ _specificAngularMomentum ??= ToStateVector().SpecificAngularMomentum();
+ return _specificAngularMomentum.Value;
}
///
@@ -59,7 +82,8 @@ public virtual Vector3 SpecificAngularMomentum()
///
public virtual double SpecificOrbitalEnergy()
{
- return ToStateVector().SpecificOrbitalEnergy();
+ _specificOrbitalEnergy ??= ToStateVector().SpecificOrbitalEnergy();
+ return _specificOrbitalEnergy.Value;
}
///
@@ -85,7 +109,8 @@ public virtual Vector3 AscendingNodeVector()
return Vector3.VectorX;
}
- return ToStateVector().AscendingNodeVector();
+ _ascendingNodeVector ??= ToStateVector().AscendingNodeVector();
+ return _ascendingNodeVector.Value;
}
///
@@ -94,7 +119,8 @@ public virtual Vector3 AscendingNodeVector()
///
public Vector3 DescendingNodeVector()
{
- return AscendingNodeVector().Inverse();
+ _decendingNodeVector ??= AscendingNodeVector().Inverse();
+ return _decendingNodeVector.Value;
}
///
@@ -163,9 +189,14 @@ public static double TrueAnomalyToMeanAnomaly(double trueAnomaly, double eccentr
///
public TimeSpan Period()
{
- double a = SemiMajorAxis();
- double T = Constants._2PI * System.Math.Sqrt((a * a * a) / Observer.GM);
- return TimeSpan.FromSeconds(T);
+ if (!_period.HasValue)
+ {
+ double a = SemiMajorAxis();
+ double T = Constants._2PI * System.Math.Sqrt((a * a * a) / Observer.GM);
+ _period = TimeSpan.FromSeconds(T);
+ }
+
+ return _period.Value;
}
///
@@ -174,7 +205,8 @@ public TimeSpan Period()
///
public double MeanMotion()
{
- return Constants._2PI / Period().TotalSeconds;
+ _meanMotion ??= Constants._2PI / Period().TotalSeconds;
+ return _meanMotion.Value;
}
@@ -184,24 +216,29 @@ public double MeanMotion()
///
public virtual StateVector ToStateVector()
{
- var e = Eccentricity();
- var p = SemiMajorAxis() * (1 - e * e);
- var v = TrueAnomaly();
- var r0 = p / (1 + e * System.Math.Cos(v));
- var x = r0 * System.Math.Cos(v);
- var y = r0 * System.Math.Sin(v);
- var dotX = -System.Math.Sqrt(Observer.GM / p) * System.Math.Sin(v);
- var dotY = System.Math.Sqrt(Observer.GM / p) * (e + System.Math.Cos(v));
- Matrix R3 = Matrix.CreateRotationMatrixZ(AscendingNode());
- Matrix R1 = Matrix.CreateRotationMatrixX(Inclination());
- Matrix R3w = Matrix.CreateRotationMatrixZ(ArgumentOfPeriapsis());
- Matrix R = R3 * R1 * R3w;
- double[] pos = { x, y, 0.0 };
- double[] vel = { dotX, dotY, 0.0 };
- double[] finalPos = pos * R;
- double[] finalV = vel * R;
-
- return new StateVector(new Vector3(finalPos[0], finalPos[1], finalPos[2]), new Vector3(finalV[0], finalV[1], finalV[2]), Observer, Epoch, Frame);
+ if (_stateVector is null)
+ {
+ var e = Eccentricity();
+ var p = SemiMajorAxis() * (1 - e * e);
+ var v = TrueAnomaly();
+ var r0 = p / (1 + e * System.Math.Cos(v));
+ var x = r0 * System.Math.Cos(v);
+ var y = r0 * System.Math.Sin(v);
+ var dotX = -System.Math.Sqrt(Observer.GM / p) * System.Math.Sin(v);
+ var dotY = System.Math.Sqrt(Observer.GM / p) * (e + System.Math.Cos(v));
+ Matrix R3 = Matrix.CreateRotationMatrixZ(AscendingNode());
+ Matrix R1 = Matrix.CreateRotationMatrixX(Inclination());
+ Matrix R3w = Matrix.CreateRotationMatrixZ(ArgumentOfPeriapsis());
+ Matrix R = R3 * R1 * R3w;
+ double[] pos = { x, y, 0.0 };
+ double[] vel = { dotX, dotY, 0.0 };
+ double[] finalPos = pos * R;
+ double[] finalV = vel * R;
+
+ _stateVector = new StateVector(new Vector3(finalPos[0], finalPos[1], finalPos[2]), new Vector3(finalV[0], finalV[1], finalV[2]), Observer, Epoch, Frame);
+ }
+
+ return _stateVector;
}
public virtual StateVector ToStateVector(DateTime epoch)
@@ -215,20 +252,25 @@ public virtual StateVector ToStateVector(DateTime epoch)
///
public virtual EquinoctialElements ToEquinoctial()
{
- double e = Eccentricity();
- double o = AscendingNode();
- double w = ArgumentOfPeriapsis();
- double i = Inclination();
- double v = TrueAnomaly();
-
- double p = SemiMajorAxis() * (1 - e * e);
- double f = e * System.Math.Cos(o + w);
- double g = e * System.Math.Sin(o + w);
- double h = System.Math.Tan(i * 0.5) * System.Math.Cos(o);
- double k = System.Math.Tan(i * 0.5) * System.Math.Sin(o);
- double l0 = o + w + v;
+ if (_equinoctial is null)
+ {
+ double e = Eccentricity();
+ double o = AscendingNode();
+ double w = ArgumentOfPeriapsis();
+ double i = Inclination();
+ double v = TrueAnomaly();
+
+ double p = SemiMajorAxis() * (1 - e * e);
+ double f = e * System.Math.Cos(o + w);
+ double g = e * System.Math.Sin(o + w);
+ double h = System.Math.Tan(i * 0.5) * System.Math.Cos(o);
+ double k = System.Math.Tan(i * 0.5) * System.Math.Sin(o);
+ double l0 = o + w + v;
+
+ _equinoctial = new EquinoctialElements(p, f, g, h, k, l0, Observer, Epoch, Frame);
+ }
- return new EquinoctialElements(p, f, g, h, k, l0, Observer, Epoch, Frame);
+ return _equinoctial;
}
///
@@ -242,7 +284,8 @@ public Vector3 PerigeeVector()
return Vector3.VectorX * SemiMajorAxis();
}
- return EccentricityVector().Normalize() * SemiMajorAxis() * (1.0 - Eccentricity());
+ _perigeevector ??= EccentricityVector().Normalize() * SemiMajorAxis() * (1.0 - Eccentricity());
+ return _perigeevector.Value;
}
///
@@ -256,7 +299,8 @@ public Vector3 ApogeeVector()
return Vector3.VectorX.Inverse() * SemiMajorAxis();
}
- return EccentricityVector().Normalize().Inverse() * SemiMajorAxis() * (1.0 + Eccentricity());
+ _apogeeVector ??= EccentricityVector().Normalize().Inverse() * SemiMajorAxis() * (1.0 + Eccentricity());
+ return _apogeeVector.Value;
}
///
@@ -275,7 +319,8 @@ public virtual OrbitalParameters AtEpoch(DateTime epoch)
///
public double TrueLongitude()
{
- return (AscendingNode() + ArgumentOfPeriapsis() + TrueAnomaly()) % Constants._2PI;
+ _trueLongitude ??= (AscendingNode() + ArgumentOfPeriapsis() + TrueAnomaly()) % Constants._2PI;
+ return _trueLongitude.Value;
}
///
@@ -284,22 +329,26 @@ public double TrueLongitude()
///
public double MeanLongitude()
{
- return (AscendingNode() + ArgumentOfPeriapsis() + MeanAnomaly()) % Constants._2PI;
+ _meanLongitude ??= (AscendingNode() + ArgumentOfPeriapsis() + MeanAnomaly()) % Constants._2PI;
+ return _meanLongitude.Value;
}
public bool IsCircular()
{
- return Eccentricity() < 1E-03;
+ _isCircular ??= Eccentricity() < 1E-03;
+ return _isCircular.Value;
}
public bool IsParabolic()
{
- return System.Math.Abs(Eccentricity() - 1.0) < double.Epsilon;
+ _isParabolic ??= System.Math.Abs(Eccentricity() - 1.0) < double.Epsilon;
+ return _isParabolic.Value;
}
public bool IsHyperbolic()
{
- return Eccentricity() > 1.0;
+ _isHyperbolic ??= Eccentricity() > 1.0;
+ return _isHyperbolic.Value;
}
private KeplerianElements ToKeplerianElements(DateTime epoch)
@@ -316,7 +365,8 @@ private KeplerianElements ToKeplerianElements(DateTime epoch)
public virtual KeplerianElements ToKeplerianElements()
{
- return ToKeplerianElements(Epoch);
+ _keplerianElements ??= ToKeplerianElements(Epoch);
+ return _keplerianElements;
}
public OrbitalParameters ToFrame(Frame frame)
@@ -335,17 +385,20 @@ public OrbitalParameters ToFrame(Frame frame)
public Equatorial ToEquatorial()
{
- return new Equatorial(ToStateVector());
+ _equatorial ??= new Equatorial(ToStateVector());
+ return _equatorial.Value;
}
public double PerigeeVelocity()
{
- return System.Math.Sqrt(Observer.GM * (2 / PerigeeVector().Magnitude() - 1.0 / SemiMajorAxis()));
+ _perigeeVelocity ??= System.Math.Sqrt(Observer.GM * (2 / PerigeeVector().Magnitude() - 1.0 / SemiMajorAxis()));
+ return _perigeeVelocity.Value;
}
public double ApogeeVelocity()
{
- return System.Math.Sqrt(Observer.GM * (2 / ApogeeVector().Magnitude() - 1.0 / SemiMajorAxis()));
+ _apogeeVelocity ??= System.Math.Sqrt(Observer.GM * (2 / ApogeeVector().Magnitude() - 1.0 / SemiMajorAxis()));
+ return _apogeeVelocity.Value;
}
public override bool Equals(object obj)
diff --git a/IO.Astrodynamics/OrbitalParameters/StateVector.cs b/IO.Astrodynamics/OrbitalParameters/StateVector.cs
index eb65b12..2c0988f 100644
--- a/IO.Astrodynamics/OrbitalParameters/StateVector.cs
+++ b/IO.Astrodynamics/OrbitalParameters/StateVector.cs
@@ -7,6 +7,15 @@ namespace IO.Astrodynamics.OrbitalParameters
{
public class StateVector : OrbitalParameters, IEquatable
{
+ private double? _eccentricity;
+ private double? _inclination;
+ private double? _semiMajorAxis;
+ private double? _ascendingNode;
+ private double? _argumentOfPeriapsis;
+ private double? _trueAnomaly;
+ private double? _eccentricAnomaly;
+ private double? _meanAnomaly;
+ private StateVector _inverse;
public Vector3 Position { get; internal set; }
public Vector3 Velocity { get; internal set; }
@@ -26,48 +35,66 @@ public StateVector(Vector3 position, Vector3 velocity, ILocalizable observer, Da
public override Vector3 SpecificAngularMomentum()
{
- return Position.Cross(Velocity);
+ _specificAngularMomentum ??= Position.Cross(Velocity);
+ return _specificAngularMomentum.Value;
}
public override double Eccentricity()
{
- return EccentricityVector().Magnitude();
+ _eccentricity ??= EccentricityVector().Magnitude();
+ return _eccentricity.Value;
}
public override Vector3 EccentricityVector()
{
- return (Velocity.Cross(SpecificAngularMomentum()) / Observer.GM) - (Position / Position.Magnitude());
+ _eccentricVector ??= (Velocity.Cross(SpecificAngularMomentum()) / Observer.GM) - (Position / Position.Magnitude());
+ return _eccentricVector.Value;
}
public override double Inclination()
{
- return SpecificAngularMomentum().Angle(Vector3.VectorZ);
+ _inclination ??= SpecificAngularMomentum().Angle(Vector3.VectorZ);
+ return _inclination.Value;
}
public override double SpecificOrbitalEnergy()
{
- return System.Math.Pow(Velocity.Magnitude(), 2.0) / 2.0 - (Observer.GM / Position.Magnitude());
+ _specificOrbitalEnergy ??= System.Math.Pow(Velocity.Magnitude(), 2.0) / 2.0 - (Observer.GM / Position.Magnitude());
+ return _specificOrbitalEnergy.Value;
}
public override double SemiMajorAxis()
{
- return -(Observer.GM / (2.0 * SpecificOrbitalEnergy()));
+ _semiMajorAxis ??= -(Observer.GM / (2.0 * SpecificOrbitalEnergy()));
+ return _semiMajorAxis.Value;
}
public override Vector3 AscendingNodeVector()
{
+ if (_ascendingNodeVector.HasValue)
+ {
+ return _ascendingNodeVector.Value;
+ }
+
if (Inclination() == 0.0)
{
return Vector3.VectorX;
}
var h = SpecificAngularMomentum();
- return new Vector3(-h.Y, h.X, 0.0);
+ _ascendingNodeVector = new Vector3(-h.Y, h.X, 0.0);
+
+ return _ascendingNodeVector.Value;
}
public override double AscendingNode()
{
+ if (_ascendingNode.HasValue)
+ {
+ return _ascendingNode.Value;
+ }
+
Vector3 n = AscendingNodeVector();
var omega = System.Math.Acos(n.X / n.Magnitude());
@@ -76,41 +103,58 @@ public override double AscendingNode()
omega = 2 * System.Math.PI - omega;
}
- return omega;
+ _ascendingNode = omega;
+
+
+ return _ascendingNode.Value;
}
public override double ArgumentOfPeriapsis()
{
+ if (_argumentOfPeriapsis.HasValue)
+ {
+ return _argumentOfPeriapsis.Value;
+ }
+
var n = AscendingNodeVector();
var e = EccentricityVector();
- var w = System.Math.Acos((n * e) / (n.Magnitude() * e.Magnitude()));
+ _argumentOfPeriapsis = System.Math.Acos((n * e) / (n.Magnitude() * e.Magnitude()));
if (e.Z < 0.0)
{
- w = System.Math.PI * 2.0 - w;
+ _argumentOfPeriapsis = System.Math.PI * 2.0 - _argumentOfPeriapsis;
}
- return w;
+ return _argumentOfPeriapsis.Value;
}
public override double TrueAnomaly()
{
+ if (_trueAnomaly.HasValue)
+ {
+ return _trueAnomaly.Value;
+ }
+
+
if (IsCircular())
{
if (Inclination() < 1E-03)
{
- return CircularNoInclinationTrueAnomaly();
+ _trueAnomaly = CircularNoInclinationTrueAnomaly();
+ return _trueAnomaly.Value;
}
- return CircularTrueAnomaly();
+ _trueAnomaly = CircularTrueAnomaly();
+ return _trueAnomaly.Value;
}
+
var e = EccentricityVector();
- var v = System.Math.Acos((e * Position) / (e.Magnitude() * Position.Magnitude()));
+ _trueAnomaly = System.Math.Acos((e * Position) / (e.Magnitude() * Position.Magnitude()));
if (Position * Velocity < 0.0)
{
- v = System.Math.PI * 2.0 - v;
+ _trueAnomaly = System.Math.PI * 2.0 - _trueAnomaly;
}
- return v;
+ return _trueAnomaly.Value;
}
private double CircularTrueAnomaly()
@@ -130,7 +174,7 @@ private double CircularTrueAnomaly()
return v % Constants._2PI;
}
-
+
private double CircularNoInclinationTrueAnomaly()
{
var l = System.Math.Acos(Position.X / Position.Magnitude());
@@ -150,9 +194,15 @@ private double CircularNoInclinationTrueAnomaly()
public override double EccentricAnomaly()
{
+ if (_eccentricAnomaly.HasValue)
+ {
+ return _eccentricAnomaly.Value;
+ }
+
double v = TrueAnomaly();
double e = Eccentricity();
- return 2 * System.Math.Atan((System.Math.Tan(v / 2.0)) / System.Math.Sqrt((1 + e) / (1 - e)));
+ _eccentricAnomaly ??= 2 * System.Math.Atan((System.Math.Tan(v / 2.0)) / System.Math.Sqrt((1 + e) / (1 - e)));
+ return _eccentricAnomaly.Value;
}
public override StateVector ToStateVector()
@@ -162,7 +212,13 @@ public override StateVector ToStateVector()
public override double MeanAnomaly()
{
- return EccentricAnomaly() - Eccentricity() * System.Math.Sin(EccentricAnomaly());
+ if (_meanAnomaly.HasValue)
+ {
+ return _meanAnomaly.Value;
+ }
+
+ _meanAnomaly ??= EccentricAnomaly() - Eccentricity() * System.Math.Sin(EccentricAnomaly());
+ return _meanAnomaly.Value;
}
public static StateVector operator +(StateVector sv1, StateVector sv2)
@@ -193,7 +249,13 @@ public double[] ToArray()
public StateVector Inverse()
{
- return new StateVector(Position.Inverse(), Velocity.Inverse(), Observer, Epoch, Frame);
+ if (_inverse is not null)
+ {
+ return _inverse;
+ }
+
+ _inverse ??= new StateVector(Position.Inverse(), Velocity.Inverse(), Observer, Epoch, Frame);
+ return _inverse;
}
diff --git a/IO.Astrodynamics/resources/IO.Astrodynamics.dll b/IO.Astrodynamics/resources/IO.Astrodynamics.dll
index ca952ff..6580bb1 100644
Binary files a/IO.Astrodynamics/resources/IO.Astrodynamics.dll and b/IO.Astrodynamics/resources/IO.Astrodynamics.dll differ
diff --git a/IO.Astrodynamics/resources/IO.Astrodynamics.lib b/IO.Astrodynamics/resources/IO.Astrodynamics.lib
index 6365687..265eb51 100644
Binary files a/IO.Astrodynamics/resources/IO.Astrodynamics.lib and b/IO.Astrodynamics/resources/IO.Astrodynamics.lib differ
diff --git a/IO.Astrodynamics/resources/libIO.Astrodynamics.so b/IO.Astrodynamics/resources/libIO.Astrodynamics.so
index d802f7f..2f85301 100755
Binary files a/IO.Astrodynamics/resources/libIO.Astrodynamics.so and b/IO.Astrodynamics/resources/libIO.Astrodynamics.so differ