Skip to content

Commit c9304a4

Browse files
Feature/lambert solver (#234)
* Add LambertSolver.cs * Add SpecialFunctions class with Hypergeometric method Introduces a new class `SpecialFunctions` in the `IO.Astrodynamics.Math` namespace. The class features a `Hypergeometric` method that computes the value of a hypergeometric series based on input parameters `z` and `tol`. The method iteratively calculates the series until the absolute value of the next term is within the specified tolerance. Detailed XML documentation is provided for clarity on the method's purpose, parameters, and return value. * Add time of flight methods to LambertSolver Updated `LambertSolver.cs` with two new methods: `XToTimeOfFlight` for computing time of flight based on the x parameter and number of revolutions, and `XToTimeOfFlightGeneral` for selecting the appropriate calculation method (Battin, Lagrange, or Lancaster). Code cleanup includes removal of unnecessary using directives and enhanced documentation with XML comments. * Update packages and enhance mathematical functions - Upgraded package references in `IO.Astrodynamics.Tests.csproj`. - Added `TimeOfFlightDerivatives` method in `LambertSolver.cs` with XML documentation. - Implemented validation in `Hypergeometric` method in `Functions.cs` to check for non-negative tolerance. - Created `SpecialFunctionsTests` class in `SpecialFunctionsTests.cs` to unit test the `Hypergeometric` method. * Add documentation and implement Halley's method in LambertSolver * Add LambertResult and LambertSolution classes for Lambert problem solutions * Update tests and refactor Lambert problem classes - Enhanced `.gitignore` to include build artifacts and IDE directories. - Added unit tests for `LambertResult`, `LambertSolution`, and `LambertSolver` classes using `Xunit`. - Modified `LambertResult` to return a read-only collection of solutions and changed `MaxRevolutions` type to `ushort`. - Refactored `LambertSolver` constructor and updated the `Solve` method for improved robustness. - Enhanced `ComputeSolution` method for accurate velocity vector calculations. - Added documentation comments to improve code maintainability. * Refactor namespaces and improve Lambert solver tests This commit refactors the namespace from IO.Astrodynamics.Tests.Maneuver.Lambert to IO.Astrodynamics.Tests.Maneuvers.Lambert for consistency across multiple test files. In LambertSolverTests.cs, instances of DummyCelestialItem were replaced with DummyBody, and tests now utilize TestHelpers.EarthAtJ2000 for better clarity. The CreateStateVector method was updated to accept an epoch parameter. Significant changes were made to the LambertSolver class, including the removal of the m_lambda member in favor of a local variable lambda, simplifying state management. Time of flight calculation methods were also updated to accept the lambda parameter. New test cases were added to validate the solver's functionality for Earth to Moon transfers in both direct and retrograde scenarios, enhancing test reliability and ensuring correct behavior under various conditions. * Bump version to 0.6.5.0 and 6.5.0; enhance LambertSolution with DeltaV properties * Update IO.Astrodynamics.Net/IO.Astrodynamics/Math/Functions.cs Co-authored-by: Copilot <[email protected]> * Refactor namespaces and improve Lambert solver tests This commit refactors the namespace from `IO.Astrodynamics.Tests.Maneuver.Lambert` to `IO.Astrodynamics.Tests.Maneuvers.Lambert` for consistency across multiple test files. In `LambertSolverTests.cs`, instances of `DummyCelestialItem` were replaced with `DummyBody`, and tests now utilize `TestHelpers.EarthAtJ2000` for better clarity. The `CreateStateVector` method was updated to accept an epoch parameter. Significant changes were made to the `LambertSolver` class, including the removal of the `m_lambda` member in favor of a local variable `lambda`, simplifying state management. Time of flight calculation methods were also updated to accept the `lambda` parameter. New test cases were added to validate the solver's functionality for Earth to Moon transfers in both direct and retrograde scenarios, enhancing test reliability and ensuring correct behavior under various conditions. * Fix variable name for threshold comparison Renamed `battinThreshold` to `BattinThreshold` in the conditional statement to ensure consistency with its definition elsewhere in the code. * Refactor DateTimeTests for accurate TDT conversions Updated `LocalToTdt` and `TdtToLocal` methods to calculate expected TDT and local time based on the system's local time zone offset. Removed hardcoded values and added assertions with a tolerance of 1 millisecond for improved accuracy in time conversions. --------- Authored-by: Sylvain Guillet <[email protected]>
1 parent 641ee24 commit c9304a4

File tree

14 files changed

+1035
-13
lines changed

14 files changed

+1035
-13
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ cmake-build-debug-linux/
1919
build/
2020
/.idea/
2121
build_release/
22+
/.vs
23+
/IO.Astrodynamics.Net/IO.Astrodynamics/pykep

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.4.0</Version>
12+
<Version>0.6.5.0</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>

IO.Astrodynamics.Net/IO.Astrodynamics.Tests/IO.Astrodynamics.Tests.csproj

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
14-
<PackageReference Include="JetBrains.Annotations" Version="2024.2.0" />
15-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
16-
<PackageReference Include="xunit" Version="2.9.0" />
17-
<PackageReference Include="coverlet.collector" Version="6.0.2">
13+
<PackageReference Include="BenchmarkDotNet" Version="0.15.2" />
14+
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" />
15+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
16+
<PackageReference Include="xunit" Version="2.9.3" />
17+
<PackageReference Include="coverlet.collector" Version="6.0.4">
1818
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1919
<PrivateAssets>all</PrivateAssets>
2020
</PackageReference>
21+
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.1">
22+
<PrivateAssets>all</PrivateAssets>
23+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
24+
</PackageReference>
2125
</ItemGroup>
2226

2327
<ItemGroup>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using IO.Astrodynamics.Maneuver.Lambert;
5+
using IO.Astrodynamics.Math;
6+
using Xunit;
7+
8+
namespace IO.Astrodynamics.Tests.Maneuvers.Lambert
9+
{
10+
public class LambertResultTests
11+
{
12+
private LambertSolution CreateLambertSolution(uint revolutions)
13+
{
14+
var v1 = new Vector3(1.0, 2.0, 3.0);
15+
var v2 = new Vector3(4.0, 5.0, 6.0);
16+
double x = 0.5;
17+
uint iterations = 10;
18+
LambertBranch? branch = revolutions == 0 ? null : LambertBranch.Left;
19+
return new LambertSolution(revolutions, v1, v2, x, iterations, v1, v2, branch);
20+
}
21+
22+
[Fact]
23+
public void Constructor_InitializesProperties()
24+
{
25+
ushort maxRevolutions = 2;
26+
var result = new LambertResult(maxRevolutions);
27+
28+
Assert.Equal(maxRevolutions, result.MaxRevolutions);
29+
Assert.NotNull(result.Solutions);
30+
Assert.Empty(result.Solutions);
31+
}
32+
33+
[Fact]
34+
public void AddSolution_AddsSolutionToCollection()
35+
{
36+
var result = new LambertResult(1);
37+
var solution = CreateLambertSolution(0);
38+
39+
result.AddSolution(solution);
40+
41+
Assert.Single(result.Solutions);
42+
Assert.Contains(solution, result.Solutions);
43+
}
44+
45+
[Fact]
46+
public void GetZeroRevolutionSolution_ReturnsCorrectSolution()
47+
{
48+
var result = new LambertResult(2);
49+
var sol0 = CreateLambertSolution(0);
50+
var sol1 = CreateLambertSolution(1);
51+
52+
result.AddSolution(sol1);
53+
result.AddSolution(sol0);
54+
55+
var found = result.GetZeroRevolutionSolution();
56+
Assert.Equal(sol0, found);
57+
}
58+
59+
[Fact]
60+
public void GetZeroRevolutionSolution_ReturnsNullIfNotFound()
61+
{
62+
var result = new LambertResult(1);
63+
var sol1 = CreateLambertSolution(1);
64+
result.AddSolution(sol1);
65+
66+
var found = result.GetZeroRevolutionSolution();
67+
Assert.Null(found);
68+
}
69+
70+
[Fact]
71+
public void GetMultiRevolutionSolutions_ReturnsCorrectSolutions()
72+
{
73+
var result = new LambertResult(3);
74+
var sol0 = CreateLambertSolution(0);
75+
var sol1a = CreateLambertSolution(1);
76+
var sol1b = CreateLambertSolution(1);
77+
var sol2 = CreateLambertSolution(2);
78+
79+
result.AddSolution(sol0);
80+
result.AddSolution(sol1a);
81+
result.AddSolution(sol1b);
82+
result.AddSolution(sol2);
83+
84+
var found = result.GetMultiRevolutionSolutions(1).ToList();
85+
Assert.Equal(2, found.Count);
86+
Assert.All(found, s => Assert.Equal((uint)1, s.Revolutions));
87+
}
88+
}
89+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using Xunit;
2+
using IO.Astrodynamics.Maneuver.Lambert;
3+
using IO.Astrodynamics.Math;
4+
5+
namespace IO.Astrodynamics.Tests.Maneuvers.Lambert;
6+
7+
public class LambertSolutionTests
8+
{
9+
[Fact]
10+
public void Constructor_WithAllParameters_SetsPropertiesCorrectly()
11+
{
12+
// Arrange
13+
uint revolutions = 2;
14+
var v1 = new Vector3(1.0, 2.0, 3.0);
15+
var v2 = new Vector3(4.0, 5.0, 6.0);
16+
double x = 42.0;
17+
uint iterations = 7;
18+
LambertBranch branch = LambertBranch.Right;
19+
20+
// Act
21+
var solution = new LambertSolution(revolutions, v1, v2, x, iterations, v1, v2, branch);
22+
23+
// Assert
24+
Assert.Equal(revolutions, solution.Revolutions);
25+
Assert.Equal(branch, solution.Branch);
26+
Assert.Equal(v1, solution.V1);
27+
Assert.Equal(v1, solution.DeltaV1);
28+
Assert.Equal(v2, solution.V2);
29+
Assert.Equal(v2, solution.DeltaV2);
30+
Assert.Equal(x, solution.X);
31+
Assert.Equal(iterations, solution.Iterations);
32+
}
33+
34+
[Fact]
35+
public void Constructor_DirectTransfer_SetsRevolutionsZeroAndBranchNull()
36+
{
37+
// Arrange
38+
var v1 = new Vector3(1.0, 0.0, 0.0);
39+
var v2 = new Vector3(0.0, 1.0, 0.0);
40+
double x = 3.14;
41+
uint iterations = 2;
42+
43+
// Act
44+
var solution = new LambertSolution(v1, v2, x, iterations, v1, v2);
45+
46+
// Assert
47+
Assert.Equal(0u, solution.Revolutions);
48+
Assert.Null(solution.Branch);
49+
Assert.Equal(v1, solution.V1);
50+
Assert.Equal(v1, solution.DeltaV1);
51+
Assert.Equal(v2, solution.V2);
52+
Assert.Equal(v2, solution.DeltaV2);
53+
Assert.Equal(x, solution.X);
54+
Assert.Equal(iterations, solution.Iterations);
55+
}
56+
57+
[Fact]
58+
public void LambertBranch_Enum_HasLeftAndRightValues()
59+
{
60+
Assert.Equal(0, (int)LambertBranch.Left);
61+
Assert.Equal(1, (int)LambertBranch.Right);
62+
}
63+
64+
[Fact]
65+
public void LambertSolution_Constructor_SetsDeltaVProperties()
66+
{
67+
// Arrange
68+
var v1 = new Vector3(1.0, 2.0, 3.0);
69+
var v2 = new Vector3(4.0, 5.0, 6.0);
70+
double x = 42.0;
71+
uint iterations = 7;
72+
73+
// Act
74+
var solution = new LambertSolution(0, v1, v2, x, iterations, v1, v2);
75+
76+
// Assert
77+
Assert.Equal(v1, solution.DeltaV1);
78+
Assert.Equal(v2, solution.DeltaV2);
79+
Assert.Equal(v1.Magnitude() + v2.Magnitude(), solution.DeltaV);
80+
}
81+
}

0 commit comments

Comments
 (0)