diff --git a/IO.Astrodynamics.Tests/APITest.cs b/IO.Astrodynamics.Tests/APITest.cs index ad5b01c..f342a6e 100644 --- a/IO.Astrodynamics.Tests/APITest.cs +++ b/IO.Astrodynamics.Tests/APITest.cs @@ -439,9 +439,9 @@ public void FindWindowsInFieldOfViewConstraint() new Vector3(0.0, -System.Math.PI * 0.5, 0.0))); scenario.AddSpacecraft(spacecraft); + var root = Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name); //Execute scenario - API.Instance.PropagateScenario(scenario, Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name).CreateSubdirectory("Sites"), - Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name).CreateSubdirectory("Spacecrafts")); + API.Instance.PropagateScenario(scenario, root.CreateSubdirectory("Sites"), root.CreateSubdirectory("Spacecrafts")); //Find windows when the earth is in field of view of camera 600 var res = API.Instance.FindWindowsInFieldOfViewConstraint( @@ -570,8 +570,8 @@ public void ReadOrientation() scenario.AddSpacecraft(spacecraft); //Execute scenario - API.Instance.PropagateScenario(scenario, Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name).CreateSubdirectory("Sites"), - Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name).CreateSubdirectory("Spacecrafts")); + var root = Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name); + API.Instance.PropagateScenario(scenario, root.CreateSubdirectory("Sites"), root.CreateSubdirectory("Spacecrafts")); //Read spacecraft orientation var res = API.Instance.ReadOrientation(window, spacecraft, TimeSpan.FromSeconds(10.0), Frames.Frame.ICRF, diff --git a/IO.Astrodynamics.Tests/Body/InstrumentTests.cs b/IO.Astrodynamics.Tests/Body/InstrumentTests.cs index 774f6b7..2f90d02 100644 --- a/IO.Astrodynamics.Tests/Body/InstrumentTests.cs +++ b/IO.Astrodynamics.Tests/Body/InstrumentTests.cs @@ -90,9 +90,9 @@ public void FindWindowInFieldOfView() new Vector3(0.0, -System.Math.PI * 0.5, 0.0))); scenario.AddSpacecraft(spacecraft); + var root = Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name); //Execute scenario - API.Instance.PropagateScenario(scenario, Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name).CreateSubdirectory("Sites"), - Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name).CreateSubdirectory("Spacecrafts")); + API.Instance.PropagateScenario(scenario, root.CreateSubdirectory("Sites"), root.CreateSubdirectory("Spacecrafts")); //Find windows when the earth is in field of view of camera 600 var res = spacecraft.Intruments.First().FindWindowsInFieldOfViewConstraint( diff --git a/IO.Astrodynamics.Tests/Body/SpacecraftTests.cs b/IO.Astrodynamics.Tests/Body/SpacecraftTests.cs index ffb44d3..52f12c0 100644 --- a/IO.Astrodynamics.Tests/Body/SpacecraftTests.cs +++ b/IO.Astrodynamics.Tests/Body/SpacecraftTests.cs @@ -100,9 +100,11 @@ public void GetOrientation() Vector3.VectorZ, Vector3.VectorX, Vector3.VectorX)); scenario.AddSpacecraft(spacecraft); + var root = Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name); + //Execute scenario - API.Instance.PropagateScenario(scenario, Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name).CreateSubdirectory("Sites"), - Constants.OutputPath.CreateSubdirectory(scenario.Mission.Name).CreateSubdirectory(scenario.Name).CreateSubdirectory("Spacecrafts")); + API.Instance.PropagateScenario(scenario, root.CreateSubdirectory("Sites"), root.CreateSubdirectory("Spacecrafts")); + var orientation = spacecraft.GetOrientation(Frames.Frame.ICRF, start); Vector3.VectorY.Rotate(orientation.Rotation); } @@ -295,7 +297,7 @@ void SetInitialOrbitalParameters() Assert.True((sv.Observer as CelestialBody)?.Satellites?.Count == 1); spc.SetInitialOrbitalParameters(sv2); - Assert.True((sv.Observer as CelestialBody)?.Satellites.Count==1); + Assert.True((sv.Observer as CelestialBody)?.Satellites.Count == 1); Assert.Equal(spc, (sv.Observer as CelestialBody)?.Satellites.First()); Assert.Throws(() => spc.SetInitialOrbitalParameters(null)); } diff --git a/IO.Astrodynamics.Tests/Mission/ScenarioTests.cs b/IO.Astrodynamics.Tests/Mission/ScenarioTests.cs index 61dbcee..79488a4 100644 --- a/IO.Astrodynamics.Tests/Mission/ScenarioTests.cs +++ b/IO.Astrodynamics.Tests/Mission/ScenarioTests.cs @@ -4,6 +4,7 @@ using BenchmarkDotNet.Attributes; using IO.Astrodynamics.Body; using IO.Astrodynamics.Body.Spacecraft; +using IO.Astrodynamics.Coordinates; using IO.Astrodynamics.Maneuver; using IO.Astrodynamics.Math; using IO.Astrodynamics.Mission; @@ -164,6 +165,113 @@ public void Propagate() Assert.Equal(2442.7800000000002, summary.SpacecraftSummaries.First().FuelConsumption, 3); } + [Fact] + [Benchmark] + public void PropagateWithoutManeuver() + { + DateTime start = DateTimeExtension.CreateUTC(667915269.18539762).ToTDB(); + DateTime startPropagator = DateTimeExtension.CreateUTC(668085555.829810).ToTDB(); + DateTime end = DateTimeExtension.CreateUTC(668174400.000000).ToTDB(); + + Astrodynamics.Mission.Mission mission = new Astrodynamics.Mission.Mission("mission102"); + Scenario scenario = new Scenario("scn100", mission, new Window(startPropagator, end)); + scenario.AddAdditionalCelestialBody(TestHelpers.MoonAtJ2000); + + //Define parking orbit + StateVector parkingOrbit = new StateVector( + new Vector3(5056554.1874925727, 4395595.4942363985, 0.0), + new Vector3(-3708.6305608890916, 4266.2914313011433, 6736.8538488755494), TestHelpers.EarthAtJ2000, + start, Frames.Frame.ICRF); + + //Define target orbit + StateVector targetOrbit = new StateVector( + new Vector3(4390853.7278876612, 5110607.0005866792, 917659.86391987884), + new Vector3(-4979.4693432656513, 3033.2639866911495, 6933.1803797017265), TestHelpers.EarthAtJ2000, + start, Frames.Frame.ICRF); + + //Create and configure spacecraft + Clock clock = new Clock("clk1", System.Math.Pow(2.0, 16.0)); + Spacecraft spacecraft = + new Spacecraft(-1785, "DRAGONFLY32", 1000.0, 10000.0, clock, parkingOrbit); + + FuelTank fuelTank = new FuelTank("ft1", "model1", "sn1", 9000.0, 9000.0); + Engine engine = new Engine("engine1", "model1", "sn1", 450.0, 50.0, fuelTank); + spacecraft.AddFuelTank(fuelTank); + spacecraft.AddEngine(engine); + spacecraft.AddPayload(new Payload("payload1", 50.0, "pay01")); + spacecraft.AddInstrument( + new Instrument(-1785601, "CAM601", "mod1", 80.0 * IO.Astrodynamics.Constants.Deg2Rad, + InstrumentShape.Circular, Vector3.VectorZ, Vector3.VectorX, Vector3.VectorX)); + + scenario.AddSpacecraft(spacecraft); + var summary = scenario.Simulate(Constants.OutputPath); + + Assert.Equal(scenario.Window, summary.Window); + Assert.Single(summary.SpacecraftSummaries); + var maneuverWindow = summary.SpacecraftSummaries.First().ManeuverWindow; + if (maneuverWindow != null) + { + Assert.Equal(new DateTime(2021, 3, 4, 0, 32, 53, 814, DateTimeKind.Unspecified), maneuverWindow.Value.StartDate, TimeSpan.FromMilliseconds(1)); + Assert.Equal(new DateTime(2021, 3, 4, 5, 27, 13, 014, DateTimeKind.Unspecified), maneuverWindow.Value.EndDate, TimeSpan.FromMilliseconds(1)); + } + + Assert.Equal(0.0, summary.SpacecraftSummaries.First().FuelConsumption, 3); + } + + [Fact] + [Benchmark] + public void PropagateWithSite() + { + DateTime start = DateTimeExtension.CreateUTC(667915269.18539762).ToTDB(); + DateTime startPropagator = DateTimeExtension.CreateUTC(668085555.829810).ToTDB(); + DateTime end = DateTimeExtension.CreateUTC(668174400.000000).ToTDB(); + + Astrodynamics.Mission.Mission mission = new Astrodynamics.Mission.Mission("mission102"); + Scenario scenario = new Scenario("scn100", mission, new Window(startPropagator, end)); + scenario.AddAdditionalCelestialBody(TestHelpers.MoonAtJ2000); + scenario.AddSite(new Site(132, "MySite", TestHelpers.EarthAtJ2000,new Planetodetic(0.5,0.3,0.0))); + + //Define parking orbit + StateVector parkingOrbit = new StateVector( + new Vector3(5056554.1874925727, 4395595.4942363985, 0.0), + new Vector3(-3708.6305608890916, 4266.2914313011433, 6736.8538488755494), TestHelpers.EarthAtJ2000, + start, Frames.Frame.ICRF); + + //Define target orbit + StateVector targetOrbit = new StateVector( + new Vector3(4390853.7278876612, 5110607.0005866792, 917659.86391987884), + new Vector3(-4979.4693432656513, 3033.2639866911495, 6933.1803797017265), TestHelpers.EarthAtJ2000, + start, Frames.Frame.ICRF); + + //Create and configure spacecraft + Clock clock = new Clock("clk1", System.Math.Pow(2.0, 16.0)); + Spacecraft spacecraft = + new Spacecraft(-1785, "DRAGONFLY32", 1000.0, 10000.0, clock, parkingOrbit); + + FuelTank fuelTank = new FuelTank("ft1", "model1", "sn1", 9000.0, 9000.0); + Engine engine = new Engine("engine1", "model1", "sn1", 450.0, 50.0, fuelTank); + spacecraft.AddFuelTank(fuelTank); + spacecraft.AddEngine(engine); + spacecraft.AddPayload(new Payload("payload1", 50.0, "pay01")); + spacecraft.AddInstrument( + new Instrument(-1785601, "CAM601", "mod1", 80.0 * IO.Astrodynamics.Constants.Deg2Rad, + InstrumentShape.Circular, Vector3.VectorZ, Vector3.VectorX, Vector3.VectorX)); + + scenario.AddSpacecraft(spacecraft); + var summary = scenario.Simulate(Constants.OutputPath); + + Assert.Equal(scenario.Window, summary.Window); + Assert.Single(summary.SpacecraftSummaries); + var maneuverWindow = summary.SpacecraftSummaries.First().ManeuverWindow; + if (maneuverWindow != null) + { + Assert.Equal(new DateTime(2021, 3, 4, 0, 32, 53, 814, DateTimeKind.Unspecified), maneuverWindow.Value.StartDate, TimeSpan.FromMilliseconds(1)); + Assert.Equal(new DateTime(2021, 3, 4, 5, 27, 13, 014, DateTimeKind.Unspecified), maneuverWindow.Value.EndDate, TimeSpan.FromMilliseconds(1)); + } + + Assert.Equal(0.0, summary.SpacecraftSummaries.First().FuelConsumption, 3); + } + [Fact] public void Equality() { diff --git a/IO.Astrodynamics/API.cs b/IO.Astrodynamics/API.cs index 8d57c41..3d02759 100644 --- a/IO.Astrodynamics/API.cs +++ b/IO.Astrodynamics/API.cs @@ -181,7 +181,8 @@ public void PropagateSite(in Time.Window window, Surface.Site site, DirectoryInf } /// - /// Execute the scenario + /// Execute the scenario. + /// Kernels stay loaded after this execution /// /// /// @@ -195,7 +196,7 @@ public void PropagateScenario(Mission.Scenario scenario, DirectoryInfo siteDirec { API.Instance.UnloadKernels(siteDirectoryInfo); API.Instance.UnloadKernels(spacecraftDirectoryInfo); - + //Clean outputs siteDirectoryInfo.Delete(true); spacecraftDirectoryInfo.Delete(true); @@ -469,14 +470,16 @@ public void PropagateScenario(Mission.Scenario scenario, DirectoryInfo siteDirec order++; } + PropagateSpacecraftProxy(ref scenarioDto); + if (scenarioDto.HasError()) { throw new InvalidOperationException($"Scenario can't be executed : {scenarioDto.Error}"); } - - LoadKernels(siteDirectoryInfo); - LoadKernels(spacecraftDirectoryInfo); + + API.Instance.LoadKernels(siteDirectoryInfo); + API.Instance.LoadKernels(spacecraftDirectoryInfo); foreach (var maneuverResult in scenarioDto.Spacecraft.CombinedManeuvers.Where(x => x.ManeuverOrder > -1)) @@ -596,9 +599,12 @@ public void LoadKernels(FileSystemInfo path) if (path == null) throw new ArgumentNullException(nameof(path)); lock (lockObject) { - if (!LoadKernelsProxy(path.FullName)) + if (path.Exists) { - throw new InvalidOperationException($"Kernel {path.FullName} can't be loaded. You can have more details on standard output"); + if (!LoadKernelsProxy(path.FullName)) + { + throw new InvalidOperationException($"Kernel {path.FullName} can't be loaded. You can have more details on standard output"); + } } } } @@ -612,9 +618,12 @@ public void UnloadKernels(FileSystemInfo path) if (path == null) throw new ArgumentNullException(nameof(path)); lock (lockObject) { - if (!UnloadKernelsProxy(path.FullName)) + if (path.Exists) { - throw new InvalidOperationException($"Kernel {path.FullName} can't be unloaded. You can have more details on standard output"); + if (!UnloadKernelsProxy(path.FullName)) + { + throw new InvalidOperationException($"Kernel {path.FullName} can't be unloaded. You can have more details on standard output"); + } } } } @@ -881,12 +890,12 @@ public IEnumerable FindLaunchWindows(Maneuver.Launch launch, const int messageSize = 10000; List orbitalParameters = new List(); int occurences = (int)(searchWindow.Length / stepSize / messageSize); - + for (int i = 0; i <= occurences; i++) { var start = searchWindow.StartDate + i * messageSize * stepSize; - var end = start + messageSize * stepSize > searchWindow.EndDate ? searchWindow.EndDate : (start + messageSize * stepSize)-stepSize; + var end = start + messageSize * stepSize > searchWindow.EndDate ? searchWindow.EndDate : (start + messageSize * stepSize) - stepSize; var window = new Time.Window(start, end); var stateVectors = new StateVector[messageSize]; ReadEphemerisProxy(_mapper.Map(window), observer.NaifId, target.NaifId, frame.Name, diff --git a/IO.Astrodynamics/IO.Astrodynamics.nuspec b/IO.Astrodynamics/IO.Astrodynamics.nuspec index 1f6d569..fe23598 100644 --- a/IO.Astrodynamics/IO.Astrodynamics.nuspec +++ b/IO.Astrodynamics/IO.Astrodynamics.nuspec @@ -4,7 +4,7 @@ IO.Astrodynamics Sylvain Guillet Sylvain Guillet - 1.9.2 + 1.9.10 Astrodynamics framework images\dragonfly-dark-trans.png docs\README.md diff --git a/IO.Astrodynamics/Mission/Scenario.cs b/IO.Astrodynamics/Mission/Scenario.cs index b5a72f5..6e0fc9d 100644 --- a/IO.Astrodynamics/Mission/Scenario.cs +++ b/IO.Astrodynamics/Mission/Scenario.cs @@ -22,7 +22,7 @@ public class Scenario : IEquatable public DirectoryInfo SpacecraftDirectory { get; private set; } public DirectoryInfo SiteDirectory { get; private set; } - public bool IsSimulated => RootDirectory?.Exists == true && SpacecraftDirectory?.Exists == true && SiteDirectory?.Exists == true; + public bool IsSimulated => RootDirectory?.Exists == true && (SpacecraftDirectory?.Exists == true || SiteDirectory?.Exists == true); /// /// Constructor @@ -93,21 +93,26 @@ public ScenarioSummary Simulate(DirectoryInfo outputDirectory) throw new InvalidOperationException("There is nothing to simulate"); } - var rootDirectory = outputDirectory.CreateSubdirectory(this.Mission.Name).CreateSubdirectory(this.Name); - var spacecraftDirectory = rootDirectory.CreateSubdirectory("Spacecrafts"); - var siteDirectory = rootDirectory.CreateSubdirectory("Sites"); + RootDirectory = outputDirectory.CreateSubdirectory(this.Mission.Name).CreateSubdirectory(this.Name); + SpacecraftDirectory = RootDirectory.CreateSubdirectory("Spacecrafts"); + SiteDirectory = RootDirectory.CreateSubdirectory("Sites"); - API.Instance.PropagateScenario(this, siteDirectory, spacecraftDirectory); + try + { + API.Instance.PropagateScenario(this, SiteDirectory, SpacecraftDirectory); + } + finally + { + API.Instance.UnloadKernels(SiteDirectory); + API.Instance.UnloadKernels(SpacecraftDirectory); + } - ScenarioSummary scenarioSummary = new ScenarioSummary(this.Window, siteDirectory, spacecraftDirectory); + ScenarioSummary scenarioSummary = new ScenarioSummary(this.Window, SiteDirectory, SpacecraftDirectory); foreach (var spacecraft in _spacecrafts) { scenarioSummary.AddSpacecraftSummary(spacecraft.GetSummary()); } - RootDirectory = outputDirectory.CreateSubdirectory(this.Mission.Name).CreateSubdirectory(this.Name); - SpacecraftDirectory = rootDirectory.CreateSubdirectory("Spacecrafts"); - SiteDirectory = rootDirectory.CreateSubdirectory("Sites"); return scenarioSummary; } diff --git a/IO.Astrodynamics/resources/libIO.Astrodynamics.so b/IO.Astrodynamics/resources/libIO.Astrodynamics.so index 2f85301..cd7e6f7 100755 Binary files a/IO.Astrodynamics/resources/libIO.Astrodynamics.so and b/IO.Astrodynamics/resources/libIO.Astrodynamics.so differ