Skip to content

Commit

Permalink
Features/removespicedependencies (#220)
Browse files Browse the repository at this point in the history
* Add bodies factory

* Upgrade sgp4

* Load barycenter at date

* Factorize light time correction and fix spacecraft based on TLE

* Add synchronous methods

* Add tests
  • Loading branch information
sylvain-guillet authored Oct 9, 2024
1 parent b71cb24 commit 145da93
Show file tree
Hide file tree
Showing 28 changed files with 1,018 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void CallWithAllOptions()
var res = sb.ToString();

Assert.Equal(
$"Epoch : 2023-01-01T00:51:49.3107004 TDB A : 149547967550.09717 Ecc. : 0.016383451297742043 Inc. : 0.40904753897404755 AN : 6.283111166771382 AOP : 1.8230033425173697 M : 6.20820988037115 Frame : j2000{Environment.NewLine}Epoch : 2023-01-01T00:52:49.3107080 TDB A : 149547949469.53668 Ecc. : 0.01638333076736937 Inc. : 0.4090475391061235 AN : 6.283111164887601 AOP : 1.8230023130675248 M : 6.208222811942813 Frame : j2000{Environment.NewLine}"
$"Epoch : 2023-01-01T01:00:00.0000000 TDB A : 149547984744.6522 Ecc. : 0.016383513214941237 Inc. : 0.40904753866331567 AN : 6.283111166910646 AOP : 1.8230032812672177 M : 6.208209945338079 Frame : j2000{Environment.NewLine}Epoch : 2023-01-01T01:01:00.0000000 TDB A : 149547966664.0716 Ecc. : 0.01638339268455749 Inc. : 0.40904753879539246 AN : 6.283111165026861 AOP : 1.8230022519007245 M : 6.208222876826916 Frame : j2000{Environment.NewLine}"
, res);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<FileVersion>0.0.1</FileVersion>
<PackAsTool>true</PackAsTool>
<ToolCommandName>astro</ToolCommandName>
<Version>0.6.0-preview-1</Version>
<Version>0.6.0</Version>
<Title>Astrodynamics command line interface</Title>
<Authors>Sylvain Guillet</Authors>
<Description>This CLI allows end user to exploit IO.Astrodynamics framework </Description>
Expand Down
211 changes: 180 additions & 31 deletions IO.Astrodynamics.Net/IO.Astrodynamics.Tests/APITest.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public void Equality()
Assert.True(earth1.Equals((object)earth1));
Assert.False(earth1.Equals(null));
Assert.False(earth1.Equals((object)null));
Assert.False(earth1.Equals("null"));
Assert.False(earth1.Equals(null));
}

[Fact]
Expand All @@ -180,6 +180,18 @@ public void GetEphemeris()
new StateVector(new Vector3(-29069076368.64741, 132303142494.37561, 57359794320.98976), new Vector3(-29695.854459557304, -5497.347182651619, -2382.9422283991967),
TestHelpers.Sun, TimeSystem.Time.J2000TDB + TimeSpan.FromDays(1.0), Frames.Frame.ICRF), res.ElementAt(1).ToStateVector(), TestHelpers.StateVectorComparer);
}

[Fact]
public void GetEphemerisLT()
{
var earth = PlanetsAndMoons.MOON_BODY;
var res = earth.GetEphemeris(new Window(TimeSystem.Time.J2000TDB, TimeSpan.FromDays(1.0)), TestHelpers.EarthAtJ2000, Frames.Frame.ICRF, Aberration.LT,
TimeSpan.FromDays(1.0)).ToArray();
Assert.Equal(2, res.Length);
Assert.Equal(
new StateVector(new Vector3(-291569264.4915199, -266709187.16285706, -76099155.2442627), new Vector3(643.5274874728093, -666.082425667777, -301.3230984482848),
TestHelpers.Earth, TimeSystem.Time.J2000TDB, Frames.Frame.ICRF), res.ElementAt(0).ToStateVector(), TestHelpers.StateVectorComparer);
}

[Fact]
public void AngularSeparation()
Expand Down Expand Up @@ -279,7 +291,7 @@ public void TrueSolarDayJan()
public void TrueSolarDayJMar()
{
var res1 = TestHelpers.Earth.TrueSolarDay(new TimeSystem.Time(new DateTime(2021, 3, 26, 0, 0, 0, DateTimeKind.Unspecified), TimeFrame.TDBFrame));
Assert.Equal(86400.359499400001, res1.TotalSeconds, 3);
Assert.Equal(86400.359507999994, res1.TotalSeconds, 3);
}

