diff --git a/IO.Astrodynamics.Net/IO.Astrodynamics.CLI/IO.Astrodynamics.CLI.csproj b/IO.Astrodynamics.Net/IO.Astrodynamics.CLI/IO.Astrodynamics.CLI.csproj
index eac9f42e..1210f2a4 100644
--- a/IO.Astrodynamics.Net/IO.Astrodynamics.CLI/IO.Astrodynamics.CLI.csproj
+++ b/IO.Astrodynamics.Net/IO.Astrodynamics.CLI/IO.Astrodynamics.CLI.csproj
@@ -9,7 +9,7 @@
0.0.1
true
astro
- 0.5.0-preview-5
+ 0.5.0-preview-6
Astrodynamics command line interface
Sylvain Guillet
This CLI allows end user to exploit IO.Astrodynamics framework
diff --git a/IO.Astrodynamics.Net/IO.Astrodynamics.Tests/APITest.cs b/IO.Astrodynamics.Net/IO.Astrodynamics.Tests/APITest.cs
index 6139af59..80c653e3 100644
--- a/IO.Astrodynamics.Net/IO.Astrodynamics.Tests/APITest.cs
+++ b/IO.Astrodynamics.Net/IO.Astrodynamics.Tests/APITest.cs
@@ -497,8 +497,7 @@ void GetCelestialBodyInformationWithoutJ()
void TransformFrame()
{
//Get the quaternion to transform
- var res = API.Instance.TransformFrame(Frames.Frame.ICRF, new Frames.Frame(PlanetsAndMoons.EARTH.Frame),
- TimeSystem.Time.J2000TDB);
+ var res = API.Instance.TransformFrame(TimeSystem.Time.J2000TDB,Frames.Frame.ICRF, new Frames.Frame(PlanetsAndMoons.EARTH.Frame));
Assert.Equal(0.76713121207787449, res.Rotation.W, 6);
Assert.Equal(-1.8618836714990174E-05, res.Rotation.VectorPart.X, 6);
Assert.Equal(8.4688405480964646E-07, res.Rotation.VectorPart.Y, 6);
@@ -513,9 +512,9 @@ void TransformFrameExceptions()
{
//Get the quaternion to transform
Assert.Throws(() =>
- API.Instance.TransformFrame(Frames.Frame.ICRF, null, TimeSystem.Time.J2000TDB));
+ API.Instance.TransformFrame(TimeSystem.Time.J2000TDB,Frames.Frame.ICRF, null));
Assert.Throws(() =>
- API.Instance.TransformFrame(null, new Frames.Frame(PlanetsAndMoons.EARTH.Frame), TimeSystem.Time.J2000TDB));
+ API.Instance.TransformFrame(TimeSystem.Time.J2000TDB,null, new Frames.Frame(PlanetsAndMoons.EARTH.Frame)));
}
[Fact]
diff --git a/IO.Astrodynamics.Net/IO.Astrodynamics/API.cs b/IO.Astrodynamics.Net/IO.Astrodynamics/API.cs
index d478ad01..821059f5 100644
--- a/IO.Astrodynamics.Net/IO.Astrodynamics/API.cs
+++ b/IO.Astrodynamics.Net/IO.Astrodynamics/API.cs
@@ -159,711 +159,719 @@ private static IntPtr Resolver(string libraryName, Assembly assembly, DllImportS
//Use the same lock for all cspice calls because it doesn't support multithreading.
private static object lockObject = new object();
- ///
- /// Get spice toolkit version number
- ///
- ///
- public string GetSpiceVersion()
- {
- lock (lockObject)
- {
- var strptr = GetSpiceVersionProxy();
- var str = Marshal.PtrToStringAnsi(strptr);
- Marshal.FreeHGlobal(strptr);
- return str;
- }
- }
-
- public IEnumerable GetLoadedKernels()
- {
- return _kernels;
- }
-
- ///
- /// Load kernel at given path
- ///
- /// Path where kernels are located. This could be a file path or a directory path
- public void LoadKernels(FileSystemInfo path)
- {
- if (path == null) throw new ArgumentNullException(nameof(path));
- lock (lockObject)
- {
- if (_kernels.Any(x => path.FullName.Contains(x.FullName)))
- {
- foreach (var kernel in _kernels.Where(x => path.FullName.Contains(x.FullName)).ToArray())
- {
- UnloadKernels(kernel);
- LoadKernels(kernel);
- }
-
- return;
- }
-
-
- var existingKernels = _kernels.Where(x => x.FullName.Contains(path.FullName)).ToArray();
- foreach (var existingKernel in existingKernels)
- {
- UnloadKernels(existingKernel);
- }
-
- if (path.Exists)
- {
- if (!LoadKernelsProxy(path.FullName))
- {
- throw new InvalidOperationException($"Kernel {path.FullName} can't be loaded. You can have more details on standard output");
- }
-
- _kernels.Add(path);
- }
- }
- }
-
- ///
- /// Unload kernel at given path
- ///
- /// Path where kernels are located. This could be a file path or a directory path
- public void UnloadKernels(FileSystemInfo path)
- {
- if (path == null) return;
- lock (lockObject)
- {
- if (path.Exists)
- {
- if (!UnloadKernelsProxy(path.FullName))
- {
- throw new InvalidOperationException($"Kernel {path.FullName} can't be unloaded. You can have more details on standard output");
- }
-
- _kernels.RemoveAll(x => x.FullName == path.FullName);
- foreach (var kernel in _kernels.Where(x => x.FullName.Contains(path.FullName)).ToArray())
- {
- UnloadKernels(kernel);
- }
- }
- }
- }
-
- public void ClearKernels()
- {
- lock (lockObject)
- {
- foreach (var kernel in _kernels.ToArray())
- {
- UnloadKernels(kernel);
- }
-
- KClearProxy();
- }
- }
-
- ///
- /// Find launch windows
- ///
- ///
- ///
- ///
- public IEnumerable FindLaunchWindows(Maneuver.Launch launch,
- in TimeSystem.Window window, DirectoryInfo outputDirectory)
- {
- if (launch == null) throw new ArgumentNullException(nameof(launch));
- lock (lockObject)
- {
- //Convert data
- Launch launchDto = launch.Convert();
- launchDto.Window = window.Convert();
- launchDto.LaunchSite.DirectoryPath = outputDirectory.CreateSubdirectory("Sites").FullName;
- launchDto.RecoverySite.DirectoryPath = outputDirectory.CreateSubdirectory("Sites").FullName;
-
- //Execute request
- LaunchProxy(ref launchDto);
-
- //Filter result
- var windows = launchDto.Windows.Where(x => x.Start != 0 && x.End != 0).ToArray();
-
- //Build result
- List launchWindows = [];
-
- for (int i = 0; i < windows.Length; i++)
- {
- launchWindows.Add(new LaunchWindow(windows[i].Convert(),
- launchDto.InertialInsertionVelocity[i], launchDto.NonInertialInsertionVelocity[i],
- launchDto.InertialAzimuth[i], launchDto.NonInertialAzimuth[i]));
- }
-
- return launchWindows;
- }
- }
-
- ///
- /// Find time windows based on distance constraint
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IEnumerable FindWindowsOnDistanceConstraint(TimeSystem.Window searchWindow, INaifObject observer,
- INaifObject target, RelationnalOperator relationalOperator, double value, Aberration aberration,
- TimeSpan stepSize)
- {
- if (observer == null) throw new ArgumentNullException(nameof(observer));
- if (target == null) throw new ArgumentNullException(nameof(target));
- lock (lockObject)
- {
- return FindWindowsOnDistanceConstraint(searchWindow, observer.NaifId, target.NaifId, relationalOperator, value, aberration, stepSize);
- }
- }
-
- public IEnumerable FindWindowsOnDistanceConstraint(TimeSystem.Window searchWindow, int observerId,
- int targetId, RelationnalOperator relationalOperator, double value, Aberration aberration,
- TimeSpan stepSize)
- {
- lock (lockObject)
- {
- var windows = new Window[1000];
- for (var i = 0; i < 1000; i++)
- {
- windows[i] = new Window(double.NaN, double.NaN);
- }
-
- FindWindowsOnDistanceConstraintProxy(searchWindow.Convert(), observerId, targetId, relationalOperator.GetDescription(), value,
- aberration.GetDescription(), stepSize.TotalSeconds, windows);
- return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
- }
- }
-
- ///
- /// Find time windows based on occultation constraint
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IEnumerable FindWindowsOnOccultationConstraint(TimeSystem.Window searchWindow, INaifObject observer,
- INaifObject target, ShapeType targetShape, INaifObject frontBody, ShapeType frontShape,
- OccultationType occultationType, Aberration aberration, TimeSpan stepSize)
- {
- if (observer == null) throw new ArgumentNullException(nameof(observer));
- if (target == null) throw new ArgumentNullException(nameof(target));
- if (frontBody == null) throw new ArgumentNullException(nameof(frontBody));
- lock (lockObject)
- {
- string frontFrame = frontShape == ShapeType.Ellipsoid
- ? (frontBody as Body.CelestialBody)?.Frame.Name
- : string.Empty;
- string targetFrame = targetShape == ShapeType.Ellipsoid
- ? (target as Body.CelestialBody)?.Frame.Name
- : String.Empty;
- var windows = new Window[1000];
- for (var i = 0; i < 1000; i++)
- {
- windows[i] = new Window(double.NaN, double.NaN);
- }
-
- FindWindowsOnOccultationConstraintProxy(searchWindow.Convert(), observer.NaifId, target.NaifId,
- targetFrame, targetShape.GetDescription(),
- frontBody.NaifId, frontFrame, frontShape.GetDescription(), occultationType.GetDescription(),
- aberration.GetDescription(), stepSize.TotalSeconds, windows);
- return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
- }
- }
-
- ///
- /// Find time windows based on occultation constraint
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IEnumerable FindWindowsOnOccultationConstraint(TimeSystem.Window searchWindow, int observerId,
- int targetId, ShapeType targetShape, int frontBodyId, ShapeType frontShape,
- OccultationType occultationType, Aberration aberration, TimeSpan stepSize)
- {
- lock (lockObject)
- {
- IO.Astrodynamics.Body.CelestialBody frontBody = new IO.Astrodynamics.Body.CelestialBody(frontBodyId);
- IO.Astrodynamics.Body.CelestialBody targetBody = new IO.Astrodynamics.Body.CelestialBody(targetId);
- string frontFrame = frontShape == ShapeType.Ellipsoid
- ? frontBody.Frame.Name
- : string.Empty;
- string targetFrame = targetShape == ShapeType.Ellipsoid
- ? targetBody.Frame.Name
- : String.Empty;
- var windows = new Window[1000];
- for (var i = 0; i < 1000; i++)
- {
- windows[i] = new Window(double.NaN, double.NaN);
- }
-
- FindWindowsOnOccultationConstraintProxy(searchWindow.Convert(), observerId, targetId, targetFrame, targetShape.GetDescription(),
- frontBody.NaifId, frontFrame, frontShape.GetDescription(), occultationType.GetDescription(), aberration.GetDescription(), stepSize.TotalSeconds, windows);
- return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
- }
- }
-
- ///
- /// Find time windows based on coordinate constraint
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IEnumerable FindWindowsOnCoordinateConstraint(TimeSystem.Window searchWindow, INaifObject observer,
- INaifObject target, Frame frame, CoordinateSystem coordinateSystem, Coordinate coordinate,
- RelationnalOperator relationalOperator, double value, double adjustValue, Aberration aberration,
- TimeSpan stepSize)
- {
- if (observer == null) throw new ArgumentNullException(nameof(observer));
- if (target == null) throw new ArgumentNullException(nameof(target));
- if (frame == null) throw new ArgumentNullException(nameof(frame));
- lock (lockObject)
- {
- var windows = new Window[1000];
- for (var i = 0; i < 1000; i++)
- {
- windows[i] = new Window(double.NaN, double.NaN);
- }
-
- FindWindowsOnCoordinateConstraintProxy(searchWindow.Convert(), observer.NaifId, target.NaifId,
- frame.Name, coordinateSystem.GetDescription(),
- coordinate.GetDescription(), relationalOperator.GetDescription(), value, adjustValue,
- aberration.GetDescription(), stepSize.TotalSeconds, windows);
- return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
- }
- }
-
- ///
- /// Find time windows based on coordinate constraint
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IEnumerable FindWindowsOnCoordinateConstraint(TimeSystem.Window searchWindow, int observerId,
- int targetId, Frame frame, CoordinateSystem coordinateSystem, Coordinate coordinate,
- RelationnalOperator relationalOperator, double value, double adjustValue, Aberration aberration,
- TimeSpan stepSize)
- {
- if (frame == null) throw new ArgumentNullException(nameof(frame));
- lock (lockObject)
- {
- var windows = new Window[1000];
- for (var i = 0; i < 1000; i++)
- {
- windows[i] = new Window(double.NaN, double.NaN);
- }
-
- FindWindowsOnCoordinateConstraintProxy(searchWindow.Convert(), observerId, targetId,
- frame.Name, coordinateSystem.GetDescription(),
- coordinate.GetDescription(), relationalOperator.GetDescription(), value, adjustValue,
- aberration.GetDescription(), stepSize.TotalSeconds, windows);
- return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
- }
- }
-
- ///
- /// Find time windows based on illumination constraint
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IEnumerable FindWindowsOnIlluminationConstraint(TimeSystem.Window searchWindow, INaifObject observer,
- INaifObject targetBody, Frame fixedFrame,
- Coordinates.Planetodetic planetodetic, IlluminationAngle illuminationType, RelationnalOperator relationalOperator,
- double value, double adjustValue, Aberration aberration, TimeSpan stepSize, INaifObject illuminationSource,
- string method = "Ellipsoid")
- {
- if (observer == null) throw new ArgumentNullException(nameof(observer));
- if (targetBody == null) throw new ArgumentNullException(nameof(targetBody));
- if (fixedFrame == null) throw new ArgumentNullException(nameof(fixedFrame));
- if (illuminationSource == null) throw new ArgumentNullException(nameof(illuminationSource));
- if (method == null) throw new ArgumentNullException(nameof(method));
- lock (lockObject)
- {
- var windows = new Window[1000];
- for (var i = 0; i < 1000; i++)
- {
- windows[i] = new Window(double.NaN, double.NaN);
- }
-
- FindWindowsOnIlluminationConstraintProxy(searchWindow.Convert(), observer.NaifId,
- illuminationSource.Name, targetBody.NaifId, fixedFrame.Name,
- planetodetic.Convert(),
- illuminationType.GetDescription(), relationalOperator.GetDescription(), value, adjustValue,
- aberration.GetDescription(), stepSize.TotalSeconds, method, windows);
- return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
- }
- }
-
- public IEnumerable FindWindowsOnIlluminationConstraint(TimeSystem.Window searchWindow, int observerId,
- int targetBodyId, Frame fixedFrame, Coordinates.Planetodetic planetodetic, IlluminationAngle illuminationType, RelationnalOperator relationalOperator,
- double value, double adjustValue, Aberration aberration, TimeSpan stepSize, int illuminationSourceId,
- string method = "Ellipsoid")
- {
- if (fixedFrame == null) throw new ArgumentNullException(nameof(fixedFrame));
- if (method == null) throw new ArgumentNullException(nameof(method));
- lock (lockObject)
- {
- var windows = new Window[1000];
- for (var i = 0; i < 1000; i++)
- {
- windows[i] = new Window(double.NaN, double.NaN);
- }
-
- FindWindowsOnIlluminationConstraintProxy(searchWindow.Convert(), observerId,
- illuminationSourceId.ToString(), targetBodyId, fixedFrame.Name,
- planetodetic.Convert(),
- illuminationType.GetDescription(), relationalOperator.GetDescription(), value, adjustValue,
- aberration.GetDescription(), stepSize.TotalSeconds, method, windows);
- return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
- }
- }
-
- ///
- /// Find time window when a target is in instrument's field of view
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IEnumerable FindWindowsInFieldOfViewConstraint(TimeSystem.Window searchWindow, Spacecraft observer,
- Instrument instrument, INaifObject target, Frame targetFrame, ShapeType targetShape, Aberration aberration,
- TimeSpan stepSize)
- {
- if (observer == null) throw new ArgumentNullException(nameof(observer));
- if (instrument == null) throw new ArgumentNullException(nameof(instrument));
- if (target == null) throw new ArgumentNullException(nameof(target));
- if (targetFrame == null) throw new ArgumentNullException(nameof(targetFrame));
- lock (lockObject)
- {
- return FindWindowsInFieldOfViewConstraint(searchWindow, observer.NaifId, instrument.NaifId, target.NaifId, targetFrame, targetShape, aberration, stepSize);
- }
- }
-
- ///
- /// Find time window when a target is in instrument's field of view
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IEnumerable FindWindowsInFieldOfViewConstraint(TimeSystem.Window searchWindow, int observerId,
- int instrumentId, int targetId, Frame targetFrame, ShapeType targetShape, Aberration aberration, TimeSpan stepSize)
- {
- if (targetFrame == null) throw new ArgumentNullException(nameof(targetFrame));
- lock (lockObject)
- {
- var windows = new Window[1000];
- for (var i = 0; i < 1000; i++)
- {
- windows[i] = new Window(double.NaN, double.NaN);
- }
-
- var searchWindowDto = searchWindow.Convert();
-
- FindWindowsInFieldOfViewConstraintProxy(searchWindowDto, observerId, instrumentId, targetId, targetFrame.Name, targetShape.GetDescription(),
- aberration.GetDescription(), stepSize.TotalSeconds, windows);
-
- return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
- }
- }
-
- ///
- /// Read object ephemeris for a given period
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IEnumerable ReadEphemeris(TimeSystem.Window searchWindow,
- ILocalizable observer, ILocalizable target, Frame frame,
- Aberration aberration, TimeSpan stepSize)
- {
- ArgumentNullException.ThrowIfNull(observer);
- ArgumentNullException.ThrowIfNull(target);
- ArgumentNullException.ThrowIfNull(frame);
- lock (lockObject)
- {
- const int messageSize = 10000;
- List orbitalParameters = [];
- int occurrences = (int)(searchWindow.Length / stepSize / messageSize);
-
- for (int i = 0; i <= occurrences; i++)
- {
- var start = searchWindow.StartDate + i * messageSize * stepSize;
- var end = start + messageSize * stepSize > searchWindow.EndDate ? searchWindow.EndDate : (start + messageSize * stepSize) - stepSize;
- var window = new TimeSystem.Window(start, end);
- var stateVectors = new StateVector[messageSize];
- ReadEphemerisProxy(window.Convert(), observer.NaifId, target.NaifId, frame.Name,
- aberration.GetDescription(), stepSize.TotalSeconds,
- stateVectors);
- orbitalParameters.AddRange(stateVectors.Where(x => !string.IsNullOrEmpty(x.Frame)).Select(x =>
- new OrbitalParameters.StateVector(x.Position.Convert(), x.Velocity.Convert(), observer, Time.Create(x.Epoch, TimeFrame.TDBFrame), frame)));
- }
-
- return orbitalParameters;
- }
- }
-
- ///
- /// Return state vector at given epoch
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public OrbitalParameters.OrbitalParameters ReadEphemeris(Time epoch, ILocalizable observer,
- ILocalizable target, Frame frame, Aberration aberration)
- {
- ArgumentNullException.ThrowIfNull(observer);
- ArgumentNullException.ThrowIfNull(target);
- ArgumentNullException.ThrowIfNull(frame);
- lock (lockObject)
- {
- if (frame == null) throw new ArgumentNullException(nameof(frame));
- var stateVector = ReadEphemerisAtGivenEpochProxy(epoch.TimeSpanFromJ2000().TotalSeconds, observer.NaifId,
- target.NaifId, frame.Name, aberration.GetDescription());
- return new OrbitalParameters.StateVector(stateVector.Position.Convert(), stateVector.Velocity.Convert(), observer,
- Time.Create(stateVector.Epoch, TimeFrame.TDBFrame), frame);
- }
- }
-
- ///
- /// Read spacecraft orientation for a given period
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public IEnumerable ReadOrientation(TimeSystem.Window searchWindow,
- Spacecraft spacecraft, TimeSpan tolerance,
- Frame referenceFrame, TimeSpan stepSize)
- {
- if (spacecraft == null) throw new ArgumentNullException(nameof(spacecraft));
- if (referenceFrame == null) throw new ArgumentNullException(nameof(referenceFrame));
- lock (lockObject)
- {
- var stateOrientations = new StateOrientation[10000];
- ReadOrientationProxy(searchWindow.Convert(), spacecraft.NaifId, tolerance.TotalSeconds,
- referenceFrame.Name, stepSize.TotalSeconds,
- stateOrientations);
- return stateOrientations.Where(x => x.Frame != null).Select(x => new OrbitalParameters.StateOrientation(
- x.Rotation.Convert(), x.AngularVelocity.Convert(), Time.Create(x.Epoch, TimeFrame.TDBFrame), referenceFrame));
- }
- }
-
- ///
- /// Write ephemeris file
- ///
- ///
- ///
- ///
- ///
- public bool WriteEphemeris(FileInfo filePath, INaifObject naifObject,
- IEnumerable stateVectors)
- {
- if (naifObject == null) throw new ArgumentNullException(nameof(naifObject));
- if (filePath == null) throw new ArgumentNullException(nameof(filePath));
- if (stateVectors == null) throw new ArgumentNullException(nameof(stateVectors));
- lock (lockObject)
- {
- var enumerable = stateVectors as OrbitalParameters.StateVector[] ?? stateVectors.ToArray();
- if (!enumerable.Any())
- throw new ArgumentException("Value cannot be an empty collection.", nameof(stateVectors));
- bool res = WriteEphemerisProxy(filePath.FullName, naifObject.NaifId, stateVectors.Select(x => x.Convert()).ToArray(),
- (uint)enumerable.Length);
- if (res == false)
- {
- throw new InvalidOperationException(
- "An error occurred while writing ephemeris. You can have more details on standard output.");
- }
-
- return true;
- }
- }
-
- public bool WriteOrientation(FileInfo filePath, INaifObject naifObject, IEnumerable stateOrientations)
- {
- if (naifObject == null) throw new ArgumentNullException(nameof(naifObject));
- if (filePath == null) throw new ArgumentNullException(nameof(filePath));
- if (stateOrientations == null) throw new ArgumentNullException(nameof(stateOrientations));
- lock (lockObject)
- {
- var enumerable = stateOrientations as OrbitalParameters.StateOrientation[] ?? stateOrientations.ToArray();
- if (!enumerable.Any())
- throw new ArgumentException("Value cannot be an empty collection.", nameof(stateOrientations));
- bool res = WriteOrientationProxy(filePath.FullName, naifObject.NaifId, stateOrientations.Select(x => x.Convert()).ToArray(), (uint)enumerable.Length);
- if (res == false)
- {
- throw new InvalidOperationException(
- "An error occurred while writing orientation. You can have more details on standard output.");
- }
-
- return true;
- }
- }
-
- ///
- /// Get celestial celestialItem information like radius, GM, name, associated frame, ...
- ///
- ///
- ///
- public CelestialBody GetCelestialBodyInfo(int naifId)
- {
- lock (lockObject)
- {
- return GetCelestialBodyInfoProxy(naifId);
- }
- }
-
- ///
- /// Transform a frame to another
- ///
- ///
- ///
- ///
- ///
- ///
- public OrbitalParameters.StateOrientation TransformFrame(Frame fromFrame, Frame toFrame, Time epoch)
- {
- lock (lockObject)
- {
- if (fromFrame == null) throw new ArgumentNullException(nameof(fromFrame));
- if (toFrame == null) throw new ArgumentNullException(nameof(toFrame));
- var res = TransformFrameProxy(fromFrame.Name, toFrame.Name, epoch.ToTDB().TimeSpanFromJ2000().TotalSeconds);
-
- return new OrbitalParameters.StateOrientation(
- new Quaternion(res.Rotation.W, res.Rotation.X, res.Rotation.Y, res.Rotation.Z),
- new Vector3(res.AngularVelocity.X, res.AngularVelocity.Y, res.AngularVelocity.Z), epoch, fromFrame);
- }
- }
-
- ///
- /// Convert TLE to state vector at given epoch
- ///
- ///
- ///
- ///
- ///
- ///
- public OrbitalParameters.OrbitalParameters ConvertTleToStateVector(string line1, string line2, string line3,
- Time epoch)
- {
- lock (lockObject)
- {
- var res = ConvertTLEToStateVectorProxy(line1, line2, line3, epoch.ToTDB().TimeSpanFromJ2000().TotalSeconds);
- return new OrbitalParameters.StateVector(res.Position.Convert(), res.Velocity.Convert(),
- new Body.CelestialBody(PlanetsAndMoons.EARTH, Frame.ECLIPTIC_J2000, epoch), epoch,
- new Frame(res.Frame)).ToFrame(Frame.ICRF);
- }
- }
-
- public IO.Astrodynamics.OrbitalParameters.KeplerianElements ConvertStateVectorToConicOrbitalElement(IO.Astrodynamics.OrbitalParameters.StateVector stateVector)
- {
- lock (lockObject)
- {
- var svDto = stateVector.Convert();
- return ConvertStateVectorToConicOrbitalElementProxy(svDto, stateVector.Observer.GM).Convert();
- }
- }
-
- public IO.Astrodynamics.OrbitalParameters.StateVector ConvertEquinoctialElementsToStateVector(IO.Astrodynamics.OrbitalParameters.EquinoctialElements equinoctialElements)
- {
- lock (lockObject)
- {
- return ConvertEquinoctialElementsToStateVectorProxy(equinoctialElements.Convert()).Convert();
- }
- }
-
- public IO.Astrodynamics.OrbitalParameters.StateVector ConvertConicElementsToStateVector(IO.Astrodynamics.OrbitalParameters.KeplerianElements keplerianElements)
- {
- lock (lockObject)
- {
- return ConvertConicElementsToStateVectorProxy(keplerianElements.Convert()).Convert();
- }
- }
-
- public IO.Astrodynamics.OrbitalParameters.StateVector ConvertConicElementsToStateVector(IO.Astrodynamics.OrbitalParameters.KeplerianElements keplerianElements, Time epoch)
- {
- lock (lockObject)
- {
- return ConvertConicElementsToStateVectorAtEpochProxy(keplerianElements.Convert(), epoch.ToTDB().TimeSpanFromJ2000().TotalSeconds, keplerianElements.Observer.GM)
- .Convert();
- }
- }
-
- public OrbitalParameters.StateVector Propagate2Bodies(OrbitalParameters.StateVector stateVector, TimeSpan dt)
- {
- lock (lockObject)
- {
- return Propagate2BodiesProxy(stateVector.Convert(), stateVector.Observer.GM, dt.TotalSeconds).Convert();
- }
- }
-
- public OrbitalParameters.StateVector Propagate2Bodies(OrbitalParameters.StateVector stateVector, Time targetEpoch)
- {
- return Propagate2Bodies(stateVector, targetEpoch - stateVector.Epoch);
- }
+ ///
+ /// Get spice toolkit version number
+ ///
+ ///
+ public string GetSpiceVersion()
+ {
+ lock (lockObject)
+ {
+ var strptr = GetSpiceVersionProxy();
+ var str = Marshal.PtrToStringAnsi(strptr);
+ Marshal.FreeHGlobal(strptr);
+ return str;
+ }
+ }
+
+ public IEnumerable GetLoadedKernels()
+ {
+ return _kernels;
+ }
+
+ ///
+ /// Load kernel at given path
+ ///
+ /// Path where kernels are located. This could be a file path or a directory path
+ public void LoadKernels(FileSystemInfo path)
+ {
+ if (path == null) throw new ArgumentNullException(nameof(path));
+ lock (lockObject)
+ {
+ if (_kernels.Any(x => path.FullName.Contains(x.FullName)))
+ {
+ foreach (var kernel in _kernels.Where(x => path.FullName.Contains(x.FullName)).ToArray())
+ {
+ UnloadKernels(kernel);
+ LoadKernels(kernel);
+ }
+
+ return;
+ }
+
+
+ var existingKernels = _kernels.Where(x => x.FullName.Contains(path.FullName)).ToArray();
+ foreach (var existingKernel in existingKernels)
+ {
+ UnloadKernels(existingKernel);
+ }
+
+ if (path.Exists)
+ {
+ if (!LoadKernelsProxy(path.FullName))
+ {
+ throw new InvalidOperationException($"Kernel {path.FullName} can't be loaded. You can have more details on standard output");
+ }
+
+ _kernels.Add(path);
+ }
+ }
+ }
+
+ ///
+ /// Unload kernel at given path
+ ///
+ /// Path where kernels are located. This could be a file path or a directory path
+ public void UnloadKernels(FileSystemInfo path)
+ {
+ if (path == null) return;
+ lock (lockObject)
+ {
+ if (path.Exists)
+ {
+ if (!UnloadKernelsProxy(path.FullName))
+ {
+ throw new InvalidOperationException($"Kernel {path.FullName} can't be unloaded. You can have more details on standard output");
+ }
+
+ _kernels.RemoveAll(x => x.FullName == path.FullName);
+ foreach (var kernel in _kernels.Where(x => x.FullName.Contains(path.FullName)).ToArray())
+ {
+ UnloadKernels(kernel);
+ }
+ }
+ }
+ }
+
+ public void ClearKernels()
+ {
+ lock (lockObject)
+ {
+ foreach (var kernel in _kernels.ToArray())
+ {
+ UnloadKernels(kernel);
+ }
+
+ KClearProxy();
+ }
+ }
+
+ ///
+ /// Find launch windows
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable FindLaunchWindows(Maneuver.Launch launch,
+ in TimeSystem.Window window, DirectoryInfo outputDirectory)
+ {
+ if (launch == null) throw new ArgumentNullException(nameof(launch));
+ lock (lockObject)
+ {
+ //Convert data
+ Launch launchDto = launch.Convert();
+ launchDto.Window = window.Convert();
+ launchDto.LaunchSite.DirectoryPath = outputDirectory.CreateSubdirectory("Sites").FullName;
+ launchDto.RecoverySite.DirectoryPath = outputDirectory.CreateSubdirectory("Sites").FullName;
+
+ //Execute request
+ LaunchProxy(ref launchDto);
+
+ //Filter result
+ var windows = launchDto.Windows.Where(x => x.Start != 0 && x.End != 0).ToArray();
+
+ //Build result
+ List launchWindows = [];
+
+ for (int i = 0; i < windows.Length; i++)
+ {
+ launchWindows.Add(new LaunchWindow(windows[i].Convert(),
+ launchDto.InertialInsertionVelocity[i], launchDto.NonInertialInsertionVelocity[i],
+ launchDto.InertialAzimuth[i], launchDto.NonInertialAzimuth[i]));
+ }
+
+ return launchWindows;
+ }
+ }
+
+ ///
+ /// Find time windows based on distance constraint
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable FindWindowsOnDistanceConstraint(TimeSystem.Window searchWindow, INaifObject observer,
+ INaifObject target, RelationnalOperator relationalOperator, double value, Aberration aberration,
+ TimeSpan stepSize)
+ {
+ if (observer == null) throw new ArgumentNullException(nameof(observer));
+ if (target == null) throw new ArgumentNullException(nameof(target));
+ lock (lockObject)
+ {
+ return FindWindowsOnDistanceConstraint(searchWindow, observer.NaifId, target.NaifId, relationalOperator, value, aberration, stepSize);
+ }
+ }
+
+ public IEnumerable FindWindowsOnDistanceConstraint(TimeSystem.Window searchWindow, int observerId,
+ int targetId, RelationnalOperator relationalOperator, double value, Aberration aberration,
+ TimeSpan stepSize)
+ {
+ lock (lockObject)
+ {
+ var windows = new Window[1000];
+ for (var i = 0; i < 1000; i++)
+ {
+ windows[i] = new Window(double.NaN, double.NaN);
+ }
+
+ FindWindowsOnDistanceConstraintProxy(searchWindow.Convert(), observerId, targetId, relationalOperator.GetDescription(), value,
+ aberration.GetDescription(), stepSize.TotalSeconds, windows);
+ return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
+ }
+ }
+
+ ///
+ /// Find time windows based on occultation constraint
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable FindWindowsOnOccultationConstraint(TimeSystem.Window searchWindow, INaifObject observer,
+ INaifObject target, ShapeType targetShape, INaifObject frontBody, ShapeType frontShape,
+ OccultationType occultationType, Aberration aberration, TimeSpan stepSize)
+ {
+ if (observer == null) throw new ArgumentNullException(nameof(observer));
+ if (target == null) throw new ArgumentNullException(nameof(target));
+ if (frontBody == null) throw new ArgumentNullException(nameof(frontBody));
+ lock (lockObject)
+ {
+ string frontFrame = frontShape == ShapeType.Ellipsoid
+ ? (frontBody as Body.CelestialBody)?.Frame.Name
+ : string.Empty;
+ string targetFrame = targetShape == ShapeType.Ellipsoid
+ ? (target as Body.CelestialBody)?.Frame.Name
+ : String.Empty;
+ var windows = new Window[1000];
+ for (var i = 0; i < 1000; i++)
+ {
+ windows[i] = new Window(double.NaN, double.NaN);
+ }
+
+ FindWindowsOnOccultationConstraintProxy(searchWindow.Convert(), observer.NaifId, target.NaifId,
+ targetFrame, targetShape.GetDescription(),
+ frontBody.NaifId, frontFrame, frontShape.GetDescription(), occultationType.GetDescription(),
+ aberration.GetDescription(), stepSize.TotalSeconds, windows);
+ return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
+ }
+ }
+
+ ///
+ /// Find time windows based on occultation constraint
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable FindWindowsOnOccultationConstraint(TimeSystem.Window searchWindow, int observerId,
+ int targetId, ShapeType targetShape, int frontBodyId, ShapeType frontShape,
+ OccultationType occultationType, Aberration aberration, TimeSpan stepSize)
+ {
+ lock (lockObject)
+ {
+ IO.Astrodynamics.Body.CelestialBody frontBody = new IO.Astrodynamics.Body.CelestialBody(frontBodyId);
+ IO.Astrodynamics.Body.CelestialBody targetBody = new IO.Astrodynamics.Body.CelestialBody(targetId);
+ string frontFrame = frontShape == ShapeType.Ellipsoid
+ ? frontBody.Frame.Name
+ : string.Empty;
+ string targetFrame = targetShape == ShapeType.Ellipsoid
+ ? targetBody.Frame.Name
+ : String.Empty;
+ var windows = new Window[1000];
+ for (var i = 0; i < 1000; i++)
+ {
+ windows[i] = new Window(double.NaN, double.NaN);
+ }
+
+ FindWindowsOnOccultationConstraintProxy(searchWindow.Convert(), observerId, targetId, targetFrame, targetShape.GetDescription(),
+ frontBody.NaifId, frontFrame, frontShape.GetDescription(), occultationType.GetDescription(), aberration.GetDescription(), stepSize.TotalSeconds, windows);
+ return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
+ }
+ }
+
+ ///
+ /// Find time windows based on coordinate constraint
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable FindWindowsOnCoordinateConstraint(TimeSystem.Window searchWindow, INaifObject observer,
+ INaifObject target, Frame frame, CoordinateSystem coordinateSystem, Coordinate coordinate,
+ RelationnalOperator relationalOperator, double value, double adjustValue, Aberration aberration,
+ TimeSpan stepSize)
+ {
+ if (observer == null) throw new ArgumentNullException(nameof(observer));
+ if (target == null) throw new ArgumentNullException(nameof(target));
+ if (frame == null) throw new ArgumentNullException(nameof(frame));
+ lock (lockObject)
+ {
+ var windows = new Window[1000];
+ for (var i = 0; i < 1000; i++)
+ {
+ windows[i] = new Window(double.NaN, double.NaN);
+ }
+
+ FindWindowsOnCoordinateConstraintProxy(searchWindow.Convert(), observer.NaifId, target.NaifId,
+ frame.Name, coordinateSystem.GetDescription(),
+ coordinate.GetDescription(), relationalOperator.GetDescription(), value, adjustValue,
+ aberration.GetDescription(), stepSize.TotalSeconds, windows);
+ return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
+ }
+ }
+
+ ///
+ /// Find time windows based on coordinate constraint
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable FindWindowsOnCoordinateConstraint(TimeSystem.Window searchWindow, int observerId,
+ int targetId, Frame frame, CoordinateSystem coordinateSystem, Coordinate coordinate,
+ RelationnalOperator relationalOperator, double value, double adjustValue, Aberration aberration,
+ TimeSpan stepSize)
+ {
+ if (frame == null) throw new ArgumentNullException(nameof(frame));
+ lock (lockObject)
+ {
+ var windows = new Window[1000];
+ for (var i = 0; i < 1000; i++)
+ {
+ windows[i] = new Window(double.NaN, double.NaN);
+ }
+
+ FindWindowsOnCoordinateConstraintProxy(searchWindow.Convert(), observerId, targetId,
+ frame.Name, coordinateSystem.GetDescription(),
+ coordinate.GetDescription(), relationalOperator.GetDescription(), value, adjustValue,
+ aberration.GetDescription(), stepSize.TotalSeconds, windows);
+ return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
+ }
+ }
+
+ ///
+ /// Find time windows based on illumination constraint
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable FindWindowsOnIlluminationConstraint(TimeSystem.Window searchWindow, INaifObject observer,
+ INaifObject targetBody, Frame fixedFrame,
+ Coordinates.Planetodetic planetodetic, IlluminationAngle illuminationType, RelationnalOperator relationalOperator,
+ double value, double adjustValue, Aberration aberration, TimeSpan stepSize, INaifObject illuminationSource,
+ string method = "Ellipsoid")
+ {
+ if (observer == null) throw new ArgumentNullException(nameof(observer));
+ if (targetBody == null) throw new ArgumentNullException(nameof(targetBody));
+ if (fixedFrame == null) throw new ArgumentNullException(nameof(fixedFrame));
+ if (illuminationSource == null) throw new ArgumentNullException(nameof(illuminationSource));
+ if (method == null) throw new ArgumentNullException(nameof(method));
+ lock (lockObject)
+ {
+ var windows = new Window[1000];
+ for (var i = 0; i < 1000; i++)
+ {
+ windows[i] = new Window(double.NaN, double.NaN);
+ }
+
+ FindWindowsOnIlluminationConstraintProxy(searchWindow.Convert(), observer.NaifId,
+ illuminationSource.Name, targetBody.NaifId, fixedFrame.Name,
+ planetodetic.Convert(),
+ illuminationType.GetDescription(), relationalOperator.GetDescription(), value, adjustValue,
+ aberration.GetDescription(), stepSize.TotalSeconds, method, windows);
+ return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
+ }
+ }
+
+ public IEnumerable FindWindowsOnIlluminationConstraint(TimeSystem.Window searchWindow, int observerId,
+ int targetBodyId, Frame fixedFrame, Coordinates.Planetodetic planetodetic, IlluminationAngle illuminationType, RelationnalOperator relationalOperator,
+ double value, double adjustValue, Aberration aberration, TimeSpan stepSize, int illuminationSourceId,
+ string method = "Ellipsoid")
+ {
+ if (fixedFrame == null) throw new ArgumentNullException(nameof(fixedFrame));
+ if (method == null) throw new ArgumentNullException(nameof(method));
+ lock (lockObject)
+ {
+ var windows = new Window[1000];
+ for (var i = 0; i < 1000; i++)
+ {
+ windows[i] = new Window(double.NaN, double.NaN);
+ }
+
+ FindWindowsOnIlluminationConstraintProxy(searchWindow.Convert(), observerId,
+ illuminationSourceId.ToString(), targetBodyId, fixedFrame.Name,
+ planetodetic.Convert(),
+ illuminationType.GetDescription(), relationalOperator.GetDescription(), value, adjustValue,
+ aberration.GetDescription(), stepSize.TotalSeconds, method, windows);
+ return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
+ }
+ }
+
+ ///
+ /// Find time window when a target is in instrument's field of view
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable FindWindowsInFieldOfViewConstraint(TimeSystem.Window searchWindow, Spacecraft observer,
+ Instrument instrument, INaifObject target, Frame targetFrame, ShapeType targetShape, Aberration aberration,
+ TimeSpan stepSize)
+ {
+ if (observer == null) throw new ArgumentNullException(nameof(observer));
+ if (instrument == null) throw new ArgumentNullException(nameof(instrument));
+ if (target == null) throw new ArgumentNullException(nameof(target));
+ if (targetFrame == null) throw new ArgumentNullException(nameof(targetFrame));
+ lock (lockObject)
+ {
+ return FindWindowsInFieldOfViewConstraint(searchWindow, observer.NaifId, instrument.NaifId, target.NaifId, targetFrame, targetShape, aberration, stepSize);
+ }
+ }
+
+ ///
+ /// Find time window when a target is in instrument's field of view
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable FindWindowsInFieldOfViewConstraint(TimeSystem.Window searchWindow, int observerId,
+ int instrumentId, int targetId, Frame targetFrame, ShapeType targetShape, Aberration aberration, TimeSpan stepSize)
+ {
+ if (targetFrame == null) throw new ArgumentNullException(nameof(targetFrame));
+ lock (lockObject)
+ {
+ var windows = new Window[1000];
+ for (var i = 0; i < 1000; i++)
+ {
+ windows[i] = new Window(double.NaN, double.NaN);
+ }
+
+ var searchWindowDto = searchWindow.Convert();
+
+ FindWindowsInFieldOfViewConstraintProxy(searchWindowDto, observerId, instrumentId, targetId, targetFrame.Name, targetShape.GetDescription(),
+ aberration.GetDescription(), stepSize.TotalSeconds, windows);
+
+ return windows.Where(x => !double.IsNaN(x.Start)).Select(x => x.Convert());
+ }
+ }
+
+ ///
+ /// Read object ephemeris for a given period
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable ReadEphemeris(TimeSystem.Window searchWindow,
+ ILocalizable observer, ILocalizable target, Frame frame,
+ Aberration aberration, TimeSpan stepSize)
+ {
+ ArgumentNullException.ThrowIfNull(observer);
+ ArgumentNullException.ThrowIfNull(target);
+ ArgumentNullException.ThrowIfNull(frame);
+ lock (lockObject)
+ {
+ const int messageSize = 10000;
+ List orbitalParameters = [];
+ int occurrences = (int)(searchWindow.Length / stepSize / messageSize);
+
+ for (int i = 0; i <= occurrences; i++)
+ {
+ var start = searchWindow.StartDate + i * messageSize * stepSize;
+ var end = start + messageSize * stepSize > searchWindow.EndDate ? searchWindow.EndDate : (start + messageSize * stepSize) - stepSize;
+ var window = new TimeSystem.Window(start, end);
+ var stateVectors = new StateVector[messageSize];
+ ReadEphemerisProxy(window.Convert(), observer.NaifId, target.NaifId, frame.Name,
+ aberration.GetDescription(), stepSize.TotalSeconds,
+ stateVectors);
+ orbitalParameters.AddRange(stateVectors.Where(x => !string.IsNullOrEmpty(x.Frame)).Select(x =>
+ new OrbitalParameters.StateVector(x.Position.Convert(), x.Velocity.Convert(), observer, Time.Create(x.Epoch, TimeFrame.TDBFrame), frame)));
+ }
+
+ return orbitalParameters;
+ }
+ }
+
+ ///
+ /// Return state vector at given epoch
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public OrbitalParameters.OrbitalParameters ReadEphemeris(Time epoch, ILocalizable observer,
+ ILocalizable target, Frame frame, Aberration aberration)
+ {
+ ArgumentNullException.ThrowIfNull(observer);
+ ArgumentNullException.ThrowIfNull(target);
+ ArgumentNullException.ThrowIfNull(frame);
+ lock (lockObject)
+ {
+ if (frame == null) throw new ArgumentNullException(nameof(frame));
+ var stateVector = ReadEphemerisAtGivenEpochProxy(epoch.TimeSpanFromJ2000().TotalSeconds, observer.NaifId,
+ target.NaifId, frame.Name, aberration.GetDescription());
+ return new OrbitalParameters.StateVector(stateVector.Position.Convert(), stateVector.Velocity.Convert(), observer,
+ Time.Create(stateVector.Epoch, TimeFrame.TDBFrame), frame);
+ }
+ }
+
+ ///
+ /// Read spacecraft orientation for a given period
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable ReadOrientation(TimeSystem.Window searchWindow,
+ Spacecraft spacecraft, TimeSpan tolerance,
+ Frame referenceFrame, TimeSpan stepSize)
+ {
+ if (spacecraft == null) throw new ArgumentNullException(nameof(spacecraft));
+ if (referenceFrame == null) throw new ArgumentNullException(nameof(referenceFrame));
+ lock (lockObject)
+ {
+ var stateOrientations = new StateOrientation[10000];
+ ReadOrientationProxy(searchWindow.Convert(), spacecraft.NaifId, tolerance.TotalSeconds,
+ referenceFrame.Name, stepSize.TotalSeconds,
+ stateOrientations);
+ return stateOrientations.Where(x => x.Frame != null).Select(x => new OrbitalParameters.StateOrientation(
+ x.Rotation.Convert(), x.AngularVelocity.Convert(), Time.Create(x.Epoch, TimeFrame.TDBFrame), referenceFrame));
+ }
+ }
+
+ ///
+ /// Write ephemeris file
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool WriteEphemeris(FileInfo filePath, INaifObject naifObject,
+ IEnumerable stateVectors)
+ {
+ if (naifObject == null) throw new ArgumentNullException(nameof(naifObject));
+ if (filePath == null) throw new ArgumentNullException(nameof(filePath));
+ if (stateVectors == null) throw new ArgumentNullException(nameof(stateVectors));
+ lock (lockObject)
+ {
+ var enumerable = stateVectors as OrbitalParameters.StateVector[] ?? stateVectors.ToArray();
+ if (!enumerable.Any())
+ throw new ArgumentException("Value cannot be an empty collection.", nameof(stateVectors));
+ bool res = WriteEphemerisProxy(filePath.FullName, naifObject.NaifId, stateVectors.Select(x => x.Convert()).ToArray(),
+ (uint)enumerable.Length);
+ if (res == false)
+ {
+ throw new InvalidOperationException(
+ "An error occurred while writing ephemeris. You can have more details on standard output.");
+ }
+
+ return true;
+ }
+ }
+
+ public bool WriteOrientation(FileInfo filePath, INaifObject naifObject, IEnumerable stateOrientations)
+ {
+ if (naifObject == null) throw new ArgumentNullException(nameof(naifObject));
+ if (filePath == null) throw new ArgumentNullException(nameof(filePath));
+ if (stateOrientations == null) throw new ArgumentNullException(nameof(stateOrientations));
+ lock (lockObject)
+ {
+ var enumerable = stateOrientations as OrbitalParameters.StateOrientation[] ?? stateOrientations.ToArray();
+ if (!enumerable.Any())
+ throw new ArgumentException("Value cannot be an empty collection.", nameof(stateOrientations));
+ bool res = WriteOrientationProxy(filePath.FullName, naifObject.NaifId, stateOrientations.Select(x => x.Convert()).ToArray(), (uint)enumerable.Length);
+ if (res == false)
+ {
+ throw new InvalidOperationException(
+ "An error occurred while writing orientation. You can have more details on standard output.");
+ }
+
+ return true;
+ }
+ }
+
+ ///
+ /// Get celestial celestialItem information like radius, GM, name, associated frame, ...
+ ///
+ ///
+ ///
+ public CelestialBody GetCelestialBodyInfo(int naifId)
+ {
+ lock (lockObject)
+ {
+ return GetCelestialBodyInfoProxy(naifId);
+ }
+ }
+
+ ///
+ /// Transform a frame to another
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public OrbitalParameters.StateOrientation TransformFrame(Time epoch, Frame fromFrame, Frame toFrame)
+ {
+ lock (lockObject)
+ {
+ if (fromFrame == null) throw new ArgumentNullException(nameof(fromFrame));
+ if (toFrame == null) throw new ArgumentNullException(nameof(toFrame));
+ var res = TransformFrameProxy(fromFrame.Name, toFrame.Name, epoch.ToTDB().TimeSpanFromJ2000().TotalSeconds);
+
+ return new OrbitalParameters.StateOrientation(
+ new Quaternion(res.Rotation.W, res.Rotation.X, res.Rotation.Y, res.Rotation.Z),
+ new Vector3(res.AngularVelocity.X, res.AngularVelocity.Y, res.AngularVelocity.Z), epoch, fromFrame);
+ }
+ }
+
+ public IEnumerable TransformFrame(TimeSystem.Window window, Frame fromFrame, Frame toFrame, TimeSpan stepSize)
+ {
+ for (Time i = window.StartDate; i < window.EndDate; i += stepSize)
+ {
+ yield return TransformFrame(i, fromFrame, toFrame);
+ }
+ }
+
+ ///
+ /// Convert TLE to state vector at given epoch
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public OrbitalParameters.OrbitalParameters ConvertTleToStateVector(string line1, string line2, string line3,
+ Time epoch)
+ {
+ lock (lockObject)
+ {
+ var res = ConvertTLEToStateVectorProxy(line1, line2, line3, epoch.ToTDB().TimeSpanFromJ2000().TotalSeconds);
+ return new OrbitalParameters.StateVector(res.Position.Convert(), res.Velocity.Convert(),
+ new Body.CelestialBody(PlanetsAndMoons.EARTH, Frame.ECLIPTIC_J2000, epoch), epoch,
+ new Frame(res.Frame)).ToFrame(Frame.ICRF);
+ }
+ }
+
+ public IO.Astrodynamics.OrbitalParameters.KeplerianElements ConvertStateVectorToConicOrbitalElement(IO.Astrodynamics.OrbitalParameters.StateVector stateVector)
+ {
+ lock (lockObject)
+ {
+ var svDto = stateVector.Convert();
+ return ConvertStateVectorToConicOrbitalElementProxy(svDto, stateVector.Observer.GM).Convert();
+ }
+ }
+
+ public IO.Astrodynamics.OrbitalParameters.StateVector ConvertEquinoctialElementsToStateVector(IO.Astrodynamics.OrbitalParameters.EquinoctialElements equinoctialElements)
+ {
+ lock (lockObject)
+ {
+ return ConvertEquinoctialElementsToStateVectorProxy(equinoctialElements.Convert()).Convert();
+ }
+ }
+
+ public IO.Astrodynamics.OrbitalParameters.StateVector ConvertConicElementsToStateVector(IO.Astrodynamics.OrbitalParameters.KeplerianElements keplerianElements)
+ {
+ lock (lockObject)
+ {
+ return ConvertConicElementsToStateVectorProxy(keplerianElements.Convert()).Convert();
+ }
+ }
+
+ public IO.Astrodynamics.OrbitalParameters.StateVector ConvertConicElementsToStateVector(IO.Astrodynamics.OrbitalParameters.KeplerianElements keplerianElements, Time epoch)
+ {
+ lock (lockObject)
+ {
+ return ConvertConicElementsToStateVectorAtEpochProxy(keplerianElements.Convert(), epoch.ToTDB().TimeSpanFromJ2000().TotalSeconds, keplerianElements.Observer.GM)
+ .Convert();
+ }
+ }
+
+ public OrbitalParameters.StateVector Propagate2Bodies(OrbitalParameters.StateVector stateVector, TimeSpan dt)
+ {
+ lock (lockObject)
+ {
+ return Propagate2BodiesProxy(stateVector.Convert(), stateVector.Observer.GM, dt.TotalSeconds).Convert();
+ }
+ }
+
+ public OrbitalParameters.StateVector Propagate2Bodies(OrbitalParameters.StateVector stateVector, Time targetEpoch)
+ {
+ return Propagate2Bodies(stateVector, targetEpoch - stateVector.Epoch);
+ }
}
\ No newline at end of file
diff --git a/IO.Astrodynamics.Net/IO.Astrodynamics/Body/CelestialItem.cs b/IO.Astrodynamics.Net/IO.Astrodynamics/Body/CelestialItem.cs
index 043bb3fd..d3670676 100644
--- a/IO.Astrodynamics.Net/IO.Astrodynamics/Body/CelestialItem.cs
+++ b/IO.Astrodynamics.Net/IO.Astrodynamics/Body/CelestialItem.cs
@@ -119,7 +119,6 @@ public abstract class CelestialItem : ILocalizable, IEquatable
/// Initial orbital parameters frame
/// Epoch
///
- ///
protected CelestialItem(int naifId, Frame frame, in Time epoch, GeopotentialModelParameters geopotentialModelParameters = null)
{
_dataProvider = Configuration.Instance.DataProvider;
diff --git a/IO.Astrodynamics.Net/IO.Astrodynamics/DataProvider/IDataProvider.cs b/IO.Astrodynamics.Net/IO.Astrodynamics/DataProvider/IDataProvider.cs
index 29571baa..46e8cf47 100644
--- a/IO.Astrodynamics.Net/IO.Astrodynamics/DataProvider/IDataProvider.cs
+++ b/IO.Astrodynamics.Net/IO.Astrodynamics/DataProvider/IDataProvider.cs
@@ -1,5 +1,7 @@
+using System;
using System.Collections.Generic;
using System.IO;
+using System.Threading.Tasks;
using IO.Astrodynamics.Body;
using IO.Astrodynamics.Frames;
using IO.Astrodynamics.OrbitalParameters;
@@ -9,9 +11,12 @@ namespace IO.Astrodynamics.DataProvider;
public interface IDataProvider
{
- StateOrientation FrameTransformation(Frame source, Frame target, in Time date);
- OrbitalParameters.OrbitalParameters GetEphemeris(in Time epoch, ILocalizable target, ILocalizable observer, Frame frame, Aberration aberration);
+ Task> FrameTransformationAsync(Window window, Frame source, Frame target, TimeSpan stepSize);
+ StateOrientation FrameTransformation(in Time date, Frame source, Frame target);
+ OrbitalParameters.OrbitalParameters GetEphemeris(in Time date, ILocalizable target, ILocalizable observer, Frame frame, Aberration aberration);
+ Task> GetEphemerisAsync(Window window, ILocalizable target, ILocalizable observer, Frame frame, Aberration aberration, TimeSpan stepSize);
+ Task GetCelestialBodyInfoAsync(int naifId);
DTO.CelestialBody GetCelestialBodyInfo(int naifId);
- void WriteEphemeris(FileInfo outputFile,INaifObject naifObject, IEnumerable stateVectors);
- void WriteOrientation(FileInfo outputFile,INaifObject naifObject, IEnumerable stateOrientations);
+ void WriteEphemeris(FileInfo outputFile, INaifObject naifObject, IEnumerable stateVectors);
+ void WriteOrientation(FileInfo outputFile, INaifObject naifObject, IEnumerable stateOrientations);
}
\ No newline at end of file
diff --git a/IO.Astrodynamics.Net/IO.Astrodynamics/DataProvider/SpiceDataProvider.cs b/IO.Astrodynamics.Net/IO.Astrodynamics/DataProvider/SpiceDataProvider.cs
index aa181f69..a289329c 100644
--- a/IO.Astrodynamics.Net/IO.Astrodynamics/DataProvider/SpiceDataProvider.cs
+++ b/IO.Astrodynamics.Net/IO.Astrodynamics/DataProvider/SpiceDataProvider.cs
@@ -1,27 +1,46 @@
+using System;
using System.Collections.Generic;
using System.IO;
+using System.Threading.Tasks;
using IO.Astrodynamics.Body;
using IO.Astrodynamics.Frames;
using IO.Astrodynamics.Math;
using IO.Astrodynamics.OrbitalParameters;
using IO.Astrodynamics.SolarSystemObjects;
using IO.Astrodynamics.TimeSystem;
+using CelestialBody = IO.Astrodynamics.DTO.CelestialBody;
namespace IO.Astrodynamics.DataProvider;
public class SpiceDataProvider : IDataProvider
{
- public StateOrientation FrameTransformation(Frame source, Frame target, in Time date)
+ public Task> FrameTransformationAsync(Window window, Frame source, Frame target, TimeSpan stepSize)
{
- return API.Instance.TransformFrame(source, target, date);
+ return Task.Run(() => API.Instance.TransformFrame(window, source, target, stepSize));
}
- public OrbitalParameters.OrbitalParameters GetEphemeris(in Time epoch, ILocalizable target, ILocalizable observer, Frame frame, Aberration aberration)
+ public StateOrientation FrameTransformation(in Time date, Frame source, Frame target)
{
- return API.Instance.ReadEphemeris(epoch, observer, target, frame, aberration);
+ return API.Instance.TransformFrame(date, source, target);
}
- public DTO.CelestialBody GetCelestialBodyInfo(int naifId)
+ public OrbitalParameters.OrbitalParameters GetEphemeris(in Time date, ILocalizable target, ILocalizable observer, Frame frame, Aberration aberration)
+ {
+ return API.Instance.ReadEphemeris(date, observer, target, frame, aberration);
+ }
+
+ public Task> GetEphemerisAsync(Window window, ILocalizable target, ILocalizable observer, Frame frame, Aberration aberration,
+ TimeSpan stepSize)
+ {
+ return Task.Run(() => API.Instance.ReadEphemeris(window, observer, target, frame, aberration, stepSize));
+ }
+
+ public Task GetCelestialBodyInfoAsync(int naifId)
+ {
+ return Task.Run(() => API.Instance.GetCelestialBodyInfo(naifId));
+ }
+
+ CelestialBody IDataProvider.GetCelestialBodyInfo(int naifId)
{
return API.Instance.GetCelestialBodyInfo(naifId);
}
diff --git a/IO.Astrodynamics.Net/IO.Astrodynamics/Frames/Frame.cs b/IO.Astrodynamics.Net/IO.Astrodynamics/Frames/Frame.cs
index 5d848c29..054b1651 100644
--- a/IO.Astrodynamics.Net/IO.Astrodynamics/Frames/Frame.cs
+++ b/IO.Astrodynamics.Net/IO.Astrodynamics/Frames/Frame.cs
@@ -4,6 +4,7 @@
using System.Collections.Immutable;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using IO.Astrodynamics.DataProvider;
using IO.Astrodynamics.Math;
using IO.Astrodynamics.OrbitalParameters;
@@ -17,7 +18,7 @@ public class Frame : IEquatable
public string Name { get; }
public int? Id { get; }
- protected SortedDictionary