diff --git a/VectoCore/Exceptions/VectoExceptions.cs b/VectoCore/Exceptions/VectoExceptions.cs index 8501d66543081b9dede6ce0b6173e7e483007031..a3f8425f4a3a027a8ee61d580f74a0d812ea9a8a 100644 --- a/VectoCore/Exceptions/VectoExceptions.cs +++ b/VectoCore/Exceptions/VectoExceptions.cs @@ -2,7 +2,7 @@ namespace TUGraz.VectoCore.Exceptions { - class VectoException : Exception + public class VectoException : Exception { public VectoException(string message) : base(message) { } public VectoException(string message, Exception innerException) : base(message, innerException) { } diff --git a/VectoCore/Models/Simulation/Data/IModalDataWriter.cs b/VectoCore/Models/Simulation/Data/IModalDataWriter.cs index fa70d9e9e48c75b0beee534ec19f0ebbae83a371..d19bfb1f0ac40f49349678fb4867308706fa00f1 100644 --- a/VectoCore/Models/Simulation/Data/IModalDataWriter.cs +++ b/VectoCore/Models/Simulation/Data/IModalDataWriter.cs @@ -13,5 +13,7 @@ /// Commits the data of the current simulation step. /// </summary> void CommitSimulationStep(); + + void Finish(); } } diff --git a/VectoCore/Models/Simulation/Data/ModalDataWriter.cs b/VectoCore/Models/Simulation/Data/ModalDataWriter.cs new file mode 100644 index 0000000000000000000000000000000000000000..1bf238d03dae259d7c53755e838e89b1053e09fd --- /dev/null +++ b/VectoCore/Models/Simulation/Data/ModalDataWriter.cs @@ -0,0 +1,38 @@ +using System.Data; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Simulation.Data +{ + public class ModalDataWriter : IModalDataWriter + { + private ModalResults Data { get; set; } + + private DataRow CurrentRow { get; set; } + + public ModalDataWriter(string fileName) + { + FileName = fileName; + Data = new ModalResults(); + CurrentRow = Data.NewRow(); + } + + public string FileName { get; set; } + + public void CommitSimulationStep() + { + Data.Rows.Add(CurrentRow); + CurrentRow = Data.NewRow(); + } + + public void Finish() + { + VectoCSVFile.Write(FileName, Data); + } + + public object this[ModalResultField key] + { + get { return CurrentRow[key.GetName()]; } + set { CurrentRow[key.GetName()] = value; } + } + } +} \ No newline at end of file diff --git a/VectoCore/Models/Simulation/IVectoJob.cs b/VectoCore/Models/Simulation/IVectoJob.cs new file mode 100644 index 0000000000000000000000000000000000000000..57b45c519d302d025972c0bf532dda84e985c77d --- /dev/null +++ b/VectoCore/Models/Simulation/IVectoJob.cs @@ -0,0 +1,9 @@ +namespace TUGraz.VectoCore.Models.Simulation +{ + public interface IVectoJob + { + void Run(); + + IVehicleContainer GetContainer(); + } +} \ No newline at end of file diff --git a/VectoCore/Models/Simulation/IVectoSimulator.cs b/VectoCore/Models/Simulation/IVectoSimulator.cs new file mode 100644 index 0000000000000000000000000000000000000000..c07fb0bfc73a2bba321431681d4ec565b86e27a8 --- /dev/null +++ b/VectoCore/Models/Simulation/IVectoSimulator.cs @@ -0,0 +1,6 @@ +namespace TUGraz.VectoCore.Models.Simulation +{ + public interface IVectoSimulator + { + } +} \ No newline at end of file diff --git a/VectoCore/Models/Simulation/IVehicleContainer.cs b/VectoCore/Models/Simulation/IVehicleContainer.cs index 58f827591aa3f05704348c68e7d39379c1343dbd..999e601ae63d4d03379c49d59c2946d124e17c7a 100644 --- a/VectoCore/Models/Simulation/IVehicleContainer.cs +++ b/VectoCore/Models/Simulation/IVehicleContainer.cs @@ -6,6 +6,5 @@ namespace TUGraz.VectoCore.Models.Simulation public interface IVehicleContainer : ICockpit { void AddComponent(VectoSimulationComponent component); - } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/EngineOnlyTimeBasedVectoJob.cs b/VectoCore/Models/Simulation/Impl/EngineOnlyTimeBasedVectoJob.cs new file mode 100644 index 0000000000000000000000000000000000000000..4d3160fe26a10e47d6217056a9761e6a47e84ca2 --- /dev/null +++ b/VectoCore/Models/Simulation/Impl/EngineOnlyTimeBasedVectoJob.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using TUGraz.VectoCore.Models.Simulation.Data; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + public class EngineOnlyTimeBasedVectoJob : TimeBasedVectoJob + { + private List<EngineOnlyDrivingCycle> _cycles; + private IModalDataWriter _dataWriter; + + public EngineOnlyTimeBasedVectoJob(VehicleContainer container, List<EngineOnlyDrivingCycle> cycles, IModalDataWriter dataWriter) + : base(container) + { + _cycles = cycles; + _dataWriter = dataWriter; + } + + public override void Run() + { + var port = Container.GetEngineOnlyStartPort(); + var absTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0); + var dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0); + + foreach (var cycle in _cycles) + { + port.Request(absTime, dt, cycle.Torque, cycle.EngineSpeed); + Container.CommitSimulationStep(_dataWriter); + + absTime += dt; + } + Container.FinishSimulation(_dataWriter); + } + } +} \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/SimulationFactory.cs b/VectoCore/Models/Simulation/Impl/SimulationFactory.cs new file mode 100644 index 0000000000000000000000000000000000000000..036f2868f17263016f8f9013593bddc8f0005292 --- /dev/null +++ b/VectoCore/Models/Simulation/Impl/SimulationFactory.cs @@ -0,0 +1,29 @@ +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + public class SimulationFactory + { + public static IVectoJob CreateTimeBasedEngineOnlyJob(string engineFile, string cycleFile, string resultFile) + { + var container = new VehicleContainer(); + var engineData = CombustionEngineData.ReadFromFile(engineFile); + var engine = new CombustionEngine(container, engineData); + var gearBox = new EngineOnlyGearbox(container); + + var engineOutShaft = engine.OutShaft(); + var gearBoxInShaft = gearBox.InShaft(); + + gearBoxInShaft.Connect(engineOutShaft); + + var cycles = EngineOnlyDrivingCycle.ReadFromFile(cycleFile.ToString()); + var dataWriter = new ModalDataWriter(resultFile); + + var job = new EngineOnlyTimeBasedVectoJob(container, cycles, dataWriter); + + return job; + } + } +} \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/VectoJob.cs b/VectoCore/Models/Simulation/Impl/VectoJob.cs new file mode 100644 index 0000000000000000000000000000000000000000..023bb5dec15b1ad9d21ae3f3d69630d263e6b679 --- /dev/null +++ b/VectoCore/Models/Simulation/Impl/VectoJob.cs @@ -0,0 +1,36 @@ +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + public abstract class VectoJob : IVectoJob + { + protected VehicleContainer Container { get; set; } + + protected VectoJob(VehicleContainer container) + { + Container = container; + } + + public abstract void Run(); + public IVehicleContainer GetContainer() + { + return Container; + } + } + + public abstract class DistanceBasedVectoJob : VectoJob + { + protected DistanceBasedVectoJob(VehicleContainer container) + : base(container) + { + + } + + } + + public abstract class TimeBasedVectoJob : VectoJob + { + protected TimeBasedVectoJob(VehicleContainer container) + : base(container) + { + } + } +} \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/VectoSimulator.cs b/VectoCore/Models/Simulation/Impl/VectoSimulator.cs new file mode 100644 index 0000000000000000000000000000000000000000..d73e3ebca75e9c437d100135154826969f4ecdfd --- /dev/null +++ b/VectoCore/Models/Simulation/Impl/VectoSimulator.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + public class VectoSimulator : IVectoSimulator + { + private List<IVectoJob> _jobs = new List<IVectoJob>(); + private List<Task> _runningTasks = new List<Task>(); + + public void AddJob(IVectoJob job) + { + _jobs.Add(job); + } + + public void RunSimulation() + { + foreach (var job in _jobs) + { + var task = Task.Factory.StartNew(() => job.Run()); + _runningTasks.Add(task); + } + } + } +} \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index 01bd713b48bf9ff1e05cde492e80dbe252aa6637..9fa4eb98a2cdf54635a3bffcf7f6210a034e519a 100644 --- a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using TUGraz.VectoCore.Exceptions; +using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Simulation.Cockpit; +using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent; namespace TUGraz.VectoCore.Models.Simulation.Impl @@ -56,7 +58,25 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl { _components.Add(component); } - - + + + public ITnOutPort GetEngineOnlyStartPort() + { + //todo: find a better solution for getting the initial port in a powertrain + return (_gearbox as IGearbox).OutShaft(); + } + + public void CommitSimulationStep(IModalDataWriter dataWriter) + { + foreach (var c in _components) + { + c.CommitSimulationStep(dataWriter); + } + } + + public void FinishSimulation(IModalDataWriter dataWriter) + { + dataWriter.Finish(); + } } } diff --git a/VectoCore/VectoCore.csproj b/VectoCore/VectoCore.csproj index b8d6895b3a13ab719d04458c29badcf413cf8414..6827b10477a833031c97c8bbd516e5948dd37c29 100644 --- a/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore.csproj @@ -87,6 +87,13 @@ <Compile Include="Models\Simulation\Data\ModalResult.cs"> <SubType>Component</SubType> </Compile> + <Compile Include="Models\Simulation\Impl\EngineOnlyTimeBasedVectoJob.cs" /> + <Compile Include="Models\Simulation\IVectoJob.cs" /> + <Compile Include="Models\Simulation\IVectoSimulator.cs" /> + <Compile Include="Models\Simulation\Data\ModalDataWriter.cs" /> + <Compile Include="Models\Simulation\Impl\SimulationFactory.cs" /> + <Compile Include="Models\Simulation\Impl\VectoJob.cs" /> + <Compile Include="Models\Simulation\Impl\VectoSimulator.cs" /> <Compile Include="Models\Simulation\Impl\VehicleContainer.cs" /> <Compile Include="Models\Simulation\Cockpit\ICockpit.cs" /> <Compile Include="Models\Simulation\Cockpit\IEngineCockpit.cs" /> diff --git a/VectoCoreTest/Models/Simulation/SimulationFactoryTests.cs b/VectoCoreTest/Models/Simulation/SimulationFactoryTests.cs new file mode 100644 index 0000000000000000000000000000000000000000..6f12d0aa7e8c8dabf8e9f762d0912e38d47f276c --- /dev/null +++ b/VectoCoreTest/Models/Simulation/SimulationFactoryTests.cs @@ -0,0 +1,50 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Exceptions; + +namespace TUGraz.VectoCore.Tests.Models.Simulation +{ + [TestClass] + public class SimulationFactoryTests + { + private const string EngineFile = @"TestData\EngineOnly\EngineMaps\24t Coach.veng"; + private const string CycleFile = @"TestData\EngineOnly\Cycles\Coach Engine Only.vdri"; + + [TestMethod] + public void TestEngineOnly() + { + var job = SimulationFactory.CreateTimeBasedEngineOnlyJob(EngineFile, CycleFile, "TestEngineOnly-result.vmod"); + + var container = job.GetContainer(); + + Assert.AreEqual(560, container.EngineSpeed(), "Engine Speed"); + Assert.AreEqual(0U, container.Gear(), "Gear"); + + try + { + container.VehicleSpeed(); + Assert.Fail("Access to Vehicle speed should fail, because there should be no vehicle in EngineOnly Mode."); + } + catch (VectoException ex) + { + Assert.AreEqual(ex.Message, "no vehicle available!", "Vehicle speed wrong exception message."); + } + } + + [TestMethod] + public void TestEngineOnly_JobRun() + { + var job = SimulationFactory.CreateTimeBasedEngineOnlyJob(EngineFile, CycleFile, "TestEngineOnly-result.vmod"); + job.Run(); + } + + [TestMethod] + public void TestEngineOnly_SimulatorRun() + { + var sim = new VectoSimulator(); + var job = SimulationFactory.CreateTimeBasedEngineOnlyJob(EngineFile, CycleFile, "TestEngineOnly-result.vmod"); + sim.AddJob(job); + sim.RunSimulation(); + } + } +} diff --git a/VectoCoreTest/Utils/TestModalDataWriter.cs b/VectoCoreTest/Utils/TestModalDataWriter.cs index 1bab253151e176e25e93248fff5940ab5996abef..4718d6e2e94f6c75345d429542a1245974d04754 100644 --- a/VectoCoreTest/Utils/TestModalDataWriter.cs +++ b/VectoCoreTest/Utils/TestModalDataWriter.cs @@ -23,6 +23,11 @@ namespace TUGraz.VectoCore.Tests.Utils CurrentRow = Data.NewRow(); } + public void Finish() + { + + } + public object this[ModalResultField key] { get { return CurrentRow[key.GetName()]; } diff --git a/VectoCoreTest/VectoCoreTest.csproj b/VectoCoreTest/VectoCoreTest.csproj index 4483c5b508f8e66a5ef0cca709f3982ef140c590..6d25d042319a7efd6c891895558649e87cfd07f0 100644 --- a/VectoCoreTest/VectoCoreTest.csproj +++ b/VectoCoreTest/VectoCoreTest.csproj @@ -71,6 +71,7 @@ <Compile Include="Models\SimulationComponent\CombustionEngineTest.cs" /> <Compile Include="Models\SimulationComponent\GearboxTest.cs" /> <Compile Include="Models\SimulationComponent\WheelTest.cs" /> + <Compile Include="Models\Simulation\SimulationFactoryTests.cs" /> <Compile Include="Models\Simulation\VechicleContainerTests.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\Settings.Designer.cs">