[Fact]
Expand Down Expand Up @@ -316,7 +328,7 @@ public void PhaseHelioSynchronousOrbit()
{
var epoch = new TimeSystem.Time(new DateTime(2021, 11, 22, 0, 0, 0, DateTimeKind.Unspecified), TimeFrame.TDBFrame);
var res = TestHelpers.Earth.HelioSynchronousOrbit(0.0001724, epoch, 14);
Assert.Equal(7272221.8771249438, res.A, 3);
Assert.Equal(7272221.8764740741, res.A, 3);
Assert.Equal(0.0001724, res.E, 6);
Assert.Equal(99.018, res.I * Astrodynamics.Constants.Rad2Deg, 3);
Assert.Equal(327.43000000000001, res.RAAN * Astrodynamics.Constants.Rad2Deg, 3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public void Create()
Assert.Equal("MySpacecraft", spc.Name);
Assert.Equal(1000.0, spc.DryOperatingMass);
Assert.Equal(10000.0, spc.MaximumOperatingMass);
Assert.True(spc.IsSpacecraft);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public void Create()
Assert.Equal(8.1373353929324900E+16, star.Distance);
Assert.Null(star.InitialOrbitalParameters);
Assert.Equal(0.0, star.Flattening);
Assert.True(star.IsStar);
}

[Fact]
Expand Down
177 changes: 177 additions & 0 deletions IO.Astrodynamics.Net/IO.Astrodynamics.Tests/ConfigurationTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using IO.Astrodynamics.Body;
using IO.Astrodynamics.DataProvider;
using IO.Astrodynamics.DTO;
using IO.Astrodynamics.Math;
using Xunit;
using CelestialBody = IO.Astrodynamics.DTO.CelestialBody;
using Quaternion = IO.Astrodynamics.Math.Quaternion;
using StateOrientation = IO.Astrodynamics.OrbitalParameters.StateOrientation;
using StateVector = IO.Astrodynamics.OrbitalParameters.StateVector;

namespace IO.Astrodynamics.Tests;

public class ConfigurationTest
{
public ConfigurationTest()
{
API.Instance.LoadKernels(Constants.SolarSystemKernelPath);
}

[Fact]
public void SetDataProviderException()
{
// Arrange

Assert.Throws<ArgumentNullException>(() => Configuration.Instance.SetDataProvider(null));
}

[Fact]
public void FrameTransformationToICRF_ThrowsArgumentException_WhenFrameNotFound()
{
var dataProvider = new MemoryDataProvider();
var frame = new Frames.Frame("NonExistentFrame");
var date = TimeSystem.Time.J2000TDB;

Assert.Throws<ArgumentException>(() => dataProvider.FrameTransformationToICRF(date, frame));
}

[Fact]
public void FrameTransformationToICRF_ReturnsStateOrientation_WhenDateExists()
{
var dataProvider = new MemoryDataProvider();
var frame = Frames.Frame.ICRF;
var date = TimeSystem.Time.J2000TDB;
var stateOrientation = new StateOrientation(Quaternion.Zero, Vector3.Zero, date, frame);

dataProvider.AddStateOrientationToICRF(frame, date, stateOrientation);

var result = dataProvider.FrameTransformationToICRF(date, frame);

Assert.Equal(stateOrientation, result);
}

[Fact]
public void FrameTransformationToICRF_InterpolatesStateOrientation_WhenDateDoesNotExist()
{
var dataProvider = new MemoryDataProvider();
var frame = Frames.Frame.ICRF;
var date1 = TimeSystem.Time.J2000TDB;
var date2 = date1.AddHours(1.0);
var dateToInterpolate = date1.AddHours(0.5);
var stateOrientation1 = new StateOrientation(Quaternion.Zero, Vector3.Zero, TimeSystem.Time.J2000TDB, frame);
var stateOrientation2 = new StateOrientation(new Quaternion(Vector3.VectorZ, Astrodynamics.Constants.PI2), new Vector3(1.0, 1.0, 1.0), date2, frame);

dataProvider.AddStateOrientationToICRF(frame, date1, stateOrientation1);
dataProvider.AddStateOrientationToICRF(frame, date2, stateOrientation2);

var result = dataProvider.FrameTransformationToICRF(dateToInterpolate, frame);

Assert.NotNull(result);
}

[Fact]
public void FrameTransformationToICRF_InterpolatesStateOrientation_WhenDateOutOfRange()
{
var dataProvider = new MemoryDataProvider();
var frame = Frames.Frame.ICRF;
var date1 = TimeSystem.Time.J2000TDB;
var date2 = date1.AddHours(1.0);
var dateToInterpolate = date1.AddHours(2);
var stateOrientation1 = new StateOrientation(Quaternion.Zero, Vector3.Zero, TimeSystem.Time.J2000TDB, frame);
var stateOrientation2 = new StateOrientation(new Quaternion(Vector3.VectorZ, Astrodynamics.Constants.PI2), new Vector3(1.0, 1.0, 1.0), date2, frame);

dataProvider.AddStateOrientationToICRF(frame, date1, stateOrientation1);
dataProvider.AddStateOrientationToICRF(frame, date2, stateOrientation2);

Assert.Throws<ArgumentException>(() => dataProvider.FrameTransformationToICRF(dateToInterpolate, frame));
}

[Fact]
public void GetEphemerisFromICRF_ThrowsArgumentException_WhenTargetNotFound()
{
var dataProvider = new MemoryDataProvider();
var target = TestHelpers.EarthAtJ2000;
var date = TimeSystem.Time.J2000TDB;
var frame = Frames.Frame.ICRF;

Assert.Throws<ArgumentException>(() => dataProvider.GetEphemerisFromICRF(date, target, frame, Aberration.None));
}

[Fact]
public void GetEphemerisFromICRF_ReturnsStateVector_WhenDateExists()
{
var dataProvider = new MemoryDataProvider();
var target = TestHelpers.EarthAtJ2000;
var date = TimeSystem.Time.J2000TDB;
var frame = Frames.Frame.ICRF;
var stateVector = new StateVector(Vector3.Zero, Vector3.Zero, target, date, frame);


dataProvider.AddStateVector(target.NaifId, date, stateVector);

var result = dataProvider.GetEphemerisFromICRF(date, target, frame, Aberration.None);

Assert.Equal(stateVector, result);
}

[Fact]
public void GetEphemerisFromICRF_InterpolatesStateVector_WhenDateDoesNotExist()
{
var dataProvider = new MemoryDataProvider();
var target = TestHelpers.EarthAtJ2000;
var frame = Frames.Frame.ICRF;
var date1 = TimeSystem.Time.J2000TDB;
var date2 = date1.AddHours(1.0);
var dateToInterpolate = date1.AddHours(0.5);
var stateVector1 = new StateVector(Vector3.Zero, Vector3.Zero, target, date1, frame);
var stateVector2 = new StateVector(new Vector3(1.0, 1.0, 1.0), new Vector3(1.0, 1.0, 1.0), target, date2, frame);

dataProvider.AddStateVector(target.NaifId, date1, stateVector1);
dataProvider.AddStateVector(target.NaifId, date2, stateVector2);

var result = dataProvider.GetEphemerisFromICRF(dateToInterpolate, target, frame, Aberration.None);

Assert.NotNull(result);
}

[Fact]
public void GetEphemerisFromICRF_InterpolatesStateVector_WhenDateOutOfRange()
{
var dataProvider = new MemoryDataProvider();
var target = TestHelpers.EarthAtJ2000;
var frame = Frames.Frame.ICRF;
var date1 = TimeSystem.Time.J2000TDB;
var date2 = date1.AddHours(1.0);
var dateToInterpolate = date1.AddHours(2.0);
var stateVector1 = new StateVector(Vector3.Zero, Vector3.Zero, target, date1, frame);
var stateVector2 = new StateVector(new Vector3(1.0, 1.0, 1.0), new Vector3(1.0, 1.0, 1.0), target, date2, frame);

dataProvider.AddStateVector(target.NaifId, date1, stateVector1);
dataProvider.AddStateVector(target.NaifId, date2, stateVector2);

Assert.Throws<ArgumentException>(()=> dataProvider.GetEphemerisFromICRF(dateToInterpolate, target, frame, Aberration.None));
}

[Fact]
public void GetCelestialBodyInfo_ReturnsCelestialBody_WhenNaifIdExists()
{
var dataProvider = new MemoryDataProvider();
var celestialBody = new CelestialBody(10, 0, 0, "Sun", new Vector3D(150000000, 150000000, 0), 12345698, "IAU_SUN", 0, 2, 3, 4);

dataProvider.AddCelestialBodyInfo(celestialBody);

var result = dataProvider.GetCelestialBodyInfo(10);

Assert.Equal(celestialBody, result);
}

[Fact]
public void GetCelestialBodyInfo_ThrowsKeyNotFoundException_WhenNaifIdDoesNotExist()
{
var dataProvider = new MemoryDataProvider();

Assert.Throws<KeyNotFoundException>(() => dataProvider.GetCelestialBodyInfo(999));
}
}
4 changes: 2 additions & 2 deletions IO.Astrodynamics.Net/IO.Astrodynamics.Tests/Example.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public class Example
public void ReadEphemeris()
{
//In this example we want the ephemeris of the moon at epoch (2000-01-01T12:00Z) in ICRF frame with earth at center
API.Instance.LoadKernels(new DirectoryInfo("Data/SolarSystem"));//replace Data/SolarSytem by your kernel path
API.Instance.LoadKernels(new DirectoryInfo("Data/SolarSystem"));//replace Data/SolarSystem by your kernel path
var earth = PlanetsAndMoons.EARTH_BODY;
var moon = new CelestialBody(PlanetsAndMoons.MOON);
var ephemerid = moon.GetEphemeris(new TimeSystem.Time(new DateTime(2000, 1, 1, 12, 0, 0), TimeFrame.UTCFrame), earth, Frames.Frame.ICRF, Aberration.None);
var ephemeris = moon.GetEphemeris(new TimeSystem.Time(new DateTime(2000, 1, 1, 12, 0, 0), TimeFrame.UTCFrame), earth, Frames.Frame.ICRF, Aberration.None);
}
}
69 changes: 69 additions & 0 deletions IO.Astrodynamics.Net/IO.Astrodynamics.Tests/Math/JacobianTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,73 @@ public void Evaluate_ShouldThrowArgumentExceptionWhenDimensionsMismatch()
// Act & Assert
Assert.Throws<IndexOutOfRangeException>(() => jacobian.Evaluate(functions, x));
}

