Skip to content
This repository has been archived by the owner on Aug 5, 2024. It is now read-only.

Commit

Permalink
Feature/performance (#71)
Browse files Browse the repository at this point in the history
* Optimized OrbitalParameters and StateVector classes with lazy evaluation

Refactored OrbitalParameters and StateVector classes to optimize them with lazy evaluation. The state is now calculated just-in-time, when accessed for the first time, rather than upfront, which can lead to improved performance for sceneries where not all parameters or vectors are used. The calculated state is cached for further use.

This pattern is particularly beneficial when computations are expensive, and not all computed values are needed in subsequent operations, thereby potentially avoiding unnecessary work. Each parameter and vector is now only computed when it's actually accessed, making it more performant especially for users who only need a subset of all possible properties.

* Refactor code to cache calculations and modify angle computations

This refactoring changes the OrbitalParameters, StateVector, and Vector3 classes to store computed values to reduce redundant calculations. The changes include caching values in various Astrodynamics classes like the StateVector, Equinoctial and Keplerian Elements to avoid recalculation, especially in orbital parameters-related methods. The Vector3.Angle method is also modified to use atan2 instead of acos for angle calculation to handle full circle angle differences. Additional test cases for Vector3 angles have been added to ensure correctness.

* Updated Math and Maneuver classes, added new methods

This update includes significant changes to classes in Astrodynamics/Math and Astrodynamics/Maneuver. In the Math group, Plane and Vector3 classes have been upgraded with new methods. In the Maneuver group, many classes added a new `ManeuverPointComputation` method, which currently throws NotImplementedException. The ComputeDeltaV, ComputeDeltaT, and ComputeDeltaM methods are also updated in the Maneuver class.

* Add performance testing for spacecraft propagation

The commit includes the addition of the BenchmarkDotNet library to the IO.Astrodynamics.Tests project. A new 'Performance' class is created in the same project, with a benchmark test for the 'ScenarioTests' class. Additionally, a new project 'IO.Astrodynamics.Performance' has been added to the solution for dedicated performance testing.

* Remove unimplemented methods from maneuver classes

Several classes under the 'maneuver' namespace contained unimplemented methods, specifically 'Execute', 'ManeuverPointComputation', and some related utility methods and properties. These have been removed across multiple files to clean up the codebase. This is part of an effort to refactor the astrodynamics components and prioritize planned features.

* Remove Performance.cs and update tests

Deleted Performance.cs test file as it's no longer necessary. Updated logic in APITest.cs, Vector3.cs and Vector3Test.cs for better performance and accuracy. Also modified the attribute in Scenario.cs for Markdown export.

* Update astrodynamics test data and assert conditions

This commit updates the maneuver windows start dates, end dates, length, deltaV, and fuel burned values in ScenarioTests.cs and APITest.cs. Also, the IO.Astrodynamics version has been changed from 1.9.1 to 1.9.2. This reflects the recent changes in the maneuver calculations and astrodynamics data.
  • Loading branch information
sylvain-guillet authored Dec 3, 2023
1 parent 3cc8211 commit adacdb2
Show file tree
Hide file tree
Showing 32 changed files with 551 additions and 175 deletions.
60 changes: 60 additions & 0 deletions IO.Astrodynamics.Performance/IO.Astrodynamics.Performance.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\IO.Astrodynamics.Tests\IO.Astrodynamics.Tests.csproj" />
</ItemGroup>

<ItemGroup>
<Content Update="Data\SolarSystem\de440s.bsp">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\earth_assoc_itrf93.tf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\earth_fixed.tf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\earth_latest_high_prec.bpc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\earth_topo_201023.tf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\earthstns_itrf93_201023.bsp">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\geophysical.ker">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\gm_de431.tpc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\moon_080317.tf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\moon_assoc_me.tf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\moon_pa_de421_1900-2050.bpc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\pck00011.tpc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Data\SolarSystem\latest_leapseconds.tls">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.10" />
</ItemGroup>

</Project>
11 changes: 11 additions & 0 deletions IO.Astrodynamics.Performance/Program.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
21 changes: 21 additions & 0 deletions IO.Astrodynamics.Performance/Scenario.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
85 changes: 41 additions & 44 deletions IO.Astrodynamics.Tests/APITest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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 =
Expand All @@ -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]
Expand Down Expand Up @@ -667,7 +664,7 @@ void GetCelestialBodyInformation()
Assert.Equal(-2.5388099999999996E-06, res.J3);
Assert.Equal(-1.6559699999999999E-06, res.J4);
}

[Fact]
void GetCelestialBodyInformationWithoutJ()
{
Expand Down
1 change: 1 addition & 0 deletions IO.Astrodynamics.Tests/IO.Astrodynamics.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.10" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.6.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
Expand Down
47 changes: 46 additions & 1 deletion IO.Astrodynamics.Tests/Math/Vector3Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand All @@ -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()
{
Expand Down
Loading

0 comments on commit adacdb2

Please sign in to comment.