[Fact]
public void Evaluate_WithValidInputs_ReturnsExpectedMatrix()
{
// Arrange
var jacobian = new Jacobian();
Func<double[], double>[] functions =
{
x => x[0] * x[0],
x => x[1] * x[1]
};
double[] x = { 2.0, 3.0 };
double[] currentValues = { 4.0, 9.0 };

// Act
var result = jacobian.Evaluate(functions, x, currentValues);

// Assert
Assert.Equal(2, result.Rows);
Assert.Equal(2, result.Columns);
}


[Fact]
public void Evaluate_WithNullFunctionsArray_ThrowsArgumentNullException()
{
// Arrange
var jacobian = new Jacobian();
Func<double[], double>[] functions = null;
double[] x = { 2.0, 3.0 };
double[] currentValues = { 4.0, 9.0 };

// Act & Assert
Assert.Throws<ArgumentNullException>(() => jacobian.Evaluate(functions, x, currentValues));
}

[Fact]
public void Evaluate_WithNullXArray_ThrowsArgumentNullException()
{
// Arrange
var jacobian = new Jacobian();
Func<double[], double>[] functions =
{
x => x[0] * x[0],
x => x[1] * x[1]
};
double[] x = null;
double[] currentValues = { 4.0, 9.0 };

// Act & Assert
Assert.Throws<ArgumentNullException>(() => jacobian.Evaluate(functions, x, currentValues));
}

[Fact]
public void Evaluate_WithNullCurrentValuesArray_ThrowsArgumentNullException()
{
// Arrange
var jacobian = new Jacobian();
Func<double[], double>[] functions =
{
x => x[0] * x[0],
x => x[1] * x[1]
};
double[] x = { 2.0, 3.0 };
double[] currentValues = null;

// Act & Assert
Assert.Throws<ArgumentNullException>(() => jacobian.Evaluate(functions, x, currentValues));
}
}
Loading

0 comments on commit 145da93

Please sign in to comment.