diff --git a/VectoCommon/VectoHashing/VectoComponents.cs b/VectoCommon/VectoHashing/VectoComponents.cs index 08f873020f5144e198a9f18c8c4b7783bfc7f4af..81665bc0e7f19511112365273f643a9e5f949907 100644 --- a/VectoCommon/VectoHashing/VectoComponents.cs +++ b/VectoCommon/VectoHashing/VectoComponents.cs @@ -29,84 +29,84 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using TUGraz.VectoCommon.Resources; - -namespace TUGraz.VectoHashing -{ - public enum VectoComponents - { - Engine, - Gearbox, - Axlegear, - Retarder, - TorqueConverter, - Angledrive, - Airdrag, - Tyre, - Vehicle, - VectoOutput, - VectoCustomerInformation - } - - public static class VectoComponentsExtensionMethods - { - public static string XMLElementName(this VectoComponents component) - { - switch (component) { - case VectoComponents.Engine: - return XMLNames.Component_Engine; - case VectoComponents.Gearbox: - return XMLNames.Component_Gearbox; - case VectoComponents.Axlegear: - return XMLNames.Component_Axlegear; - case VectoComponents.Retarder: - return XMLNames.Component_Retarder; - case VectoComponents.TorqueConverter: - return XMLNames.Component_TorqueConverter; - case VectoComponents.Angledrive: - return XMLNames.Component_Angledrive; - case VectoComponents.Airdrag: - return XMLNames.Component_AirDrag; - case VectoComponents.Tyre: - return XMLNames.AxleWheels_Axles_Axle_Tyre; - case VectoComponents.Vehicle: - return XMLNames.Component_Vehicle; - case VectoComponents.VectoOutput: - return "VectoOutput"; - case VectoComponents.VectoCustomerInformation: - return "VectoCustomerInformation"; - default: - throw new ArgumentOutOfRangeException("VectoComponents", component, null); - } - } - - public static string HashIdPrefix(this VectoComponents component) - { - switch (component) { - case VectoComponents.Engine: - return "ENG-"; - case VectoComponents.Gearbox: - return "GBX-"; - case VectoComponents.Axlegear: - return "AXL-"; - case VectoComponents.Retarder: - return "RET-"; - case VectoComponents.TorqueConverter: - return "TC-"; - case VectoComponents.Angledrive: - return "ANGL-"; - case VectoComponents.Airdrag: - return "AD-"; - case VectoComponents.Tyre: - return "TYRE-"; - case VectoComponents.VectoOutput: - return "RESULT-"; - case VectoComponents.VectoCustomerInformation: - return "COC-"; - default: - throw new ArgumentOutOfRangeException("VectoComponents", component, null); - } - } - } +using System; +using TUGraz.VectoCommon.Resources; + +namespace TUGraz.VectoHashing +{ + public enum VectoComponents + { + Engine, + Gearbox, + Axlegear, + Retarder, + TorqueConverter, + Angledrive, + Airdrag, + Tyre, + Vehicle, + VectoOutput, + VectoCustomerInformation + } + + public static class VectoComponentsExtensionMethods + { + public static string XMLElementName(this VectoComponents component) + { + switch (component) { + case VectoComponents.Engine: + return XMLNames.Component_Engine; + case VectoComponents.Gearbox: + return XMLNames.Component_Gearbox; + case VectoComponents.Axlegear: + return XMLNames.Component_Axlegear; + case VectoComponents.Retarder: + return XMLNames.Component_Retarder; + case VectoComponents.TorqueConverter: + return XMLNames.Component_TorqueConverter; + case VectoComponents.Angledrive: + return XMLNames.Component_Angledrive; + case VectoComponents.Airdrag: + return XMLNames.Component_AirDrag; + case VectoComponents.Tyre: + return XMLNames.AxleWheels_Axles_Axle_Tyre; + case VectoComponents.Vehicle: + return XMLNames.Component_Vehicle; + case VectoComponents.VectoOutput: + return "VectoOutput"; + case VectoComponents.VectoCustomerInformation: + return "VectoCustomerInformation"; + default: + throw new ArgumentOutOfRangeException("VectoComponents", component, null); + } + } + + public static string HashIdPrefix(this VectoComponents component) + { + switch (component) { + case VectoComponents.Engine: + return "ENG-"; + case VectoComponents.Gearbox: + return "GBX-"; + case VectoComponents.Axlegear: + return "AXL-"; + case VectoComponents.Retarder: + return "RET-"; + case VectoComponents.TorqueConverter: + return "TC-"; + case VectoComponents.Angledrive: + return "ANGL-"; + case VectoComponents.Airdrag: + return "AD-"; + case VectoComponents.Tyre: + return "TYRE-"; + case VectoComponents.VectoOutput: + return "RESULT-"; + case VectoComponents.VectoCustomerInformation: + return "COC-"; + default: + throw new ArgumentOutOfRangeException("VectoComponents", component, null); + } + } + } } \ No newline at end of file diff --git a/VectoCommon/VectoHashing/VectoHash.cs b/VectoCommon/VectoHashing/VectoHash.cs index 67a8b759a69f2e1adf5d90bbc735f4e789e139a7..22a0d468df16149266d70a1a0ad9008ca45826d6 100644 --- a/VectoCommon/VectoHashing/VectoHash.cs +++ b/VectoCommon/VectoHashing/VectoHash.cs @@ -155,44 +155,27 @@ namespace TUGraz.VectoHashing public XDocument AddHash() { - if (Document.DocumentElement == null) { - throw new Exception("invalid input document"); - } - IList<VectoComponents> components; - if (Document.DocumentElement.LocalName.Equals(XMLNames.VectoInputDeclaration)) { - components = GetContainigComponents(); - if (components.Contains(VectoComponents.Vehicle)) { - throw new Exception("adding hash for Vehicle is not supported"); - } - if (components.Count > 1) { - throw new Exception("input must not contain multiple components!"); - } - if (components.Count == 0) { - throw new Exception("input does not contain a known component!"); - } - } else if (Document.DocumentElement.LocalName.Equals("VectoOutput")) { - components = new List<VectoComponents>() { VectoComponents.VectoOutput }; - } else if (Document.DocumentElement.LocalName.Equals("VectoCustomerInformation")) { - components = new List<VectoComponents>() { VectoComponents.VectoCustomerInformation }; - } else { - throw new Exception("unknown document structure! neither input data nor output data format"); - } - var query = string.Format("//*[local-name()='{0}']/*[local-name()='Data']", components[0].XMLElementName()); + var component = GetComponentToHash(); + var query = string.Format("//*[local-name()='{0}']/*[local-name()='Data']", component.XMLElementName()); var node = Document.SelectSingleNode(query); if (node == null) { - throw new Exception(string.Format("'Data' element for component '{0}' not found!", components[0].XMLElementName())); + throw new Exception(string.Format("'Data' element for component '{0}' not found!", component.XMLElementName())); } - query = string.Format("//*[local-name()='{0}']/*[local-name()='Signature']", components[0].XMLElementName()); + query = string.Format("//*[local-name()='{0}']/*[local-name()='Signature']", component.XMLElementName()); var sigNodes = Document.SelectNodes(query); if (sigNodes != null && sigNodes.Count > 0) { throw new Exception("input data already contains a signature element"); } var attributes = node.Attributes; - var id = components[0].HashIdPrefix() + Guid.NewGuid().ToString("n").Substring(0, 20); + var id = component.HashIdPrefix() + Guid.NewGuid().ToString("n").Substring(0, 20); var idSet = false; if (attributes != null && attributes[XMLNames.Component_ID_Attr] != null) { - attributes[XMLNames.Component_ID_Attr].Value = id; + if (attributes[XMLNames.Component_ID_Attr].Value.Length < 5) { + attributes[XMLNames.Component_ID_Attr].Value = id; + } else { + id = attributes[XMLNames.Component_ID_Attr].Value; + } idSet = true; } if (!idSet) { @@ -204,6 +187,16 @@ namespace TUGraz.VectoHashing node.Attributes.Append(attr); } + query = component == VectoComponents.VectoCustomerInformation || component == VectoComponents.VectoOutput + ? string.Format("*/*[local-name()='Data']/*[local-name()='ApplicationInformation']/*[local-name()='Date']") + : string.Format("*/*[local-name()='{0}']/*/*[local-name()='Date']", component); + var dateNode = Document.SelectSingleNode(query); + if (dateNode == null) { + throw new Exception("Date-Element not found in input!"); + } + dateNode.FirstChild.Value = XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc); + + var hash = XMLHashProvider.ComputeHash(Document, id); var sig = Document.CreateElement(XMLNames.DI_Signature, node.NamespaceURI); @@ -215,6 +208,33 @@ namespace TUGraz.VectoHashing return Document.ToXDocument(); } + private VectoComponents GetComponentToHash() + { + if (Document.DocumentElement == null) { + throw new Exception("invalid input document"); + } + if (Document.DocumentElement.LocalName.Equals(XMLNames.VectoInputDeclaration)) { + var components = GetContainigComponents(); + if (components.Contains(VectoComponents.Vehicle)) { + throw new Exception("adding hash for Vehicle is not supported"); + } + if (components.Count > 1) { + throw new Exception("input must not contain multiple components!"); + } + if (components.Count == 0) { + throw new Exception("input does not contain a known component!"); + } + return components.First(); + } + if (Document.DocumentElement.LocalName.Equals("VectoOutput")) { + return VectoComponents.VectoOutput; + } + if (Document.DocumentElement.LocalName.Equals("VectoCustomerInformation")) { + return VectoComponents.VectoCustomerInformation; + } + throw new Exception("unknown document structure! neither input data nor output data format"); + } + public string ReadHash() { var nodes = Document.SelectNodes(GetComponentQueryString()); diff --git a/VectoCommon/VectoHashingTest/VectoHashTest.cs b/VectoCommon/VectoHashingTest/VectoHashTest.cs index a38bbeacaa4f12c341bbeb90019ade3c44ff749a..8075dc91655b067f4993c1552c13226721c937ed 100644 --- a/VectoCommon/VectoHashingTest/VectoHashTest.cs +++ b/VectoCommon/VectoHashingTest/VectoHashTest.cs @@ -36,6 +36,7 @@ using System.Text; using System.Xml; using System.Xml.Linq; using System.Xml.Schema; +using System.Xml.XPath; using NUnit.Framework; using TUGraz.VectoCore.Utils; using TUGraz.VectoHashing; @@ -276,6 +277,67 @@ namespace VectoHashingTest Assert.IsTrue(h2.ValidateHash()); } + [TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml", 5), + TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml", 10), + TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml", 15), + TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml", 20), + ] + public void TestAddHashoDoNotOverwriteID(string file, int idLength) + { + var newid = "x" + Guid.NewGuid().ToString("n").Substring(0, idLength - 1); + var input = new XmlDocument(); + input.Load(file); + var data = input.SelectSingleNode("//*[local-name()='Data']"); + data.Attributes["id"].Value = newid; + + var h = VectoHash.Load(input); + var r = h.AddHash(); + + var id = r.XPathSelectElement("//*[local-name()='Data']"); + Assert.IsNotNull(id.Attribute("id")); + Assert.AreEqual(newid, id.Attribute("id").Value); + } + + [TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml", 2), + TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml", 3), + TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml", 4)] + public void TestAddHashoDoOverwriteID(string file, int idLength) + { + var newid = "x" + Guid.NewGuid().ToString("n").Substring(0, idLength - 1); + var input = new XmlDocument(); + input.Load(file); + var data = input.SelectSingleNode("//*[local-name()='Data']"); + data.Attributes["id"].Value = newid; + + var h = VectoHash.Load(input); + var r = h.AddHash(); + + var id = r.XPathSelectElement("//*[local-name()='Data']"); + Assert.IsNotNull(id.Attribute("id")); + Assert.AreNotEqual(newid, id.Attribute("id").Value); + } + + [TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml")] + public void TestReplaceDate(string file) + { + var input = new XmlDocument(); + input.Load(file); + var dateNode = input.SelectSingleNode("//*[local-name()='Date']"); + var date = XmlConvert.ToDateTime(dateNode.FirstChild.Value); + + var h = VectoHash.Load(input); + var r = h.AddHash(); + + var newDateNode = r.XPathSelectElement("//*[local-name()='Date']"); + var newDate = XmlConvert.ToDateTime(newDateNode.Value); + + var now = DateTime.Now; + + Assert.AreNotEqual(date.ToString(), newDate.ToString()); + Assert.IsTrue(now - date > new TimeSpan(0, 0, 0, 1)); + Assert.IsTrue(now - newDate < new TimeSpan(0, 0, 0, 1)); + } + [TestCase(@"Testdata\XML\ToHash\vecto_engine_withhash-input.xml", "input data already contains a signature element"), TestCase(@"Testdata\XML\ToHash\vecto_vehicle-sample.xml", "adding hash for Vehicle is not supported"), TestCase(@"Testdata\XML\ToHash\vecto_gearbox-input_nodata.xml", "'Data' element for component 'Gearbox' not found!"), diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs index 201451de671cc15783395728810412506986e909..75d495f288d41927c7a0715de7138c1a106f1c14 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs @@ -131,7 +131,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl _segment.VehicleClass), InputDataHash = InputDataProvider.XMLHash }; - Report.InitializeReport(powertrainConfig, _segment); + Report.InitializeReport(powertrainConfig); } public IEnumerable<VectoRunData> NextRun() diff --git a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs index 83f67a12679fe968c8b94cb4cd8e7e0f9f8ef023..a37cd3514b0fcad6f16b795a2cdec4b758cd1022 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs @@ -101,6 +101,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Data public XElement InputDataHash { get; internal set; } + public int JobRunId { get; internal set; } + public class AuxData { // ReSharper disable once InconsistentNaming diff --git a/VectoCore/VectoCore/Models/Simulation/IVectoRun.cs b/VectoCore/VectoCore/Models/Simulation/IVectoRun.cs index aba7fae6fdb8acf583747a8ddf9d7bc5a0b87a42..03be4c1749e8acda9447c2004fdc33f9166972c9 100644 --- a/VectoCore/VectoCore/Models/Simulation/IVectoRun.cs +++ b/VectoCore/VectoCore/Models/Simulation/IVectoRun.cs @@ -51,6 +51,11 @@ namespace TUGraz.VectoCore.Models.Simulation /// </summary> int RunIdentifier { get; } + /// <summary> + /// identifier of a simulation run within a job + /// </summary> + int JobRunIdentifier { get; } + string RunName { get; } string CycleName { get; } diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/DistanceRun.cs b/VectoCore/VectoCore/Models/Simulation/Impl/DistanceRun.cs index cd8a1d8182426e525aa4950338a181730f1d2127..9daf59e0c110bc4ebf1ff5902c7c49da6f088ba1 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/DistanceRun.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/DistanceRun.cs @@ -29,64 +29,64 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Simulation.Impl -{ - public class DistanceRun : VectoRun - { - public DistanceRun(IVehicleContainer container) : base(container) {} - - protected override IResponse DoSimulationStep() - { - IterationStatistics.StartIteration(); - - // estimate distance to be traveled within the next TargetTimeInterval - var ds = Container.VehicleSpeed.IsEqual(0) - ? Constants.SimulationSettings.DriveOffDistance - : Constants.SimulationSettings.TargetTimeInterval * Container.VehicleSpeed; - - var loopCount = 0; - IResponse response; - do { - IterationStatistics.Increment(this, "Iterations"); - - Container.BrakePower = 0.SI<Watt>(); - response = CyclePort.Request(AbsTime, ds); - response.Switch(). - Case<ResponseSuccess>(r => { dt = r.SimulationInterval; }). - Case<ResponseDrivingCycleDistanceExceeded>(r => { - if (r.MaxDistance.IsSmallerOrEqual(0)) { - throw new VectoSimulationException("DistanceExceeded, MaxDistance is invalid: {0}", r.MaxDistance); - } - ds = r.MaxDistance; - }). - Case<ResponseCycleFinished>(r => { - FinishedWithoutErrors = true; - Log.Info("========= Driving Cycle Finished"); - }). - Default(r => { throw new VectoException("DistanceRun got an unexpected response: {0}", r); }); - if (loopCount++ > Constants.SimulationSettings.MaximumIterationCountForSimulationStep) { - throw new VectoSimulationException("Maximum iteration count for a single simulation interval reached! Aborting!"); - } - } while (!(response is ResponseSuccess || response is ResponseCycleFinished)); - - IterationStatistics.Increment(this, "Distance", Container.Distance.Value()); - IterationStatistics.Increment(this, "Time", AbsTime.Value()); - IterationStatistics.FinishIteration(AbsTime); - response.AbsTime = AbsTime; - return response; - } - - protected override IResponse Initialize() - { - Log.Info("Starting {0}", RunIdentifier); - return CyclePort.Initialize(); - } - } +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + public class DistanceRun : VectoRun + { + public DistanceRun(IVehicleContainer container) : base(container) {} + + protected override IResponse DoSimulationStep() + { + IterationStatistics.StartIteration(); + + // estimate distance to be traveled within the next TargetTimeInterval + var ds = Container.VehicleSpeed.IsEqual(0) + ? Constants.SimulationSettings.DriveOffDistance + : Constants.SimulationSettings.TargetTimeInterval * Container.VehicleSpeed; + + var loopCount = 0; + IResponse response; + do { + IterationStatistics.Increment(this, "Iterations"); + + Container.BrakePower = 0.SI<Watt>(); + response = CyclePort.Request(AbsTime, ds); + response.Switch(). + Case<ResponseSuccess>(r => { dt = r.SimulationInterval; }). + Case<ResponseDrivingCycleDistanceExceeded>(r => { + if (r.MaxDistance.IsSmallerOrEqual(0)) { + throw new VectoSimulationException("DistanceExceeded, MaxDistance is invalid: {0}", r.MaxDistance); + } + ds = r.MaxDistance; + }). + Case<ResponseCycleFinished>(r => { + FinishedWithoutErrors = true; + Log.Info("========= Driving Cycle Finished"); + }). + Default(r => { throw new VectoException("DistanceRun got an unexpected response: {0}", r); }); + if (loopCount++ > Constants.SimulationSettings.MaximumIterationCountForSimulationStep) { + throw new VectoSimulationException("Maximum iteration count for a single simulation interval reached! Aborting!"); + } + } while (!(response is ResponseSuccess || response is ResponseCycleFinished)); + + IterationStatistics.Increment(this, "Distance", Container.Distance.Value()); + IterationStatistics.Increment(this, "Time", AbsTime.Value()); + IterationStatistics.FinishIteration(AbsTime); + response.AbsTime = AbsTime; + return response; + } + + protected override IResponse Initialize() + { + Log.Info("Starting {0}", RunIdentifier); + return CyclePort.Initialize(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs index 39f257b9139e565522136b35194128c4ac6aa2d0..ca76f42a5e23ddc60eab616008b978639420bd1c 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs @@ -137,11 +137,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public void WaitFinished() { - try { - Task.WaitAll(Runs.Select(r => r.RunTask).ToArray()); - } catch (Exception) { - // ignored - } + Task.WaitAll(Runs.Select(r => r.RunTask).ToArray()); } [MethodImpl(MethodImplOptions.Synchronized)] @@ -162,6 +158,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl return Runs.ToDictionary( r => r.Run.RunIdentifier, r => new ProgressEntry { + RunId = r.Run.RunIdentifier, + JobRunId = r.Run.JobRunIdentifier, RunName = r.Run.RunName, CycleName = r.Run.CycleName, RunSuffix = r.Run.RunSuffix, @@ -176,14 +174,27 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public class ProgressEntry { + // unique identifier of the simulation run + public int RunId; + // job-local identifier of the simulation run + public int JobRunId; + public string RunName; + public double Progress; + public double ExecTime; + public Exception Error; + public bool Canceled; + public bool Success; + public bool Done; + public string CycleName; + public string RunSuffix; } @@ -208,12 +219,14 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl } catch (Exception ex) { Log.Error(ex, "Error during simulation run!"); ExecException = ex; + throw; + } finally { + stopWatch.Stop(); + Success = Run.FinishedWithoutErrors && ExecException == null; + Done = true; + ExecTime = stopWatch.Elapsed.TotalMilliseconds; + JobContainer.JobCompleted(); } - stopWatch.Stop(); - Success = Run.FinishedWithoutErrors && ExecException == null; - Done = true; - ExecTime = stopWatch.Elapsed.TotalMilliseconds; - JobContainer.JobCompleted(); }); } diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs index 2c395c3bdecff8629c84e037a59256f356582539..11c557e304aaee0106ab38126b6930bbddd7635e 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs @@ -137,8 +137,6 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public IEnumerable<IVectoRun> SimulationRuns() { var i = 0; - - var warning1Hz = false; foreach (var data in DataReader.NextRun()) { @@ -148,6 +146,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl Log.Error("Output filter for 1Hz results is only available for distance-based cycles!"); warning1Hz = true; } + var current = i++; + data.JobRunId = current; IModalDataContainer modContainer = new ModalDataContainer(data, ModWriter, addReportResult: _mode == ExecutionMode.Declaration ? addReportResult : null, @@ -156,7 +156,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl WriteAdvancedAux = data.AdvancedAux != null && data.AdvancedAux.AuxiliaryAssembly == AuxiliaryModel.Advanced, WriteModalResults = _mode != ExecutionMode.Declaration || WriteModalResults }; - var current = i++; + var builder = new PowertrainBuilder(modContainer, modData => { if (SumData != null) { SumData.Write(modData, JobNumber, current, d); diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs index 635110268b2f5d2a67744421a16dc4430cbfeb0e..044834a701c44473ff16645ed27c67fcec90cff3 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs @@ -29,173 +29,178 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.ComponentModel.DataAnnotations; -using System.Threading; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Simulation.Impl -{ - /// <summary> - /// Simulator for one vecto simulation job. - /// </summary> - public abstract class VectoRun : LoggingObject, IVectoRun - { - private static int _runIdCounter; - - protected Second AbsTime = 0.SI<Second>(); - // ReSharper disable once InconsistentNaming - protected Second dt = 1.SI<Second>(); - private bool _cancelled; - protected ISimulationOutPort CyclePort { get; set; } - - [Required, ValidateObject] - protected IVehicleContainer Container { get; set; } - - public bool FinishedWithoutErrors { get; protected set; } - - public int RunIdentifier { get; protected set; } - - public string RunName - { - get { return Container.RunData.JobName; } - } - - public string CycleName - { - get { return Container.RunData.Cycle.Name; } - } - - public string RunSuffix - { - get { return Container.RunData.ModFileSuffix; } - } - - public double Progress - { - get { return CyclePort.Progress; } - } - - protected VectoRun(IVehicleContainer container) - { - Container = container; - RunIdentifier = Interlocked.Increment(ref _runIdCounter); - Container.RunStatus = Status.Pending; - CyclePort = container.GetCycleOutPort(); - } - - public IVehicleContainer GetContainer() - { - return Container; - } - - public void Run() - { - var debug = new DebugData(); - - Log.Info("VectoJob started running."); - - Container.AbsTime = AbsTime; - - Initialize(); - try { - IResponse response; - do { - response = DoSimulationStep(); - debug.Add(response); - if (response is ResponseSuccess) { - Container.CommitSimulationStep(AbsTime, dt); - AbsTime += dt; - if (_cancelled) { - Log.Error("Run canceled!"); - Container.RunStatus = Status.Canceled; - Container.FinishSimulationRun(); - return; - } - Container.AbsTime = AbsTime; - } - } while (response is ResponseSuccess); - } catch (VectoSimulationException vse) { - Log.Error("SIMULATION RUN ABORTED! ========================"); - Log.Error(vse); - Container.RunStatus = Status.Aborted; - var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", - vse,AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), - vse.Message, RunIdentifier, CycleName, RunSuffix); - Container.FinishSimulationRun(ex); - throw ex; - } catch (VectoException ve) { - Log.Error("SIMULATION RUN ABORTED! ========================"); - Log.Error(ve); - Container.RunStatus = Status.Aborted; - var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", - ve, - AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), ve.Message, - RunIdentifier, CycleName, RunSuffix); - try { - Container.FinishSimulationRun(ex); - } catch (Exception ve2) { - ve = new VectoException("Multiple Exceptions occured.", - new AggregateException(ve, new VectoException("Exception during finishing Simulation.", ve2))); - throw ve; - } - throw ex; - } catch (Exception e) { - Log.Error("SIMULATION RUN ABORTED! ========================"); - Log.Error(e); - Container.RunStatus = Status.Aborted; - - var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", - e, AbsTime, - Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), e.Message, - RunIdentifier, CycleName, RunSuffix); - Container.FinishSimulationRun(ex); - throw ex; - } - Container.RunStatus = Progress < 1 ? Status.Aborted : Status.Success; - Container.FinishSimulationRun(); - if (Progress.IsSmaller(1, 1e-9)) { - throw new VectoSimulationException( - "{5} ({6} {7}) Progress: {8} - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4}", - AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), RunIdentifier, CycleName, - RunSuffix, Progress); - } - IterationStatistics.FinishSimulation(RunName + CycleName + RunSuffix + RunIdentifier); - - Log.Info("VectoJob finished."); - } - - public void Cancel() - { - _cancelled = true; - } - - private static object TryCatch(Func<object> action) - { - try { - return action(); - } catch (VectoException e) { - LogManager.GetLogger(typeof(VectoRun).FullName).Info(e); - return null; - } - } - - protected abstract IResponse DoSimulationStep(); - - protected abstract IResponse Initialize(); - - public enum Status - { - Pending, - Running, - Success, - Canceled, - Aborted, - } - } +using System; +using System.ComponentModel.DataAnnotations; +using System.Threading; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + /// <summary> + /// Simulator for one vecto simulation job. + /// </summary> + public abstract class VectoRun : LoggingObject, IVectoRun + { + private static int _runIdCounter; + + protected Second AbsTime = 0.SI<Second>(); + // ReSharper disable once InconsistentNaming + protected Second dt = 1.SI<Second>(); + private bool _cancelled; + protected ISimulationOutPort CyclePort { get; set; } + + [Required, ValidateObject] + protected IVehicleContainer Container { get; set; } + + public bool FinishedWithoutErrors { get; protected set; } + + public int RunIdentifier { get; protected set; } + + public string RunName + { + get { return Container.RunData.JobName; } + } + + public string CycleName + { + get { return Container.RunData.Cycle.Name; } + } + + public string RunSuffix + { + get { return Container.RunData.ModFileSuffix; } + } + + public int JobRunIdentifier + { + get { return Container.RunData.JobRunId; } + } + + public double Progress + { + get { return CyclePort.Progress; } + } + + protected VectoRun(IVehicleContainer container) + { + Container = container; + RunIdentifier = Interlocked.Increment(ref _runIdCounter); + Container.RunStatus = Status.Pending; + CyclePort = container.GetCycleOutPort(); + } + + public IVehicleContainer GetContainer() + { + return Container; + } + + public void Run() + { + var debug = new DebugData(); + + Log.Info("VectoJob started running."); + + Container.AbsTime = AbsTime; + + Initialize(); + try { + IResponse response; + do { + response = DoSimulationStep(); + debug.Add(response); + if (response is ResponseSuccess) { + Container.CommitSimulationStep(AbsTime, dt); + AbsTime += dt; + if (_cancelled) { + Log.Error("Run canceled!"); + Container.RunStatus = Status.Canceled; + Container.FinishSimulationRun(); + return; + } + Container.AbsTime = AbsTime; + } + } while (response is ResponseSuccess); + } catch (VectoSimulationException vse) { + Log.Error("SIMULATION RUN ABORTED! ========================"); + Log.Error(vse); + Container.RunStatus = Status.Aborted; + var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", + vse, AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), + vse.Message, RunIdentifier, CycleName, RunSuffix); + Container.FinishSimulationRun(ex); + throw ex; + } catch (VectoException ve) { + Log.Error("SIMULATION RUN ABORTED! ========================"); + Log.Error(ve); + Container.RunStatus = Status.Aborted; + var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", + ve, + AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), ve.Message, + RunIdentifier, CycleName, RunSuffix); + try { + Container.FinishSimulationRun(ex); + } catch (Exception ve2) { + ve = new VectoException("Multiple Exceptions occured.", + new AggregateException(ve, new VectoException("Exception during finishing Simulation.", ve2))); + throw ve; + } + throw ex; + } catch (Exception e) { + Log.Error("SIMULATION RUN ABORTED! ========================"); + Log.Error(e); + Container.RunStatus = Status.Aborted; + + var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", + e, AbsTime, + Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), e.Message, + RunIdentifier, CycleName, RunSuffix); + Container.FinishSimulationRun(ex); + throw ex; + } + Container.RunStatus = Progress < 1 ? Status.Aborted : Status.Success; + Container.FinishSimulationRun(); + if (Progress.IsSmaller(1, 1e-9)) { + throw new VectoSimulationException( + "{5} ({6} {7}) Progress: {8} - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4}", + AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), RunIdentifier, CycleName, + RunSuffix, Progress); + } + IterationStatistics.FinishSimulation(RunName + CycleName + RunSuffix + RunIdentifier); + + Log.Info("VectoJob finished."); + } + + public void Cancel() + { + _cancelled = true; + } + + private static object TryCatch(Func<object> action) + { + try { + return action(); + } catch (VectoException e) { + LogManager.GetLogger(typeof(VectoRun).FullName).Info(e); + return null; + } + } + + protected abstract IResponse DoSimulationStep(); + + protected abstract IResponse Initialize(); + + public enum Status + { + Pending, + Running, + Success, + Canceled, + Aborted, + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index 5a15388371dc50ea5cebbeebb8c193294e4cc58c..a0968b24da150ad4e5d34e35fb3e8245bd159230 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -29,412 +29,412 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Simulation.Impl -{ - public sealed class VehicleContainer : LoggingObject, IVehicleContainer - { - private List<Tuple<int, VectoSimulationComponent>> _components = - new List<Tuple<int, VectoSimulationComponent>>(); - - internal IEngineInfo Engine; - internal IGearboxInfo Gearbox; - internal IAxlegearInfo Axlegear; - internal IVehicleInfo Vehicle; - internal IBrakes Brakes; - internal IWheelsInfo Wheels; - internal IDriverInfo Driver; - - internal IMileageCounter MilageCounter; - - internal IClutchInfo Clutch; - - internal IDrivingCycleInfo DrivingCycle; - - internal ISimulationOutPort Cycle; - - internal IModalDataContainer ModData; - - internal WriteSumData WriteSumData; - - #region IGearCockpit - - public GearboxType GearboxType - { - get { return Gearbox == null ? GearboxType.MT : Gearbox.GearboxType; } - } - - public uint Gear - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - if (Gearbox == null) { - return 0; // throw new VectoException("no gearbox available!"); - } - return Gearbox.Gear; - } - } - - public MeterPerSecond StartSpeed - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - if (Gearbox == null) { - throw new VectoException("No Gearbox available. StartSpeed unkown"); - } - return Gearbox.StartSpeed; - } - } - - public MeterPerSquareSecond StartAcceleration - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - if (Gearbox == null) { - throw new VectoException("No Gearbox available. StartAcceleration unknown."); - } - return Gearbox.StartAcceleration; - } - } - - public Watt GearboxLoss() - { - return Gearbox.GearboxLoss(); - } - - public Second LastShift - { - get { return Gearbox.LastShift; } - } - - public GearData GetGearData(uint gear) - { - return Gearbox.GetGearData(gear); - } - - public GearInfo NextGear - { - get { return Gearbox.NextGear; } - } - - public Second TractionInterruption - { - get { return Gearbox.TractionInterruption; } - } - - public uint NumGears - { - get { return Gearbox.NumGears; } - } - - #endregion - - #region IEngineCockpit - - public PerSecond EngineSpeed - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - if (Engine == null) { - throw new VectoException("no engine available!"); - } - return Engine.EngineSpeed; - } - } - - public NewtonMeter EngineTorque - { - get { return Engine.EngineTorque; } - } - - public Watt EngineStationaryFullPower(PerSecond angularSpeed) - { - return Engine.EngineStationaryFullPower(angularSpeed); - } - - public Watt EngineDragPower(PerSecond angularSpeed) - { - return Engine.EngineDragPower(angularSpeed); - } - - public PerSecond EngineIdleSpeed - { - get { return Engine.EngineIdleSpeed; } - } - - public PerSecond EngineRatedSpeed - { - get { return Engine.EngineRatedSpeed; } - } - - public PerSecond EngineN95hSpeed - { - get { return Engine.EngineN95hSpeed; } - } - - public PerSecond EngineN80hSpeed - { - get { return Engine.EngineN80hSpeed; } - } - - #endregion - - #region IVehicleCockpit - - public MeterPerSecond VehicleSpeed - { - get { return Vehicle != null ? Vehicle.VehicleSpeed : 0.SI<MeterPerSecond>(); } - } - - public Kilogram VehicleMass - { - get { return Vehicle != null ? Vehicle.VehicleMass : 0.SI<Kilogram>(); } - } - - public Kilogram VehicleLoading - { - get { return Vehicle != null ? Vehicle.VehicleLoading : 0.SI<Kilogram>(); } - } - - public Kilogram TotalMass - { - get { return Vehicle != null ? Vehicle.TotalMass : 0.SI<Kilogram>(); } - } - - public CubicMeter CargoVolume - { - get { return Vehicle != null ? Vehicle.CargoVolume : 0.SI<CubicMeter>(); } - } - - public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) - { - return Vehicle.AirDragResistance(previousVelocity, nextVelocity); - } - - public Newton RollingResistance(Radian gradient) - { - return Vehicle.RollingResistance(gradient); - } - - public Newton SlopeResistance(Radian gradient) - { - return Vehicle.SlopeResistance(gradient); - } - - #endregion - - public VehicleContainer(ExecutionMode executionMode, IModalDataContainer modData = null, - WriteSumData writeSumData = null) - { - ModData = modData; - WriteSumData = writeSumData ?? delegate { }; - ExecutionMode = executionMode; - } - - #region IVehicleContainer - - public IModalDataContainer ModalData - { - get { return ModData; } - } - - public ISimulationOutPort GetCycleOutPort() - { - return Cycle; - } - - public FuelType FuelType - { - get { return ModData.FuelData.FuelType; } - } - - public Second AbsTime { get; set; } - - public void AddComponent(VectoSimulationComponent component) - { - var commitPriority = 0; - - component.Switch() - .If<IEngineInfo>(c => { - Engine = c; - commitPriority = 2; - }) - .If<IDriverInfo>(c => Driver = c) - .If<IGearboxInfo>(c => { - Gearbox = c; - commitPriority = 4; - }) - .If<IAxlegearInfo>(c => Axlegear = c) - .If<IWheelsInfo>(c => Wheels = c) - .If<IVehicleInfo>(c => { - Vehicle = c; - commitPriority = 5; - }) - .If<ISimulationOutPort>(c => Cycle = c) - .If<IMileageCounter>(c => MilageCounter = c) - .If<IBrakes>(c => Brakes = c) - .If<IClutchInfo>(c => Clutch = c) - .If<IDrivingCycleInfo>(c => { - DrivingCycle = c; - commitPriority = 6; - }) - .If<PTOCycleController>(c => { commitPriority = 99; }); - - _components.Add(Tuple.Create(commitPriority, component)); - _components = _components.OrderBy(x => x.Item1).Reverse().ToList(); - } - - public void CommitSimulationStep(Second time, Second simulationInterval) - { - Log.Info("VehicleContainer committing simulation. time: {0}, dist: {1}, speed: {2}", time, - Distance, VehicleSpeed); - - - foreach (var component in _components) { - component.Item2.CommitSimulationStep(ModData); - } - - if (ModData != null) { - ModData[ModalResultField.drivingBehavior] = DriverBehavior; - ModData[ModalResultField.time] = time + simulationInterval / 2; - ModData[ModalResultField.simulationInterval] = simulationInterval; - ModData.CommitSimulationStep(); - } - } - - public void FinishSimulationRun(Exception e = null) - { - Log.Info("VehicleContainer finishing simulation."); - ModData.Finish(RunStatus); - - WriteSumData(ModData); - - ModData.FinishSimulation(e); - DrivingCycle.FinishSimulation(); - } - - public void FinishSimulation() - { - throw new NotImplementedException(); - } - - public VectoRun.Status RunStatus { get; set; } - - #endregion - - public IReadOnlyCollection<VectoSimulationComponent> SimulationComponents() - { - return new ReadOnlyCollection<VectoSimulationComponent>(_components.Select(x => x.Item2).ToList()); - } - - public Meter Distance - { - get { - if (MilageCounter == null) { - Log.Warn("No MileageCounter in VehicleContainer. Distance cannot be measured."); - return 0.SI<Meter>(); - } - return MilageCounter.Distance; - } - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) - { - return DrivingCycle.LookAhead(lookaheadDistance); - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) - { - return DrivingCycle.LookAhead(time); - } - - - public Watt BrakePower - { - get { return Brakes.BrakePower; } - set { Brakes.BrakePower = value; } - } - - public bool ClutchClosed(Second absTime) - { - if (Clutch == null) { - Log.Warn("No Clutch in VehicleContainer. ClutchClosed set to constant true!"); - return true; - } - return Clutch.ClutchClosed(absTime); - } - - public bool VehicleStopped - { - get { return Vehicle.VehicleStopped; } - } - - public DrivingBehavior DriverBehavior - { - get { return Driver != null ? Driver.DriverBehavior : DrivingBehavior.Driving; } - } - - public MeterPerSquareSecond DriverAcceleration - { - get { return Driver != null ? Driver.DriverAcceleration : 0.SI<MeterPerSquareSecond>(); } - } - - public Meter CycleStartDistance - { - get { return DrivingCycle == null ? 0.SI<Meter>() : DrivingCycle.CycleStartDistance; } - } - - public VectoRunData RunData { get; set; } - public ExecutionMode ExecutionMode { get; set; } - - public CycleData CycleData - { - get { return DrivingCycle.CycleData; } - } - - public bool PTOActive - { - get { return DrivingCycle.PTOActive; } - } - - public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) - { - return DrivingCycle.CycleLookAhead(distance); - } - - public Meter Altitude - { - get { return DrivingCycle.Altitude; } - } - - public Watt AxlegearLoss() - { - return Axlegear.AxlegearLoss(); - } - - public Kilogram ReducedMassWheels - { - get { return Wheels.ReducedMassWheels; } - } - } +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + public sealed class VehicleContainer : LoggingObject, IVehicleContainer + { + private List<Tuple<int, VectoSimulationComponent>> _components = + new List<Tuple<int, VectoSimulationComponent>>(); + + internal IEngineInfo Engine; + internal IGearboxInfo Gearbox; + internal IAxlegearInfo Axlegear; + internal IVehicleInfo Vehicle; + internal IBrakes Brakes; + internal IWheelsInfo Wheels; + internal IDriverInfo Driver; + + internal IMileageCounter MilageCounter; + + internal IClutchInfo Clutch; + + internal IDrivingCycleInfo DrivingCycle; + + internal ISimulationOutPort Cycle; + + internal IModalDataContainer ModData; + + internal WriteSumData WriteSumData; + + #region IGearCockpit + + public GearboxType GearboxType + { + get { return Gearbox == null ? GearboxType.MT : Gearbox.GearboxType; } + } + + public uint Gear + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get { + if (Gearbox == null) { + return 0; // throw new VectoException("no gearbox available!"); + } + return Gearbox.Gear; + } + } + + public MeterPerSecond StartSpeed + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get { + if (Gearbox == null) { + throw new VectoException("No Gearbox available. StartSpeed unkown"); + } + return Gearbox.StartSpeed; + } + } + + public MeterPerSquareSecond StartAcceleration + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get { + if (Gearbox == null) { + throw new VectoException("No Gearbox available. StartAcceleration unknown."); + } + return Gearbox.StartAcceleration; + } + } + + public Watt GearboxLoss() + { + return Gearbox.GearboxLoss(); + } + + public Second LastShift + { + get { return Gearbox.LastShift; } + } + + public GearData GetGearData(uint gear) + { + return Gearbox.GetGearData(gear); + } + + public GearInfo NextGear + { + get { return Gearbox.NextGear; } + } + + public Second TractionInterruption + { + get { return Gearbox.TractionInterruption; } + } + + public uint NumGears + { + get { return Gearbox.NumGears; } + } + + #endregion + + #region IEngineCockpit + + public PerSecond EngineSpeed + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get { + if (Engine == null) { + throw new VectoException("no engine available!"); + } + return Engine.EngineSpeed; + } + } + + public NewtonMeter EngineTorque + { + get { return Engine.EngineTorque; } + } + + public Watt EngineStationaryFullPower(PerSecond angularSpeed) + { + return Engine.EngineStationaryFullPower(angularSpeed); + } + + public Watt EngineDragPower(PerSecond angularSpeed) + { + return Engine.EngineDragPower(angularSpeed); + } + + public PerSecond EngineIdleSpeed + { + get { return Engine.EngineIdleSpeed; } + } + + public PerSecond EngineRatedSpeed + { + get { return Engine.EngineRatedSpeed; } + } + + public PerSecond EngineN95hSpeed + { + get { return Engine.EngineN95hSpeed; } + } + + public PerSecond EngineN80hSpeed + { + get { return Engine.EngineN80hSpeed; } + } + + #endregion + + #region IVehicleCockpit + + public MeterPerSecond VehicleSpeed + { + get { return Vehicle != null ? Vehicle.VehicleSpeed : 0.SI<MeterPerSecond>(); } + } + + public Kilogram VehicleMass + { + get { return Vehicle != null ? Vehicle.VehicleMass : 0.SI<Kilogram>(); } + } + + public Kilogram VehicleLoading + { + get { return Vehicle != null ? Vehicle.VehicleLoading : 0.SI<Kilogram>(); } + } + + public Kilogram TotalMass + { + get { return Vehicle != null ? Vehicle.TotalMass : 0.SI<Kilogram>(); } + } + + public CubicMeter CargoVolume + { + get { return Vehicle != null ? Vehicle.CargoVolume : 0.SI<CubicMeter>(); } + } + + public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) + { + return Vehicle.AirDragResistance(previousVelocity, nextVelocity); + } + + public Newton RollingResistance(Radian gradient) + { + return Vehicle.RollingResistance(gradient); + } + + public Newton SlopeResistance(Radian gradient) + { + return Vehicle.SlopeResistance(gradient); + } + + #endregion + + public VehicleContainer(ExecutionMode executionMode, IModalDataContainer modData = null, + WriteSumData writeSumData = null) + { + ModData = modData; + WriteSumData = writeSumData ?? delegate { }; + ExecutionMode = executionMode; + } + + #region IVehicleContainer + + public IModalDataContainer ModalData + { + get { return ModData; } + } + + public ISimulationOutPort GetCycleOutPort() + { + return Cycle; + } + + public FuelType FuelType + { + get { return ModData.FuelData.FuelType; } + } + + public Second AbsTime { get; set; } + + public void AddComponent(VectoSimulationComponent component) + { + var commitPriority = 0; + + component.Switch() + .If<IEngineInfo>(c => { + Engine = c; + commitPriority = 2; + }) + .If<IDriverInfo>(c => Driver = c) + .If<IGearboxInfo>(c => { + Gearbox = c; + commitPriority = 4; + }) + .If<IAxlegearInfo>(c => Axlegear = c) + .If<IWheelsInfo>(c => Wheels = c) + .If<IVehicleInfo>(c => { + Vehicle = c; + commitPriority = 5; + }) + .If<ISimulationOutPort>(c => Cycle = c) + .If<IMileageCounter>(c => MilageCounter = c) + .If<IBrakes>(c => Brakes = c) + .If<IClutchInfo>(c => Clutch = c) + .If<IDrivingCycleInfo>(c => { + DrivingCycle = c; + commitPriority = 6; + }) + .If<PTOCycleController>(c => { commitPriority = 99; }); + + _components.Add(Tuple.Create(commitPriority, component)); + _components = _components.OrderBy(x => x.Item1).Reverse().ToList(); + } + + public void CommitSimulationStep(Second time, Second simulationInterval) + { + Log.Info("VehicleContainer committing simulation. time: {0}, dist: {1}, speed: {2}", time, + Distance, VehicleSpeed); + + + foreach (var component in _components) { + component.Item2.CommitSimulationStep(ModData); + } + + if (ModData != null) { + ModData[ModalResultField.drivingBehavior] = DriverBehavior; + ModData[ModalResultField.time] = time + simulationInterval / 2; + ModData[ModalResultField.simulationInterval] = simulationInterval; + ModData.CommitSimulationStep(); + } + } + + public void FinishSimulationRun(Exception e = null) + { + Log.Info("VehicleContainer finishing simulation."); + ModData.Finish(RunStatus, e); + + WriteSumData(ModData); + + ModData.FinishSimulation(); + DrivingCycle.FinishSimulation(); + } + + public void FinishSimulation() + { + throw new NotImplementedException(); + } + + public VectoRun.Status RunStatus { get; set; } + + #endregion + + public IReadOnlyCollection<VectoSimulationComponent> SimulationComponents() + { + return new ReadOnlyCollection<VectoSimulationComponent>(_components.Select(x => x.Item2).ToList()); + } + + public Meter Distance + { + get { + if (MilageCounter == null) { + Log.Warn("No MileageCounter in VehicleContainer. Distance cannot be measured."); + return 0.SI<Meter>(); + } + return MilageCounter.Distance; + } + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) + { + return DrivingCycle.LookAhead(lookaheadDistance); + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) + { + return DrivingCycle.LookAhead(time); + } + + + public Watt BrakePower + { + get { return Brakes.BrakePower; } + set { Brakes.BrakePower = value; } + } + + public bool ClutchClosed(Second absTime) + { + if (Clutch == null) { + Log.Warn("No Clutch in VehicleContainer. ClutchClosed set to constant true!"); + return true; + } + return Clutch.ClutchClosed(absTime); + } + + public bool VehicleStopped + { + get { return Vehicle.VehicleStopped; } + } + + public DrivingBehavior DriverBehavior + { + get { return Driver != null ? Driver.DriverBehavior : DrivingBehavior.Driving; } + } + + public MeterPerSquareSecond DriverAcceleration + { + get { return Driver != null ? Driver.DriverAcceleration : 0.SI<MeterPerSquareSecond>(); } + } + + public Meter CycleStartDistance + { + get { return DrivingCycle == null ? 0.SI<Meter>() : DrivingCycle.CycleStartDistance; } + } + + public VectoRunData RunData { get; set; } + public ExecutionMode ExecutionMode { get; set; } + + public CycleData CycleData + { + get { return DrivingCycle.CycleData; } + } + + public bool PTOActive + { + get { return DrivingCycle.PTOActive; } + } + + public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) + { + return DrivingCycle.CycleLookAhead(distance); + } + + public Meter Altitude + { + get { return DrivingCycle.Altitude; } + } + + public Watt AxlegearLoss() + { + return Axlegear.AxlegearLoss(); + } + + public Kilogram ReducedMassWheels + { + get { return Wheels.ReducedMassWheels; } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 02152d10f148ffa1f50bd06011d4a593f7cb2c18..a7cb1b718bb728f9a39c7cf50a9ac28aff0f988f 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -590,9 +590,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl angularSpeed = angularSpeed.LimitTo(_engine.ModelData.IdleSpeed, _engine.EngineRatedSpeed); retVal = RequestPort.Request(absTime, dt, 0.SI<NewtonMeter>(), angularSpeed); }). - Default(r => { - throw new UnexpectedResponseException("searching Idling point", r); - }); + Default(r => { throw new UnexpectedResponseException("searching Idling point", r); }); return retVal; } @@ -649,9 +647,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl 0.SI<NewtonMeter>(), angularSpeed); retVal = RequestPort.Request(absTime, dt, 0.SI<NewtonMeter>(), angularSpeed); }). - Default(r => { - throw new UnexpectedResponseException("searching Idling point", r); - }); + Default(r => { throw new UnexpectedResponseException("searching Idling point", r); }); return retVal; } diff --git a/VectoCore/VectoCore/OutputData/DeclarationReport.cs b/VectoCore/VectoCore/OutputData/DeclarationReport.cs index 1167eee4a5069514f9a6e12fc19c8e3ef17ac702..b70bbb0ffbf4cd50bd90761afc0318c64a1737fc 100644 --- a/VectoCore/VectoCore/OutputData/DeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/DeclarationReport.cs @@ -34,16 +34,32 @@ using System.Runtime.CompilerServices; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; namespace TUGraz.VectoCore.OutputData { public interface IDeclarationReport { + /** + * allow to initialize the report + * read the configuration of the powertrain to be used during the simulation. + * This methodd is called once befor creating the simulation runs with a temporary + * VectoRunData instance + */ + void InitializeReport(VectoRunData modelData); + + /** + * called when creating the simulation run (before starting the simulations) + * Hence, the report class knows which and how many results to expect after the simulation + * (calls to AddResult) + */ void PrepareResult(LoadingType loading, Mission mission, VectoRunData runData); + + /** + * called after the simulation run providing the modal data of the simulation + * for the given configuration + */ void AddResult(LoadingType loadingType, Mission mission, VectoRunData runData, IModalDataContainer modData); - void InitializeReport(VectoRunData modelData, Segment segment); } /// <summary> @@ -58,20 +74,6 @@ namespace TUGraz.VectoCore.OutputData public Dictionary<LoadingType, TEntry> ModData; } - //public class MissionProfile - //{ - // public readonly IList<double> DistanceKm; - // public readonly IList<double> TargetSpeed; - // public readonly IList<double> Altitude; - - // public MissionProfile(IModalDataContainer m) - // { - // DistanceKm = m.GetValues<Meter>(ModalResultField.dist).Select(v => v.ConvertTo().Kilo.Meter).ToDouble(); - // TargetSpeed = - // m.GetValues<MeterPerSecond>(ModalResultField.v_targ).Select(v => v.ConvertTo().Kilo.Meter.Per.Hour).ToDouble(); - // Altitude = m.GetValues<Meter>(ModalResultField.altitude).ToDouble(); - // } - //} /// <summary> /// Dictionary of MissionTypes and their corresponding results. @@ -84,10 +86,10 @@ namespace TUGraz.VectoCore.OutputData /// </summary> internal Dictionary<uint, EngineFullLoadCurve> Flc { get; set; } - /// <summary> - /// The declaration segment from the segment table - /// </summary> - internal Segment? Segment { get; set; } + ///// <summary> + ///// The declaration segment from the segment table + ///// </summary> + //internal Segment? Segment { get; set; } /// <summary> @@ -113,19 +115,12 @@ namespace TUGraz.VectoCore.OutputData public void AddResult(LoadingType loadingType, Mission mission, VectoRunData runData, IModalDataContainer modData) { - if (modData.RunStatus != VectoRun.Status.Success) { - //Missions.Clear(); - return; - } if (!Missions.ContainsKey(mission.MissionType)) { throw new VectoException("Unknown mission type {0} for generating declaration report", mission.MissionType); } if (!Missions[mission.MissionType].ModData.ContainsKey(loadingType)) { throw new VectoException("Unknown loading type {0} for mission {1}", loadingType, mission.MissionType); } - //if (Missions[mission.MissionType].MissionProfile == null) { - // Missions[mission.MissionType].MissionProfile = new MissionProfile(modData); - //} _resultCount--; DoAddResult(Missions[mission.MissionType].ModData[loadingType], runData, modData); @@ -133,7 +128,6 @@ namespace TUGraz.VectoCore.OutputData if (_resultCount == 0) { DoWriteReport(); Flc = null; - Segment = null; } } @@ -150,13 +144,6 @@ namespace TUGraz.VectoCore.OutputData protected internal abstract void DoWriteReport(); - public void InitializeReport(VectoRunData modelData, Segment segment) - { - Segment = segment; - - DoInitializeReport(modelData, segment); - } - - protected abstract void DoInitializeReport(VectoRunData modelData, Segment segment); + public abstract void InitializeReport(VectoRunData modelData); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs b/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs index 0520e1b177690a05adfe2f0f75cb1efa94c79eb2..e26d90445d1de3f80dbfa4d4a4b8dd5a0c737bbd 100644 --- a/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs +++ b/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs @@ -32,6 +32,9 @@ using System; using System.Data; using System.IO; +using System.Text; +using System.Xml; +using System.Xml.Linq; using TUGraz.VectoCommon.Models; using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.Utils; @@ -94,24 +97,47 @@ namespace TUGraz.VectoCore.OutputData.FileIO return Path.Combine(BasePath, modFileName); } - public void WriteModData(string runName, string cycleName, string runSuffix, DataTable modData) + public void WriteModData(int jobRunId, string runName, string cycleName, string runSuffix, DataTable modData) { VectoCSVFile.Write(GetModDataFileName(runName, cycleName, runSuffix), modData, true); } - public Stream WriteStream(ReportType type) + public virtual void WriteReport(ReportType type, XDocument data) { + string fileName = null; + switch (type) { + case ReportType.DeclarationReportManufacturerXML: + fileName = XMLFullReportName; + break; + case ReportType.DeclarationReportCustomerXML: + fileName = XMLCustomerReportName; + break; + default: + throw new ArgumentOutOfRangeException("type"); + } + using (var writer = new FileStream(fileName, FileMode.Create)) { + using (var xmlWriter = new XmlTextWriter(writer, Encoding.UTF8)) { + xmlWriter.Formatting = Formatting.Indented; + data.WriteTo(xmlWriter); + xmlWriter.Flush(); + xmlWriter.Close(); + } + } + } + + public virtual void WriteReport(ReportType type, Stream data) + { + Stream stream = null; switch (type) { case ReportType.DeclarationReportPdf: - return new FileStream(PDFReportName, FileMode.Create); - case ReportType.DeclarationReportXMLFulll: - return new FileStream(XMLFullReportName, FileMode.Create); - case ReportType.DeclarationReportXMLCOC: - return new FileStream(XMLCustomerReportName, FileMode.Create); + stream = new FileStream(PDFReportName, FileMode.Create); + break; default: throw new ArgumentOutOfRangeException("type"); } + data.CopyToAsync(stream); + //stream.Write(data); } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/IDataWriter.cs b/VectoCore/VectoCore/OutputData/IDataWriter.cs index e3b40c5fca150c5653a1844cda65a249f74b4753..288ccf0be5ebe245144b4a3fc036d895552bae93 100644 --- a/VectoCore/VectoCore/OutputData/IDataWriter.cs +++ b/VectoCore/VectoCore/OutputData/IDataWriter.cs @@ -29,32 +29,35 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Data; -using System.IO; - -namespace TUGraz.VectoCore.OutputData -{ - public interface IOutputDataWriter : IModalDataWriter, IReportWriter, ISummaryWriter {} - - public interface IModalDataWriter - { - void WriteModData(string runName, string cycleName, string runSuffix, DataTable modData); - } - - public interface ISummaryWriter - { - void WriteSumData(DataTable sortedAndFilteredTable); - } - - public interface IReportWriter - { - Stream WriteStream(ReportType type); - } - - public enum ReportType - { - DeclarationReportPdf, - DeclarationReportXMLFulll, - DeclarationReportXMLCOC - } +using System.Data; +using System.IO; +using System.Xml.Linq; + +namespace TUGraz.VectoCore.OutputData +{ + public interface IOutputDataWriter : IModalDataWriter, IReportWriter, ISummaryWriter {} + + public interface IModalDataWriter + { + void WriteModData(int jobRunId, string runName, string cycleName, string runSuffix, DataTable modData); + } + + public interface ISummaryWriter + { + void WriteSumData(DataTable sortedAndFilteredTable); + } + + public interface IReportWriter + { + void WriteReport(ReportType type, XDocument data); + + void WriteReport(ReportType type, Stream data); + } + + public enum ReportType + { + DeclarationReportPdf, + DeclarationReportManufacturerXML, + DeclarationReportCustomerXML + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs index d58d0a42cb7b122f4016ac40b118223eb777387f..b48aec3d79efaca6804a215991feccbe0c834f83 100644 --- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs @@ -78,11 +78,6 @@ namespace TUGraz.VectoCore.OutputData string StackTrace { get; } - /// <summary> - /// Finishes the writing of the DataWriter. - /// </summary> - void Finish(VectoRun.Status runStatus); - IEnumerable<T> GetValues<T>(ModalResultField key); IEnumerable<T> GetValues<T>(DataColumn col); @@ -97,12 +92,16 @@ namespace TUGraz.VectoCore.OutputData void AddAuxiliary(string id, string columnName = null); + /// <summary> + /// Finishes the writing of the DataWriter. + /// </summary> + void Finish(VectoRun.Status runStatus, Exception exception = null); + /// <summary> /// clear the modal data after the simulation /// called after the simulation is finished and the sum-entries have been written /// </summary> - /// <param name="exception"></param> - void FinishSimulation(Exception exception = null); + void FinishSimulation(); } public static class ModalDataContainerExtensions diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index a9d20247dacc6fb2c740ab6b074c2ca9b5f894d5..6e235c440260496e4fe3a8fb8e70f3d7f5a0b48e 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -29,304 +29,320 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Data; -using System.Globalization; -using System.Linq; -using System.Runtime.CompilerServices; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; - -namespace TUGraz.VectoCore.OutputData -{ - public class ModalDataContainer : IModalDataContainer - { - private readonly bool _writeEngineOnly; - private readonly IModalDataFilter[] _filters; - private readonly Action<ModalDataContainer> _addReportResult; - protected internal ModalResults Data { get; set; } - private DataRow CurrentRow { get; set; } - - private readonly IModalDataWriter _writer; - private readonly List<string> _additionalColumns = new List<string>(); - private Exception SimException; - public string RunName { get; private set; } - public string CycleName { get; private set; } - public string RunSuffix { get; private set; } - - public bool WriteModalResults { get; set; } - - public VectoRun.Status RunStatus { get; protected set; } - - public string Error { get { return SimException == null ? null : SimException.Message; } } - public string StackTrace { get { return SimException == null ? null : SimException.StackTrace; } } - - public bool WriteAdvancedAux { get; set; } - - public ModalDataContainer(string runName, FuelType fuel, IModalDataWriter writer, bool writeEngineOnly = false) - : this(runName, "", fuel, "", writer, _ => { }, writeEngineOnly) {} - - public ModalDataContainer(VectoRunData runData, IModalDataWriter writer, Action<ModalDataContainer> addReportResult, - bool writeEngineOnly, params IModalDataFilter[] filter) - : this( - runData.JobName, runData.Cycle.Name, runData.EngineData.FuelType, runData.ModFileSuffix, writer, addReportResult, - writeEngineOnly, filter) {} - - protected ModalDataContainer(string runName, string cycleName, FuelType fuelType, string runSuffix, - IModalDataWriter writer, - Action<ModalDataContainer> addReportResult, bool writeEngineOnly, params IModalDataFilter[] filters) - { - HasTorqueConverter = false; - RunName = runName; - CycleName = cycleName; - RunSuffix = runSuffix; - _writer = writer; - - FuelData = Models.Declaration.FuelData.Instance().Lookup(fuelType); - - _writeEngineOnly = writeEngineOnly; - _filters = filters ?? new IModalDataFilter[0]; - _addReportResult = addReportResult ?? (x => { }); - - Data = new ModalResults(); - Auxiliaries = new Dictionary<string, DataColumn>(); - CurrentRow = Data.NewRow(); - WriteAdvancedAux = false; - } - - public bool HasTorqueConverter { get; set; } - - public void CommitSimulationStep() - { - Data.Rows.Add(CurrentRow); - CurrentRow = Data.NewRow(); - } - - public FuelData.Entry FuelData { get; internal set; } - - public void Finish(VectoRun.Status runStatus) - { - var dataColumns = new List<ModalResultField> { ModalResultField.time }; - - RunStatus = runStatus; - - if (!_writeEngineOnly) { - dataColumns.AddRange(new[] { - ModalResultField.simulationInterval, - ModalResultField.dist, - ModalResultField.v_act, - ModalResultField.v_targ, - ModalResultField.acc, - ModalResultField.grad - }); - } - if (!_writeEngineOnly) { - dataColumns.AddRange(new[] { - ModalResultField.Gear, - }); - if (HasTorqueConverter) { - dataColumns.AddRange(new[] { ModalResultField.TC_Locked }); - } - } - dataColumns.AddRange(new[] { - ModalResultField.n_eng_avg, - ModalResultField.T_eng_fcmap, - ModalResultField.Tq_full, - ModalResultField.Tq_drag, - ModalResultField.P_eng_fcmap, - ModalResultField.P_eng_full, - ModalResultField.P_eng_full_stat, - ModalResultField.P_eng_drag, - ModalResultField.P_eng_inertia, - ModalResultField.P_eng_out, - }); - if (HasTorqueConverter) { - dataColumns.AddRange(new[] { - ModalResultField.P_gbx_shift_loss, - ModalResultField.P_TC_loss, - ModalResultField.P_TC_out, - }); - } else { - dataColumns.AddRange(new[] { - ModalResultField.P_clutch_loss, - ModalResultField.P_clutch_out, - }); - } - dataColumns.AddRange(new[] { - ModalResultField.P_aux - }); - - if (!_writeEngineOnly) { - dataColumns.AddRange(new[] { - ModalResultField.P_gbx_in, - ModalResultField.P_gbx_loss, - ModalResultField.P_gbx_inertia, - ModalResultField.P_retarder_in, - ModalResultField.P_ret_loss, - ModalResultField.P_angle_in, - ModalResultField.P_angle_loss, - ModalResultField.P_axle_in, - ModalResultField.P_axle_loss, - ModalResultField.P_brake_in, - ModalResultField.P_brake_loss, - ModalResultField.P_wheel_in, - ModalResultField.P_wheel_inertia, - ModalResultField.P_trac, - ModalResultField.P_slope, - ModalResultField.P_air, - ModalResultField.P_roll, - ModalResultField.P_veh_inertia, - ModalResultField.n_gbx_out_avg, - ModalResultField.T_gbx_out - }); - - if (HasTorqueConverter) { - dataColumns.AddRange(new[] { - ModalResultField.TorqueConverterSpeedRatio, - ModalResultField.TorqueConverterTorqueRatio, - ModalResultField.TC_TorqueOut, - ModalResultField.TC_angularSpeedOut, - ModalResultField.TC_TorqueIn, - ModalResultField.TC_angularSpeedIn, - }); - } - } - if (!_writeEngineOnly && WriteAdvancedAux) { - dataColumns.AddRange(new[] { - ModalResultField.AA_NonSmartAlternatorsEfficiency, - ModalResultField.AA_SmartIdleCurrent_Amps, - ModalResultField.AA_SmartIdleAlternatorsEfficiency, - ModalResultField.AA_SmartTractionCurrent_Amps, - ModalResultField.AA_SmartTractionAlternatorEfficiency, - ModalResultField.AA_SmartOverrunCurrent_Amps, - ModalResultField.AA_SmartOverrunAlternatorEfficiency, - ModalResultField.AA_CompressorFlowRate_LitrePerSec, - ModalResultField.AA_OverrunFlag, - ModalResultField.AA_EngineIdleFlag, - ModalResultField.AA_CompressorFlag, - ModalResultField.AA_TotalCycleFC_Grams, - ModalResultField.AA_TotalCycleFC_Litres, - ModalResultField.AA_AveragePowerDemandCrankHVACMechanicals, - ModalResultField.AA_AveragePowerDemandCrankHVACElectricals, - ModalResultField.AA_AveragePowerDemandCrankElectrics, - ModalResultField.AA_AveragePowerDemandCrankPneumatics, - ModalResultField.AA_TotalCycleFuelConsumptionCompressorOff, - ModalResultField.AA_TotalCycleFuelConsumptionCompressorOn, - }); - } - - var strCols = dataColumns.Select(x => x.GetName()) - .Concat(Auxiliaries.Values.Select(c => c.ColumnName)) - .Concat( - new[] { - ModalResultField.FCMap, ModalResultField.FCAUXc, ModalResultField.FCWHTCc, - ModalResultField.FCAAUX, ModalResultField.FCFinal - }.Select(x => x.GetName())); -#if TRACE - strCols = strCols.Concat(_additionalColumns); -#endif - if (WriteModalResults) { - var filteredData = Data; - foreach (var filter in _filters) { - RunSuffix += "_" + filter.ID; - filteredData = filter.Filter(filteredData); - } - _writer.WriteModData(RunName, CycleName, RunSuffix, new DataView(filteredData).ToTable(false, strCols.ToArray())); - } - - _addReportResult(this); - } - - public IEnumerable<T> GetValues<T>(DataColumn col) - { - return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>(col)); - } - - public IEnumerable<T> GetValues<T>(Func<DataRow, T> selectorFunc) - { - return from DataRow row in Data.Rows select selectorFunc(row); - } - - public T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T> - { - var result = 0.0; - for (var i = 0; i < Data.Rows.Count; i++) { - var value = Data.Rows[i][(int)field]; - if (value != null && value != DBNull.Value) { - var siValue = (SI)value; - if (filter == null || filter(siValue)) { - result += siValue.Value() * ((Second)Data.Rows[i][(int)ModalResultField.simulationInterval]).Value(); - } - } - } - - return result.SI<T>(); - } - - public IEnumerable<T> GetValues<T>(ModalResultField key) - { - return GetValues<T>(Data.Columns[(int)key]); - } - - public object this[ModalResultField key] - { - get { return CurrentRow[(int)key]; } - set { CurrentRow[(int)key] = value; } - } - - public object this[string auxId] - { - get { return CurrentRow[Auxiliaries[auxId]]; } - set { CurrentRow[Auxiliaries[auxId]] = value; } - } - - [MethodImpl(MethodImplOptions.Synchronized)] - public void SetDataValue(string fieldName, object value) - { - if (!Data.Columns.Contains(fieldName)) { - _additionalColumns.Add(fieldName); - Data.Columns.Add(fieldName); - } - if (value is double) { - CurrentRow[fieldName] = string.Format(CultureInfo.InvariantCulture, "{0}", value); - } else { - CurrentRow[fieldName] = value; - } - } - - public Dictionary<string, DataColumn> Auxiliaries { get; set; } - - /// <summary> - /// Adds a new auxiliary column into the mod data. - /// </summary> - /// <param name="id">The Aux-ID. This is the internal identification for the auxiliary.</param> - /// <param name="columnName">(Optional) The column name in the mod file. Default: "P_aux_" + id</param> - public void AddAuxiliary(string id, string columnName = null) - { - if (!string.IsNullOrWhiteSpace(id) && !Auxiliaries.ContainsKey(id)) { - var col = Data.Columns.Add(columnName ?? ModalResultField.P_aux_ + id, typeof(SI)); - col.ExtendedProperties[ModalResults.ExtendedPropertyNames.Decimals] = - ModalResultField.P_aux_.GetAttribute().Decimals; - col.ExtendedProperties[ModalResults.ExtendedPropertyNames.OutputFactor] = - ModalResultField.P_aux_.GetAttribute().OutputFactor; - col.ExtendedProperties[ModalResults.ExtendedPropertyNames.ShowUnit] = - ModalResultField.P_aux_.GetAttribute().ShowUnit; - - Auxiliaries[id] = col; - } - } - - public void FinishSimulation(Exception exception) - { - SimException = exception; - //Data.Clear(); //.Rows.Clear(); - Data = null; - CurrentRow = null; - Auxiliaries.Clear(); - } - } +using System; +using System.Collections.Generic; +using System.Data; +using System.Globalization; +using System.Linq; +using System.Runtime.CompilerServices; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; + +namespace TUGraz.VectoCore.OutputData +{ + public class ModalDataContainer : IModalDataContainer + { + private readonly bool _writeEngineOnly; + private readonly IModalDataFilter[] _filters; + private readonly Action<ModalDataContainer> _addReportResult; + protected internal ModalResults Data { get; set; } + private DataRow CurrentRow { get; set; } + + private readonly IModalDataWriter _writer; + private readonly List<string> _additionalColumns = new List<string>(); + private Exception SimException; + public int JobRunId { get; private set; } + public string RunName { get; private set; } + public string CycleName { get; private set; } + public string RunSuffix { get; private set; } + + public bool WriteModalResults { get; set; } + + public VectoRun.Status RunStatus { get; protected set; } + + public string Error + { + get { return SimException == null ? null : SimException.Message; } + } + + public string StackTrace + { + get { + return SimException == null + ? null + : (SimException.StackTrace ?? (SimException.InnerException != null ? SimException.InnerException.StackTrace : null)); + } + } + + public bool WriteAdvancedAux { get; set; } + + public ModalDataContainer(string runName, FuelType fuel, IModalDataWriter writer, bool writeEngineOnly = false) + : this(0, runName, "", fuel, "", writer, _ => { }, writeEngineOnly) {} + + public ModalDataContainer(VectoRunData runData, IModalDataWriter writer, Action<ModalDataContainer> addReportResult, + bool writeEngineOnly, params IModalDataFilter[] filter) + : this( + runData.JobRunId, runData.JobName, runData.Cycle.Name, runData.EngineData.FuelType, runData.ModFileSuffix, writer, + addReportResult, + writeEngineOnly, filter) {} + + protected ModalDataContainer(int jobRunId, string runName, string cycleName, FuelType fuelType, string runSuffix, + IModalDataWriter writer, + Action<ModalDataContainer> addReportResult, bool writeEngineOnly, params IModalDataFilter[] filters) + { + HasTorqueConverter = false; + RunName = runName; + CycleName = cycleName; + RunSuffix = runSuffix; + JobRunId = jobRunId; + _writer = writer; + + FuelData = Models.Declaration.FuelData.Instance().Lookup(fuelType); + + _writeEngineOnly = writeEngineOnly; + _filters = filters ?? new IModalDataFilter[0]; + _addReportResult = addReportResult ?? (x => { }); + + Data = new ModalResults(); + Auxiliaries = new Dictionary<string, DataColumn>(); + CurrentRow = Data.NewRow(); + WriteAdvancedAux = false; + } + + + public bool HasTorqueConverter { get; set; } + + public void CommitSimulationStep() + { + Data.Rows.Add(CurrentRow); + CurrentRow = Data.NewRow(); + } + + public FuelData.Entry FuelData { get; internal set; } + + public void Finish(VectoRun.Status runStatus, Exception exception = null) + { + var dataColumns = new List<ModalResultField> { ModalResultField.time }; + + RunStatus = runStatus; + SimException = exception; + + if (!_writeEngineOnly) { + dataColumns.AddRange(new[] { + ModalResultField.simulationInterval, + ModalResultField.dist, + ModalResultField.v_act, + ModalResultField.v_targ, + ModalResultField.acc, + ModalResultField.grad + }); + } + if (!_writeEngineOnly) { + dataColumns.AddRange(new[] { + ModalResultField.Gear, + }); + if (HasTorqueConverter) { + dataColumns.AddRange(new[] { ModalResultField.TC_Locked }); + } + } + dataColumns.AddRange(new[] { + ModalResultField.n_eng_avg, + ModalResultField.T_eng_fcmap, + ModalResultField.Tq_full, + ModalResultField.Tq_drag, + ModalResultField.P_eng_fcmap, + ModalResultField.P_eng_full, + ModalResultField.P_eng_full_stat, + ModalResultField.P_eng_drag, + ModalResultField.P_eng_inertia, + ModalResultField.P_eng_out, + }); + if (HasTorqueConverter) { + dataColumns.AddRange(new[] { + ModalResultField.P_gbx_shift_loss, + ModalResultField.P_TC_loss, + ModalResultField.P_TC_out, + }); + } else { + dataColumns.AddRange(new[] { + ModalResultField.P_clutch_loss, + ModalResultField.P_clutch_out, + }); + } + dataColumns.AddRange(new[] { + ModalResultField.P_aux + }); + + if (!_writeEngineOnly) { + dataColumns.AddRange(new[] { + ModalResultField.P_gbx_in, + ModalResultField.P_gbx_loss, + ModalResultField.P_gbx_inertia, + ModalResultField.P_retarder_in, + ModalResultField.P_ret_loss, + ModalResultField.P_angle_in, + ModalResultField.P_angle_loss, + ModalResultField.P_axle_in, + ModalResultField.P_axle_loss, + ModalResultField.P_brake_in, + ModalResultField.P_brake_loss, + ModalResultField.P_wheel_in, + ModalResultField.P_wheel_inertia, + ModalResultField.P_trac, + ModalResultField.P_slope, + ModalResultField.P_air, + ModalResultField.P_roll, + ModalResultField.P_veh_inertia, + ModalResultField.n_gbx_out_avg, + ModalResultField.T_gbx_out + }); + + if (HasTorqueConverter) { + dataColumns.AddRange(new[] { + ModalResultField.TorqueConverterSpeedRatio, + ModalResultField.TorqueConverterTorqueRatio, + ModalResultField.TC_TorqueOut, + ModalResultField.TC_angularSpeedOut, + ModalResultField.TC_TorqueIn, + ModalResultField.TC_angularSpeedIn, + }); + } + } + if (!_writeEngineOnly && WriteAdvancedAux) { + dataColumns.AddRange(new[] { + ModalResultField.AA_NonSmartAlternatorsEfficiency, + ModalResultField.AA_SmartIdleCurrent_Amps, + ModalResultField.AA_SmartIdleAlternatorsEfficiency, + ModalResultField.AA_SmartTractionCurrent_Amps, + ModalResultField.AA_SmartTractionAlternatorEfficiency, + ModalResultField.AA_SmartOverrunCurrent_Amps, + ModalResultField.AA_SmartOverrunAlternatorEfficiency, + ModalResultField.AA_CompressorFlowRate_LitrePerSec, + ModalResultField.AA_OverrunFlag, + ModalResultField.AA_EngineIdleFlag, + ModalResultField.AA_CompressorFlag, + ModalResultField.AA_TotalCycleFC_Grams, + ModalResultField.AA_TotalCycleFC_Litres, + ModalResultField.AA_AveragePowerDemandCrankHVACMechanicals, + ModalResultField.AA_AveragePowerDemandCrankHVACElectricals, + ModalResultField.AA_AveragePowerDemandCrankElectrics, + ModalResultField.AA_AveragePowerDemandCrankPneumatics, + ModalResultField.AA_TotalCycleFuelConsumptionCompressorOff, + ModalResultField.AA_TotalCycleFuelConsumptionCompressorOn, + }); + } + + var strCols = dataColumns.Select(x => x.GetName()) + .Concat(Auxiliaries.Values.Select(c => c.ColumnName)) + .Concat( + new[] { + ModalResultField.FCMap, ModalResultField.FCAUXc, ModalResultField.FCWHTCc, + ModalResultField.FCAAUX, ModalResultField.FCFinal + }.Select(x => x.GetName())); +#if TRACE + strCols = strCols.Concat(_additionalColumns); +#endif + if (WriteModalResults) { + var filteredData = Data; + foreach (var filter in _filters) { + RunSuffix += "_" + filter.ID; + filteredData = filter.Filter(filteredData); + } + _writer.WriteModData(JobRunId, RunName, CycleName, RunSuffix, + new DataView(filteredData).ToTable(false, strCols.ToArray())); + } + + _addReportResult(this); + } + + public IEnumerable<T> GetValues<T>(DataColumn col) + { + return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>(col)); + } + + public IEnumerable<T> GetValues<T>(Func<DataRow, T> selectorFunc) + { + return from DataRow row in Data.Rows select selectorFunc(row); + } + + public T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T> + { + var result = 0.0; + for (var i = 0; i < Data.Rows.Count; i++) { + var value = Data.Rows[i][(int)field]; + if (value != null && value != DBNull.Value) { + var siValue = (SI)value; + if (filter == null || filter(siValue)) { + result += siValue.Value() * ((Second)Data.Rows[i][(int)ModalResultField.simulationInterval]).Value(); + } + } + } + + return result.SI<T>(); + } + + public IEnumerable<T> GetValues<T>(ModalResultField key) + { + return GetValues<T>(Data.Columns[(int)key]); + } + + public object this[ModalResultField key] + { + get { return CurrentRow[(int)key]; } + set { CurrentRow[(int)key] = value; } + } + + public object this[string auxId] + { + get { return CurrentRow[Auxiliaries[auxId]]; } + set { CurrentRow[Auxiliaries[auxId]] = value; } + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public void SetDataValue(string fieldName, object value) + { + if (!Data.Columns.Contains(fieldName)) { + _additionalColumns.Add(fieldName); + Data.Columns.Add(fieldName); + } + if (value is double) { + CurrentRow[fieldName] = string.Format(CultureInfo.InvariantCulture, "{0}", value); + } else { + CurrentRow[fieldName] = value; + } + } + + public Dictionary<string, DataColumn> Auxiliaries { get; set; } + + /// <summary> + /// Adds a new auxiliary column into the mod data. + /// </summary> + /// <param name="id">The Aux-ID. This is the internal identification for the auxiliary.</param> + /// <param name="columnName">(Optional) The column name in the mod file. Default: "P_aux_" + id</param> + public void AddAuxiliary(string id, string columnName = null) + { + if (!string.IsNullOrWhiteSpace(id) && !Auxiliaries.ContainsKey(id)) { + var col = Data.Columns.Add(columnName ?? ModalResultField.P_aux_ + id, typeof(SI)); + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.Decimals] = + ModalResultField.P_aux_.GetAttribute().Decimals; + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.OutputFactor] = + ModalResultField.P_aux_.GetAttribute().OutputFactor; + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.ShowUnit] = + ModalResultField.P_aux_.GetAttribute().ShowUnit; + + Auxiliaries[id] = col; + } + } + + public void FinishSimulation() + { + //Data.Clear(); //.Rows.Clear(); + Data = null; + CurrentRow = null; + Auxiliaries.Clear(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/AbstractXMLWriter.cs b/VectoCore/VectoCore/OutputData/XML/AbstractXMLWriter.cs index 7d6135a18c147fd32461f422c1bce29fd4ebbfe2..33dac0d7cb6bb4618099c556cdd43c03cc51f4ab 100644 --- a/VectoCore/VectoCore/OutputData/XML/AbstractXMLWriter.cs +++ b/VectoCore/VectoCore/OutputData/XML/AbstractXMLWriter.cs @@ -29,68 +29,68 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Xml.Linq; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Resources; -using TUGraz.VectoCommon.Utils; - -namespace TUGraz.IVT.VectoXML.Writer -{ - public abstract class AbstractXMLWriter - { - //protected const string SchemaLocationBaseUrl = "http://markus.quaritsch.at/VECTO/"; - public const string SchemaLocationBaseUrl = "https://webgate.ec.europa.eu/CITnet/svn/VECTO/trunk/Share/XML/XSD/"; - protected const string SchemaVersion = "1.0"; - - protected XNamespace tns; - protected XNamespace rootNamespace; - protected readonly XNamespace di; - - protected const string Creator = "TU Graz, IVT-EM XML Exporter"; - protected readonly string Vendor; - - protected readonly string BasePath; - - - protected AbstractXMLWriter(string basePath, string vendor) - { - BasePath = basePath; - Vendor = vendor; - - di = "http://www.w3.org/2000/09/xmldsig#"; - } - - protected XElement CreateTorqueLimits(IVehicleDeclarationInputData vehicle) - { - return vehicle.TorqueLimits.Count == 0 - ? null - : new XElement(tns + XMLNames.Vehicle_TorqueLimits, - vehicle.TorqueLimits - .OrderBy(x => x.Gear) - .Select(entry => new XElement(tns + XMLNames.Vehicle_TorqueLimits_Entry, - new XAttribute(XMLNames.Vehicle_TorqueLimits_Entry_Gear_Attr, entry.Gear), - new XAttribute(XMLNames.Vehicle_TorqueLimits_Entry_MaxTorque_Attr, entry.MaxTorque.ToXMLFormat(0)) - ) - ) - ); - } - - protected object[] EmbedDataTable(DataTable table, Dictionary<string, string> mapping, string tagName = "Entry", - Dictionary<string, uint> precision = null) - { - return (from DataRow row in table.Rows - select - new XElement(tns + tagName, - table.Columns.Cast<DataColumn>() - .Where(c => mapping.ContainsKey(c.ColumnName)) - .Select(c => { - var p = precision != null && precision.ContainsKey(c.ColumnName) ? precision[c.ColumnName] : 2; - return new XAttribute(mapping[c.ColumnName], row.Field<string>(c).ToDouble().ToXMLFormat(p)); - }))) - .Cast<object>().ToArray(); - } - } +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Xml.Linq; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.IVT.VectoXML.Writer +{ + public abstract class AbstractXMLWriter + { + //protected const string SchemaLocationBaseUrl = "http://markus.quaritsch.at/VECTO/"; + public const string SchemaLocationBaseUrl = "https://webgate.ec.europa.eu/CITnet/svn/VECTO/trunk/Share/XML/XSD/"; + protected const string SchemaVersion = "1.0"; + + protected XNamespace tns; + protected XNamespace rootNamespace; + protected readonly XNamespace di; + + protected const string Creator = "TU Graz, IVT-EM XML Exporter"; + protected readonly string Vendor; + + protected readonly string BasePath; + + + protected AbstractXMLWriter(string basePath, string vendor) + { + BasePath = basePath; + Vendor = vendor; + + di = "http://www.w3.org/2000/09/xmldsig#"; + } + + protected XElement CreateTorqueLimits(IVehicleDeclarationInputData vehicle) + { + return vehicle.TorqueLimits.Count == 0 + ? null + : new XElement(tns + XMLNames.Vehicle_TorqueLimits, + vehicle.TorqueLimits + .OrderBy(x => x.Gear) + .Select(entry => new XElement(tns + XMLNames.Vehicle_TorqueLimits_Entry, + new XAttribute(XMLNames.Vehicle_TorqueLimits_Entry_Gear_Attr, entry.Gear), + new XAttribute(XMLNames.Vehicle_TorqueLimits_Entry_MaxTorque_Attr, entry.MaxTorque.ToXMLFormat(0)) + ) + ) + ); + } + + protected object[] EmbedDataTable(DataTable table, Dictionary<string, string> mapping, string tagName = "Entry", + Dictionary<string, uint> precision = null) + { + return (from DataRow row in table.Rows + select + new XElement(tns + tagName, + table.Columns.Cast<DataColumn>() + .Where(c => mapping.ContainsKey(c.ColumnName)) + .Select(c => { + var p = precision != null && precision.ContainsKey(c.ColumnName) ? precision[c.ColumnName] : 2; + return new XAttribute(mapping[c.ColumnName], row.Field<string>(c).ToDouble().ToXMLFormat(p)); + }))) + .Cast<object>().ToArray(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs index e430fd531535fd6d736f92a572368bb59921b283..889b2a9e704d7a4072cbd56eef1b7821f2378e45 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs @@ -62,12 +62,12 @@ namespace TUGraz.VectoCore.OutputData.XML public XMLCustomerReport() { di = "http://www.w3.org/2000/09/xmldsig#"; - tns = "urn:tugraz:ivt:VectoAPI:COCOutput:v0.4"; + tns = "urn:tugraz:ivt:VectoAPI:CustomerOutput:v0.4"; VehiclePart = new XElement(tns + XMLNames.Component_Vehicle); Results = new XElement(tns + "Results"); } - public void Initialize(VectoRunData modelData, Segment segment) + public void Initialize(VectoRunData modelData) { VehiclePart.Add( new XElement(tns + XMLNames.Component_Model, modelData.VehicleData.ModelName), @@ -75,7 +75,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + XMLNames.Component_ManufacturerAddress, modelData.VehicleData.ManufacturerAddress), new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), new XElement(tns + XMLNames.Vehicle_LegislativeClass, modelData.VehicleData.LegislativeClass.ToXMLFormat()), - new XElement(tns + "VehicleGroup", segment.VehicleClass.GetClassNumber()), + new XElement(tns + "VehicleGroup", modelData.VehicleData.VehicleClass.GetClassNumber()), new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), new XElement(tns + XMLNames.Vehicle_CurbMassChassis, modelData.VehicleData.CurbWeight.ToXMLFormat(0)), @@ -108,7 +108,7 @@ namespace TUGraz.VectoCore.OutputData.XML foreach (var resultEntry in entry.ModData) { allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success; Results.Add(new XElement(tns + "Result", - new XAttribute("status", resultEntry.Value.Status.ToString().ToLower()), + new XAttribute("status", resultEntry.Value.Status == VectoRun.Status.Success ? "success" : "error"), new XElement(tns + "Mission", entry.Mission.ToXMLFormat()), GetResults(resultEntry))); } @@ -125,7 +125,7 @@ namespace TUGraz.VectoCore.OutputData.XML case VectoRun.Status.Canceled: case VectoRun.Status.Aborted: return new object[] { - new XElement("Error", resultEntry.Value.Error) + new XElement(tns + "Error", resultEntry.Value.Error) }; default: throw new ArgumentOutOfRangeException(); @@ -164,7 +164,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XAttribute("xmlns", tns), new XAttribute(XNamespace.Xmlns + "di", di), new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoCOC.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), + string.Format("{0} {1}VectoOutputCustomer.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), new XElement(tns + "Data", vehicle, new XElement(tns + "ResultDataSignature", resultSignature), diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs index cd8e02123c5fcfd9655c3b31ce0041886c57b222..79a575703bb299fb6fc8757c71b7ca889b839abe 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs @@ -45,7 +45,7 @@ namespace TUGraz.VectoCore.OutputData.XML { public class XMLDeclarationReport : DeclarationReport<XMLDeclarationReport.ResultEntry> { - private readonly XMLFullReport _fullReport; + private readonly XMLManufacturerReport _manufacturerReport; private readonly XMLCustomerReport _customerReport; private readonly IOutputDataWriter _writer; @@ -116,7 +116,7 @@ namespace TUGraz.VectoCore.OutputData.XML public XMLDeclarationReport(IOutputDataWriter writer = null) { - _fullReport = new XMLFullReport(); //new XDocument(new XDeclaration("1.0", "utf-8", "yes")); + _manufacturerReport = new XMLManufacturerReport(); //new XDocument(new XDeclaration("1.0", "utf-8", "yes")); _customerReport = new XMLCustomerReport(); //CustomerReport = new XDocument(new XDeclaration("1.0", "utf-8", "yes")); @@ -125,7 +125,7 @@ namespace TUGraz.VectoCore.OutputData.XML public XDocument FullReport { - get { return _fullReport.Report; } + get { return _manufacturerReport.Report; } } public XDocument CustomerReport @@ -142,28 +142,17 @@ namespace TUGraz.VectoCore.OutputData.XML protected internal override void DoWriteReport() { foreach (var result in Missions.OrderBy(m => m.Key)) { - _fullReport.AddResult(result.Value); + _manufacturerReport.AddResult(result.Value); _customerReport.AddResult(result.Value); } - _fullReport.GenerateReport(); - var fullReportHash = GetSignature(_fullReport.Report); + _manufacturerReport.GenerateReport(); + var fullReportHash = GetSignature(_manufacturerReport.Report); _customerReport.GenerateReport(fullReportHash); if (_writer != null) { - using (var xmlWriter = new XmlTextWriter(_writer.WriteStream(ReportType.DeclarationReportXMLFulll), Encoding.UTF8)) { - xmlWriter.Formatting = Formatting.Indented; - _fullReport.Report.WriteTo(xmlWriter); - xmlWriter.Flush(); - xmlWriter.Close(); - } - - using (var xmlWriter = new XmlTextWriter(_writer.WriteStream(ReportType.DeclarationReportXMLCOC), Encoding.UTF8)) { - xmlWriter.Formatting = Formatting.Indented; - _customerReport.Report.WriteTo(xmlWriter); - xmlWriter.Flush(); - xmlWriter.Close(); - } + _writer.WriteReport(ReportType.DeclarationReportCustomerXML, _customerReport.Report); + _writer.WriteReport(ReportType.DeclarationReportManufacturerXML, _manufacturerReport.Report); } } @@ -173,10 +162,10 @@ namespace TUGraz.VectoCore.OutputData.XML } - protected override void DoInitializeReport(VectoRunData modelData, Segment segment) + public override void InitializeReport(VectoRunData modelData) { - _fullReport.Initialize(modelData, segment); - _customerReport.Initialize(modelData, segment); + _manufacturerReport.Initialize(modelData); + _customerReport.Initialize(modelData); } diff --git a/VectoCore/VectoCore/OutputData/XML/XMLEngineeringWriter.cs b/VectoCore/VectoCore/OutputData/XML/XMLEngineeringWriter.cs index 4bba607d2ac88beb1ca31c34664a1eb1dc2699fb..18771c538e1345b74bba4a68d7fa91250ef15441 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLEngineeringWriter.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLEngineeringWriter.cs @@ -29,574 +29,574 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Data; -using System.IO; -using System.Text.RegularExpressions; -using System.Xml; -using System.Xml.Linq; -using TUGraz.IVT.VectoXML; -using TUGraz.IVT.VectoXML.Writer; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Resources; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.OutputData.XML -{ - public class XMLEngineeringWriter : AbstractXMLWriter - { - private readonly bool _singleFile; - private readonly XNamespace _declarationNamespace; - - - public XMLEngineeringWriter(string basePath, bool singleFile, string vendor) : base(basePath, vendor) - { - _singleFile = singleFile; - - tns = Constants.XML.VectoEngineeringDefinitionsNS; // "urn:tugraz:ivt:VectoAPI:EngineeringDefinitions:v0.6"; - rootNamespace = Constants.XML.VectoEngineeringInputNS; // "urn:tugraz:ivt:VectoAPI:EngineeringInput:v0.6"; - _declarationNamespace = Constants.XML.VectoDeclarationDefinitionsNS; - //"urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v0.6"; - } - - public XDocument GenerateVectoJob(IEngineeringInputDataProvider data) - { - var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); - - var job = new XDocument(); - job.Add(new XElement(rootNamespace + XMLNames.VectoInputEngineering, - new XAttribute("schemaVersion", SchemaVersion), - new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), - new XAttribute("xmlns", tns), - new XAttribute(XNamespace.Xmlns + "tns", rootNamespace), - new XAttribute(XNamespace.Xmlns + "vdecdef", _declarationNamespace), - new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoEngineeringInput.xsd", rootNamespace, SchemaLocationBaseUrl)), - data.JobInputData().EngineOnlyMode - ? CreateEngineOnly(data) - : CreateEngineeringJob(data)) - ); - return job; - } - - public XDocument GenerateVectoComponent(IGearboxEngineeringInputData gearbox, - ITorqueConverterEngineeringInputData torqueConverter) - { - return GenerateComponentDocument(CreateGearbox(gearbox, torqueConverter)); - } - - public XDocument GenerateVectoComponent(IAxleGearInputData data) - { - return GenerateComponentDocument(CreateAxlegear(data)); - } - - protected XDocument GenerateComponentDocument(XElement content) - { - var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); - - var component = new XDocument(); - component.Add(new XElement(rootNamespace + XMLNames.VectoComponentEngineering, - new XAttribute("schemaVersion", SchemaVersion), - new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), - new XAttribute("xmlns", tns), - new XAttribute(XNamespace.Xmlns + "tns", rootNamespace), - new XAttribute(XNamespace.Xmlns + "vdecdef", _declarationNamespace), - new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoEngineeringInput.xsd", rootNamespace, SchemaLocationBaseUrl)), - content) - ); - return component; - } - - protected XElement[] CreateEngineOnly(IEngineeringInputDataProvider data) - { - return new[] { - new XElement(tns + XMLNames.VectoJob_EngineOnlyMode, true), - CreateEngine(data.EngineInputData, false), - CreateMissions(data.JobInputData().Cycles) - }; - } - - protected XElement[] CreateEngineeringJob(IEngineeringInputDataProvider data) - { - return new[] { - new XElement(tns + XMLNames.VectoJob_EngineOnlyMode, false), - CreateVehicle(data), - CreateDriverModel(data), - CreateMissions(data.JobInputData().Cycles) - }; - } - - private XElement CreateMissions(IEnumerable<ICycleData> data) - { - var retVal = new XElement(tns + XMLNames.VectoJob_MissionCycles); - foreach (var cycle in data) { - var filename = cycle.CycleData.Source; - if (filename == null) { - continue; - } - VectoCSVFile.Write(Path.Combine(BasePath, Path.GetFileName(filename)), cycle.CycleData); - retVal.Add(new XElement(tns + XMLNames.Missions_Cycle, - new XAttribute(XMLNames.ExtResource_Type_Attr, XMLNames.ExtResource_Type_Value_CSV), - new XAttribute(XMLNames.ExtResource_File_Attr, Path.GetFileName(filename)) - ) - ); - } - return retVal; - } - - private XElement CreateDriverModel(IEngineeringInputDataProvider engineering) - { - var driver = engineering.DriverInputData; - var gbx = engineering.GearboxInputData; - var lookahead = driver.Lookahead; - var overspeed = driver.OverSpeedEcoRoll; - - return new XElement(tns + XMLNames.Component_DriverModel, - new XElement(tns + XMLNames.DriverModel_LookAheadCoasting, - new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_Enabled, lookahead.Enabled), - new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_MinSpeed, lookahead.MinSpeed.AsKmph), - new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_PreviewDistanceFactor, lookahead.LookaheadDistanceFactor), - new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_DecisionFactorOffset, - lookahead.CoastingDecisionFactorOffset), - new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_DecisionFactorScaling, - lookahead.CoastingDecisionFactorScaling), - lookahead.CoastingDecisionFactorTargetSpeedLookup == null - ? null - : new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_SpeedDependentDecisionFactor, - _singleFile - ? EmbedDataTable(lookahead.CoastingDecisionFactorTargetSpeedLookup, - AttributeMappings.CoastingDFTargetSpeedLookupMapping) - : ExtCSVResource(lookahead.CoastingDecisionFactorTargetSpeedLookup, "Driver_LAC_TargetspeedLookup.csv")), - lookahead.CoastingDecisionFactorVelocityDropLookup == null - ? null - : new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_VelocityDropDecisionFactor, - _singleFile - ? EmbedDataTable(lookahead.CoastingDecisionFactorVelocityDropLookup, - AttributeMappings.CoastingDFVelocityDropLookupMapping) - : ExtCSVResource(lookahead.CoastingDecisionFactorVelocityDropLookup, "Driver_LAC_VelocityDropLookup.csv")) - ), - new XElement(tns + XMLNames.DriverModel_Overspeed, - new XElement(tns + XMLNames.DriverModel_Overspeed_Mode, driver.OverSpeedEcoRoll.Mode), - new XElement(tns + XMLNames.DriverModel_Overspeed_MinSpeed, overspeed.MinSpeed.AsKmph), - new XElement(tns + XMLNames.DriverModel_Overspeed_AllowedOverspeed, overspeed.OverSpeed.AsKmph), - new XElement(tns + XMLNames.DriverModel_Overspeed_AllowedUnderspeed, overspeed.UnderSpeed.AsKmph) - ), - driver.AccelerationCurve == null - ? null - : new XElement(tns + XMLNames.DriverModel_DriverAccelerationCurve, - _singleFile - ? EmbedDataTable(driver.AccelerationCurve, AttributeMappings.DriverAccelerationCurveMapping) - : ExtCSVResource(driver.AccelerationCurve, - Path.GetFileName(driver.AccelerationCurve.Source ?? "Driver.vacc")) - ), - new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters, - new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_UpshiftMinAcceleration, - gbx.UpshiftMinAcceleration.Value()), - new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_DownshiftAfterUpshiftDelay, - gbx.DownshiftAfterUpshiftDelay.Value()), - new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_UpshiftAfterDownshiftDelay, - gbx.UpshiftAfterDownshiftDelay.Value()), - new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_TorqueReserve, gbx.TorqueReserve), - new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_TimeBetweenGearshift, - gbx.MinTimeBetweenGearshift.Value()), - new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_StartSpeed, gbx.StartSpeed.Value()), - new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_StartAcceleration, gbx.StartAcceleration.Value()), - new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_StartTorqueReserve, gbx.StartTorqueReserve)) - ); - } - - protected XElement CreateVehicle(IEngineeringInputDataProvider data) - { - var retarder = data.RetarderInputData; - var gearbox = data.GearboxInputData; - var vehicle = data.VehicleInputData; - var angledrive = data.AngledriveInputData; - var pto = data.PTOTransmissionInputData; - - return new XElement(tns + XMLNames.Component_Vehicle, - new XAttribute(XMLNames.Component_ID_Attr, "VEH-" + vehicle.Model), - GetDefaultComponentElements(vehicle.Model), - new XElement(tns + XMLNames.Vehicle_VehicleCategory, vehicle.VehicleCategory.ToXMLFormat()), - new XElement(tns + XMLNames.Vehicle_AxleConfiguration, vehicle.AxleConfiguration.GetName()), - new XElement(tns + XMLNames.Vehicle_CurbMassChassis, vehicle.CurbMassChassis.Value().ToXMLFormat(0)), - new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, vehicle.GrossVehicleMassRating.Value().ToXMLFormat(0)), - //new XElement(tns + XMLNames.Vehicle_AirDragArea, airdrag.AirDragArea.Value()), - new XElement(tns + XMLNames.Vehicle_RetarderType, retarder.Type.ToXMLFormat()), - retarder.Type.IsDedicatedComponent() - ? new XElement(tns + XMLNames.Vehicle_RetarderRatio, retarder.Ratio.ToXMLFormat(3)) - : null, - new XElement(tns + XMLNames.Vehicle_AngledriveType, angledrive.Type.ToXMLFormat()), - new XElement(tns + XMLNames.Vehicle_PTOType, pto.PTOTransmissionType), - GetPTOData(pto), - CreateTorqueLimits(vehicle), - new XElement(tns + XMLNames.Vehicle_CurbMassExtra, vehicle.CurbMassExtra.Value()), - new XElement(tns + XMLNames.Vehicle_Loading, vehicle.Loading.Value()), - new XElement(tns + XMLNames.Vehicle_Components, - CreateEngine(data.EngineInputData), - CreateGearbox(gearbox, gearbox.TorqueConverter), - angledrive.Type == AngledriveType.SeparateAngledrive ? CreateAngleDrive(angledrive) : null, - retarder.Type.IsDedicatedComponent() ? CreateRetarder(retarder) : null, - CreateAxlegear(data.AxleGearInputData), - CreateAxleWheels(data.VehicleInputData), - CreateAuxiliaries(data.AuxiliaryInputData(), RemoveInvalidFileCharacters(data.VehicleInputData.Model)), - CreateAirdrag(data.AirdragInputData) - ), - new XElement(tns + XMLNames.Vehicle_AdvancedDriverAssist, - new XElement(tns + XMLNames.Vehicle_AdvancedDriverAssist_EngineStartStop, - new XElement(tns + XMLNames.Vehicle_AdvancedDriverAssist_EngineStartStop_Enabled, false)) - )); - } - - - private object[] GetPTOData(IPTOTransmissionInputData pto) - { - if (pto.PTOTransmissionType == "None") { - return null; - } - var ptoLossMap = new XElement(tns + XMLNames.Vehicle_PTOIdleLossMap); - ptoLossMap.Add(_singleFile - ? EmbedDataTable(pto.PTOLossMap, AttributeMappings.PTOLossMap) - : ExtCSVResource(pto.PTOLossMap, "PTO_LossMap.vptol")); - var ptoCycle = new XElement(tns + XMLNames.Vehicle_PTOCycle); - ptoCycle.Add(_singleFile - ? EmbedDataTable(pto.PTOCycle, AttributeMappings.PTOCycleMap) - : ExtCSVResource(pto.PTOCycle, "PTO_cycle.vptoc")); - - return new object[] { ptoLossMap, ptoCycle }; - } - - private XElement GetCrossWindCorrectionData(IAirdragEngineeringInputData airdrag) - { - if (airdrag.CrossWindCorrectionMode == CrossWindCorrectionMode.NoCorrection || - airdrag.CrossWindCorrectionMode == CrossWindCorrectionMode.DeclarationModeCorrection) { - return null; - } - - var correctionMap = new XElement(tns + XMLNames.Vehicle_CrosswindCorrectionData); - - if (_singleFile) { - correctionMap.Add(EmbedDataTable(airdrag.CrosswindCorrectionMap, AttributeMappings.CrossWindCorrectionMapping)); - } else { - var ext = airdrag.CrossWindCorrectionMode == CrossWindCorrectionMode.SpeedDependentCorrectionFactor - ? "vcdv" - : "vcdb"; - correctionMap.Add(ExtCSVResource(airdrag.CrosswindCorrectionMap, "CrossWindCorrection." + ext)); - } - - return correctionMap; - } - - private XElement CreateAngleDrive(IAngledriveInputData data) - { - var angledrive = new XElement(tns + XMLNames.Component_Angledrive, - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, "ANGL-" + data.Model), - GetDefaultComponentElements(data.Model), - new XElement(tns + XMLNames.AngleDrive_Ratio, data.Ratio.ToXMLFormat(3)), - data.LossMap == null - ? new XElement(tns + XMLNames.AngleDrive_TorqueLossMap, - new XElement(tns + XMLNames.AngleDrive_Efficiency, data.Efficiency)) - : new XElement(tns + XMLNames.AngleDrive_TorqueLossMap, GetTransmissionLossMap(data.LossMap)))); - //if (_singleFile) { - return angledrive; - //} - //return ExtComponent(XMLNames.Component_Angledrive, angledrive, - // string.Format("ANGL_{0}.xml", RemoveInvalidFileCharacters(data.ModelName))); - } - - private string RemoveInvalidFileCharacters(string filename) - { - string regexSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); - Regex r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch))); - return r.Replace(filename, ""); - } - - public XElement CreateAuxiliaries(IAuxiliariesEngineeringInputData data, string fileSuffix) - { - var auxList = new List<XElement>(); - foreach (var auxData in data.Auxiliaries) { - var entry = new XElement(tns + XMLNames.Auxiliaries_Auxiliary, - new XAttribute(XMLNames.Auxiliaries_Auxiliary_ID_Attr, auxData.ID)); - if (auxData.ConstantPowerDemand > 0) { - entry.Add(new XElement(tns + XMLNames.Auxiliaries_Auxiliary_ConstantAuxLoad, auxData.ConstantPowerDemand.Value())); - auxList.Add(entry); - continue; - } - if (_singleFile) { - entry.Add(new XElement(tns + XMLNames.Auxiliaries_Auxiliary_TransmissionRatioToEngine, auxData.TransmissionRatio), - new XElement(tns + XMLNames.Auxiliaries_Auxiliary_EfficiencyToEngine, auxData.EfficiencyToEngine), - new XElement(tns + XMLNames.Auxiliaries_Auxiliary_EfficiencyAuxSupply, auxData.EfficiencyToSupply), - new XElement(tns + XMLNames.Auxiliaries_Auxiliary_AuxMap, - EmbedDataTable(auxData.DemandMap, AttributeMappings.AuxMapMapping))); - } else { - entry.Add(ExtCSVResource(auxData.DemandMap, Path.GetFileName(auxData.DemandMap.Source))); - } - } - - var aux = new XElement(tns + XMLNames.Component_Auxiliaries, - new XElement(tns + XMLNames.ComponentDataWrapper, - //new XAttribute(XMLNames.Component_ID_Attr, "AUX-none"), - auxList)); - if (_singleFile) { - return aux; - } - return ExtComponent(XMLNames.Component_Auxiliaries, aux, string.Format("AUX_{0}.xml", fileSuffix)); - } - - public XElement CreateAxleWheels(IVehicleEngineeringInputData data) - { - var axleData = data.Axles; - var numAxles = axleData.Count; - var axles = new List<XElement>(numAxles); - for (var i = 0; i < numAxles; i++) { - var axle = axleData[i]; - axles.Add(new XElement(tns + XMLNames.AxleWheels_Axles_Axle, - new XAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, i + 1), - GetDefaultComponentElements(axle.Wheels), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_AxleType, - i == 1 ? AxleType.VehicleDriven.ToString() : AxleType.VehicleNonDriven.ToString()), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_TwinTyres_Attr, axle.TwinTyres), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Steered, i == 0), - string.IsNullOrWhiteSpace(axle.Wheels) - ? null - : new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Dimension, axle.Wheels), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_RRCISO, axle.RollResistanceCoefficient), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_FzISO, axle.TyreTestLoad.Value()), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_WeightShare, axle.AxleWeightShare), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Inertia, axle.Inertia.Value()), - i == 1 - ? new XElement(tns + XMLNames.AxleWheels_Axles_Axle_DynamicTyreRadius, data.DynamicTyreRadius.Value() * 1000) - : null)); - } - - var axleWheels = new XElement(tns + XMLNames.Component_AxleWheels, - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, string.Format("AXLWHL-{0}", data.AxleConfiguration.GetName())), - new XElement(tns + XMLNames.AxleWheels_Axles, axles))); - if (_singleFile) { - return axleWheels; - } - return ExtComponent(XMLNames.Component_AxleWheels, axleWheels, - String.Format("AXLWHL-{0}.xml", data.AxleConfiguration.GetName())); - } - - //private XElement CreateTyre(IAxleDeclarationInputData axle) - //{ - // var id = string.Format("TYRE-{0}", axle.Wheels).RemoveWhitespace().Replace("/", "_"); - // return new XElement(tns + "Tyre", - // new XAttribute(XMLNames.Component_CertificationNumber, id), - // new XElement(tns + XMLNames.ComponentDataWrapper, - // GetDefaultComponentElements(string.Format("TYRE-{0}", axle.Wheels), axle.Wheels), - // string.IsNullOrWhiteSpace(axle.Wheels) - // ? null - // : new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Dimension, axle.Wheels), - // new XElement(tns + XMLNames.AxleWheels_Axles_Axle_RRCISO, axle.RollResistanceCoefficient.ToXMLFormat(4)), - // new XElement(tns + XMLNames.AxleWheels_Axles_Axle_FzISO, axle.TyreTestLoad.Value().ToXMLFormat(0)) - // ) - // ); - //} - - public XElement CreateAxlegear(IAxleGearInputData data) - { - var typeId = string.Format("AXLGEAR-{0:0.000}", data.Ratio); - var axl = new XElement(tns + XMLNames.Component_Axlegear, - new XElement(tns + XMLNames.ComponentDataWrapper, new XAttribute(XMLNames.Component_ID_Attr, typeId), - GetDefaultComponentElements("N.A."), - new XElement(tns + XMLNames.Axlegear_Ratio, data.Ratio.ToXMLFormat(3)), - data.LossMap == null - ? new XElement(tns + XMLNames.Axlegear_TorqueLossMap, - new XElement(tns + XMLNames.Axlegear_Efficiency, data.Efficiency)) - : new XElement(tns + XMLNames.Axlegear_TorqueLossMap, GetTransmissionLossMap(data.LossMap)))); - if (_singleFile) { - return axl; - } - return ExtComponent(XMLNames.Component_Axlegear, axl, string.Format("AXL_{0:0.00}.xml", data.Ratio)); - } - - - public XElement CreateRetarder(IRetarderInputData data) - { - var retarder = new XElement(tns + XMLNames.Component_Retarder, - new XElement(tns + XMLNames.ComponentDataWrapper, new XAttribute(XMLNames.Component_ID_Attr, "RET-none"), - GetDefaultComponentElements(data.Model), - new XElement(tns + XMLNames.Retarder_RetarderLossMap, - _singleFile - ? EmbedDataTable(data.LossMap, AttributeMappings.RetarderLossmapMapping) - : ExtCSVResource(data.LossMap, string.Format("RET_{0}.vrlm", RemoveInvalidFileCharacters(data.Model)))))); - //if (_singleFile) { - return retarder; - //} - //return ExtComponent(XMLNames.Component_Retarder, retarder, - // string.Format("RET_{0}.xml", RemoveInvalidFileCharacters(data.ModelName))); - } - - protected XElement CreateGearbox(IGearboxEngineeringInputData data, ITorqueConverterEngineeringInputData tcData) - { - var gears = new XElement(tns + XMLNames.Gearbox_Gears); - var i = 1; - foreach (var gearData in data.Gears) { - var gear = new XElement(tns + XMLNames.Gearbox_Gears_Gear, - new XAttribute(XMLNames.Gearbox_Gear_GearNumber_Attr, i++), - new XElement(tns + XMLNames.Gearbox_Gear_Ratio, gearData.Ratio.ToXMLFormat(3)), - gearData.MaxTorque != null - ? new XElement(tns + XMLNames.Gearbox_Gears_MaxTorque, gearData.MaxTorque.Value()) - : null, - gearData.MaxInputSpeed != null - ? new XElement(tns + XMLNames.Gearbox_Gear_MaxSpeed, gearData.MaxInputSpeed.AsRPM) - : null); - - if (gearData.LossMap != null) { - gear.Add(new XElement(tns + XMLNames.Gearbox_Gear_TorqueLossMap, GetTransmissionLossMap(gearData.LossMap))); - } else { - gear.Add(new XElement(tns + XMLNames.Gearbox_Gear_TorqueLossMap, - new XElement(tns + XMLNames.Gearbox_Gear_Efficiency, gearData.Efficiency))); - } - if (gearData.ShiftPolygon != null) { - gear.Add(new XElement(tns + XMLNames.Gearbox_Gears_Gear_ShiftPolygon, CreateShiftPolygon(gearData.ShiftPolygon))); - } - - gears.Add(gear); - } - var gbx = new XElement(tns + XMLNames.Component_Gearbox, - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, string.Format("GBX-{0}", data.Model)), - GetDefaultComponentElements(data.Model), - new XElement(tns + XMLNames.Gearbox_TransmissionType, data.Type.ToXMLFormat()), - new XElement(tns + XMLNames.Gearbox_Inertia, data.Inertia.Value()), - new XElement(tns + XMLNames.Gearbox_TractionInterruption, data.TractionInterruption.Value()), gears), - data.Type.AutomaticTransmission() ? CreateTorqueConverter(tcData) : null); - - if (_singleFile) { - return gbx; - } - return ExtComponent(XMLNames.Component_Gearbox, gbx, string.Format("GBX-{0}.xml", data.Model)); - } - - private XElement CreateTorqueConverter(ITorqueConverterEngineeringInputData torqueConverterData) - { - var tc = new XElement(tns + XMLNames.Component_TorqueConverter, - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, string.Format("TC-{0}", torqueConverterData.Model)), - GetDefaultComponentElements(torqueConverterData.Model), - new XElement(tns + XMLNames.TorqueConverter_ReferenceRPM, torqueConverterData.ReferenceRPM.AsRPM.ToXMLFormat()), - new XElement(tns + XMLNames.TorqueConverter_Characteristics, - _singleFile - ? EmbedDataTable(torqueConverterData.TCData, AttributeMappings.TorqueConverterDataMapping, - precision: new Dictionary<string, uint>() { - { TorqueConverterDataReader.Fields.SpeedRatio, 4 } - }) - : ExtCSVResource(torqueConverterData.TCData, Path.GetFileName(torqueConverterData.TCData.Source))), - new XElement(tns + XMLNames.TorqueConverter_Inertia, torqueConverterData.Inertia.Value()))); - if (_singleFile) { - return tc; - } - return new XElement(tns + XMLNames.Component_TorqueConverter, - ExtComponent(XMLNames.Component_TorqueConverter, tc, "TorqueConverter.xml")); - } - - private object[] GetTransmissionLossMap(TableData lossmap) - { - if (_singleFile) { - return EmbedDataTable(lossmap, AttributeMappings.TransmissionLossmapMapping); - } - return ExtCSVResource(lossmap, Path.GetFileName(lossmap.Source)); - } - - private object[] CreateShiftPolygon(TableData shiftPolygon) - { - if (_singleFile) { - return EmbedDataTable(shiftPolygon, AttributeMappings.ShiftPolygonMapping); - } - return ExtCSVResource(shiftPolygon, Path.GetFileName(shiftPolygon.Source)); - } - - public XElement CreateEngine(IEngineEngineeringInputData data, bool allowSeparateFile = true) - { - var engine = new XElement(tns + XMLNames.Component_Engine, - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, string.Format("ENG-{0}", data.Model)), - GetDefaultComponentElements(data.Model), - new XElement(tns + XMLNames.Engine_Displacement, (data.Displacement.Value() * 1000 * 1000).ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_IdlingSpeed, data.IdleSpeed.AsRPM.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_Inertia, data.Inertia.Value()), - new XElement(tns + XMLNames.Engine_WHTCEngineering, data.WHTCEngineering.ToXMLFormat(4)), - new XElement(tns + XMLNames.Engine_FuelConsumptionMap, GetFuelConsumptionMap(data)), - new XElement(tns + XMLNames.Engine_FullLoadAndDragCurve, GetFullLoadDragCurve(data)))); - if (!allowSeparateFile || _singleFile) { - return engine; - } - return ExtComponent(XMLNames.Component_Engine, engine, string.Format("ENG-{0}.xml", data.Model)); - } - - private XElement CreateAirdrag(IAirdragEngineeringInputData data) - { - var id = string.Format("Airdrag-{0}", data.Model); - return new XElement(tns + XMLNames.Component_AirDrag, - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, id), - GetDefaultComponentElements("N.A."), - new XElement(tns + XMLNames.Vehicle_CrossWindCorrectionMode, data.CrossWindCorrectionMode.ToXMLFormat()), - new XElement(tns + XMLNames.Vehicle_AirDragArea, data.AirDragArea.Value().ToXMLFormat(2))), - GetCrossWindCorrectionData(data) - ); - } - - private XElement ExtComponent(string component, XElement componentXML, string filename) - { - GenerateComponentDocument(componentXML).Save(Path.Combine(BasePath, filename)); - - var retVal = new XElement(tns + XMLNames.ExternalResource, - new XAttribute(XMLNames.ExtResource_Type_Attr, XMLNames.ExtResource_Type_Value_XML), - new XAttribute(XMLNames.ExtResource_Component_Attr, component), - new XAttribute(XMLNames.ExtResource_File_Attr, filename)); - return retVal; - } - - private object[] GetFullLoadDragCurve(IEngineEngineeringInputData data) - { - if (_singleFile) { - return EmbedDataTable(data.FullLoadCurve, AttributeMappings.EngineFullLoadCurveMapping); - } - var filename = string.Format("ENG_{0}.vfld", data.Model); - return ExtCSVResource(data.FullLoadCurve, filename); - } - - private object[] GetFuelConsumptionMap(IEngineEngineeringInputData data) - { - if (_singleFile) { - return EmbedDataTable(data.FuelConsumptionMap, AttributeMappings.FuelConsumptionMapMapping); - } - - var filename = string.Format("ENG_{0}.vmap", data.Model); - return ExtCSVResource(data.FuelConsumptionMap, filename); - } - - - private object[] ExtCSVResource(DataTable data, string filename) - { - VectoCSVFile.Write(Path.Combine(BasePath, filename), data); - return new object[] { - new XElement(tns + XMLNames.ExternalResource, - new XAttribute(XMLNames.ExtResource_Type_Attr, XMLNames.ExtResource_Type_Value_CSV), - new XAttribute(XMLNames.ExtResource_File_Attr, filename)) - }; - } - - protected XElement[] GetDefaultComponentElements(string makeAndModel) - { - return new[] { - new XElement(tns + XMLNames.Component_Manufacturer, Vendor), - new XElement(tns + XMLNames.Component_Model, makeAndModel), - new XElement(tns + XMLNames.Component_Creator, Creator), - new XElement(tns + XMLNames.Component_Date, XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)), - new XElement(tns + XMLNames.Component_AppVersion, "VectoCore"), - }; - } - } +using System; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Text.RegularExpressions; +using System.Xml; +using System.Xml.Linq; +using TUGraz.IVT.VectoXML; +using TUGraz.IVT.VectoXML.Writer; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.OutputData.XML +{ + public class XMLEngineeringWriter : AbstractXMLWriter + { + private readonly bool _singleFile; + private readonly XNamespace _declarationNamespace; + + + public XMLEngineeringWriter(string basePath, bool singleFile, string vendor) : base(basePath, vendor) + { + _singleFile = singleFile; + + tns = Constants.XML.VectoEngineeringDefinitionsNS; // "urn:tugraz:ivt:VectoAPI:EngineeringDefinitions:v0.6"; + rootNamespace = Constants.XML.VectoEngineeringInputNS; // "urn:tugraz:ivt:VectoAPI:EngineeringInput:v0.6"; + _declarationNamespace = Constants.XML.VectoDeclarationDefinitionsNS; + //"urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v0.6"; + } + + public XDocument GenerateVectoJob(IEngineeringInputDataProvider data) + { + var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); + + var job = new XDocument(); + job.Add(new XElement(rootNamespace + XMLNames.VectoInputEngineering, + new XAttribute("schemaVersion", SchemaVersion), + new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), + new XAttribute("xmlns", tns), + new XAttribute(XNamespace.Xmlns + "tns", rootNamespace), + new XAttribute(XNamespace.Xmlns + "vdecdef", _declarationNamespace), + new XAttribute(xsi + "schemaLocation", + string.Format("{0} {1}VectoEngineeringInput.xsd", rootNamespace, SchemaLocationBaseUrl)), + data.JobInputData().EngineOnlyMode + ? CreateEngineOnly(data) + : CreateEngineeringJob(data)) + ); + return job; + } + + public XDocument GenerateVectoComponent(IGearboxEngineeringInputData gearbox, + ITorqueConverterEngineeringInputData torqueConverter) + { + return GenerateComponentDocument(CreateGearbox(gearbox, torqueConverter)); + } + + public XDocument GenerateVectoComponent(IAxleGearInputData data) + { + return GenerateComponentDocument(CreateAxlegear(data)); + } + + protected XDocument GenerateComponentDocument(XElement content) + { + var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); + + var component = new XDocument(); + component.Add(new XElement(rootNamespace + XMLNames.VectoComponentEngineering, + new XAttribute("schemaVersion", SchemaVersion), + new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), + new XAttribute("xmlns", tns), + new XAttribute(XNamespace.Xmlns + "tns", rootNamespace), + new XAttribute(XNamespace.Xmlns + "vdecdef", _declarationNamespace), + new XAttribute(xsi + "schemaLocation", + string.Format("{0} {1}VectoEngineeringInput.xsd", rootNamespace, SchemaLocationBaseUrl)), + content) + ); + return component; + } + + protected XElement[] CreateEngineOnly(IEngineeringInputDataProvider data) + { + return new[] { + new XElement(tns + XMLNames.VectoJob_EngineOnlyMode, true), + CreateEngine(data.EngineInputData, false), + CreateMissions(data.JobInputData().Cycles) + }; + } + + protected XElement[] CreateEngineeringJob(IEngineeringInputDataProvider data) + { + return new[] { + new XElement(tns + XMLNames.VectoJob_EngineOnlyMode, false), + CreateVehicle(data), + CreateDriverModel(data), + CreateMissions(data.JobInputData().Cycles) + }; + } + + private XElement CreateMissions(IEnumerable<ICycleData> data) + { + var retVal = new XElement(tns + XMLNames.VectoJob_MissionCycles); + foreach (var cycle in data) { + var filename = cycle.CycleData.Source; + if (filename == null) { + continue; + } + VectoCSVFile.Write(Path.Combine(BasePath, Path.GetFileName(filename)), cycle.CycleData); + retVal.Add(new XElement(tns + XMLNames.Missions_Cycle, + new XAttribute(XMLNames.ExtResource_Type_Attr, XMLNames.ExtResource_Type_Value_CSV), + new XAttribute(XMLNames.ExtResource_File_Attr, Path.GetFileName(filename)) + ) + ); + } + return retVal; + } + + private XElement CreateDriverModel(IEngineeringInputDataProvider engineering) + { + var driver = engineering.DriverInputData; + var gbx = engineering.GearboxInputData; + var lookahead = driver.Lookahead; + var overspeed = driver.OverSpeedEcoRoll; + + return new XElement(tns + XMLNames.Component_DriverModel, + new XElement(tns + XMLNames.DriverModel_LookAheadCoasting, + new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_Enabled, lookahead.Enabled), + new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_MinSpeed, lookahead.MinSpeed.AsKmph), + new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_PreviewDistanceFactor, lookahead.LookaheadDistanceFactor), + new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_DecisionFactorOffset, + lookahead.CoastingDecisionFactorOffset), + new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_DecisionFactorScaling, + lookahead.CoastingDecisionFactorScaling), + lookahead.CoastingDecisionFactorTargetSpeedLookup == null + ? null + : new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_SpeedDependentDecisionFactor, + _singleFile + ? EmbedDataTable(lookahead.CoastingDecisionFactorTargetSpeedLookup, + AttributeMappings.CoastingDFTargetSpeedLookupMapping) + : ExtCSVResource(lookahead.CoastingDecisionFactorTargetSpeedLookup, "Driver_LAC_TargetspeedLookup.csv")), + lookahead.CoastingDecisionFactorVelocityDropLookup == null + ? null + : new XElement(tns + XMLNames.DriverModel_LookAheadCoasting_VelocityDropDecisionFactor, + _singleFile + ? EmbedDataTable(lookahead.CoastingDecisionFactorVelocityDropLookup, + AttributeMappings.CoastingDFVelocityDropLookupMapping) + : ExtCSVResource(lookahead.CoastingDecisionFactorVelocityDropLookup, "Driver_LAC_VelocityDropLookup.csv")) + ), + new XElement(tns + XMLNames.DriverModel_Overspeed, + new XElement(tns + XMLNames.DriverModel_Overspeed_Mode, driver.OverSpeedEcoRoll.Mode), + new XElement(tns + XMLNames.DriverModel_Overspeed_MinSpeed, overspeed.MinSpeed.AsKmph), + new XElement(tns + XMLNames.DriverModel_Overspeed_AllowedOverspeed, overspeed.OverSpeed.AsKmph), + new XElement(tns + XMLNames.DriverModel_Overspeed_AllowedUnderspeed, overspeed.UnderSpeed.AsKmph) + ), + driver.AccelerationCurve == null + ? null + : new XElement(tns + XMLNames.DriverModel_DriverAccelerationCurve, + _singleFile + ? EmbedDataTable(driver.AccelerationCurve, AttributeMappings.DriverAccelerationCurveMapping) + : ExtCSVResource(driver.AccelerationCurve, + Path.GetFileName(driver.AccelerationCurve.Source ?? "Driver.vacc")) + ), + new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters, + new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_UpshiftMinAcceleration, + gbx.UpshiftMinAcceleration.Value()), + new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_DownshiftAfterUpshiftDelay, + gbx.DownshiftAfterUpshiftDelay.Value()), + new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_UpshiftAfterDownshiftDelay, + gbx.UpshiftAfterDownshiftDelay.Value()), + new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_TorqueReserve, gbx.TorqueReserve), + new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_TimeBetweenGearshift, + gbx.MinTimeBetweenGearshift.Value()), + new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_StartSpeed, gbx.StartSpeed.Value()), + new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_StartAcceleration, gbx.StartAcceleration.Value()), + new XElement(tns + XMLNames.DriverModel_ShiftStrategyParameters_StartTorqueReserve, gbx.StartTorqueReserve)) + ); + } + + protected XElement CreateVehicle(IEngineeringInputDataProvider data) + { + var retarder = data.RetarderInputData; + var gearbox = data.GearboxInputData; + var vehicle = data.VehicleInputData; + var angledrive = data.AngledriveInputData; + var pto = data.PTOTransmissionInputData; + + return new XElement(tns + XMLNames.Component_Vehicle, + new XAttribute(XMLNames.Component_ID_Attr, "VEH-" + vehicle.Model), + GetDefaultComponentElements(vehicle.Model), + new XElement(tns + XMLNames.Vehicle_VehicleCategory, vehicle.VehicleCategory.ToXMLFormat()), + new XElement(tns + XMLNames.Vehicle_AxleConfiguration, vehicle.AxleConfiguration.GetName()), + new XElement(tns + XMLNames.Vehicle_CurbMassChassis, vehicle.CurbMassChassis.Value().ToXMLFormat(0)), + new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, vehicle.GrossVehicleMassRating.Value().ToXMLFormat(0)), + //new XElement(tns + XMLNames.Vehicle_AirDragArea, airdrag.AirDragArea.Value()), + new XElement(tns + XMLNames.Vehicle_RetarderType, retarder.Type.ToXMLFormat()), + retarder.Type.IsDedicatedComponent() + ? new XElement(tns + XMLNames.Vehicle_RetarderRatio, retarder.Ratio.ToXMLFormat(3)) + : null, + new XElement(tns + XMLNames.Vehicle_AngledriveType, angledrive.Type.ToXMLFormat()), + new XElement(tns + XMLNames.Vehicle_PTOType, pto.PTOTransmissionType), + GetPTOData(pto), + CreateTorqueLimits(vehicle), + new XElement(tns + XMLNames.Vehicle_CurbMassExtra, vehicle.CurbMassExtra.Value()), + new XElement(tns + XMLNames.Vehicle_Loading, vehicle.Loading.Value()), + new XElement(tns + XMLNames.Vehicle_Components, + CreateEngine(data.EngineInputData), + CreateGearbox(gearbox, gearbox.TorqueConverter), + angledrive.Type == AngledriveType.SeparateAngledrive ? CreateAngleDrive(angledrive) : null, + retarder.Type.IsDedicatedComponent() ? CreateRetarder(retarder) : null, + CreateAxlegear(data.AxleGearInputData), + CreateAxleWheels(data.VehicleInputData), + CreateAuxiliaries(data.AuxiliaryInputData(), RemoveInvalidFileCharacters(data.VehicleInputData.Model)), + CreateAirdrag(data.AirdragInputData) + ), + new XElement(tns + XMLNames.Vehicle_AdvancedDriverAssist, + new XElement(tns + XMLNames.Vehicle_AdvancedDriverAssist_EngineStartStop, + new XElement(tns + XMLNames.Vehicle_AdvancedDriverAssist_EngineStartStop_Enabled, false)) + )); + } + + + private object[] GetPTOData(IPTOTransmissionInputData pto) + { + if (pto.PTOTransmissionType == "None") { + return null; + } + var ptoLossMap = new XElement(tns + XMLNames.Vehicle_PTOIdleLossMap); + ptoLossMap.Add(_singleFile + ? EmbedDataTable(pto.PTOLossMap, AttributeMappings.PTOLossMap) + : ExtCSVResource(pto.PTOLossMap, "PTO_LossMap.vptol")); + var ptoCycle = new XElement(tns + XMLNames.Vehicle_PTOCycle); + ptoCycle.Add(_singleFile + ? EmbedDataTable(pto.PTOCycle, AttributeMappings.PTOCycleMap) + : ExtCSVResource(pto.PTOCycle, "PTO_cycle.vptoc")); + + return new object[] { ptoLossMap, ptoCycle }; + } + + private XElement GetCrossWindCorrectionData(IAirdragEngineeringInputData airdrag) + { + if (airdrag.CrossWindCorrectionMode == CrossWindCorrectionMode.NoCorrection || + airdrag.CrossWindCorrectionMode == CrossWindCorrectionMode.DeclarationModeCorrection) { + return null; + } + + var correctionMap = new XElement(tns + XMLNames.Vehicle_CrosswindCorrectionData); + + if (_singleFile) { + correctionMap.Add(EmbedDataTable(airdrag.CrosswindCorrectionMap, AttributeMappings.CrossWindCorrectionMapping)); + } else { + var ext = airdrag.CrossWindCorrectionMode == CrossWindCorrectionMode.SpeedDependentCorrectionFactor + ? "vcdv" + : "vcdb"; + correctionMap.Add(ExtCSVResource(airdrag.CrosswindCorrectionMap, "CrossWindCorrection." + ext)); + } + + return correctionMap; + } + + private XElement CreateAngleDrive(IAngledriveInputData data) + { + var angledrive = new XElement(tns + XMLNames.Component_Angledrive, + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, "ANGL-" + data.Model), + GetDefaultComponentElements(data.Model), + new XElement(tns + XMLNames.AngleDrive_Ratio, data.Ratio.ToXMLFormat(3)), + data.LossMap == null + ? new XElement(tns + XMLNames.AngleDrive_TorqueLossMap, + new XElement(tns + XMLNames.AngleDrive_Efficiency, data.Efficiency)) + : new XElement(tns + XMLNames.AngleDrive_TorqueLossMap, GetTransmissionLossMap(data.LossMap)))); + //if (_singleFile) { + return angledrive; + //} + //return ExtComponent(XMLNames.Component_Angledrive, angledrive, + // string.Format("ANGL_{0}.xml", RemoveInvalidFileCharacters(data.ModelName))); + } + + private string RemoveInvalidFileCharacters(string filename) + { + string regexSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); + Regex r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch))); + return r.Replace(filename, ""); + } + + public XElement CreateAuxiliaries(IAuxiliariesEngineeringInputData data, string fileSuffix) + { + var auxList = new List<XElement>(); + foreach (var auxData in data.Auxiliaries) { + var entry = new XElement(tns + XMLNames.Auxiliaries_Auxiliary, + new XAttribute(XMLNames.Auxiliaries_Auxiliary_ID_Attr, auxData.ID)); + if (auxData.ConstantPowerDemand > 0) { + entry.Add(new XElement(tns + XMLNames.Auxiliaries_Auxiliary_ConstantAuxLoad, auxData.ConstantPowerDemand.Value())); + auxList.Add(entry); + continue; + } + if (_singleFile) { + entry.Add(new XElement(tns + XMLNames.Auxiliaries_Auxiliary_TransmissionRatioToEngine, auxData.TransmissionRatio), + new XElement(tns + XMLNames.Auxiliaries_Auxiliary_EfficiencyToEngine, auxData.EfficiencyToEngine), + new XElement(tns + XMLNames.Auxiliaries_Auxiliary_EfficiencyAuxSupply, auxData.EfficiencyToSupply), + new XElement(tns + XMLNames.Auxiliaries_Auxiliary_AuxMap, + EmbedDataTable(auxData.DemandMap, AttributeMappings.AuxMapMapping))); + } else { + entry.Add(ExtCSVResource(auxData.DemandMap, Path.GetFileName(auxData.DemandMap.Source))); + } + } + + var aux = new XElement(tns + XMLNames.Component_Auxiliaries, + new XElement(tns + XMLNames.ComponentDataWrapper, + //new XAttribute(XMLNames.Component_ID_Attr, "AUX-none"), + auxList)); + if (_singleFile) { + return aux; + } + return ExtComponent(XMLNames.Component_Auxiliaries, aux, string.Format("AUX_{0}.xml", fileSuffix)); + } + + public XElement CreateAxleWheels(IVehicleEngineeringInputData data) + { + var axleData = data.Axles; + var numAxles = axleData.Count; + var axles = new List<XElement>(numAxles); + for (var i = 0; i < numAxles; i++) { + var axle = axleData[i]; + axles.Add(new XElement(tns + XMLNames.AxleWheels_Axles_Axle, + new XAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, i + 1), + GetDefaultComponentElements(axle.Wheels), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_AxleType, + i == 1 ? AxleType.VehicleDriven.ToString() : AxleType.VehicleNonDriven.ToString()), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_TwinTyres_Attr, axle.TwinTyres), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Steered, i == 0), + string.IsNullOrWhiteSpace(axle.Wheels) + ? null + : new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Dimension, axle.Wheels), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_RRCISO, axle.RollResistanceCoefficient), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_FzISO, axle.TyreTestLoad.Value()), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_WeightShare, axle.AxleWeightShare), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Inertia, axle.Inertia.Value()), + i == 1 + ? new XElement(tns + XMLNames.AxleWheels_Axles_Axle_DynamicTyreRadius, data.DynamicTyreRadius.Value() * 1000) + : null)); + } + + var axleWheels = new XElement(tns + XMLNames.Component_AxleWheels, + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, string.Format("AXLWHL-{0}", data.AxleConfiguration.GetName())), + new XElement(tns + XMLNames.AxleWheels_Axles, axles))); + if (_singleFile) { + return axleWheels; + } + return ExtComponent(XMLNames.Component_AxleWheels, axleWheels, + String.Format("AXLWHL-{0}.xml", data.AxleConfiguration.GetName())); + } + + //private XElement CreateTyre(IAxleDeclarationInputData axle) + //{ + // var id = string.Format("TYRE-{0}", axle.Wheels).RemoveWhitespace().Replace("/", "_"); + // return new XElement(tns + "Tyre", + // new XAttribute(XMLNames.Component_CertificationNumber, id), + // new XElement(tns + XMLNames.ComponentDataWrapper, + // GetDefaultComponentElements(string.Format("TYRE-{0}", axle.Wheels), axle.Wheels), + // string.IsNullOrWhiteSpace(axle.Wheels) + // ? null + // : new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Dimension, axle.Wheels), + // new XElement(tns + XMLNames.AxleWheels_Axles_Axle_RRCISO, axle.RollResistanceCoefficient.ToXMLFormat(4)), + // new XElement(tns + XMLNames.AxleWheels_Axles_Axle_FzISO, axle.TyreTestLoad.Value().ToXMLFormat(0)) + // ) + // ); + //} + + public XElement CreateAxlegear(IAxleGearInputData data) + { + var typeId = string.Format("AXLGEAR-{0:0.000}", data.Ratio); + var axl = new XElement(tns + XMLNames.Component_Axlegear, + new XElement(tns + XMLNames.ComponentDataWrapper, new XAttribute(XMLNames.Component_ID_Attr, typeId), + GetDefaultComponentElements("N.A."), + new XElement(tns + XMLNames.Axlegear_Ratio, data.Ratio.ToXMLFormat(3)), + data.LossMap == null + ? new XElement(tns + XMLNames.Axlegear_TorqueLossMap, + new XElement(tns + XMLNames.Axlegear_Efficiency, data.Efficiency)) + : new XElement(tns + XMLNames.Axlegear_TorqueLossMap, GetTransmissionLossMap(data.LossMap)))); + if (_singleFile) { + return axl; + } + return ExtComponent(XMLNames.Component_Axlegear, axl, string.Format("AXL_{0:0.00}.xml", data.Ratio)); + } + + + public XElement CreateRetarder(IRetarderInputData data) + { + var retarder = new XElement(tns + XMLNames.Component_Retarder, + new XElement(tns + XMLNames.ComponentDataWrapper, new XAttribute(XMLNames.Component_ID_Attr, "RET-none"), + GetDefaultComponentElements(data.Model), + new XElement(tns + XMLNames.Retarder_RetarderLossMap, + _singleFile + ? EmbedDataTable(data.LossMap, AttributeMappings.RetarderLossmapMapping) + : ExtCSVResource(data.LossMap, string.Format("RET_{0}.vrlm", RemoveInvalidFileCharacters(data.Model)))))); + //if (_singleFile) { + return retarder; + //} + //return ExtComponent(XMLNames.Component_Retarder, retarder, + // string.Format("RET_{0}.xml", RemoveInvalidFileCharacters(data.ModelName))); + } + + protected XElement CreateGearbox(IGearboxEngineeringInputData data, ITorqueConverterEngineeringInputData tcData) + { + var gears = new XElement(tns + XMLNames.Gearbox_Gears); + var i = 1; + foreach (var gearData in data.Gears) { + var gear = new XElement(tns + XMLNames.Gearbox_Gears_Gear, + new XAttribute(XMLNames.Gearbox_Gear_GearNumber_Attr, i++), + new XElement(tns + XMLNames.Gearbox_Gear_Ratio, gearData.Ratio.ToXMLFormat(3)), + gearData.MaxTorque != null + ? new XElement(tns + XMLNames.Gearbox_Gears_MaxTorque, gearData.MaxTorque.Value()) + : null, + gearData.MaxInputSpeed != null + ? new XElement(tns + XMLNames.Gearbox_Gear_MaxSpeed, gearData.MaxInputSpeed.AsRPM) + : null); + + if (gearData.LossMap != null) { + gear.Add(new XElement(tns + XMLNames.Gearbox_Gear_TorqueLossMap, GetTransmissionLossMap(gearData.LossMap))); + } else { + gear.Add(new XElement(tns + XMLNames.Gearbox_Gear_TorqueLossMap, + new XElement(tns + XMLNames.Gearbox_Gear_Efficiency, gearData.Efficiency))); + } + if (gearData.ShiftPolygon != null) { + gear.Add(new XElement(tns + XMLNames.Gearbox_Gears_Gear_ShiftPolygon, CreateShiftPolygon(gearData.ShiftPolygon))); + } + + gears.Add(gear); + } + var gbx = new XElement(tns + XMLNames.Component_Gearbox, + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, string.Format("GBX-{0}", data.Model)), + GetDefaultComponentElements(data.Model), + new XElement(tns + XMLNames.Gearbox_TransmissionType, data.Type.ToXMLFormat()), + new XElement(tns + XMLNames.Gearbox_Inertia, data.Inertia.Value()), + new XElement(tns + XMLNames.Gearbox_TractionInterruption, data.TractionInterruption.Value()), gears), + data.Type.AutomaticTransmission() ? CreateTorqueConverter(tcData) : null); + + if (_singleFile) { + return gbx; + } + return ExtComponent(XMLNames.Component_Gearbox, gbx, string.Format("GBX-{0}.xml", data.Model)); + } + + private XElement CreateTorqueConverter(ITorqueConverterEngineeringInputData torqueConverterData) + { + var tc = new XElement(tns + XMLNames.Component_TorqueConverter, + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, string.Format("TC-{0}", torqueConverterData.Model)), + GetDefaultComponentElements(torqueConverterData.Model), + new XElement(tns + XMLNames.TorqueConverter_ReferenceRPM, torqueConverterData.ReferenceRPM.AsRPM.ToXMLFormat()), + new XElement(tns + XMLNames.TorqueConverter_Characteristics, + _singleFile + ? EmbedDataTable(torqueConverterData.TCData, AttributeMappings.TorqueConverterDataMapping, + precision: new Dictionary<string, uint>() { + { TorqueConverterDataReader.Fields.SpeedRatio, 4 } + }) + : ExtCSVResource(torqueConverterData.TCData, Path.GetFileName(torqueConverterData.TCData.Source))), + new XElement(tns + XMLNames.TorqueConverter_Inertia, torqueConverterData.Inertia.Value()))); + if (_singleFile) { + return tc; + } + return new XElement(tns + XMLNames.Component_TorqueConverter, + ExtComponent(XMLNames.Component_TorqueConverter, tc, "TorqueConverter.xml")); + } + + private object[] GetTransmissionLossMap(TableData lossmap) + { + if (_singleFile) { + return EmbedDataTable(lossmap, AttributeMappings.TransmissionLossmapMapping); + } + return ExtCSVResource(lossmap, Path.GetFileName(lossmap.Source)); + } + + private object[] CreateShiftPolygon(TableData shiftPolygon) + { + if (_singleFile) { + return EmbedDataTable(shiftPolygon, AttributeMappings.ShiftPolygonMapping); + } + return ExtCSVResource(shiftPolygon, Path.GetFileName(shiftPolygon.Source)); + } + + public XElement CreateEngine(IEngineEngineeringInputData data, bool allowSeparateFile = true) + { + var engine = new XElement(tns + XMLNames.Component_Engine, + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, string.Format("ENG-{0}", data.Model)), + GetDefaultComponentElements(data.Model), + new XElement(tns + XMLNames.Engine_Displacement, (data.Displacement.Value() * 1000 * 1000).ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_IdlingSpeed, data.IdleSpeed.AsRPM.ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_Inertia, data.Inertia.Value()), + new XElement(tns + XMLNames.Engine_WHTCEngineering, data.WHTCEngineering.ToXMLFormat(4)), + new XElement(tns + XMLNames.Engine_FuelConsumptionMap, GetFuelConsumptionMap(data)), + new XElement(tns + XMLNames.Engine_FullLoadAndDragCurve, GetFullLoadDragCurve(data)))); + if (!allowSeparateFile || _singleFile) { + return engine; + } + return ExtComponent(XMLNames.Component_Engine, engine, string.Format("ENG-{0}.xml", data.Model)); + } + + private XElement CreateAirdrag(IAirdragEngineeringInputData data) + { + var id = string.Format("Airdrag-{0}", data.Model); + return new XElement(tns + XMLNames.Component_AirDrag, + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, id), + GetDefaultComponentElements("N.A."), + new XElement(tns + XMLNames.Vehicle_CrossWindCorrectionMode, data.CrossWindCorrectionMode.ToXMLFormat()), + new XElement(tns + XMLNames.Vehicle_AirDragArea, data.AirDragArea.Value().ToXMLFormat(2))), + GetCrossWindCorrectionData(data) + ); + } + + private XElement ExtComponent(string component, XElement componentXML, string filename) + { + GenerateComponentDocument(componentXML).Save(Path.Combine(BasePath, filename)); + + var retVal = new XElement(tns + XMLNames.ExternalResource, + new XAttribute(XMLNames.ExtResource_Type_Attr, XMLNames.ExtResource_Type_Value_XML), + new XAttribute(XMLNames.ExtResource_Component_Attr, component), + new XAttribute(XMLNames.ExtResource_File_Attr, filename)); + return retVal; + } + + private object[] GetFullLoadDragCurve(IEngineEngineeringInputData data) + { + if (_singleFile) { + return EmbedDataTable(data.FullLoadCurve, AttributeMappings.EngineFullLoadCurveMapping); + } + var filename = string.Format("ENG_{0}.vfld", data.Model); + return ExtCSVResource(data.FullLoadCurve, filename); + } + + private object[] GetFuelConsumptionMap(IEngineEngineeringInputData data) + { + if (_singleFile) { + return EmbedDataTable(data.FuelConsumptionMap, AttributeMappings.FuelConsumptionMapMapping); + } + + var filename = string.Format("ENG_{0}.vmap", data.Model); + return ExtCSVResource(data.FuelConsumptionMap, filename); + } + + + private object[] ExtCSVResource(DataTable data, string filename) + { + VectoCSVFile.Write(Path.Combine(BasePath, filename), data); + return new object[] { + new XElement(tns + XMLNames.ExternalResource, + new XAttribute(XMLNames.ExtResource_Type_Attr, XMLNames.ExtResource_Type_Value_CSV), + new XAttribute(XMLNames.ExtResource_File_Attr, filename)) + }; + } + + protected XElement[] GetDefaultComponentElements(string makeAndModel) + { + return new[] { + new XElement(tns + XMLNames.Component_Manufacturer, Vendor), + new XElement(tns + XMLNames.Component_Model, makeAndModel), + new XElement(tns + XMLNames.Component_Creator, Creator), + new XElement(tns + XMLNames.Component_Date, XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)), + new XElement(tns + XMLNames.Component_AppVersion, "VectoCore"), + }; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs similarity index 96% rename from VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs rename to VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs index 18f336a58d4bbb4f500e91fa7dd9d4ed9ebf78dd..d2c3ea2e8c1823d4904a3ac92ebc8999e3c9cbfa 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs @@ -49,7 +49,7 @@ using TUGraz.VectoHashing; namespace TUGraz.VectoCore.OutputData.XML { - public class XMLFullReport + public class XMLManufacturerReport { protected XElement VehiclePart; @@ -61,7 +61,7 @@ namespace TUGraz.VectoCore.OutputData.XML protected XNamespace di; private bool allSuccess = true; - public XMLFullReport() + public XMLManufacturerReport() { di = "http://www.w3.org/2000/09/xmldsig#"; tns = "urn:tugraz:ivt:VectoAPI:DeclarationOutput:v0.4"; @@ -69,12 +69,12 @@ namespace TUGraz.VectoCore.OutputData.XML Results = new XElement(tns + "Results"); } - public void Initialize(VectoRunData modelData, Segment segment) + public void Initialize(VectoRunData modelData) { VehiclePart.Add( new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), new XElement(tns + XMLNames.Vehicle_LegislativeClass, modelData.VehicleData.LegislativeClass.ToXMLFormat()), - new XElement(tns + "VehicleGroup", segment.VehicleClass.GetClassNumber()), + new XElement(tns + "VehicleGroup", modelData.VehicleData.VehicleClass.GetClassNumber()), new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), new XElement(tns + XMLNames.Vehicle_CurbMassChassis, modelData.VehicleData.CurbWeight.ToXMLFormat(0)), @@ -269,7 +269,7 @@ namespace TUGraz.VectoCore.OutputData.XML foreach (var resultEntry in entry.ModData) { allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success; Results.Add(new XElement(tns + "Result", - new XAttribute("status", resultEntry.Value.Status.ToString().ToLower()), + new XAttribute("status", resultEntry.Value.Status == VectoRun.Status.Success?"success" : "error"), new XElement(tns + "Mission", entry.Mission.ToXMLFormat()), GetResults(resultEntry))); } @@ -286,8 +286,8 @@ namespace TUGraz.VectoCore.OutputData.XML case VectoRun.Status.Canceled: case VectoRun.Status.Aborted: return new object[] { - new XElement("Error", resultEntry.Value.Error), - new XElement("ErrorDetails", resultEntry.Value.StackTrace), + new XElement(tns+"Error", resultEntry.Value.Error), + new XElement(tns+"ErrorDetails", resultEntry.Value.StackTrace), }; default: throw new ArgumentOutOfRangeException(); @@ -339,7 +339,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XAttribute("xmlns", tns), new XAttribute(XNamespace.Xmlns + "di", di), new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoOutput.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), + string.Format("{0} {1}VectoOutputManufacturer.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), new XElement(tns + "Data", vehicle, results, diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index 72a0ccda5bb9b2d4c02324f48c836f848d279cab..3a3a2b2dffd81bbf1d90051ff9724c06a71c01be 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -194,7 +194,7 @@ <Compile Include="OutputData\XML\XMLDeclarationReport.cs" /> <Compile Include="OutputData\XML\XMLDeclarationWriter.cs" /> <Compile Include="OutputData\XML\XMLEngineeringWriter.cs" /> - <Compile Include="OutputData\XML\XMLFullReport.cs" /> + <Compile Include="OutputData\XML\XMLManufacturerReport.cs" /> <Compile Include="Utils\ProviderExtensions.cs" /> <Compile Include="Models\Declaration\AirDrag.cs" /> <Compile Include="Models\Declaration\Fan.cs" /> diff --git a/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs b/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs index c2d47be8df92f088be214388ff5ff26e58528bfe..2a79558071a616de25cd39f4025e73a51336b791 100644 --- a/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs +++ b/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs @@ -95,6 +95,7 @@ namespace TUGraz.VectoCore.Tests.Integration var driverData = CreateDriverData(AccelerationFile, overspeed); var runData = new VectoRunData() { + JobRunId = 0, AxleGearData = axleGearData, VehicleData = vehicleData, AirdragData = airdragData, diff --git a/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs b/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs index 76c72e3126610af2c795687b0da884c49b3db583..5cdd090255da983b82dca553a3ef4ac7f88b7cae 100644 --- a/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs +++ b/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs @@ -29,203 +29,204 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; -using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; - -namespace TUGraz.VectoCore.Tests.Integration -{ - public class CoachAdvancedAuxPowertrain - { - public const string AccelerationFile = @"TestData\Components\Truck.vacc"; - public const string EngineFile = @"TestData\Components\24t Coach.veng"; - public const string EngineFileHigh = @"TestData\Components\24t Coach_high.veng"; - public const string AxleGearLossMap = @"TestData\Components\Axle.vtlm"; - public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm"; - public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm"; - public const string GearboxShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; - //public const string GearboxFullLoadCurveFile = @"TestData\Components\Gearbox.vfld"; - - public const string AdvancedAuxFile = @"Testdata\Integration\BusAuxiliaries\AdvAuxTest.aaux"; - - public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, - bool overspeed = false, bool highEnginePower = true) - { - var container = CreatePowerTrain(cycleData, modFileName.Replace(".vmod", ""), overspeed, highEnginePower); - - return new DistanceRun(container); - } - - public static VehicleContainer CreatePowerTrain(DrivingCycleData cycleData, string modFileName, bool overspeed = false, - bool highEnginePower = true) - { - var fileWriter = new FileOutputWriter(modFileName); - var modData = new ModalDataContainer(modFileName, FuelType.DieselCI, fileWriter) { - WriteAdvancedAux = true, - WriteModalResults = true - }; - var container = new VehicleContainer(ExecutionMode.Engineering, modData) { - RunData = new VectoRunData { JobName = modFileName, Cycle = cycleData } - }; - - var gearboxData = CreateGearboxData(); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(highEnginePower ? EngineFileHigh : EngineFile, - gearboxData.Gears.Count); - var axleGearData = CreateAxleGearData(); - var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); - var airdragData = CreateAirdragData(); - var driverData = CreateDriverData(AccelerationFile, overspeed); - - var cycle = new DistanceBasedDrivingCycle(container, cycleData); - var engine = new CombustionEngine(container, engineData); - - var runData = new VectoRunData() { - AxleGearData = axleGearData, - VehicleData = vehicleData, - AirdragData = airdragData, - GearboxData = gearboxData, - EngineData = engineData - }; - - cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) - .AddComponent(new Vehicle(container, vehicleData, airdragData)) - .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, axleGearData)) - .AddComponent(new DummyRetarder(container)) - .AddComponent(new Gearbox(container, new AMTShiftStrategy(runData, container), runData)) - .AddComponent(new Clutch(container, engineData)) - .AddComponent(engine); - - var aux = new BusAuxiliariesAdapter(container, AdvancedAuxFile, "Coach", - vehicleData.TotalVehicleWeight, engineData.ConsumptionMap, engineData.IdleSpeed); - - engine.Connect(aux.Port()); - - return container; - } - - private static GearboxData CreateGearboxData() - { - var ratios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 }; - - return new GearboxData { - Gears = ratios.Select((ratio, i) => - Tuple.Create((uint)i, - new GearData { - //MaxTorque = 2300.SI<NewtonMeter>(), - LossMap = ratio.IsEqual(1) - ? TransmissionLossMapReader.ReadFromFile(GearboxIndirectLoss, ratio, string.Format("Gear {0}", i)) - : TransmissionLossMapReader.ReadFromFile(GearboxDirectLoss, ratio, string.Format("Gear {0}", i)), - Ratio = ratio, - ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile) - })) - .ToDictionary(k => k.Item1 + 1, v => v.Item2), - ShiftTime = 2.SI<Second>(), - Inertia = 0.SI<KilogramSquareMeter>(), - TractionInterruption = 1.SI<Second>(), - StartSpeed = 2.SI<MeterPerSecond>(), - StartAcceleration = 0.6.SI<MeterPerSquareSecond>(), - StartTorqueReserve = 0.2, - TorqueReserve = 0.2, - DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay, - UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay, - UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration - }; - } - - private static AxleGearData CreateAxleGearData() - { - const double ratio = 3.240355; - return new AxleGearData { - AxleGear = new GearData { - Ratio = ratio, - LossMap = TransmissionLossMapReader.ReadFromFile(AxleGearLossMap, ratio, "AxleGear") - } - }; - } - - private static VehicleData CreateVehicleData(Kilogram loading) - { - var axles = new List<Axle> { - new Axle { - AxleWeightShare = 0.4375, - Inertia = 21.66667.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 62538.75.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.375, - Inertia = 10.83333.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0065, - TwinTyres = true, - TyreTestLoad = 52532.55.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.1875, - Inertia = 21.66667.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 62538.75.SI<Newton>() - } - }; - return new VehicleData { - AxleConfiguration = AxleConfiguration.AxleConfig_6x2, - CurbWeight = 15700.SI<Kilogram>(), - Loading = loading, - DynamicTyreRadius = 0.52.SI<Meter>(), - AxleData = axles, - SavedInDeclarationMode = false - }; - } - - private static AirdragData CreateAirdragData() - { - return new AirdragData() { - CrossWindCorrectionCurve = - new CrosswindCorrectionCdxALookup(3.2634.SI<SquareMeter>(), - CrossWindCorrectionCurveReader.GetNoCorrectionCurve(3.2634.SI<SquareMeter>()), - CrossWindCorrectionMode.NoCorrection), - }; - } - - private static DriverData CreateDriverData(string accelerationFile, bool overspeed = false) - { - return new DriverData { - AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), - LookAheadCoasting = new DriverData.LACData { - Enabled = true, - MinSpeed = 50.KMPHtoMeterPerSecond(), - //Deceleration = -0.5.SI<MeterPerSquareSecond>() - LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor, - LookAheadDecisionFactor = new LACDecisionFactor() - }, - OverSpeedEcoRoll = overspeed - ? new DriverData.OverSpeedEcoRollData { - Mode = DriverMode.Overspeed, - MinSpeed = 50.KMPHtoMeterPerSecond(), - OverSpeed = 5.KMPHtoMeterPerSecond() - } - : new DriverData.OverSpeedEcoRollData { - Mode = DriverMode.Off - }, - }; - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; +using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; + +namespace TUGraz.VectoCore.Tests.Integration +{ + public class CoachAdvancedAuxPowertrain + { + public const string AccelerationFile = @"TestData\Components\Truck.vacc"; + public const string EngineFile = @"TestData\Components\24t Coach.veng"; + public const string EngineFileHigh = @"TestData\Components\24t Coach_high.veng"; + public const string AxleGearLossMap = @"TestData\Components\Axle.vtlm"; + public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm"; + public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm"; + public const string GearboxShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; + //public const string GearboxFullLoadCurveFile = @"TestData\Components\Gearbox.vfld"; + + public const string AdvancedAuxFile = @"Testdata\Integration\BusAuxiliaries\AdvAuxTest.aaux"; + + public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, + bool overspeed = false, bool highEnginePower = true) + { + var container = CreatePowerTrain(cycleData, modFileName.Replace(".vmod", ""), overspeed, highEnginePower); + + return new DistanceRun(container); + } + + public static VehicleContainer CreatePowerTrain(DrivingCycleData cycleData, string modFileName, bool overspeed = false, + bool highEnginePower = true) + { + var fileWriter = new FileOutputWriter(modFileName); + var modData = new ModalDataContainer(modFileName, FuelType.DieselCI, fileWriter) { + WriteAdvancedAux = true, + WriteModalResults = true + }; + var container = new VehicleContainer(ExecutionMode.Engineering, modData) { + RunData = new VectoRunData { JobName = modFileName, Cycle = cycleData } + }; + + var gearboxData = CreateGearboxData(); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(highEnginePower ? EngineFileHigh : EngineFile, + gearboxData.Gears.Count); + var axleGearData = CreateAxleGearData(); + var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); + var airdragData = CreateAirdragData(); + var driverData = CreateDriverData(AccelerationFile, overspeed); + + var cycle = new DistanceBasedDrivingCycle(container, cycleData); + var engine = new CombustionEngine(container, engineData); + + var runData = new VectoRunData() { + JobRunId = 0, + AxleGearData = axleGearData, + VehicleData = vehicleData, + AirdragData = airdragData, + GearboxData = gearboxData, + EngineData = engineData + }; + + cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) + .AddComponent(new Vehicle(container, vehicleData, airdragData)) + .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, axleGearData)) + .AddComponent(new DummyRetarder(container)) + .AddComponent(new Gearbox(container, new AMTShiftStrategy(runData, container), runData)) + .AddComponent(new Clutch(container, engineData)) + .AddComponent(engine); + + var aux = new BusAuxiliariesAdapter(container, AdvancedAuxFile, "Coach", + vehicleData.TotalVehicleWeight, engineData.ConsumptionMap, engineData.IdleSpeed); + + engine.Connect(aux.Port()); + + return container; + } + + private static GearboxData CreateGearboxData() + { + var ratios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 }; + + return new GearboxData { + Gears = ratios.Select((ratio, i) => + Tuple.Create((uint)i, + new GearData { + //MaxTorque = 2300.SI<NewtonMeter>(), + LossMap = ratio.IsEqual(1) + ? TransmissionLossMapReader.ReadFromFile(GearboxIndirectLoss, ratio, string.Format("Gear {0}", i)) + : TransmissionLossMapReader.ReadFromFile(GearboxDirectLoss, ratio, string.Format("Gear {0}", i)), + Ratio = ratio, + ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile) + })) + .ToDictionary(k => k.Item1 + 1, v => v.Item2), + ShiftTime = 2.SI<Second>(), + Inertia = 0.SI<KilogramSquareMeter>(), + TractionInterruption = 1.SI<Second>(), + StartSpeed = 2.SI<MeterPerSecond>(), + StartAcceleration = 0.6.SI<MeterPerSquareSecond>(), + StartTorqueReserve = 0.2, + TorqueReserve = 0.2, + DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay, + UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay, + UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration + }; + } + + private static AxleGearData CreateAxleGearData() + { + const double ratio = 3.240355; + return new AxleGearData { + AxleGear = new GearData { + Ratio = ratio, + LossMap = TransmissionLossMapReader.ReadFromFile(AxleGearLossMap, ratio, "AxleGear") + } + }; + } + + private static VehicleData CreateVehicleData(Kilogram loading) + { + var axles = new List<Axle> { + new Axle { + AxleWeightShare = 0.4375, + Inertia = 21.66667.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 62538.75.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.375, + Inertia = 10.83333.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0065, + TwinTyres = true, + TyreTestLoad = 52532.55.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.1875, + Inertia = 21.66667.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 62538.75.SI<Newton>() + } + }; + return new VehicleData { + AxleConfiguration = AxleConfiguration.AxleConfig_6x2, + CurbWeight = 15700.SI<Kilogram>(), + Loading = loading, + DynamicTyreRadius = 0.52.SI<Meter>(), + AxleData = axles, + SavedInDeclarationMode = false + }; + } + + private static AirdragData CreateAirdragData() + { + return new AirdragData() { + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(3.2634.SI<SquareMeter>(), + CrossWindCorrectionCurveReader.GetNoCorrectionCurve(3.2634.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection), + }; + } + + private static DriverData CreateDriverData(string accelerationFile, bool overspeed = false) + { + return new DriverData { + AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), + LookAheadCoasting = new DriverData.LACData { + Enabled = true, + MinSpeed = 50.KMPHtoMeterPerSecond(), + //Deceleration = -0.5.SI<MeterPerSquareSecond>() + LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor, + LookAheadDecisionFactor = new LACDecisionFactor() + }, + OverSpeedEcoRoll = overspeed + ? new DriverData.OverSpeedEcoRollData { + Mode = DriverMode.Overspeed, + MinSpeed = 50.KMPHtoMeterPerSecond(), + OverSpeed = 5.KMPHtoMeterPerSecond() + } + : new DriverData.OverSpeedEcoRollData { + Mode = DriverMode.Off + }, + }; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs b/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs index d1f2dcec0a15f2d063463da5ea7bb693310932ba..1667a0f535f22004fcb8a329ee88f0909b78953a 100644 --- a/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs +++ b/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs @@ -96,6 +96,7 @@ namespace TUGraz.VectoCore.Tests.Integration var airDragData = CreateAirdragData(); var runData = new VectoRunData() { + JobRunId = 0, VehicleData = vehicleData, AxleGearData = axleGearData, GearboxData = gearboxData, diff --git a/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs b/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs index f6313adfe31c5e9be65de30a72925080476a6cfe..994f5be1133a87f32a821025a910c7defcbcb1b3 100644 --- a/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs +++ b/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs @@ -29,109 +29,109 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.IO; -using System.Linq; -using NUnit.Framework; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.Tests.Utils; - -namespace TUGraz.VectoCore.Tests.Integration.EngineOnlyCycle -{ - [TestFixture] - public class EngineOnlyCycleTest - { - private const string EngineFile = @"TestData\Components\24t Coach.veng"; - - [TestCase("24tCoach_EngineOnly", - @"TestData\Components\24t Coach.veng", - @"TestData\Cycles\Coach Engine Only.vdri", - @"TestData\Results\EngineOnlyCycles\24tCoach_EngineOnly.vmod")] - [TestCase("24tCoach_EngineOnlyPaux", - @"TestData\Components\24t Coach.veng", - @"TestData\Cycles\Coach Engine Only Paux.vdri", - @"TestData\Results\EngineOnlyCycles\24tCoach_EngineOnlyPaux.vmod")] - [TestCase("24tCoach_EngineOnlyFullLoad", - @"TestData\Components\24t Coach.veng", - @"TestData\Cycles\Coach Engine Only FullLoad.vdri", - @"TestData\Results\EngineOnlyCycles\24tCoach_EngineOnlyFullLoad.vmod")] - public void TestEngineOnlyDrivingCycle(string testName, string engineFile, string cycleFile, string modalResultFile) - { - var data = DrivingCycleDataReader.ReadFromFile(cycleFile, CycleType.EngineOnly, - false); - var vehicle = new VehicleContainer(ExecutionMode.Engineering); - // ReSharper disable once ObjectCreationAsStatement - new MockDrivingCycle(vehicle, data); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 0); - - var aux = new EngineAuxiliary(vehicle); - aux.AddCycle(Constants.Auxiliaries.Cycle); - - var engine = new EngineOnlyCombustionEngine(vehicle, engineData); - engine.Connect(aux); - - //aux.InPort().Connect(engine.OutPort()); - var port = engine.OutPort(); - - var absTime = 0.SI<Second>(); - var dt = 1.SI<Second>(); - - var modFile = Path.GetFileNameWithoutExtension(modalResultFile); - //Path.GetFileNameWithoutExtension(Path.GetRandomFileName()); // + ".vmod"; - var fileWriter = new FileOutputWriter(modFile); - var modData = new ModalDataContainer(modFile, FuelType.DieselCI, fileWriter, true) { WriteModalResults = true }; - modData.AddAuxiliary(Constants.Auxiliaries.Cycle); - port.Initialize(data.Entries.First().Torque, data.Entries.First().AngularVelocity); - foreach (var cycleEntry in data.Entries) { - // ReSharper disable once UnusedVariable - var response = (ResponseSuccess)port.Request(absTime, dt, cycleEntry.Torque, cycleEntry.AngularVelocity); - foreach (var sc in vehicle.SimulationComponents()) { - modData[ModalResultField.time] = absTime + dt / 2; - sc.CommitSimulationStep(modData); - } - - modData.CommitSimulationStep(); - absTime += dt; - } - modData.Finish(VectoRun.Status.Success); - - ResultFileHelper.TestModFile(modalResultFile, modFile + Constants.FileExtensions.ModDataFile); - } - - [TestCase] - public void AssembleEngineOnlyPowerTrain() - { - var dataWriter = new MockModalDataContainer(); - - var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); - - var engine = new CombustionEngine(vehicleContainer, MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 0)); - var gbx = new MockGearbox(vehicleContainer) { Gear = 0 }; - - var absTime = 0.SI<Second>(); - var dt = 1.SI<Second>(); - - var angularVelocity = 644.4445.RPMtoRad(); - var power = 2329.973.SI<Watt>(); - - engine.OutPort().Initialize(power / angularVelocity, angularVelocity); - engine.OutPort().Request(absTime, dt, power / angularVelocity, angularVelocity); - - foreach (var sc in vehicleContainer.SimulationComponents()) { - sc.CommitSimulationStep(dataWriter); - } - - Assert.IsNotNull(dataWriter.CurrentRow); - } - } +using System.IO; +using System.Linq; +using NUnit.Framework; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Tests.Utils; + +namespace TUGraz.VectoCore.Tests.Integration.EngineOnlyCycle +{ + [TestFixture] + public class EngineOnlyCycleTest + { + private const string EngineFile = @"TestData\Components\24t Coach.veng"; + + [TestCase("24tCoach_EngineOnly", + @"TestData\Components\24t Coach.veng", + @"TestData\Cycles\Coach Engine Only.vdri", + @"TestData\Results\EngineOnlyCycles\24tCoach_EngineOnly.vmod")] + [TestCase("24tCoach_EngineOnlyPaux", + @"TestData\Components\24t Coach.veng", + @"TestData\Cycles\Coach Engine Only Paux.vdri", + @"TestData\Results\EngineOnlyCycles\24tCoach_EngineOnlyPaux.vmod")] + [TestCase("24tCoach_EngineOnlyFullLoad", + @"TestData\Components\24t Coach.veng", + @"TestData\Cycles\Coach Engine Only FullLoad.vdri", + @"TestData\Results\EngineOnlyCycles\24tCoach_EngineOnlyFullLoad.vmod")] + public void TestEngineOnlyDrivingCycle(string testName, string engineFile, string cycleFile, string modalResultFile) + { + var data = DrivingCycleDataReader.ReadFromFile(cycleFile, CycleType.EngineOnly, + false); + var vehicle = new VehicleContainer(ExecutionMode.Engineering); + // ReSharper disable once ObjectCreationAsStatement + new MockDrivingCycle(vehicle, data); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 0); + + var aux = new EngineAuxiliary(vehicle); + aux.AddCycle(Constants.Auxiliaries.Cycle); + + var engine = new EngineOnlyCombustionEngine(vehicle, engineData); + engine.Connect(aux); + + //aux.InPort().Connect(engine.OutPort()); + var port = engine.OutPort(); + + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); + + var modFile = Path.GetFileNameWithoutExtension(modalResultFile); + //Path.GetFileNameWithoutExtension(Path.GetRandomFileName()); // + ".vmod"; + var fileWriter = new FileOutputWriter(modFile); + var modData = new ModalDataContainer(modFile, FuelType.DieselCI, fileWriter, true) { WriteModalResults = true }; + modData.AddAuxiliary(Constants.Auxiliaries.Cycle); + port.Initialize(data.Entries.First().Torque, data.Entries.First().AngularVelocity); + foreach (var cycleEntry in data.Entries) { + // ReSharper disable once UnusedVariable + var response = (ResponseSuccess)port.Request(absTime, dt, cycleEntry.Torque, cycleEntry.AngularVelocity); + foreach (var sc in vehicle.SimulationComponents()) { + modData[ModalResultField.time] = absTime + dt / 2; + sc.CommitSimulationStep(modData); + } + + modData.CommitSimulationStep(); + absTime += dt; + } + modData.Finish(VectoRun.Status.Success); + + ResultFileHelper.TestModFile(modalResultFile, modFile + Constants.FileExtensions.ModDataFile); + } + + [TestCase] + public void AssembleEngineOnlyPowerTrain() + { + var dataWriter = new MockModalDataContainer(); + + var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); + + var engine = new CombustionEngine(vehicleContainer, MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 0)); + var gbx = new MockGearbox(vehicleContainer) { Gear = 0 }; + + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); + + var angularVelocity = 644.4445.RPMtoRad(); + var power = 2329.973.SI<Watt>(); + + engine.OutPort().Initialize(power / angularVelocity, angularVelocity); + engine.OutPort().Request(absTime, dt, power / angularVelocity, angularVelocity); + + foreach (var sc in vehicleContainer.SimulationComponents()) { + sc.CommitSimulationStep(dataWriter); + } + + Assert.IsNotNull(dataWriter.CurrentRow); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs b/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs index a07878d29c25c5fed065c21b26ccfb9eab0108c5..7e350453665b6c3a3e6c50e7e6133d9119508c0b 100644 --- a/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs +++ b/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs @@ -29,413 +29,413 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.FileIO.JSON; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; -using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; - -namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns -{ - [TestClass] - public class FullPowerTrain - { - public const string CycleFile = @"TestData\Integration\FullPowerTrain\1-Gear-Test-dist.vdri"; - public const string CoachCycleFile = @"TestData\Integration\FullPowerTrain\Coach.vdri"; - public const string EngineFile = @"TestData\Components\24t Coach.veng"; - public const string AccelerationFile = @"TestData\Components\Coach.vacc"; - public const string GearboxLossMap = @"TestData\Components\Indirect Gear.vtlm"; - public const string AxleLossMap = @"TestData\Components\Axle.vtlm"; - public const string GearboxShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; - //public const string GearboxFullLoadCurveFile = @"TestData\Components\Gearbox.vfld"; - private static readonly LoggingObject Log = LogManager.GetLogger(typeof(FullPowerTrain).ToString()); - - [TestMethod, TestCategory("LongRunning")] - public void Test_FullPowertrain_SimpleGearbox() - { - var fileWriter = new FileOutputWriter("Coach_FullPowertrain_SimpleGearbox"); - var modData = new ModalDataContainer("Coach_FullPowertrain_SimpleGearbox", FuelType.DieselCI, fileWriter); - var container = new VehicleContainer(ExecutionMode.Engineering, modData); - - var gearboxData = CreateSimpleGearboxData(); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); - var cycleData = DrivingCycleDataReader.ReadFromFile(CycleFile, CycleType.DistanceBased, false); - var axleGearData = CreateAxleGearData(); - var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); - var driverData = CreateDriverData(AccelerationFile); - var airDragData = CreateAirdragData(); - - var cycle = new DistanceBasedDrivingCycle(container, cycleData); - var cyclePort = cycle.OutPort(); - - var runData = new VectoRunData() { - EngineData = engineData, - AxleGearData = axleGearData, - GearboxData = gearboxData, - VehicleData = vehicleData, - AirdragData = airDragData - }; - - cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) - .AddComponent(new Vehicle(container, vehicleData,airDragData)) - .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, axleGearData)) - .AddComponent(new Gearbox(container, new AMTShiftStrategy(runData, container), runData)) - .AddComponent(new Clutch(container, engineData)) - .AddComponent(new CombustionEngine(container, engineData)); - - cyclePort.Initialize(); - - var absTime = 0.SI<Second>(); - var ds = Constants.SimulationSettings.DriveOffDistance; - IResponse response; - - var cnt = 0; - do { - response = cyclePort.Request(absTime, ds); - response.Switch(). - Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). - Case<ResponseCycleFinished>(r => { }). - Case<ResponseSuccess>(r => { - container.CommitSimulationStep(absTime, r.SimulationInterval); - absTime += r.SimulationInterval; - - ds = container.VehicleSpeed.IsEqual(0) - ? Constants.SimulationSettings.DriveOffDistance - : Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed; - - if (cnt++ % 100 == 0) { - modData.Finish(VectoRun.Status.Success); - } - }). - Default(r => Assert.Fail("Unexpected Response: {0}", r)); - } while (!(response is ResponseCycleFinished)); - modData.Finish(VectoRun.Status.Success); - Assert.IsInstanceOfType(response, typeof(ResponseCycleFinished)); - } - - [TestMethod] - public void Test_FullPowertrain() - { - var fileWriter = new FileOutputWriter("Coach_FullPowertrain"); - var modData = new ModalDataContainer("Coach_FullPowertrain", FuelType.DieselCI, fileWriter); - var container = new VehicleContainer(ExecutionMode.Engineering, modData); - - var gearboxData = CreateGearboxData(); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); - var cycleData = DrivingCycleDataReader.ReadFromFile(CoachCycleFile, CycleType.DistanceBased, false); - var axleGearData = CreateAxleGearData(); - var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); - var driverData = CreateDriverData(AccelerationFile); - var airDragData = CreateAirdragData(); - - var cycle = new DistanceBasedDrivingCycle(container, cycleData); - - var runData = new VectoRunData() { - EngineData = engineData, - VehicleData = vehicleData, - AxleGearData = axleGearData, - GearboxData = gearboxData, - AirdragData = airDragData - }; - - var cyclePort = cycle.OutPort(); - cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) - .AddComponent(new Vehicle(container, vehicleData,airDragData)) - .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, axleGearData)) - .AddComponent(new Gearbox(container, new AMTShiftStrategy(runData, container), runData)) - .AddComponent(new Clutch(container, engineData)) - .AddComponent(new CombustionEngine(container, engineData)); - - cyclePort.Initialize(); - - //gbx.Gear = 0; - - var absTime = 0.SI<Second>(); - var ds = Constants.SimulationSettings.DriveOffDistance; - var response = cyclePort.Request(absTime, ds); - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - container.CommitSimulationStep(absTime, response.SimulationInterval); - absTime += response.SimulationInterval; - - //gbx.Gear = 1; - var cnt = 0; - while (!(response is ResponseCycleFinished) && container.Distance < 17000) { - Log.Info("Test New Request absTime: {0}, ds: {1}", absTime, ds); - try { - response = cyclePort.Request(absTime, ds); - } catch (Exception) { - modData.Finish(VectoRun.Status.Success); - throw; - } - Log.Info("Test Got Response: {0},", response); - - response.Switch(). - Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). - Case<ResponseCycleFinished>(r => { }). - Case<ResponseGearShift>(r => { Log.Debug("Gearshift"); }). - Case<ResponseSuccess>(r => { - container.CommitSimulationStep(absTime, r.SimulationInterval); - absTime += r.SimulationInterval; - - ds = container.VehicleSpeed.IsEqual(0) - ? Constants.SimulationSettings.DriveOffDistance - : Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed; - - if (cnt++ % 100 == 0) { - modData.Finish(VectoRun.Status.Success); - } - }). - Default(r => Assert.Fail("Unexpected Response: {0}", r)); - } - modData.Finish(VectoRun.Status.Success); - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - } - - [TestMethod, TestCategory("LongRunning")] - public void Test_FullPowertrain_LowSpeed() - { - var fileWriter = new FileOutputWriter("Coach_FullPowertrain_LowSpeed"); - var modData = new ModalDataContainer("Coach_FullPowertrain_LowSpeed", FuelType.DieselCI, fileWriter); - var container = new VehicleContainer(ExecutionMode.Engineering, modData); - - var gearboxData = CreateGearboxData(); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); - var cycleData = DrivingCycleDataReader.ReadFromFile(CycleFile, CycleType.DistanceBased, false); - var axleGearData = CreateAxleGearData(); - var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); - var airDragData = CreateAirdragData(); - var driverData = CreateDriverData(AccelerationFile); - - var runData = new VectoRunData() { - EngineData = engineData, - VehicleData = vehicleData, - AxleGearData = axleGearData, - GearboxData = gearboxData, - AirdragData = airDragData - }; - - var cycle = new DistanceBasedDrivingCycle(container, cycleData); - var cyclePort = cycle.OutPort(); - cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) - .AddComponent(new Vehicle(container, vehicleData, airDragData)) - .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, axleGearData)) - .AddComponent(new Gearbox(container, new AMTShiftStrategy(runData, container), runData)) - .AddComponent(new Clutch(container, engineData)) - .AddComponent(new CombustionEngine(container, engineData)); - - cyclePort.Initialize(); - - //container.Gear = 0; - var absTime = 0.SI<Second>(); - var ds = Constants.SimulationSettings.DriveOffDistance; - var response = cyclePort.Request(absTime, ds); - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - container.CommitSimulationStep(absTime, response.SimulationInterval); - absTime += response.SimulationInterval; - - //container.Gear = 1; - var cnt = 0; - while (!(response is ResponseCycleFinished) && container.Distance < 17000) { - Log.Info("Test New Request absTime: {0}, ds: {1}", absTime, ds); - try { - response = cyclePort.Request(absTime, ds); - } catch (Exception) { - modData.Finish(VectoRun.Status.Success); - throw; - } - Log.Info("Test Got Response: {0},", response); - - response.Switch(). - Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). - Case<ResponseCycleFinished>(r => { }). - Case<ResponseGearShift>(r => { Log.Debug("Gearshift"); }). - Case<ResponseSuccess>(r => { - container.CommitSimulationStep(absTime, r.SimulationInterval); - absTime += r.SimulationInterval; - - ds = container.VehicleSpeed.IsEqual(0) - ? Constants.SimulationSettings.DriveOffDistance - : Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed; - - if (cnt++ % 100 == 0) { - modData.Finish(VectoRun.Status.Success); - } - }). - Default(r => { - modData.Finish(VectoRun.Status.Success); - Assert.Fail("Unexpected Response: {0}", r); - }); - } - modData.Finish(VectoRun.Status.Success); - Assert.IsInstanceOfType(response, typeof(ResponseCycleFinished)); - } - - [TestMethod] - public void Test_FullPowerTrain_JobFile() - { - const string jobFile = @"TestData\job.vecto"; - var fileWriter = new FileOutputWriter(jobFile); - var sumData = new SummaryDataContainer(fileWriter); - var jobContainer = new JobContainer(sumData); - - var inputData = JSONInputDataFactory.ReadJsonJob(jobFile); - var factory = new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter); - - jobContainer.AddRuns(factory); - jobContainer.Execute(); - - jobContainer.WaitFinished(); - ResultFileHelper.TestSumFile(@"TestData\Results\Integration\job.vsum", @"TestData\job.vsum"); - - ResultFileHelper.TestModFile(@"TestData\Results\Integration\job_1-Gear-Test-dist.vmod", - @"TestData\job_1-Gear-Test-dist.vmod", testRowCount: false); - } - - private static GearboxData CreateGearboxData() - { - var ratios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 }; - - return new GearboxData { - Gears = ratios.Select((ratio, i) => - Tuple.Create((uint)i, - new GearData { -// MaxTorque = ratio > 5 ? 2300.SI<NewtonMeter>() : null, - LossMap = TransmissionLossMapReader.ReadFromFile(GearboxLossMap, ratio, string.Format("Gear {0}", i)), - Ratio = ratio, - ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile) - })) - .ToDictionary(k => k.Item1 + 1, v => v.Item2), - ShiftTime = 2.SI<Second>(), - Inertia = 0.SI<KilogramSquareMeter>(), - TractionInterruption = 1.SI<Second>(), - StartSpeed = 2.SI<MeterPerSecond>(), - StartAcceleration = 0.6.SI<MeterPerSquareSecond>(), - StartTorqueReserve = 0.2, - TorqueReserve = 0.2, - DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay, - UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay, - UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration - }; - } - - private static AxleGearData CreateAxleGearData() - { - var ratio = 3.240355; - return new AxleGearData { - AxleGear = new GearData { - Ratio = ratio, - LossMap = TransmissionLossMapReader.ReadFromFile(AxleLossMap, ratio, "AxleGear") - } - }; - } - - private static GearboxData CreateSimpleGearboxData() - { - var ratio = 3.44; - return new GearboxData { - Gears = new Dictionary<uint, GearData> { - { - 1, new GearData { - LossMap = TransmissionLossMapReader.ReadFromFile(GearboxLossMap, ratio, "Gear 1"), - Ratio = ratio, - ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile) - } - } - }, - Inertia = 0.SI<KilogramSquareMeter>(), - TractionInterruption = 0.SI<Second>(), - ShiftTime = 2.SI<Second>(), - StartSpeed = 2.SI<MeterPerSecond>(), - StartAcceleration = 0.6.SI<MeterPerSquareSecond>(), - StartTorqueReserve = 0.2, - TorqueReserve = 0.2, - DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay, - UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay, - UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration - }; - } - - private static VehicleData CreateVehicleData(Kilogram loading) - { - var axles = new List<Axle> { - new Axle { - AxleWeightShare = 0.4375, - Inertia = 21.66667.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 62538.75.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.375, - Inertia = 10.83333.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0065, - TwinTyres = true, - TyreTestLoad = 52532.55.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.1875, - Inertia = 21.66667.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 62538.75.SI<Newton>() - } - }; - return new VehicleData { - AxleConfiguration = AxleConfiguration.AxleConfig_6x2, - - CurbWeight = 15700.SI<Kilogram>(), - Loading = loading, - DynamicTyreRadius = 0.52.SI<Meter>(), - AxleData = axles, - SavedInDeclarationMode = false - }; - } - - private static AirdragData CreateAirdragData() - { - return new AirdragData(){ - CrossWindCorrectionCurve = - new CrosswindCorrectionCdxALookup(3.2634.SI<SquareMeter>(), - CrossWindCorrectionCurveReader.GetNoCorrectionCurve(3.2634.SI<SquareMeter>()), - CrossWindCorrectionMode.NoCorrection),}; - } - - private static DriverData CreateDriverData(string accelerationFile) - { - return new DriverData { - AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), - LookAheadCoasting = new DriverData.LACData { - Enabled = false, - //Deceleration = -0.5.SI<MeterPerSquareSecond>() - LookAheadDecisionFactor = new LACDecisionFactor() - }, - OverSpeedEcoRoll = new DriverData.OverSpeedEcoRollData { - Mode = DriverMode.Off - }, - }; - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; +using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; + +namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns +{ + [TestClass] + public class FullPowerTrain + { + public const string CycleFile = @"TestData\Integration\FullPowerTrain\1-Gear-Test-dist.vdri"; + public const string CoachCycleFile = @"TestData\Integration\FullPowerTrain\Coach.vdri"; + public const string EngineFile = @"TestData\Components\24t Coach.veng"; + public const string AccelerationFile = @"TestData\Components\Coach.vacc"; + public const string GearboxLossMap = @"TestData\Components\Indirect Gear.vtlm"; + public const string AxleLossMap = @"TestData\Components\Axle.vtlm"; + public const string GearboxShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; + //public const string GearboxFullLoadCurveFile = @"TestData\Components\Gearbox.vfld"; + private static readonly LoggingObject Log = LogManager.GetLogger(typeof(FullPowerTrain).ToString()); + + [TestMethod, TestCategory("LongRunning")] + public void Test_FullPowertrain_SimpleGearbox() + { + var fileWriter = new FileOutputWriter("Coach_FullPowertrain_SimpleGearbox"); + var modData = new ModalDataContainer("Coach_FullPowertrain_SimpleGearbox", FuelType.DieselCI, fileWriter); + var container = new VehicleContainer(ExecutionMode.Engineering, modData); + + var gearboxData = CreateSimpleGearboxData(); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); + var cycleData = DrivingCycleDataReader.ReadFromFile(CycleFile, CycleType.DistanceBased, false); + var axleGearData = CreateAxleGearData(); + var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); + var driverData = CreateDriverData(AccelerationFile); + var airDragData = CreateAirdragData(); + + var cycle = new DistanceBasedDrivingCycle(container, cycleData); + var cyclePort = cycle.OutPort(); + + var runData = new VectoRunData() { + EngineData = engineData, + AxleGearData = axleGearData, + GearboxData = gearboxData, + VehicleData = vehicleData, + AirdragData = airDragData + }; + + cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) + .AddComponent(new Vehicle(container, vehicleData,airDragData)) + .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, axleGearData)) + .AddComponent(new Gearbox(container, new AMTShiftStrategy(runData, container), runData)) + .AddComponent(new Clutch(container, engineData)) + .AddComponent(new CombustionEngine(container, engineData)); + + cyclePort.Initialize(); + + var absTime = 0.SI<Second>(); + var ds = Constants.SimulationSettings.DriveOffDistance; + IResponse response; + + var cnt = 0; + do { + response = cyclePort.Request(absTime, ds); + response.Switch(). + Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). + Case<ResponseCycleFinished>(r => { }). + Case<ResponseSuccess>(r => { + container.CommitSimulationStep(absTime, r.SimulationInterval); + absTime += r.SimulationInterval; + + ds = container.VehicleSpeed.IsEqual(0) + ? Constants.SimulationSettings.DriveOffDistance + : Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed; + + if (cnt++ % 100 == 0) { + modData.Finish(VectoRun.Status.Success); + } + }). + Default(r => Assert.Fail("Unexpected Response: {0}", r)); + } while (!(response is ResponseCycleFinished)); + modData.Finish(VectoRun.Status.Success); + Assert.IsInstanceOfType(response, typeof(ResponseCycleFinished)); + } + + [TestMethod] + public void Test_FullPowertrain() + { + var fileWriter = new FileOutputWriter("Coach_FullPowertrain"); + var modData = new ModalDataContainer("Coach_FullPowertrain", FuelType.DieselCI, fileWriter); + var container = new VehicleContainer(ExecutionMode.Engineering, modData); + + var gearboxData = CreateGearboxData(); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); + var cycleData = DrivingCycleDataReader.ReadFromFile(CoachCycleFile, CycleType.DistanceBased, false); + var axleGearData = CreateAxleGearData(); + var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); + var driverData = CreateDriverData(AccelerationFile); + var airDragData = CreateAirdragData(); + + var cycle = new DistanceBasedDrivingCycle(container, cycleData); + + var runData = new VectoRunData() { + EngineData = engineData, + VehicleData = vehicleData, + AxleGearData = axleGearData, + GearboxData = gearboxData, + AirdragData = airDragData + }; + + var cyclePort = cycle.OutPort(); + cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) + .AddComponent(new Vehicle(container, vehicleData,airDragData)) + .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, axleGearData)) + .AddComponent(new Gearbox(container, new AMTShiftStrategy(runData, container), runData)) + .AddComponent(new Clutch(container, engineData)) + .AddComponent(new CombustionEngine(container, engineData)); + + cyclePort.Initialize(); + + //gbx.Gear = 0; + + var absTime = 0.SI<Second>(); + var ds = Constants.SimulationSettings.DriveOffDistance; + var response = cyclePort.Request(absTime, ds); + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + container.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + + //gbx.Gear = 1; + var cnt = 0; + while (!(response is ResponseCycleFinished) && container.Distance < 17000) { + Log.Info("Test New Request absTime: {0}, ds: {1}", absTime, ds); + try { + response = cyclePort.Request(absTime, ds); + } catch (Exception) { + modData.Finish(VectoRun.Status.Success); + throw; + } + Log.Info("Test Got Response: {0},", response); + + response.Switch(). + Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). + Case<ResponseCycleFinished>(r => { }). + Case<ResponseGearShift>(r => { Log.Debug("Gearshift"); }). + Case<ResponseSuccess>(r => { + container.CommitSimulationStep(absTime, r.SimulationInterval); + absTime += r.SimulationInterval; + + ds = container.VehicleSpeed.IsEqual(0) + ? Constants.SimulationSettings.DriveOffDistance + : Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed; + + if (cnt++ % 100 == 0) { + modData.Finish(VectoRun.Status.Success); + } + }). + Default(r => Assert.Fail("Unexpected Response: {0}", r)); + } + modData.Finish(VectoRun.Status.Success); + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + } + + [TestMethod, TestCategory("LongRunning")] + public void Test_FullPowertrain_LowSpeed() + { + var fileWriter = new FileOutputWriter("Coach_FullPowertrain_LowSpeed"); + var modData = new ModalDataContainer("Coach_FullPowertrain_LowSpeed", FuelType.DieselCI, fileWriter); + var container = new VehicleContainer(ExecutionMode.Engineering, modData); + + var gearboxData = CreateGearboxData(); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); + var cycleData = DrivingCycleDataReader.ReadFromFile(CycleFile, CycleType.DistanceBased, false); + var axleGearData = CreateAxleGearData(); + var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); + var airDragData = CreateAirdragData(); + var driverData = CreateDriverData(AccelerationFile); + + var runData = new VectoRunData() { + EngineData = engineData, + VehicleData = vehicleData, + AxleGearData = axleGearData, + GearboxData = gearboxData, + AirdragData = airDragData + }; + + var cycle = new DistanceBasedDrivingCycle(container, cycleData); + var cyclePort = cycle.OutPort(); + cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) + .AddComponent(new Vehicle(container, vehicleData, airDragData)) + .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, axleGearData)) + .AddComponent(new Gearbox(container, new AMTShiftStrategy(runData, container), runData)) + .AddComponent(new Clutch(container, engineData)) + .AddComponent(new CombustionEngine(container, engineData)); + + cyclePort.Initialize(); + + //container.Gear = 0; + var absTime = 0.SI<Second>(); + var ds = Constants.SimulationSettings.DriveOffDistance; + var response = cyclePort.Request(absTime, ds); + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + container.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + + //container.Gear = 1; + var cnt = 0; + while (!(response is ResponseCycleFinished) && container.Distance < 17000) { + Log.Info("Test New Request absTime: {0}, ds: {1}", absTime, ds); + try { + response = cyclePort.Request(absTime, ds); + } catch (Exception) { + modData.Finish(VectoRun.Status.Success); + throw; + } + Log.Info("Test Got Response: {0},", response); + + response.Switch(). + Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). + Case<ResponseCycleFinished>(r => { }). + Case<ResponseGearShift>(r => { Log.Debug("Gearshift"); }). + Case<ResponseSuccess>(r => { + container.CommitSimulationStep(absTime, r.SimulationInterval); + absTime += r.SimulationInterval; + + ds = container.VehicleSpeed.IsEqual(0) + ? Constants.SimulationSettings.DriveOffDistance + : Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed; + + if (cnt++ % 100 == 0) { + modData.Finish(VectoRun.Status.Success); + } + }). + Default(r => { + modData.Finish(VectoRun.Status.Success); + Assert.Fail("Unexpected Response: {0}", r); + }); + } + modData.Finish(VectoRun.Status.Success); + Assert.IsInstanceOfType(response, typeof(ResponseCycleFinished)); + } + + [TestMethod] + public void Test_FullPowerTrain_JobFile() + { + const string jobFile = @"TestData\job.vecto"; + var fileWriter = new FileOutputWriter(jobFile); + var sumData = new SummaryDataContainer(fileWriter); + var jobContainer = new JobContainer(sumData); + + var inputData = JSONInputDataFactory.ReadJsonJob(jobFile); + var factory = new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter); + + jobContainer.AddRuns(factory); + jobContainer.Execute(); + + jobContainer.WaitFinished(); + ResultFileHelper.TestSumFile(@"TestData\Results\Integration\job.vsum", @"TestData\job.vsum"); + + ResultFileHelper.TestModFile(@"TestData\Results\Integration\job_1-Gear-Test-dist.vmod", + @"TestData\job_1-Gear-Test-dist.vmod", testRowCount: false); + } + + private static GearboxData CreateGearboxData() + { + var ratios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 }; + + return new GearboxData { + Gears = ratios.Select((ratio, i) => + Tuple.Create((uint)i, + new GearData { +// MaxTorque = ratio > 5 ? 2300.SI<NewtonMeter>() : null, + LossMap = TransmissionLossMapReader.ReadFromFile(GearboxLossMap, ratio, string.Format("Gear {0}", i)), + Ratio = ratio, + ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile) + })) + .ToDictionary(k => k.Item1 + 1, v => v.Item2), + ShiftTime = 2.SI<Second>(), + Inertia = 0.SI<KilogramSquareMeter>(), + TractionInterruption = 1.SI<Second>(), + StartSpeed = 2.SI<MeterPerSecond>(), + StartAcceleration = 0.6.SI<MeterPerSquareSecond>(), + StartTorqueReserve = 0.2, + TorqueReserve = 0.2, + DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay, + UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay, + UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration + }; + } + + private static AxleGearData CreateAxleGearData() + { + var ratio = 3.240355; + return new AxleGearData { + AxleGear = new GearData { + Ratio = ratio, + LossMap = TransmissionLossMapReader.ReadFromFile(AxleLossMap, ratio, "AxleGear") + } + }; + } + + private static GearboxData CreateSimpleGearboxData() + { + var ratio = 3.44; + return new GearboxData { + Gears = new Dictionary<uint, GearData> { + { + 1, new GearData { + LossMap = TransmissionLossMapReader.ReadFromFile(GearboxLossMap, ratio, "Gear 1"), + Ratio = ratio, + ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile) + } + } + }, + Inertia = 0.SI<KilogramSquareMeter>(), + TractionInterruption = 0.SI<Second>(), + ShiftTime = 2.SI<Second>(), + StartSpeed = 2.SI<MeterPerSecond>(), + StartAcceleration = 0.6.SI<MeterPerSquareSecond>(), + StartTorqueReserve = 0.2, + TorqueReserve = 0.2, + DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay, + UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay, + UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration + }; + } + + private static VehicleData CreateVehicleData(Kilogram loading) + { + var axles = new List<Axle> { + new Axle { + AxleWeightShare = 0.4375, + Inertia = 21.66667.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 62538.75.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.375, + Inertia = 10.83333.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0065, + TwinTyres = true, + TyreTestLoad = 52532.55.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.1875, + Inertia = 21.66667.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 62538.75.SI<Newton>() + } + }; + return new VehicleData { + AxleConfiguration = AxleConfiguration.AxleConfig_6x2, + + CurbWeight = 15700.SI<Kilogram>(), + Loading = loading, + DynamicTyreRadius = 0.52.SI<Meter>(), + AxleData = axles, + SavedInDeclarationMode = false + }; + } + + private static AirdragData CreateAirdragData() + { + return new AirdragData(){ + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(3.2634.SI<SquareMeter>(), + CrossWindCorrectionCurveReader.GetNoCorrectionCurve(3.2634.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection),}; + } + + private static DriverData CreateDriverData(string accelerationFile) + { + return new DriverData { + AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), + LookAheadCoasting = new DriverData.LACData { + Enabled = false, + //Deceleration = -0.5.SI<MeterPerSquareSecond>() + LookAheadDecisionFactor = new LACDecisionFactor() + }, + OverSpeedEcoRoll = new DriverData.OverSpeedEcoRollData { + Mode = DriverMode.Off + }, + }; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs b/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs index a3248672a7d7cef1fe7bee76f688dfb2941a88df..2bb855d596e50825e1a2cbe00766433e7328c6d2 100644 --- a/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs +++ b/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs @@ -29,238 +29,239 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; -using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; - -namespace TUGraz.VectoCore.Tests.Integration -{ - // ReSharper disable once InconsistentNaming - public class Truck40tPowerTrain - { - public const string ShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; - public const string AccelerationFile = @"TestData\Components\Truck.vacc"; - public const string EngineFile = @"TestData\Components\40t_Long_Haul_Truck.veng"; - public const string AxleGearLossMap = @"TestData\Components\Axle 40t Truck.vtlm"; - public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm"; - public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm"; - public const string GearboxShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; - //public const string GearboxFullLoadCurveFile = @"TestData\Components\Gearbox.vfld"; - - public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, - bool overspeed = false, GearboxType gbxType = GearboxType.AMT) - { - var container = CreatePowerTrain(cycleData, modFileName.Replace(".vmod", ""), 7500.SI<Kilogram>(), - 19300.SI<Kilogram>(), overspeed, gbxType); - - return new DistanceRun(container); - } - - public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, Kilogram massExtra, - Kilogram loading, bool overspeed = false) - { - var container = CreatePowerTrain(cycleData, modFileName.Replace(".vmod", ""), massExtra, loading, overspeed); - - return new DistanceRun(container); - } - - public static VehicleContainer CreatePowerTrain(DrivingCycleData cycleData, string modFileName, - Kilogram massExtra, Kilogram loading, bool overspeed = false, GearboxType gbxType = GearboxType.AMT) - { - var fileWriter = new FileOutputWriter(modFileName); - var modData = new ModalDataContainer(Path.GetFileName(modFileName), FuelType.DieselCI, fileWriter) { - WriteModalResults = true - }; - var container = new VehicleContainer(ExecutionMode.Engineering, modData) { - RunData = new VectoRunData { JobName = modFileName, Cycle = cycleData } - }; - - var gearboxData = CreateGearboxData(); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); - var axleGearData = CreateAxleGearData(); - var vehicleData = CreateVehicleData(massExtra, loading); - var airdragData = CreateAirdragData(); - var driverData = CreateDriverData(AccelerationFile, overspeed); - - var cycle = new DistanceBasedDrivingCycle(container, cycleData); - var engine = new CombustionEngine(container, engineData); - var clutch = new Clutch(container, engineData); - - var runData = new VectoRunData() { - EngineData = engineData, - VehicleData = vehicleData, - AirdragData = airdragData, - AxleGearData = axleGearData, - GearboxData = gearboxData - }; - - IShiftStrategy gbxStrategy; - switch (gbxType) { - case GearboxType.MT: - gbxStrategy = new MTShiftStrategy(runData, container); - break; - case GearboxType.AMT: - gbxStrategy = new AMTShiftStrategy(runData, container); - break; - default: - throw new ArgumentOutOfRangeException("gbxType", gbxType, null); - } - - dynamic tmp = cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) - .AddComponent(new Vehicle(container, vehicleData, airdragData)) - .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, axleGearData)) - .AddComponent(new DummyRetarder(container)) - .AddComponent(new Gearbox(container, gbxStrategy, runData)) - .AddComponent(clutch) - .AddComponent(engine); - - var aux = new EngineAuxiliary(container); - aux.AddConstant("ZERO", 0.SI<Watt>()); - engine.Connect(aux.Port()); - container.ModalData.AddAuxiliary("ZERO"); - - return container; - } - - private static GearboxData CreateGearboxData() - { - var ratios = new[] { 14.93, 11.64, 9.02, 7.04, 5.64, 4.4, 3.39, 2.65, 2.05, 1.6, 1.28, 1.0 }; - - return new GearboxData { - Gears = ratios.Select((ratio, i) => Tuple.Create((uint)i, new GearData { - //MaxTorque = 2300.SI<NewtonMeter>(), - LossMap = - TransmissionLossMapReader.ReadFromFile(ratio.IsEqual(1) ? GearboxIndirectLoss : GearboxDirectLoss, ratio, - string.Format("Gear {0}", i)), - Ratio = ratio, - ShiftPolygon = ShiftPolygonReader.ReadFromFile(ShiftPolygonFile) - })).ToDictionary(k => k.Item1 + 1, v => v.Item2), - ShiftTime = 2.SI<Second>(), - Inertia = 0.SI<KilogramSquareMeter>(), - TractionInterruption = 1.SI<Second>(), - StartAcceleration = 0.6.SI<MeterPerSquareSecond>(), - StartSpeed = 2.SI<MeterPerSecond>(), - TorqueReserve = 0.2, - StartTorqueReserve = 0.2, - DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay, - UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay, - UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration - }; - } - - private static AxleGearData CreateAxleGearData() - { - const double ratio = 2.59; - return new AxleGearData { - AxleGear = new GearData { - Ratio = ratio, - LossMap = TransmissionLossMapReader.ReadFromFile(AxleGearLossMap, ratio, "AxleGear") - } - }; - } - - private static VehicleData CreateVehicleData(Kilogram massExtra, Kilogram loading) - { - var wheelsType = "385/65 R 22.5"; - var axles = new List<Axle> { - new Axle { - AxleWeightShare = 0.2, - Inertia = 14.9.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 31300.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.25, - Inertia = 14.9.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0065, - TwinTyres = true, - TyreTestLoad = 31300.SI<Newton>() - }, - - // trailer - declaration wheel data - new Axle { - AxleWeightShare = 0.55 / 3, - TwinTyres = DeclarationData.Trailer.TwinTyres, - RollResistanceCoefficient = DeclarationData.Trailer.RollResistanceCoefficient, - TyreTestLoad = DeclarationData.Trailer.TyreTestLoad.SI<Newton>(), - Inertia = DeclarationData.Wheels.Lookup(wheelsType).Inertia - }, - new Axle { - AxleWeightShare = 0.55 / 3, - TwinTyres = DeclarationData.Trailer.TwinTyres, - RollResistanceCoefficient = DeclarationData.Trailer.RollResistanceCoefficient, - TyreTestLoad = DeclarationData.Trailer.TyreTestLoad.SI<Newton>(), - Inertia = DeclarationData.Wheels.Lookup(wheelsType).Inertia - }, - new Axle { - AxleWeightShare = 0.55 / 3, - TwinTyres = DeclarationData.Trailer.TwinTyres, - RollResistanceCoefficient = DeclarationData.Trailer.RollResistanceCoefficient, - TyreTestLoad = DeclarationData.Trailer.TyreTestLoad.SI<Newton>(), - Inertia = DeclarationData.Wheels.Lookup(wheelsType).Inertia - } - }; - return new VehicleData { - AxleConfiguration = AxleConfiguration.AxleConfig_4x2, - CurbWeight = 7100.SI<Kilogram>() + massExtra, - Loading = loading, - DynamicTyreRadius = 0.4882675.SI<Meter>(), - AxleData = axles, - SavedInDeclarationMode = false, - }; - } - - private static AirdragData CreateAirdragData() - { - return new AirdragData() { - CrossWindCorrectionCurve = - new CrosswindCorrectionCdxALookup(6.2985.SI<SquareMeter>(), - CrossWindCorrectionCurveReader.GetNoCorrectionCurve(6.2985.SI<SquareMeter>()), - CrossWindCorrectionMode.NoCorrection), - }; - } - - private static DriverData CreateDriverData(string accelerationFile, bool overspeed = false) - { - return new DriverData { - AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), - LookAheadCoasting = new DriverData.LACData { - Enabled = true, - MinSpeed = 50.KMPHtoMeterPerSecond(), - //Deceleration = -0.5.SI<MeterPerSquareSecond>(), - LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor, - LookAheadDecisionFactor = new LACDecisionFactor() - }, - OverSpeedEcoRoll = overspeed - ? new DriverData.OverSpeedEcoRollData() { - Mode = DriverMode.Overspeed, - MinSpeed = 50.KMPHtoMeterPerSecond(), - OverSpeed = 5.KMPHtoMeterPerSecond(), - } - : new DriverData.OverSpeedEcoRollData { - Mode = DriverMode.Off - }, - }; - } - } +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; +using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; + +namespace TUGraz.VectoCore.Tests.Integration +{ + // ReSharper disable once InconsistentNaming + public class Truck40tPowerTrain + { + public const string ShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; + public const string AccelerationFile = @"TestData\Components\Truck.vacc"; + public const string EngineFile = @"TestData\Components\40t_Long_Haul_Truck.veng"; + public const string AxleGearLossMap = @"TestData\Components\Axle 40t Truck.vtlm"; + public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm"; + public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm"; + public const string GearboxShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; + //public const string GearboxFullLoadCurveFile = @"TestData\Components\Gearbox.vfld"; + + public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, + bool overspeed = false, GearboxType gbxType = GearboxType.AMT) + { + var container = CreatePowerTrain(cycleData, modFileName.Replace(".vmod", ""), 7500.SI<Kilogram>(), + 19300.SI<Kilogram>(), overspeed, gbxType); + + return new DistanceRun(container); + } + + public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, Kilogram massExtra, + Kilogram loading, bool overspeed = false) + { + var container = CreatePowerTrain(cycleData, modFileName.Replace(".vmod", ""), massExtra, loading, overspeed); + + return new DistanceRun(container); + } + + public static VehicleContainer CreatePowerTrain(DrivingCycleData cycleData, string modFileName, + Kilogram massExtra, Kilogram loading, bool overspeed = false, GearboxType gbxType = GearboxType.AMT) + { + var fileWriter = new FileOutputWriter(modFileName); + var modData = new ModalDataContainer(Path.GetFileName(modFileName), FuelType.DieselCI, fileWriter) { + WriteModalResults = true + }; + var container = new VehicleContainer(ExecutionMode.Engineering, modData) { + RunData = new VectoRunData { JobName = modFileName, Cycle = cycleData } + }; + + var gearboxData = CreateGearboxData(); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); + var axleGearData = CreateAxleGearData(); + var vehicleData = CreateVehicleData(massExtra, loading); + var airdragData = CreateAirdragData(); + var driverData = CreateDriverData(AccelerationFile, overspeed); + + var cycle = new DistanceBasedDrivingCycle(container, cycleData); + var engine = new CombustionEngine(container, engineData); + var clutch = new Clutch(container, engineData); + + var runData = new VectoRunData() { + JobRunId = 0, + EngineData = engineData, + VehicleData = vehicleData, + AirdragData = airdragData, + AxleGearData = axleGearData, + GearboxData = gearboxData + }; + + IShiftStrategy gbxStrategy; + switch (gbxType) { + case GearboxType.MT: + gbxStrategy = new MTShiftStrategy(runData, container); + break; + case GearboxType.AMT: + gbxStrategy = new AMTShiftStrategy(runData, container); + break; + default: + throw new ArgumentOutOfRangeException("gbxType", gbxType, null); + } + + dynamic tmp = cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) + .AddComponent(new Vehicle(container, vehicleData, airdragData)) + .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, axleGearData)) + .AddComponent(new DummyRetarder(container)) + .AddComponent(new Gearbox(container, gbxStrategy, runData)) + .AddComponent(clutch) + .AddComponent(engine); + + var aux = new EngineAuxiliary(container); + aux.AddConstant("ZERO", 0.SI<Watt>()); + engine.Connect(aux.Port()); + container.ModalData.AddAuxiliary("ZERO"); + + return container; + } + + private static GearboxData CreateGearboxData() + { + var ratios = new[] { 14.93, 11.64, 9.02, 7.04, 5.64, 4.4, 3.39, 2.65, 2.05, 1.6, 1.28, 1.0 }; + + return new GearboxData { + Gears = ratios.Select((ratio, i) => Tuple.Create((uint)i, new GearData { + //MaxTorque = 2300.SI<NewtonMeter>(), + LossMap = + TransmissionLossMapReader.ReadFromFile(ratio.IsEqual(1) ? GearboxIndirectLoss : GearboxDirectLoss, ratio, + string.Format("Gear {0}", i)), + Ratio = ratio, + ShiftPolygon = ShiftPolygonReader.ReadFromFile(ShiftPolygonFile) + })).ToDictionary(k => k.Item1 + 1, v => v.Item2), + ShiftTime = 2.SI<Second>(), + Inertia = 0.SI<KilogramSquareMeter>(), + TractionInterruption = 1.SI<Second>(), + StartAcceleration = 0.6.SI<MeterPerSquareSecond>(), + StartSpeed = 2.SI<MeterPerSecond>(), + TorqueReserve = 0.2, + StartTorqueReserve = 0.2, + DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay, + UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay, + UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration + }; + } + + private static AxleGearData CreateAxleGearData() + { + const double ratio = 2.59; + return new AxleGearData { + AxleGear = new GearData { + Ratio = ratio, + LossMap = TransmissionLossMapReader.ReadFromFile(AxleGearLossMap, ratio, "AxleGear") + } + }; + } + + private static VehicleData CreateVehicleData(Kilogram massExtra, Kilogram loading) + { + var wheelsType = "385/65 R 22.5"; + var axles = new List<Axle> { + new Axle { + AxleWeightShare = 0.2, + Inertia = 14.9.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 31300.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.25, + Inertia = 14.9.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0065, + TwinTyres = true, + TyreTestLoad = 31300.SI<Newton>() + }, + + // trailer - declaration wheel data + new Axle { + AxleWeightShare = 0.55 / 3, + TwinTyres = DeclarationData.Trailer.TwinTyres, + RollResistanceCoefficient = DeclarationData.Trailer.RollResistanceCoefficient, + TyreTestLoad = DeclarationData.Trailer.TyreTestLoad.SI<Newton>(), + Inertia = DeclarationData.Wheels.Lookup(wheelsType).Inertia + }, + new Axle { + AxleWeightShare = 0.55 / 3, + TwinTyres = DeclarationData.Trailer.TwinTyres, + RollResistanceCoefficient = DeclarationData.Trailer.RollResistanceCoefficient, + TyreTestLoad = DeclarationData.Trailer.TyreTestLoad.SI<Newton>(), + Inertia = DeclarationData.Wheels.Lookup(wheelsType).Inertia + }, + new Axle { + AxleWeightShare = 0.55 / 3, + TwinTyres = DeclarationData.Trailer.TwinTyres, + RollResistanceCoefficient = DeclarationData.Trailer.RollResistanceCoefficient, + TyreTestLoad = DeclarationData.Trailer.TyreTestLoad.SI<Newton>(), + Inertia = DeclarationData.Wheels.Lookup(wheelsType).Inertia + } + }; + return new VehicleData { + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + CurbWeight = 7100.SI<Kilogram>() + massExtra, + Loading = loading, + DynamicTyreRadius = 0.4882675.SI<Meter>(), + AxleData = axles, + SavedInDeclarationMode = false, + }; + } + + private static AirdragData CreateAirdragData() + { + return new AirdragData() { + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(6.2985.SI<SquareMeter>(), + CrossWindCorrectionCurveReader.GetNoCorrectionCurve(6.2985.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection), + }; + } + + private static DriverData CreateDriverData(string accelerationFile, bool overspeed = false) + { + return new DriverData { + AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), + LookAheadCoasting = new DriverData.LACData { + Enabled = true, + MinSpeed = 50.KMPHtoMeterPerSecond(), + //Deceleration = -0.5.SI<MeterPerSquareSecond>(), + LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor, + LookAheadDecisionFactor = new LACDecisionFactor() + }, + OverSpeedEcoRoll = overspeed + ? new DriverData.OverSpeedEcoRollData() { + Mode = DriverMode.Overspeed, + MinSpeed = 50.KMPHtoMeterPerSecond(), + OverSpeed = 5.KMPHtoMeterPerSecond(), + } + : new DriverData.OverSpeedEcoRollData { + Mode = DriverMode.Off + }, + }; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs index cef987e2b8cf9c2e5d7eb0cb65559359d44176e9..3ce0723f68e2b7eb4797349a4181f0d497cf1223 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs @@ -29,537 +29,537 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using System.Data; -using System.Diagnostics; -using System.Linq; -using NUnit.Framework; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; - -// ReSharper disable UnusedVariable -// ReSharper disable NotAccessedVariable -// ReSharper disable CollectionNeverQueried.Local -// ReSharper disable RedundantAssignment - -namespace TUGraz.VectoCore.Tests.Models.SimulationComponent -{ - [TestFixture] - public class CombustionEngineTest - { - protected double Tolerance = 1E-3; - - private const string CoachEngine = @"TestData\Components\24t Coach.veng"; - - private const string TruckEngine = @"TestData\Components\40t_Long_Haul_Truck.veng"; - - [TestCase] - public void TestEngineHasOutPort() - { - var vehicle = new VehicleContainer(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); - var engine = new CombustionEngine(vehicle, engineData); - - var port = engine.OutPort(); - Assert.IsNotNull(port); - } - - [TestCase] - public void TestOutPortRequestNotFailing() - { - var vehicle = new VehicleContainer(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); - var engine = new CombustionEngine(vehicle, engineData); - var gearbox = new MockGearbox(vehicle) { Gear = 0 }; - - var port = engine.OutPort(); - - var absTime = 0.SI<Second>(); - var dt = 1.SI<Second>(); - var torque = 400.SI<NewtonMeter>(); - var engineSpeed = 1500.RPMtoRad(); - - port.Initialize(torque, engineSpeed); - port.Request(absTime, dt, torque, engineSpeed); - } - - [TestCase] - public void TestSimpleModalData() - { - var vehicle = new VehicleContainer(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); - var engine = new CombustionEngine(vehicle, engineData); - var gearbox = new MockGearbox(vehicle) { Gear = 0 }; - var port = engine.OutPort(); - - var absTime = 0.SI<Second>(); - var dt = 1.SI<Second>(); - - var torque = 0.SI<NewtonMeter>(); - var engineSpeed = 600.RPMtoRad(); - var dataWriter = new MockModalDataContainer(); - - port.Initialize(torque, engineSpeed); - for (var i = 0; i < 21; i++) { - port.Request(absTime, dt, torque, engineSpeed); - engine.CommitSimulationStep(dataWriter); - if (i > 0) { - dataWriter.CommitSimulationStep(absTime, dt); - } - absTime += dt; - } - - engineSpeed = 644.4445.RPMtoRad(); - port.Request(absTime, dt, Formulas.PowerToTorque(2329.973.SI<Watt>(), engineSpeed), engineSpeed); - engine.CommitSimulationStep(dataWriter); - - AssertHelper.AreRelativeEqual(1152.40304, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value()); - - dataWriter.CommitSimulationStep(absTime, dt); - absTime += dt; - - var power = new[] { 569.3641, 4264.177 }; - for (var i = 0; i < 2; i++) { - port.Request(absTime, dt, Formulas.PowerToTorque(power[i].SI<Watt>(), engineSpeed), engineSpeed); - engine.CommitSimulationStep(dataWriter); - dataWriter.CommitSimulationStep(absTime, dt); - absTime += dt; - } - - engineSpeed = 869.7512.RPMtoRad(); - port.Request(absTime, dt, Formulas.PowerToTorque(7984.56.SI<Watt>(), engineSpeed), engineSpeed); - engine.CommitSimulationStep(dataWriter); - - Assert.AreEqual(7108.32, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value(), 0.001); - dataWriter.CommitSimulationStep(absTime, dt); - absTime += dt; - - engineSpeed = 644.4445.RPMtoRad(); - port.Request(absTime, dt, Formulas.PowerToTorque(1351.656.SI<Watt>(), engineSpeed), engineSpeed); - engine.CommitSimulationStep(dataWriter); - - Assert.AreEqual(-7108.32, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value(), 0.001); - dataWriter.CommitSimulationStep(absTime, dt); - - VectoCSVFile.Write(@"test1.csv", dataWriter.Data, true); - } - - [TestCase("Test1Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_1Hz.csv")] - [TestCase("Test10Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz.csv")] - [TestCase("TestvarHz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_varHz.csv")] - [TestCase("Test10Hz", @"TestData\Components\24t Coach_IncPT1.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz_IncPT1.csv")] - public void TestEngineOnlyEngineFullLoadJump(string testName, string engineFile, double rpm, double initialIdleLoad, - double finalIdleLoad, string resultFile) - { - var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 0); - var engine = new EngineOnlyCombustionEngine(vehicleContainer, engineData); - - var expectedResults = VectoCSVFile.Read(resultFile); - - var requestPort = engine.OutPort(); - - //var modalData = new ModalDataWriter(string.Format("load_jump_{0}.csv", TestContext.DataRow["TestName"].ToString())); - var modalData = new MockModalDataContainer(); - - var idlePower = initialIdleLoad.SI<Watt>(); - - var angularSpeed = rpm.RPMtoRad(); - - var t = 0.SI<Second>(); - var dt = 0.1.SI<Second>(); - requestPort.Initialize(Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); - for (; t < 2; t += dt) { - requestPort.Request(t, dt, Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); - engine.CommitSimulationStep(modalData); - } - - var i = 0; - // dt = TimeSpan.FromSeconds(double.Parse(TestContext.DataRow["dt"].ToString(), CultureInfo.InvariantCulture)); - // dt = TimeSpan.FromSeconds(expectedResults.Rows[i].ParseDouble(0)) - t; - var engineLoadPower = engineData.FullLoadCurves[0].FullLoadStationaryPower(angularSpeed); - idlePower = finalIdleLoad.SI<Watt>(); - for (; t < 25; t += dt, i++) { - dt = (expectedResults.Rows[i + 1].ParseDouble(0) - expectedResults.Rows[i].ParseDouble(0)).SI<Second>(); - if (t >= 10.SI<Second>()) { - engineLoadPower = idlePower; - } - requestPort.Request(t, dt, Formulas.PowerToTorque(engineLoadPower, angularSpeed), angularSpeed); - modalData[ModalResultField.time] = t; - modalData[ModalResultField.simulationInterval] = dt; - engine.CommitSimulationStep(modalData); - Assert.AreEqual(expectedResults.Rows[i].ParseDouble(0), t.Value(), 0.001, "Time"); - Assert.AreEqual(expectedResults.Rows[i].ParseDouble(1), ((SI)modalData[ModalResultField.P_eng_full]).Value(), 0.1, - string.Format("Load in timestep {0}", t)); - modalData.CommitSimulationStep(); - } - modalData.Finish(VectoRun.Status.Success); - } - - [TestCase("Test1Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_1Hz.csv")] - [TestCase("Test10Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz.csv")] - [TestCase("TestvarHz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_varHz.csv")] - [TestCase("Test10Hz", @"TestData\Components\24t Coach_IncPT1.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz_IncPT1.csv")] - public void TestEngineFullLoadJump(string testName, string engineFile, double rpm, double initialIdleLoad, - double finalIdleLoad, string resultFile) - { - var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 0); - var engine = new CombustionEngine(vehicleContainer, engineData); - var gearbox = new MockGearbox(vehicleContainer) { Gear = 0 }; - - var expectedResults = VectoCSVFile.Read(resultFile); - - var requestPort = engine.OutPort(); - - //var modalData = new ModalDataWriter(string.Format("load_jump_{0}.csv", TestName)); - var modalData = new MockModalDataContainer(); - - var idlePower = initialIdleLoad.SI<Watt>(); - - var angularSpeed = rpm.RPMtoRad(); - - var t = 0.SI<Second>(); - var dt = 0.1.SI<Second>(); - requestPort.Initialize(Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); - for (; t < 2; t += dt) { - requestPort.Request(t, dt, Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); - engine.CommitSimulationStep(modalData); - } - - var i = 0; - // dt = TimeSpan.FromSeconds(double.Parse(TestContext.DataRow["dt"].ToString(), CultureInfo.InvariantCulture)); - // dt = TimeSpan.FromSeconds(expectedResults.Rows[i].ParseDouble(0)) - t; - var engineLoadPower = engineData.FullLoadCurves[0].FullLoadStationaryPower(angularSpeed); - idlePower = finalIdleLoad.SI<Watt>(); - for (; t < 25; t += dt, i++) { - dt = (expectedResults.Rows[i + 1].ParseDouble(0) - expectedResults.Rows[i].ParseDouble(0)).SI<Second>(); - if (t >= 10.SI<Second>()) { - engineLoadPower = idlePower; - } - requestPort.Request(t, dt, Formulas.PowerToTorque(engineLoadPower, angularSpeed), angularSpeed); - modalData[ModalResultField.time] = t; - modalData[ModalResultField.simulationInterval] = dt; - engine.CommitSimulationStep(modalData); - Assert.AreEqual(expectedResults.Rows[i].ParseDouble(0), t.Value(), 0.001, "Time"); - Assert.AreEqual(expectedResults.Rows[i].ParseDouble(1), ((SI)modalData[ModalResultField.P_eng_full]).Value(), 0.1, - string.Format("Load in timestep {0}", t)); - modalData.CommitSimulationStep(); - } - modalData.Finish(VectoRun.Status.Success); - } - - [TestCase] - public void EngineIdleJump() - { - var container = new VehicleContainer(ExecutionMode.Engineering); - var gearbox = new MockGearbox(container); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 1); - var vehicle = new MockVehicle(container); - vehicle.MyVehicleSpeed = 0.SI<MeterPerSecond>(); - var engine = new CombustionEngine(container, engineData); - var clutch = new Clutch(container, engineData); - - var d = new MockDriver(container); - - var aux = new EngineAuxiliary(container); - aux.AddConstant("CONST", 5000.SI<Watt>()); - - gearbox.Gear = 1; - - //gearbox.InPort().Connect(engine.OutPort()); - gearbox.InPort().Connect(clutch.OutPort()); - clutch.InPort().Connect(engine.OutPort()); - engine.Connect(aux.Port()); - clutch.IdleController = engine.IdleController; - - // var expectedResults = VectoCSVFile.Read(TestContext.DataRow["ResultFile"].ToString()); - - var requestPort = gearbox.OutPort(); - - //vehicleContainer.DataWriter = new ModalDataWriter("engine_idle_test.csv"); - var dataWriter = new MockModalDataContainer(); - container.ModData = dataWriter; - container.ModalData.AddAuxiliary("CONST"); - - var torque = 1200.SI<NewtonMeter>(); - var angularVelocity = 800.RPMtoRad(); - - // initialize engine... - - gearbox.Initialize(torque, angularVelocity); - - var absTime = 0.SI<Second>(); - var dt = Constants.SimulationSettings.TargetTimeInterval; - - var response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - - container.CommitSimulationStep(absTime, dt); - var row = dataWriter.Data.Rows.Cast<DataRow>().Last(); - Assert.AreEqual(100530.96491487339.SI<Watt>().Value(), ((SI)row[ModalResultField.P_eng_out.GetName()]).Value()); - Assert.AreEqual(105530.96491487339.SI<Watt>().Value(), ((SI)row[ModalResultField.P_eng_fcmap.GetName()]).Value()); - Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.P_aux.GetName()]); - Assert.AreEqual(800.RPMtoRad(), row[ModalResultField.n_eng_avg.GetName()]); - - absTime += dt; - - // actual test... - - gearbox.Gear = 0; - gearbox.SetClutch(false); - torque = 0.SI<NewtonMeter>(); - - response = (ResponseSuccess)gearbox.Request(absTime, dt, torque, angularVelocity); - - container.CommitSimulationStep(absTime, dt); - row = dataWriter.Data.Rows.Cast<DataRow>().Last(); - - Assert.AreEqual(0.SI<Watt>(), row[ModalResultField.P_eng_out.GetName()]); - Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.P_aux.GetName()]); - Assert.AreEqual(680.RPMtoRad(), row[ModalResultField.n_eng_avg.GetName()]); - } - - [TestCase] - public void EngineIdleControllerTestCoach() - { - VehicleContainer container; - CombustionEngine engine; - ITnOutPort requestPort; - MockGearbox gearbox; - VehicleContainer(CoachEngine, out container, out engine, out requestPort, out gearbox); - - var absTime = 0.SI<Second>(); - var dt = Constants.SimulationSettings.TargetTimeInterval; - - var angularVelocity = 800.RPMtoRad(); - var torque = 100000.SI<Watt>() / angularVelocity; - - var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); - - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - Assert.AreEqual(105000, response.EnginePowerRequest.Value(), Tolerance); - container.CommitSimulationStep(absTime, dt); - absTime += dt; - - var engineSpeed = new[] { 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad() }; - var enginePower = new[] { -8601.6308.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>() }; - - gearbox.SetClutch(false); - for (var i = 0; i < engineSpeed.Length; i++) { - torque = 0.SI<NewtonMeter>(); - - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); - container.CommitSimulationStep(absTime, dt); - absTime += dt; - - Assert.AreEqual(engineSpeed[i].Value(), engine.PreviousState.EngineSpeed.Value(), Tolerance, "i: {0}", i); - Assert.AreEqual(enginePower[i].Value(), engine.PreviousState.EnginePower.Value(), Tolerance, "i: {0}", i); - } - } - - /* - * VECTO 2.2 - | time [s] | P_eng_out [kW] | n_eng_avg [1/min] | T_eng_fcmap [Nm] | Gear [-] | - | 59.5 | 349.981 | 1679.281 | 1990.181 | 8 | - | 60.5 | 5 | 1679.281 | 28.43269 | 0 | - | 61.5 | -19.47213 | 1397.271 | -133.0774 | 0 | - | 62.5 | -18.11888 | 1064.296 | -162.5699 | 0 | - | 63.5 | -11.11163 | 714.1923 | -148.571 | 0 | - | 64.5 | -0.5416708 | 560 | -9.236741 | 0 | - | 65.5 | 5 | 560 | 85.26157 | 0 | - | 66.5 | 5 | 560 | 85.26157 | 0 | - | 67.5 | 5 | 560 | 85.26157 | 0 | - | 68.5 | 5 | 560 | 85.26157 | 0 | - | 69.5 | 5 | 560 | 85.26157 | 0 | - | 70.5 | 308.729 | 1284.139 | 2295.815 | 9 | - */ - - [TestCase] - public void EngineIdleControllerTestTruck() - { - VehicleContainer container; - CombustionEngine engine; - ITnOutPort requestPort; - MockGearbox gearbox; - VehicleContainer(TruckEngine, out container, out engine, out requestPort, out gearbox); - - //var dataWriter = new ModalDataWriter("EngineIdle.vmod"); - //container.DataWriter = dataWriter; - - var absTime = 0.SI<Second>(); - var dt = Constants.SimulationSettings.TargetTimeInterval; - - var angularVelocity = 1680.RPMtoRad(); - var torque = 345000.SI<Watt>() / angularVelocity; - - var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); - - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - Assert.AreEqual(350000, response.EnginePowerRequest.Value(), Tolerance); - container.CommitSimulationStep(absTime, dt); - absTime += dt; - - var engineSpeed = new[] { - 1439.5773, 1225.5363, 1026.6696, 834.1936, 641.1360, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, - 560, 560 - }; - - var enginePower = new[] { - -37334.1588, -27198.2777, -20280.7550, -15216.7221, -11076.6656, -500.7991, 5000, 5000, 5000, 5000, 5000, 5000, 5000, - 5000, 5000, 5000, 5000, 5000, 5000, 5000 - }; - - var fld = engine.ModelData.FullLoadCurves; - - gearbox.SetClutch(false); - var engSpeedResults = new List<dynamic>(); - for (var i = 0; i < 20; i++) { - torque = 0.SI<NewtonMeter>(); - - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); - - container.CommitSimulationStep(absTime, dt); - - engSpeedResults.Add(new { absTime, engine.PreviousState.EngineSpeed, engine.PreviousState.EnginePower }); - Assert.AreEqual(engineSpeed[i], engine.PreviousState.EngineSpeed.AsRPM, Tolerance, string.Format("entry {0}", i)); - Assert.AreEqual(enginePower[i], engine.PreviousState.EnginePower.Value(), Tolerance, string.Format("entry {0}", i)); - absTime += dt; - } - //dataWriter.Finish(); - } - - [TestCase] - public void EngineIdleControllerTest2Truck() - { - VehicleContainer container; - CombustionEngine engine; - ITnOutPort requestPort; - MockGearbox gearbox; - VehicleContainer(TruckEngine, out container, out engine, out requestPort, out gearbox); - - //var dataWriter = new ModalDataWriter("EngienIdle.vmod"); - //container.DataWriter = dataWriter; - - var absTime = 0.SI<Second>(); - var dt = Constants.SimulationSettings.TargetTimeInterval; - - var angularVelocity = 95.5596.SI<PerSecond>(); - - var torque = (engine.ModelData.FullLoadCurves[0].DragLoadStationaryPower(angularVelocity) - 5000.SI<Watt>()) / - angularVelocity; - - var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); - - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - Assert.AreEqual(-14829.79713, response.EnginePowerRequest.Value(), Tolerance); - container.CommitSimulationStep(absTime, dt); - absTime += dt; - - var engineSpeed = new[] { - 1680.RPMtoRad(), 1680.RPMtoRad(), 1467.014.RPMtoRad(), 1272.8658.RPMtoRad(), 1090.989.RPMtoRad(), - 915.3533.RPMtoRad(), 738.599.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), - 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), - 560.RPMtoRad() - }; - - //var enginePower = new[] { - // 5000.SI<Watt>(), 5000.SI<Watt>(), -32832.8834.SI<Watt>(), -25025.1308.SI<Watt>(), -19267.0360.SI<Watt>(), - // -14890.1962.SI<Watt>(), -11500.7991.SI<Watt>(), -8091.0577.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), - // 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), - // 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>() - //}; - - gearbox.SetClutch(false); - var engSpeedResults = new List<dynamic>(); - torque = 0.SI<NewtonMeter>(); - for (var i = 0; i < engineSpeed.Length; i++) { - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); - - container.CommitSimulationStep(absTime, dt); - - engSpeedResults.Add(new { absTime, engine.PreviousState.EngineSpeed, engine.PreviousState.EnginePower }); - //Assert.AreEqual(engineSpeed[i].Value(), engine.PreviousState.EngineSpeed.Value(), Tolerance); - //Assert.AreEqual(enginePower[i].Value(), engine.PreviousState.EnginePower.Value(), Tolerance); - - absTime += dt; - } - //dataWriter.Finish(); - } - - [TestCase] - public void Test_EngineData() - { - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); - var motorway = engineData.WHTCMotorway; - Assert.AreEqual(motorway, 1); - - var rural = engineData.WHTCRural; - Assert.AreEqual(rural, 1); - - var urban = engineData.WHTCUrban; - Assert.AreEqual(urban, 1); - - var displace = engineData.Displacement; - Assert.AreEqual(0.01273, displace.Value()); - Assert.IsTrue(displace.HasEqualUnit(new SI().Cubic.Meter)); - - var inert = engineData.Inertia; - Assert.AreEqual(3.8, inert.Value(), 0.00001); - Assert.IsTrue(inert.HasEqualUnit(new SI().Kilo.Gramm.Square.Meter)); - - var idle = engineData.IdleSpeed; - Assert.AreEqual(58.6430628670095, idle.Value(), 0.000001); - Assert.IsTrue(idle.HasEqualUnit(0.SI<PerSecond>())); - } - - private static void VehicleContainer(string engineFile, out VehicleContainer container, out CombustionEngine engine, - out ITnOutPort requestPort, out MockGearbox gearbox) - { - container = new VehicleContainer(ExecutionMode.Engineering); - gearbox = new MockGearbox(container); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 1); - - engine = new CombustionEngine(container, engineData); - var clutch = new Clutch(container, engineData); - - var d = new MockDriver(container); - - var aux = new EngineAuxiliary(container); - aux.AddConstant("CONST", 5000.SI<Watt>()); - - gearbox.Gear = 1; - var vehicle = new MockVehicle(container); - vehicle.MyVehicleSpeed = 0.SI<MeterPerSecond>(); - //gearbox.InPort().Connect(engine.OutPort()); - gearbox.InPort().Connect(clutch.OutPort()); - clutch.InPort().Connect(engine.OutPort()); - engine.Connect(aux.Port()); - - // has to be done after connecting components! - clutch.IdleController = engine.IdleController; - - requestPort = gearbox.OutPort(); - - //vehicleContainer.DataWriter = new ModalDataWriter("engine_idle_test.csv"); - var dataWriter = new MockModalDataContainer(); - container.ModData = dataWriter; - container.ModalData.AddAuxiliary("CONST"); - } - } +using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.Linq; +using NUnit.Framework; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; + +// ReSharper disable UnusedVariable +// ReSharper disable NotAccessedVariable +// ReSharper disable CollectionNeverQueried.Local +// ReSharper disable RedundantAssignment + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponent +{ + [TestFixture] + public class CombustionEngineTest + { + protected double Tolerance = 1E-3; + + private const string CoachEngine = @"TestData\Components\24t Coach.veng"; + + private const string TruckEngine = @"TestData\Components\40t_Long_Haul_Truck.veng"; + + [TestCase] + public void TestEngineHasOutPort() + { + var vehicle = new VehicleContainer(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); + var engine = new CombustionEngine(vehicle, engineData); + + var port = engine.OutPort(); + Assert.IsNotNull(port); + } + + [TestCase] + public void TestOutPortRequestNotFailing() + { + var vehicle = new VehicleContainer(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); + var engine = new CombustionEngine(vehicle, engineData); + var gearbox = new MockGearbox(vehicle) { Gear = 0 }; + + var port = engine.OutPort(); + + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); + var torque = 400.SI<NewtonMeter>(); + var engineSpeed = 1500.RPMtoRad(); + + port.Initialize(torque, engineSpeed); + port.Request(absTime, dt, torque, engineSpeed); + } + + [TestCase] + public void TestSimpleModalData() + { + var vehicle = new VehicleContainer(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); + var engine = new CombustionEngine(vehicle, engineData); + var gearbox = new MockGearbox(vehicle) { Gear = 0 }; + var port = engine.OutPort(); + + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); + + var torque = 0.SI<NewtonMeter>(); + var engineSpeed = 600.RPMtoRad(); + var dataWriter = new MockModalDataContainer(); + + port.Initialize(torque, engineSpeed); + for (var i = 0; i < 21; i++) { + port.Request(absTime, dt, torque, engineSpeed); + engine.CommitSimulationStep(dataWriter); + if (i > 0) { + dataWriter.CommitSimulationStep(absTime, dt); + } + absTime += dt; + } + + engineSpeed = 644.4445.RPMtoRad(); + port.Request(absTime, dt, Formulas.PowerToTorque(2329.973.SI<Watt>(), engineSpeed), engineSpeed); + engine.CommitSimulationStep(dataWriter); + + AssertHelper.AreRelativeEqual(1152.40304, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value()); + + dataWriter.CommitSimulationStep(absTime, dt); + absTime += dt; + + var power = new[] { 569.3641, 4264.177 }; + for (var i = 0; i < 2; i++) { + port.Request(absTime, dt, Formulas.PowerToTorque(power[i].SI<Watt>(), engineSpeed), engineSpeed); + engine.CommitSimulationStep(dataWriter); + dataWriter.CommitSimulationStep(absTime, dt); + absTime += dt; + } + + engineSpeed = 869.7512.RPMtoRad(); + port.Request(absTime, dt, Formulas.PowerToTorque(7984.56.SI<Watt>(), engineSpeed), engineSpeed); + engine.CommitSimulationStep(dataWriter); + + Assert.AreEqual(7108.32, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value(), 0.001); + dataWriter.CommitSimulationStep(absTime, dt); + absTime += dt; + + engineSpeed = 644.4445.RPMtoRad(); + port.Request(absTime, dt, Formulas.PowerToTorque(1351.656.SI<Watt>(), engineSpeed), engineSpeed); + engine.CommitSimulationStep(dataWriter); + + Assert.AreEqual(-7108.32, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value(), 0.001); + dataWriter.CommitSimulationStep(absTime, dt); + + VectoCSVFile.Write(@"test1.csv", dataWriter.Data, true); + } + + [TestCase("Test1Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_1Hz.csv")] + [TestCase("Test10Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz.csv")] + [TestCase("TestvarHz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_varHz.csv")] + [TestCase("Test10Hz", @"TestData\Components\24t Coach_IncPT1.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz_IncPT1.csv")] + public void TestEngineOnlyEngineFullLoadJump(string testName, string engineFile, double rpm, double initialIdleLoad, + double finalIdleLoad, string resultFile) + { + var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 0); + var engine = new EngineOnlyCombustionEngine(vehicleContainer, engineData); + + var expectedResults = VectoCSVFile.Read(resultFile); + + var requestPort = engine.OutPort(); + + //var modalData = new ModalDataWriter(string.Format("load_jump_{0}.csv", TestContext.DataRow["TestName"].ToString())); + var modalData = new MockModalDataContainer(); + + var idlePower = initialIdleLoad.SI<Watt>(); + + var angularSpeed = rpm.RPMtoRad(); + + var t = 0.SI<Second>(); + var dt = 0.1.SI<Second>(); + requestPort.Initialize(Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); + for (; t < 2; t += dt) { + requestPort.Request(t, dt, Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); + engine.CommitSimulationStep(modalData); + } + + var i = 0; + // dt = TimeSpan.FromSeconds(double.Parse(TestContext.DataRow["dt"].ToString(), CultureInfo.InvariantCulture)); + // dt = TimeSpan.FromSeconds(expectedResults.Rows[i].ParseDouble(0)) - t; + var engineLoadPower = engineData.FullLoadCurves[0].FullLoadStationaryPower(angularSpeed); + idlePower = finalIdleLoad.SI<Watt>(); + for (; t < 25; t += dt, i++) { + dt = (expectedResults.Rows[i + 1].ParseDouble(0) - expectedResults.Rows[i].ParseDouble(0)).SI<Second>(); + if (t >= 10.SI<Second>()) { + engineLoadPower = idlePower; + } + requestPort.Request(t, dt, Formulas.PowerToTorque(engineLoadPower, angularSpeed), angularSpeed); + modalData[ModalResultField.time] = t; + modalData[ModalResultField.simulationInterval] = dt; + engine.CommitSimulationStep(modalData); + Assert.AreEqual(expectedResults.Rows[i].ParseDouble(0), t.Value(), 0.001, "Time"); + Assert.AreEqual(expectedResults.Rows[i].ParseDouble(1), ((SI)modalData[ModalResultField.P_eng_full]).Value(), 0.1, + string.Format("Load in timestep {0}", t)); + modalData.CommitSimulationStep(); + } + modalData.Finish(VectoRun.Status.Success); + } + + [TestCase("Test1Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_1Hz.csv")] + [TestCase("Test10Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz.csv")] + [TestCase("TestvarHz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_varHz.csv")] + [TestCase("Test10Hz", @"TestData\Components\24t Coach_IncPT1.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz_IncPT1.csv")] + public void TestEngineFullLoadJump(string testName, string engineFile, double rpm, double initialIdleLoad, + double finalIdleLoad, string resultFile) + { + var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 0); + var engine = new CombustionEngine(vehicleContainer, engineData); + var gearbox = new MockGearbox(vehicleContainer) { Gear = 0 }; + + var expectedResults = VectoCSVFile.Read(resultFile); + + var requestPort = engine.OutPort(); + + //var modalData = new ModalDataWriter(string.Format("load_jump_{0}.csv", TestName)); + var modalData = new MockModalDataContainer(); + + var idlePower = initialIdleLoad.SI<Watt>(); + + var angularSpeed = rpm.RPMtoRad(); + + var t = 0.SI<Second>(); + var dt = 0.1.SI<Second>(); + requestPort.Initialize(Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); + for (; t < 2; t += dt) { + requestPort.Request(t, dt, Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); + engine.CommitSimulationStep(modalData); + } + + var i = 0; + // dt = TimeSpan.FromSeconds(double.Parse(TestContext.DataRow["dt"].ToString(), CultureInfo.InvariantCulture)); + // dt = TimeSpan.FromSeconds(expectedResults.Rows[i].ParseDouble(0)) - t; + var engineLoadPower = engineData.FullLoadCurves[0].FullLoadStationaryPower(angularSpeed); + idlePower = finalIdleLoad.SI<Watt>(); + for (; t < 25; t += dt, i++) { + dt = (expectedResults.Rows[i + 1].ParseDouble(0) - expectedResults.Rows[i].ParseDouble(0)).SI<Second>(); + if (t >= 10.SI<Second>()) { + engineLoadPower = idlePower; + } + requestPort.Request(t, dt, Formulas.PowerToTorque(engineLoadPower, angularSpeed), angularSpeed); + modalData[ModalResultField.time] = t; + modalData[ModalResultField.simulationInterval] = dt; + engine.CommitSimulationStep(modalData); + Assert.AreEqual(expectedResults.Rows[i].ParseDouble(0), t.Value(), 0.001, "Time"); + Assert.AreEqual(expectedResults.Rows[i].ParseDouble(1), ((SI)modalData[ModalResultField.P_eng_full]).Value(), 0.1, + string.Format("Load in timestep {0}", t)); + modalData.CommitSimulationStep(); + } + modalData.Finish(VectoRun.Status.Success); + } + + [TestCase] + public void EngineIdleJump() + { + var container = new VehicleContainer(ExecutionMode.Engineering); + var gearbox = new MockGearbox(container); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 1); + var vehicle = new MockVehicle(container); + vehicle.MyVehicleSpeed = 0.SI<MeterPerSecond>(); + var engine = new CombustionEngine(container, engineData); + var clutch = new Clutch(container, engineData); + + var d = new MockDriver(container); + + var aux = new EngineAuxiliary(container); + aux.AddConstant("CONST", 5000.SI<Watt>()); + + gearbox.Gear = 1; + + //gearbox.InPort().Connect(engine.OutPort()); + gearbox.InPort().Connect(clutch.OutPort()); + clutch.InPort().Connect(engine.OutPort()); + engine.Connect(aux.Port()); + clutch.IdleController = engine.IdleController; + + // var expectedResults = VectoCSVFile.Read(TestContext.DataRow["ResultFile"].ToString()); + + var requestPort = gearbox.OutPort(); + + //vehicleContainer.DataWriter = new ModalDataWriter("engine_idle_test.csv"); + var dataWriter = new MockModalDataContainer(); + container.ModData = dataWriter; + container.ModalData.AddAuxiliary("CONST"); + + var torque = 1200.SI<NewtonMeter>(); + var angularVelocity = 800.RPMtoRad(); + + // initialize engine... + + gearbox.Initialize(torque, angularVelocity); + + var absTime = 0.SI<Second>(); + var dt = Constants.SimulationSettings.TargetTimeInterval; + + var response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); + + container.CommitSimulationStep(absTime, dt); + var row = dataWriter.Data.Rows.Cast<DataRow>().Last(); + Assert.AreEqual(100530.96491487339.SI<Watt>().Value(), ((SI)row[ModalResultField.P_eng_out.GetName()]).Value()); + Assert.AreEqual(105530.96491487339.SI<Watt>().Value(), ((SI)row[ModalResultField.P_eng_fcmap.GetName()]).Value()); + Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.P_aux.GetName()]); + Assert.AreEqual(800.RPMtoRad(), row[ModalResultField.n_eng_avg.GetName()]); + + absTime += dt; + + // actual test... + + gearbox.Gear = 0; + gearbox.SetClutch(false); + torque = 0.SI<NewtonMeter>(); + + response = (ResponseSuccess)gearbox.Request(absTime, dt, torque, angularVelocity); + + container.CommitSimulationStep(absTime, dt); + row = dataWriter.Data.Rows.Cast<DataRow>().Last(); + + Assert.AreEqual(0.SI<Watt>(), row[ModalResultField.P_eng_out.GetName()]); + Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.P_aux.GetName()]); + Assert.AreEqual(680.RPMtoRad(), row[ModalResultField.n_eng_avg.GetName()]); + } + + [TestCase] + public void EngineIdleControllerTestCoach() + { + VehicleContainer container; + CombustionEngine engine; + ITnOutPort requestPort; + MockGearbox gearbox; + VehicleContainer(CoachEngine, out container, out engine, out requestPort, out gearbox); + + var absTime = 0.SI<Second>(); + var dt = Constants.SimulationSettings.TargetTimeInterval; + + var angularVelocity = 800.RPMtoRad(); + var torque = 100000.SI<Watt>() / angularVelocity; + + var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); + + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); + Assert.AreEqual(105000, response.EnginePowerRequest.Value(), Tolerance); + container.CommitSimulationStep(absTime, dt); + absTime += dt; + + var engineSpeed = new[] { 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad() }; + var enginePower = new[] { -8601.6308.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>() }; + + gearbox.SetClutch(false); + for (var i = 0; i < engineSpeed.Length; i++) { + torque = 0.SI<NewtonMeter>(); + + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); + container.CommitSimulationStep(absTime, dt); + absTime += dt; + + Assert.AreEqual(engineSpeed[i].Value(), engine.PreviousState.EngineSpeed.Value(), Tolerance, "i: {0}", i); + Assert.AreEqual(enginePower[i].Value(), engine.PreviousState.EnginePower.Value(), Tolerance, "i: {0}", i); + } + } + + /* + * VECTO 2.2 + | time [s] | P_eng_out [kW] | n_eng_avg [1/min] | T_eng_fcmap [Nm] | Gear [-] | + | 59.5 | 349.981 | 1679.281 | 1990.181 | 8 | + | 60.5 | 5 | 1679.281 | 28.43269 | 0 | + | 61.5 | -19.47213 | 1397.271 | -133.0774 | 0 | + | 62.5 | -18.11888 | 1064.296 | -162.5699 | 0 | + | 63.5 | -11.11163 | 714.1923 | -148.571 | 0 | + | 64.5 | -0.5416708 | 560 | -9.236741 | 0 | + | 65.5 | 5 | 560 | 85.26157 | 0 | + | 66.5 | 5 | 560 | 85.26157 | 0 | + | 67.5 | 5 | 560 | 85.26157 | 0 | + | 68.5 | 5 | 560 | 85.26157 | 0 | + | 69.5 | 5 | 560 | 85.26157 | 0 | + | 70.5 | 308.729 | 1284.139 | 2295.815 | 9 | + */ + + [TestCase] + public void EngineIdleControllerTestTruck() + { + VehicleContainer container; + CombustionEngine engine; + ITnOutPort requestPort; + MockGearbox gearbox; + VehicleContainer(TruckEngine, out container, out engine, out requestPort, out gearbox); + + //var dataWriter = new ModalDataWriter("EngineIdle.vmod"); + //container.DataWriter = dataWriter; + + var absTime = 0.SI<Second>(); + var dt = Constants.SimulationSettings.TargetTimeInterval; + + var angularVelocity = 1680.RPMtoRad(); + var torque = 345000.SI<Watt>() / angularVelocity; + + var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); + + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); + Assert.AreEqual(350000, response.EnginePowerRequest.Value(), Tolerance); + container.CommitSimulationStep(absTime, dt); + absTime += dt; + + var engineSpeed = new[] { + 1439.5773, 1225.5363, 1026.6696, 834.1936, 641.1360, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560 + }; + + var enginePower = new[] { + -37334.1588, -27198.2777, -20280.7550, -15216.7221, -11076.6656, -500.7991, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000 + }; + + var fld = engine.ModelData.FullLoadCurves; + + gearbox.SetClutch(false); + var engSpeedResults = new List<dynamic>(); + for (var i = 0; i < 20; i++) { + torque = 0.SI<NewtonMeter>(); + + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); + + container.CommitSimulationStep(absTime, dt); + + engSpeedResults.Add(new { absTime, engine.PreviousState.EngineSpeed, engine.PreviousState.EnginePower }); + Assert.AreEqual(engineSpeed[i], engine.PreviousState.EngineSpeed.AsRPM, Tolerance, string.Format("entry {0}", i)); + Assert.AreEqual(enginePower[i], engine.PreviousState.EnginePower.Value(), Tolerance, string.Format("entry {0}", i)); + absTime += dt; + } + //dataWriter.Finish(); + } + + [TestCase] + public void EngineIdleControllerTest2Truck() + { + VehicleContainer container; + CombustionEngine engine; + ITnOutPort requestPort; + MockGearbox gearbox; + VehicleContainer(TruckEngine, out container, out engine, out requestPort, out gearbox); + + //var dataWriter = new ModalDataWriter("EngienIdle.vmod"); + //container.DataWriter = dataWriter; + + var absTime = 0.SI<Second>(); + var dt = Constants.SimulationSettings.TargetTimeInterval; + + var angularVelocity = 95.5596.SI<PerSecond>(); + + var torque = (engine.ModelData.FullLoadCurves[0].DragLoadStationaryPower(angularVelocity) - 5000.SI<Watt>()) / + angularVelocity; + + var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); + + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); + Assert.AreEqual(-14829.79713, response.EnginePowerRequest.Value(), Tolerance); + container.CommitSimulationStep(absTime, dt); + absTime += dt; + + var engineSpeed = new[] { + 1680.RPMtoRad(), 1680.RPMtoRad(), 1467.014.RPMtoRad(), 1272.8658.RPMtoRad(), 1090.989.RPMtoRad(), + 915.3533.RPMtoRad(), 738.599.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), + 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), + 560.RPMtoRad() + }; + + //var enginePower = new[] { + // 5000.SI<Watt>(), 5000.SI<Watt>(), -32832.8834.SI<Watt>(), -25025.1308.SI<Watt>(), -19267.0360.SI<Watt>(), + // -14890.1962.SI<Watt>(), -11500.7991.SI<Watt>(), -8091.0577.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), + // 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), + // 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>() + //}; + + gearbox.SetClutch(false); + var engSpeedResults = new List<dynamic>(); + torque = 0.SI<NewtonMeter>(); + for (var i = 0; i < engineSpeed.Length; i++) { + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); + + container.CommitSimulationStep(absTime, dt); + + engSpeedResults.Add(new { absTime, engine.PreviousState.EngineSpeed, engine.PreviousState.EnginePower }); + //Assert.AreEqual(engineSpeed[i].Value(), engine.PreviousState.EngineSpeed.Value(), Tolerance); + //Assert.AreEqual(enginePower[i].Value(), engine.PreviousState.EnginePower.Value(), Tolerance); + + absTime += dt; + } + //dataWriter.Finish(); + } + + [TestCase] + public void Test_EngineData() + { + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); + var motorway = engineData.WHTCMotorway; + Assert.AreEqual(motorway, 1); + + var rural = engineData.WHTCRural; + Assert.AreEqual(rural, 1); + + var urban = engineData.WHTCUrban; + Assert.AreEqual(urban, 1); + + var displace = engineData.Displacement; + Assert.AreEqual(0.01273, displace.Value()); + Assert.IsTrue(displace.HasEqualUnit(new SI().Cubic.Meter)); + + var inert = engineData.Inertia; + Assert.AreEqual(3.8, inert.Value(), 0.00001); + Assert.IsTrue(inert.HasEqualUnit(new SI().Kilo.Gramm.Square.Meter)); + + var idle = engineData.IdleSpeed; + Assert.AreEqual(58.6430628670095, idle.Value(), 0.000001); + Assert.IsTrue(idle.HasEqualUnit(0.SI<PerSecond>())); + } + + private static void VehicleContainer(string engineFile, out VehicleContainer container, out CombustionEngine engine, + out ITnOutPort requestPort, out MockGearbox gearbox) + { + container = new VehicleContainer(ExecutionMode.Engineering); + gearbox = new MockGearbox(container); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 1); + + engine = new CombustionEngine(container, engineData); + var clutch = new Clutch(container, engineData); + + var d = new MockDriver(container); + + var aux = new EngineAuxiliary(container); + aux.AddConstant("CONST", 5000.SI<Watt>()); + + gearbox.Gear = 1; + var vehicle = new MockVehicle(container); + vehicle.MyVehicleSpeed = 0.SI<MeterPerSecond>(); + //gearbox.InPort().Connect(engine.OutPort()); + gearbox.InPort().Connect(clutch.OutPort()); + clutch.InPort().Connect(engine.OutPort()); + engine.Connect(aux.Port()); + + // has to be done after connecting components! + clutch.IdleController = engine.IdleController; + + requestPort = gearbox.OutPort(); + + //vehicleContainer.DataWriter = new ModalDataWriter("engine_idle_test.csv"); + var dataWriter = new MockModalDataContainer(); + container.ModData = dataWriter; + container.ModalData.AddAuxiliary("CONST"); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/DriverTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/DriverTest.cs index a58614f247d3c5b538d34dff9bc34496d4794ce6..377c893758a0806862a08f05e77843f56596f6f0 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/DriverTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/DriverTest.cs @@ -29,443 +29,443 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using System.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; -using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; - -namespace TUGraz.VectoCore.Tests.Models.SimulationComponent -{ - [TestClass] - public class DriverTest - { - public const string JobFile = @"TestData\Jobs\24t Coach EngineOnly.vecto"; - public const string EngineFile = @"TestData\Components\24t Coach.veng"; - public const string EngineFileHigh = @"TestData\Components\24t Coach_high.veng"; - public const string AccelerationFile = @"TestData\Components\Coach.vacc"; - public const double Tolerance = 0.001; - - [TestMethod] - public void DriverCoastingTest() - { - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 1); - - var vehicleData = CreateVehicleData(33000.SI<Kilogram>()); - var airdragData = CreateAirdragData(); - vehicleData.DynamicTyreRadius = 0.026372213.SI<Meter>(); // take into account axle ratio, gear ratio - - var driverData = CreateDriverData(); - - var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain_Coasting"); - var modData = new ModalDataContainer("Coach_MinimalPowertrain_Coasting", FuelType.DieselCI, fileWriter); - var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData); - var mockCycle = new MockDrivingCycle(vehicleContainer, null); - - var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); - var engine = new CombustionEngine(vehicleContainer, engineData); - var clutch = new Clutch(vehicleContainer, engineData); - dynamic tmp = AddComponent(driver, new Vehicle(vehicleContainer, vehicleData, airdragData)); - tmp = AddComponent(tmp, new Wheels(vehicleContainer, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)); - tmp = AddComponent(tmp, clutch); - AddComponent(tmp, engine); - clutch.IdleController = engine.IdleController; - - var gbx = new MockGearbox(vehicleContainer) { Gear = 1 }; - - var driverPort = driver.OutPort(); - - var velocity = 5.SI<MeterPerSecond>(); - driverPort.Initialize(velocity, 0.SI<Radian>()); - - var absTime = 0.SI<Second>(); - - var response = driver.DrivingActionCoast(absTime, 1.SI<Meter>(), velocity, 0.SI<Radian>()); - - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - - vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); - absTime += response.SimulationInterval; - - Assert.AreEqual(4.9877, vehicleContainer.VehicleSpeed.Value(), Tolerance); - Assert.AreEqual(0.2004, response.SimulationInterval.Value(), Tolerance); - Assert.AreEqual(engine.PreviousState.FullDragTorque.Value(), engine.PreviousState.EngineTorque.Value(), - Constants.SimulationSettings.LineSearchTolerance); - - while (vehicleContainer.VehicleSpeed > 1.7) { - response = driver.DrivingActionCoast(absTime, 1.SI<Meter>(), velocity, 0.SI<Radian>()); - - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - - vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); - absTime += response.SimulationInterval; - modData.Finish(VectoRun.Status.Success); - } - modData.Finish(VectoRun.Status.Success); - } - - [TestMethod] - public void DriverCoastingTest2() - { - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 1); - - var vehicleData = CreateVehicleData(33000.SI<Kilogram>()); - vehicleData.DynamicTyreRadius = 0.026372213.SI<Meter>(); // take into account axle ratio, gear ratio - var airdragData = CreateAirdragData(); - var driverData = CreateDriverData(); - - var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain_Coasting"); - var modData = new ModalDataContainer("Coach_MinimalPowertrain_Coasting", FuelType.DieselCI, fileWriter); - var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData); - var mockCycle = new MockDrivingCycle(vehicleContainer, null); - - var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); - var engine = new CombustionEngine(vehicleContainer, engineData); - var clutch = new Clutch(vehicleContainer, engineData); - - dynamic tmp = AddComponent(driver, new Vehicle(vehicleContainer, vehicleData, airdragData)); - tmp = AddComponent(tmp, new Wheels(vehicleContainer, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)); - tmp = AddComponent(tmp, clutch); - AddComponent(tmp, engine); - clutch.IdleController = engine.IdleController; - - var gbx = new MockGearbox(vehicleContainer); - gbx.Gear = 1; - - var driverPort = driver.OutPort(); - - var gradient = VectoMath.InclinationToAngle(-0.020237973 / 100.0); - var velocity = 5.SI<MeterPerSecond>(); - driverPort.Initialize(velocity, gradient); - - var absTime = 0.SI<Second>(); - - var response = driver.DrivingActionCoast(absTime, 1.SI<Meter>(), velocity, gradient); - - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - - vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); - absTime += response.SimulationInterval; - - Assert.AreEqual(4.9878, vehicleContainer.VehicleSpeed.Value(), Tolerance); - Assert.AreEqual(0.2004, response.SimulationInterval.Value(), Tolerance); - Assert.AreEqual(engine.PreviousState.FullDragTorque.Value(), engine.PreviousState.EngineTorque.Value(), - Constants.SimulationSettings.LineSearchTolerance); - - while (vehicleContainer.VehicleSpeed > 1.7) { - response = driver.DrivingActionCoast(absTime, 1.SI<Meter>(), velocity, gradient); - - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - - vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); - absTime += response.SimulationInterval; - modData.Finish(VectoRun.Status.Success); - } - modData.Finish(VectoRun.Status.Success); - } - - [TestMethod] - public void DriverOverloadTest() - { - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFileHigh, 1); - - var vehicleData = CreateVehicleData(33000.SI<Kilogram>()); - var airdragData = CreateAirdragData(); - - // take into account the axle ratio and 1st-gear ratio - vehicleData.DynamicTyreRadius /= (3.24 * 6.38); - - var driverData = CreateDriverData(); - - var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain"); - var modData = new ModalDataContainer("Coach_MinimalPowertrain", FuelType.DieselCI, fileWriter); - var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData); - - var cycle = new MockDrivingCycle(vehicleContainer, null); - - var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); - - dynamic tmp = AddComponent(driver, new Vehicle(vehicleContainer, vehicleData, airdragData)); - tmp = AddComponent(tmp, new Wheels(vehicleContainer, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)); - var engine = new CombustionEngine(vehicleContainer, engineData); - var clutch = new Clutch(vehicleContainer, engineData); - clutch.IdleController = engine.IdleController; - tmp = AddComponent(tmp, clutch); - AddComponent(tmp, engine); - - var gbx = new MockGearbox(vehicleContainer); - gbx.Gear = 1; - - var driverPort = driver.OutPort(); - - driverPort.Initialize(0.SI<MeterPerSecond>(), 0.SI<Radian>()); - - var absTime = 0.SI<Second>(); - - var response = driverPort.Request(absTime, 1.SI<Meter>(), 20.SI<MeterPerSecond>(), 0.SI<Radian>()); - - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - - vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); - absTime += response.SimulationInterval; - - Assert.AreEqual(0.24182, modData.GetValues<SI>(ModalResultField.acc).Last().Value(), Tolerance); - - response = driverPort.Request(absTime, 1.SI<Meter>(), 20.SI<MeterPerSecond>(), 0.SI<Radian>()); - - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - - vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); - absTime += response.SimulationInterval; - - Assert.AreEqual(0.2900, modData.GetValues<SI>(ModalResultField.acc).Last().Value(), Tolerance); - } - - [TestMethod] - public void DriverAccelerationTest() - { - var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); - var vehicle = new MockVehicle(vehicleContainer); - - var driverData = MockSimulationDataFactory.CreateDriverDataFromFile(JobFile); - var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); - - var cycle = new MockDrivingCycle(vehicleContainer, null); - - driver.Connect(vehicle.OutPort()); - - vehicle.MyVehicleSpeed = 0.SI<MeterPerSecond>(); - var absTime = 0.SI<Second>(); - var ds = 1.SI<Meter>(); - var gradient = 0.SI<Radian>(); - - var targetVelocity = 5.SI<MeterPerSecond>(); - - // var response = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); - - var accelerations = new[] { - 1.01570922, 1.384540943, 1.364944972, 1.350793466, 1.331848649, 1.314995215, 1.2999934, - 1.281996392, 1.255462262 - }; - var simulationIntervals = new[] { - 1.403234648, 0.553054094, 0.405255346, 0.33653593, 0.294559444, 0.26555781, 0.243971311, 0.22711761, - 0.213554656 - }; - - // accelerate from 0 to just below the target velocity and test derived simulation intervals & accelerations - for (var i = 0; i < accelerations.Length; i++) { - var tmpResponse = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); - - Assert.IsInstanceOfType(tmpResponse, typeof(ResponseSuccess)); - Assert.AreEqual(accelerations[i], vehicle.LastRequest.acceleration.Value(), Tolerance); - Assert.AreEqual(simulationIntervals[i], tmpResponse.SimulationInterval.Value(), Tolerance); - - vehicleContainer.CommitSimulationStep(absTime, tmpResponse.SimulationInterval); - absTime += tmpResponse.SimulationInterval; - vehicle.MyVehicleSpeed += - (tmpResponse.SimulationInterval * vehicle.LastRequest.acceleration).Cast<MeterPerSecond>(); - } - - // full acceleration would exceed target velocity, driver should limit acceleration such that target velocity is reached... - var response = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); - - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - Assert.AreEqual(0.899715479, vehicle.LastRequest.acceleration.Value(), Tolerance); - Assert.AreEqual(0.203734517, response.SimulationInterval.Value(), Tolerance); - - vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); - absTime += response.SimulationInterval; - vehicle.MyVehicleSpeed += - (response.SimulationInterval * vehicle.LastRequest.acceleration).Cast<MeterPerSecond>(); - - Assert.AreEqual(targetVelocity.Value(), vehicle.MyVehicleSpeed.Value(), Tolerance); - - // vehicle has reached target velocity, no further acceleration necessary... - - response = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); - - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - Assert.AreEqual(0, vehicle.LastRequest.acceleration.Value(), Tolerance); - Assert.AreEqual(0.2, response.SimulationInterval.Value(), Tolerance); - } - - [TestMethod] - public void DriverDecelerationTest() - { - var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); - var vehicle = new MockVehicle(vehicleContainer); - - var driverData = MockSimulationDataFactory.CreateDriverDataFromFile(JobFile); - var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); - - var cycle = new MockDrivingCycle(vehicleContainer, null); - - driver.Connect(vehicle.OutPort()); - - vehicle.MyVehicleSpeed = 5.SI<MeterPerSecond>(); - var absTime = 0.SI<Second>(); - var ds = 1.SI<Meter>(); - var gradient = 0.SI<Radian>(); - - var targetVelocity = 0.SI<MeterPerSecond>(); - - // var response = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); - - var accelerations = new[] { - -0.68799597, -0.690581291, -0.693253225, -0.696020324, -0.698892653, -0.701882183, -0.695020765, - -0.677731071, - -0.660095846, -0.642072941, -0.623611107, -0.604646998, -0.58510078, -0.56497051, -0.547893288, - -0.529859078, - -0.510598641, -0.489688151, -0.466386685, -0.425121905 - }; - var simulationIntervals = new[] { - 0.202830428, 0.20884052, 0.215445127, 0.222749141, 0.230885341, 0.240024719, 0.250311822, 0.26182762, - 0.274732249, - 0.289322578, 0.305992262, 0.325276486, 0.34792491, 0.37502941, 0.408389927, 0.451003215, 0.5081108, - 0.590388012, - 0.724477573, 1.00152602 - }; - - // accelerate from 0 to just below the target velocity and test derived simulation intervals & accelerations - for (var i = 0; i < accelerations.Length; i++) { - var tmpResponse = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); - - Assert.IsInstanceOfType(tmpResponse, typeof(ResponseSuccess)); - Assert.AreEqual(accelerations[i], vehicle.LastRequest.acceleration.Value(), Tolerance); - Assert.AreEqual(simulationIntervals[i], tmpResponse.SimulationInterval.Value(), Tolerance); - - vehicleContainer.CommitSimulationStep(absTime, tmpResponse.SimulationInterval); - absTime += tmpResponse.SimulationInterval; - vehicle.MyVehicleSpeed += - (tmpResponse.SimulationInterval * vehicle.LastRequest.acceleration).Cast<MeterPerSecond>(); - } - - var response = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); - - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - Assert.AreEqual(-0.308576594, vehicle.LastRequest.acceleration.Value(), Tolerance); - Assert.AreEqual(2.545854078, response.SimulationInterval.Value(), Tolerance); - - vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); - //absTime += response.SimulationInterval; - vehicle.MyVehicleSpeed += - (response.SimulationInterval * vehicle.LastRequest.acceleration).Cast<MeterPerSecond>(); - - Assert.AreEqual(targetVelocity.Value(), vehicle.MyVehicleSpeed.Value(), Tolerance); - } - - //================== - - private static VehicleData CreateVehicleData(Kilogram loading) - { - var axles = new List<Axle> { - new Axle { - AxleWeightShare = 0.4375, - Inertia = 21.66667.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 62538.75.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.375, - Inertia = 10.83333.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0065, - TwinTyres = false, - TyreTestLoad = 52532.55.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.1875, - Inertia = 21.66667.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 62538.75.SI<Newton>() - } - }; - return new VehicleData { - AxleConfiguration = AxleConfiguration.AxleConfig_4x2, - - CurbWeight = 15700.SI<Kilogram>(), - Loading = loading, - DynamicTyreRadius = 0.52.SI<Meter>(), - AxleData = axles, - SavedInDeclarationMode = false - }; - } - - private static AirdragData CreateAirdragData() - { - return new AirdragData() { - CrossWindCorrectionCurve = - new CrosswindCorrectionCdxALookup(3.2634.SI<SquareMeter>(), - CrossWindCorrectionCurveReader.GetNoCorrectionCurve(3.2634.SI<SquareMeter>()), - CrossWindCorrectionMode.NoCorrection), - }; - } - - private static DriverData CreateDriverData() - { - return new DriverData { - AccelerationCurve = AccelerationCurveReader.ReadFromFile(AccelerationFile), - LookAheadCoasting = new DriverData.LACData { - Enabled = false, - //Deceleration = -0.5.SI<MeterPerSquareSecond>() - }, - OverSpeedEcoRoll = new DriverData.OverSpeedEcoRollData { - Mode = DriverMode.Off - }, - }; - } - - // ======================== - - protected virtual IDriver AddComponent(IDrivingCycle prev, IDriver next) - { - prev.InPort().Connect(next.OutPort()); - return next; - } - - protected virtual IVehicle AddComponent(IDriver prev, IVehicle next) - { - prev.InPort().Connect(next.OutPort()); - return next; - } - - protected virtual IWheels AddComponent(IFvInProvider prev, IWheels next) - { - prev.InPort().Connect(next.OutPort()); - return next; - } - - protected virtual ITnOutProvider AddComponent(IWheels prev, ITnOutProvider next) - { - prev.InPort().Connect(next.OutPort()); - return next; - } - - protected virtual IPowerTrainComponent AddComponent(IPowerTrainComponent prev, IPowerTrainComponent next) - { - prev.InPort().Connect(next.OutPort()); - return next; - } - - protected virtual void AddComponent(IPowerTrainComponent prev, ITnOutProvider next) - { - prev.InPort().Connect(next.OutPort()); - } - } +using System.Collections.Generic; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; +using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponent +{ + [TestClass] + public class DriverTest + { + public const string JobFile = @"TestData\Jobs\24t Coach EngineOnly.vecto"; + public const string EngineFile = @"TestData\Components\24t Coach.veng"; + public const string EngineFileHigh = @"TestData\Components\24t Coach_high.veng"; + public const string AccelerationFile = @"TestData\Components\Coach.vacc"; + public const double Tolerance = 0.001; + + [TestMethod] + public void DriverCoastingTest() + { + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 1); + + var vehicleData = CreateVehicleData(33000.SI<Kilogram>()); + var airdragData = CreateAirdragData(); + vehicleData.DynamicTyreRadius = 0.026372213.SI<Meter>(); // take into account axle ratio, gear ratio + + var driverData = CreateDriverData(); + + var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain_Coasting"); + var modData = new ModalDataContainer("Coach_MinimalPowertrain_Coasting", FuelType.DieselCI, fileWriter); + var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData); + var mockCycle = new MockDrivingCycle(vehicleContainer, null); + + var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); + var engine = new CombustionEngine(vehicleContainer, engineData); + var clutch = new Clutch(vehicleContainer, engineData); + dynamic tmp = AddComponent(driver, new Vehicle(vehicleContainer, vehicleData, airdragData)); + tmp = AddComponent(tmp, new Wheels(vehicleContainer, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)); + tmp = AddComponent(tmp, clutch); + AddComponent(tmp, engine); + clutch.IdleController = engine.IdleController; + + var gbx = new MockGearbox(vehicleContainer) { Gear = 1 }; + + var driverPort = driver.OutPort(); + + var velocity = 5.SI<MeterPerSecond>(); + driverPort.Initialize(velocity, 0.SI<Radian>()); + + var absTime = 0.SI<Second>(); + + var response = driver.DrivingActionCoast(absTime, 1.SI<Meter>(), velocity, 0.SI<Radian>()); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + + Assert.AreEqual(4.9877, vehicleContainer.VehicleSpeed.Value(), Tolerance); + Assert.AreEqual(0.2004, response.SimulationInterval.Value(), Tolerance); + Assert.AreEqual(engine.PreviousState.FullDragTorque.Value(), engine.PreviousState.EngineTorque.Value(), + Constants.SimulationSettings.LineSearchTolerance); + + while (vehicleContainer.VehicleSpeed > 1.7) { + response = driver.DrivingActionCoast(absTime, 1.SI<Meter>(), velocity, 0.SI<Radian>()); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + modData.Finish(VectoRun.Status.Success); + } + modData.Finish(VectoRun.Status.Success); + } + + [TestMethod] + public void DriverCoastingTest2() + { + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 1); + + var vehicleData = CreateVehicleData(33000.SI<Kilogram>()); + vehicleData.DynamicTyreRadius = 0.026372213.SI<Meter>(); // take into account axle ratio, gear ratio + var airdragData = CreateAirdragData(); + var driverData = CreateDriverData(); + + var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain_Coasting"); + var modData = new ModalDataContainer("Coach_MinimalPowertrain_Coasting", FuelType.DieselCI, fileWriter); + var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData); + var mockCycle = new MockDrivingCycle(vehicleContainer, null); + + var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); + var engine = new CombustionEngine(vehicleContainer, engineData); + var clutch = new Clutch(vehicleContainer, engineData); + + dynamic tmp = AddComponent(driver, new Vehicle(vehicleContainer, vehicleData, airdragData)); + tmp = AddComponent(tmp, new Wheels(vehicleContainer, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)); + tmp = AddComponent(tmp, clutch); + AddComponent(tmp, engine); + clutch.IdleController = engine.IdleController; + + var gbx = new MockGearbox(vehicleContainer); + gbx.Gear = 1; + + var driverPort = driver.OutPort(); + + var gradient = VectoMath.InclinationToAngle(-0.020237973 / 100.0); + var velocity = 5.SI<MeterPerSecond>(); + driverPort.Initialize(velocity, gradient); + + var absTime = 0.SI<Second>(); + + var response = driver.DrivingActionCoast(absTime, 1.SI<Meter>(), velocity, gradient); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + + Assert.AreEqual(4.9878, vehicleContainer.VehicleSpeed.Value(), Tolerance); + Assert.AreEqual(0.2004, response.SimulationInterval.Value(), Tolerance); + Assert.AreEqual(engine.PreviousState.FullDragTorque.Value(), engine.PreviousState.EngineTorque.Value(), + Constants.SimulationSettings.LineSearchTolerance); + + while (vehicleContainer.VehicleSpeed > 1.7) { + response = driver.DrivingActionCoast(absTime, 1.SI<Meter>(), velocity, gradient); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + modData.Finish(VectoRun.Status.Success); + } + modData.Finish(VectoRun.Status.Success); + } + + [TestMethod] + public void DriverOverloadTest() + { + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFileHigh, 1); + + var vehicleData = CreateVehicleData(33000.SI<Kilogram>()); + var airdragData = CreateAirdragData(); + + // take into account the axle ratio and 1st-gear ratio + vehicleData.DynamicTyreRadius /= (3.24 * 6.38); + + var driverData = CreateDriverData(); + + var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain"); + var modData = new ModalDataContainer("Coach_MinimalPowertrain", FuelType.DieselCI, fileWriter); + var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData); + + var cycle = new MockDrivingCycle(vehicleContainer, null); + + var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); + + dynamic tmp = AddComponent(driver, new Vehicle(vehicleContainer, vehicleData, airdragData)); + tmp = AddComponent(tmp, new Wheels(vehicleContainer, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)); + var engine = new CombustionEngine(vehicleContainer, engineData); + var clutch = new Clutch(vehicleContainer, engineData); + clutch.IdleController = engine.IdleController; + tmp = AddComponent(tmp, clutch); + AddComponent(tmp, engine); + + var gbx = new MockGearbox(vehicleContainer); + gbx.Gear = 1; + + var driverPort = driver.OutPort(); + + driverPort.Initialize(0.SI<MeterPerSecond>(), 0.SI<Radian>()); + + var absTime = 0.SI<Second>(); + + var response = driverPort.Request(absTime, 1.SI<Meter>(), 20.SI<MeterPerSecond>(), 0.SI<Radian>()); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + + Assert.AreEqual(0.24182, modData.GetValues<SI>(ModalResultField.acc).Last().Value(), Tolerance); + + response = driverPort.Request(absTime, 1.SI<Meter>(), 20.SI<MeterPerSecond>(), 0.SI<Radian>()); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + + Assert.AreEqual(0.2900, modData.GetValues<SI>(ModalResultField.acc).Last().Value(), Tolerance); + } + + [TestMethod] + public void DriverAccelerationTest() + { + var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); + var vehicle = new MockVehicle(vehicleContainer); + + var driverData = MockSimulationDataFactory.CreateDriverDataFromFile(JobFile); + var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); + + var cycle = new MockDrivingCycle(vehicleContainer, null); + + driver.Connect(vehicle.OutPort()); + + vehicle.MyVehicleSpeed = 0.SI<MeterPerSecond>(); + var absTime = 0.SI<Second>(); + var ds = 1.SI<Meter>(); + var gradient = 0.SI<Radian>(); + + var targetVelocity = 5.SI<MeterPerSecond>(); + + // var response = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); + + var accelerations = new[] { + 1.01570922, 1.384540943, 1.364944972, 1.350793466, 1.331848649, 1.314995215, 1.2999934, + 1.281996392, 1.255462262 + }; + var simulationIntervals = new[] { + 1.403234648, 0.553054094, 0.405255346, 0.33653593, 0.294559444, 0.26555781, 0.243971311, 0.22711761, + 0.213554656 + }; + + // accelerate from 0 to just below the target velocity and test derived simulation intervals & accelerations + for (var i = 0; i < accelerations.Length; i++) { + var tmpResponse = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); + + Assert.IsInstanceOfType(tmpResponse, typeof(ResponseSuccess)); + Assert.AreEqual(accelerations[i], vehicle.LastRequest.acceleration.Value(), Tolerance); + Assert.AreEqual(simulationIntervals[i], tmpResponse.SimulationInterval.Value(), Tolerance); + + vehicleContainer.CommitSimulationStep(absTime, tmpResponse.SimulationInterval); + absTime += tmpResponse.SimulationInterval; + vehicle.MyVehicleSpeed += + (tmpResponse.SimulationInterval * vehicle.LastRequest.acceleration).Cast<MeterPerSecond>(); + } + + // full acceleration would exceed target velocity, driver should limit acceleration such that target velocity is reached... + var response = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + Assert.AreEqual(0.899715479, vehicle.LastRequest.acceleration.Value(), Tolerance); + Assert.AreEqual(0.203734517, response.SimulationInterval.Value(), Tolerance); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + vehicle.MyVehicleSpeed += + (response.SimulationInterval * vehicle.LastRequest.acceleration).Cast<MeterPerSecond>(); + + Assert.AreEqual(targetVelocity.Value(), vehicle.MyVehicleSpeed.Value(), Tolerance); + + // vehicle has reached target velocity, no further acceleration necessary... + + response = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + Assert.AreEqual(0, vehicle.LastRequest.acceleration.Value(), Tolerance); + Assert.AreEqual(0.2, response.SimulationInterval.Value(), Tolerance); + } + + [TestMethod] + public void DriverDecelerationTest() + { + var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); + var vehicle = new MockVehicle(vehicleContainer); + + var driverData = MockSimulationDataFactory.CreateDriverDataFromFile(JobFile); + var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); + + var cycle = new MockDrivingCycle(vehicleContainer, null); + + driver.Connect(vehicle.OutPort()); + + vehicle.MyVehicleSpeed = 5.SI<MeterPerSecond>(); + var absTime = 0.SI<Second>(); + var ds = 1.SI<Meter>(); + var gradient = 0.SI<Radian>(); + + var targetVelocity = 0.SI<MeterPerSecond>(); + + // var response = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); + + var accelerations = new[] { + -0.68799597, -0.690581291, -0.693253225, -0.696020324, -0.698892653, -0.701882183, -0.695020765, + -0.677731071, + -0.660095846, -0.642072941, -0.623611107, -0.604646998, -0.58510078, -0.56497051, -0.547893288, + -0.529859078, + -0.510598641, -0.489688151, -0.466386685, -0.425121905 + }; + var simulationIntervals = new[] { + 0.202830428, 0.20884052, 0.215445127, 0.222749141, 0.230885341, 0.240024719, 0.250311822, 0.26182762, + 0.274732249, + 0.289322578, 0.305992262, 0.325276486, 0.34792491, 0.37502941, 0.408389927, 0.451003215, 0.5081108, + 0.590388012, + 0.724477573, 1.00152602 + }; + + // accelerate from 0 to just below the target velocity and test derived simulation intervals & accelerations + for (var i = 0; i < accelerations.Length; i++) { + var tmpResponse = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); + + Assert.IsInstanceOfType(tmpResponse, typeof(ResponseSuccess)); + Assert.AreEqual(accelerations[i], vehicle.LastRequest.acceleration.Value(), Tolerance); + Assert.AreEqual(simulationIntervals[i], tmpResponse.SimulationInterval.Value(), Tolerance); + + vehicleContainer.CommitSimulationStep(absTime, tmpResponse.SimulationInterval); + absTime += tmpResponse.SimulationInterval; + vehicle.MyVehicleSpeed += + (tmpResponse.SimulationInterval * vehicle.LastRequest.acceleration).Cast<MeterPerSecond>(); + } + + var response = driver.OutPort().Request(absTime, ds, targetVelocity, gradient); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + Assert.AreEqual(-0.308576594, vehicle.LastRequest.acceleration.Value(), Tolerance); + Assert.AreEqual(2.545854078, response.SimulationInterval.Value(), Tolerance); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + //absTime += response.SimulationInterval; + vehicle.MyVehicleSpeed += + (response.SimulationInterval * vehicle.LastRequest.acceleration).Cast<MeterPerSecond>(); + + Assert.AreEqual(targetVelocity.Value(), vehicle.MyVehicleSpeed.Value(), Tolerance); + } + + //================== + + private static VehicleData CreateVehicleData(Kilogram loading) + { + var axles = new List<Axle> { + new Axle { + AxleWeightShare = 0.4375, + Inertia = 21.66667.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 62538.75.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.375, + Inertia = 10.83333.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0065, + TwinTyres = false, + TyreTestLoad = 52532.55.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.1875, + Inertia = 21.66667.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 62538.75.SI<Newton>() + } + }; + return new VehicleData { + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + + CurbWeight = 15700.SI<Kilogram>(), + Loading = loading, + DynamicTyreRadius = 0.52.SI<Meter>(), + AxleData = axles, + SavedInDeclarationMode = false + }; + } + + private static AirdragData CreateAirdragData() + { + return new AirdragData() { + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(3.2634.SI<SquareMeter>(), + CrossWindCorrectionCurveReader.GetNoCorrectionCurve(3.2634.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection), + }; + } + + private static DriverData CreateDriverData() + { + return new DriverData { + AccelerationCurve = AccelerationCurveReader.ReadFromFile(AccelerationFile), + LookAheadCoasting = new DriverData.LACData { + Enabled = false, + //Deceleration = -0.5.SI<MeterPerSquareSecond>() + }, + OverSpeedEcoRoll = new DriverData.OverSpeedEcoRollData { + Mode = DriverMode.Off + }, + }; + } + + // ======================== + + protected virtual IDriver AddComponent(IDrivingCycle prev, IDriver next) + { + prev.InPort().Connect(next.OutPort()); + return next; + } + + protected virtual IVehicle AddComponent(IDriver prev, IVehicle next) + { + prev.InPort().Connect(next.OutPort()); + return next; + } + + protected virtual IWheels AddComponent(IFvInProvider prev, IWheels next) + { + prev.InPort().Connect(next.OutPort()); + return next; + } + + protected virtual ITnOutProvider AddComponent(IWheels prev, ITnOutProvider next) + { + prev.InPort().Connect(next.OutPort()); + return next; + } + + protected virtual IPowerTrainComponent AddComponent(IPowerTrainComponent prev, IPowerTrainComponent next) + { + prev.InPort().Connect(next.OutPort()); + return next; + } + + protected virtual void AddComponent(IPowerTrainComponent prev, ITnOutProvider next) + { + prev.InPort().Connect(next.OutPort()); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs index 745de816d1872d48d4046eaeac75fe1b63c095b3..486e1f55bcf6e23bdad8bcda377ace5635c6b930 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs @@ -29,626 +29,628 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Data; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; - -#pragma warning disable 169 - -namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData -{ - [TestClass] - [SuppressMessage("ReSharper", "InconsistentNaming")] - [SuppressMessage("ReSharper", "UnusedMember.Local")] - public class ValidationTestClass - { - /// <summary> - /// VECTO-107 Check valid range of input parameters - /// </summary> - [TestMethod] - public void Validation_CombustionEngineData() - { - var fuelConsumption = new DataTable(); - fuelConsumption.Columns.Add(""); - fuelConsumption.Columns.Add(""); - fuelConsumption.Columns.Add(""); - fuelConsumption.Rows.Add("1", "1", "1"); - fuelConsumption.Rows.Add("2", "2", "2"); - fuelConsumption.Rows.Add("3", "3", "3"); - - var fullLoad = new DataTable(); - fullLoad.Columns.Add("Engine speed"); - fullLoad.Columns.Add("max torque"); - fullLoad.Columns.Add("drag torque"); - fullLoad.Columns.Add("PT1"); - fullLoad.Rows.Add("3", "3", "-3", "3"); - fullLoad.Rows.Add("3", "3", "-3", "3"); - - var data = new CombustionEngineData { - ModelName = "asdf", - Displacement = 6374.SI().Cubic.Centi.Meter.Cast<CubicMeter>(), - IdleSpeed = 560.RPMtoRad(), - Inertia = 1.SI<KilogramSquareMeter>(), - WHTCUrban = 1, - WHTCRural = 1, - WHTCMotorway = 1, - FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>() { { 0, FullLoadCurveReader.Create(fullLoad) } }, - ConsumptionMap = FuelConsumptionMapReader.Create(fuelConsumption) - }; - data.FullLoadCurves[0].EngineData = data; - - var results = data.Validate(ExecutionMode.Declaration, null, false); - Assert.IsFalse(results.Any(), "Validation Failed: " + string.Join("; ", results.Select(r => r.ErrorMessage))); - Assert.IsTrue(data.IsValid()); - } - - [TestMethod] - public void Validation_CombustionEngineData_Engineering() - { - var fuelConsumption = new TableData(); - fuelConsumption.Columns.Add(""); - fuelConsumption.Columns.Add(""); - fuelConsumption.Columns.Add(""); - fuelConsumption.Rows.Add("1", "1", "1"); - fuelConsumption.Rows.Add("2", "2", "2"); - fuelConsumption.Rows.Add("3", "3", "3"); - - var fullLoad = new TableData(); - fullLoad.Columns.Add("Engine speed"); - fullLoad.Columns.Add("max torque"); - fullLoad.Columns.Add("drag torque"); - fullLoad.Columns.Add("PT1"); - fullLoad.Rows.Add("3", "3", "-3", "3"); - fullLoad.Rows.Add("3", "3", "-3", "3"); - var data = new MockEngineDataProvider { - Model = "asdf", - Displacement = 6374.SI().Cubic.Centi.Meter.Cast<CubicMeter>(), - IdleSpeed = 560.RPMtoRad(), - Inertia = 1.SI<KilogramSquareMeter>(), - FullLoadCurve = fullLoad, - FuelConsumptionMap = fuelConsumption - }; - var dao = new EngineeringDataAdapter(); - - var engineData = dao.CreateEngineData(data, null, new List<ITorqueLimitInputData>()); - - var results = engineData.Validate(ExecutionMode.Declaration, null, false); - Assert.IsFalse(results.Any(), "Validation failed: " + string.Join("; ", results.Select(r => r.ErrorMessage))); - Assert.IsTrue(engineData.IsValid()); - } - - [TestMethod] - public void Validation_CombustionEngineData_Declaration() - { - var fuelConsumption = new TableData(); - fuelConsumption.Columns.Add(""); - fuelConsumption.Columns.Add(""); - fuelConsumption.Columns.Add(""); - fuelConsumption.Rows.Add("1", "1", "1"); - fuelConsumption.Rows.Add("2", "2", "2"); - fuelConsumption.Rows.Add("3", "3", "3"); - - var fullLoad = new TableData(); - fullLoad.Columns.Add("Engine speed"); - fullLoad.Columns.Add("max torque"); - fullLoad.Columns.Add("drag torque"); - fullLoad.Columns.Add("PT1"); - fullLoad.Rows.Add("3", "3", "-3", "3"); - fullLoad.Rows.Add("3", "3", "-3", "3"); - var data = new MockEngineDataProvider { - Model = "asdf", - Displacement = 6374.SI().Cubic.Centi.Meter.Cast<CubicMeter>(), - IdleSpeed = 560.RPMtoRad(), - Inertia = 1.SI<KilogramSquareMeter>(), - FullLoadCurve = fullLoad, - FuelConsumptionMap = fuelConsumption, - WHTCMotorway = 1.1, - WHTCRural = 1.1, - WHTCUrban = 1.1 - }; - var dao = new DeclarationDataAdapter(); - - var dummyGearbox = new DummyGearboxData() { - Type = GearboxType.AMT, - Gears = new List<ITransmissionInputData>() - }; - - var engineData = dao.CreateEngineData(data, null, dummyGearbox, new List<ITorqueLimitInputData>()); - - var results = engineData.Validate(ExecutionMode.Declaration, null, false); - Assert.IsFalse(results.Any(), "Validation failed: " + string.Join("; ", results.Select(r => r.ErrorMessage))); - - Assert.IsTrue(engineData.IsValid()); - } - - [TestMethod] - public void ValidationModeVehicleDataTest() - { - var vehicleData = new VehicleData { - AxleConfiguration = AxleConfiguration.AxleConfig_4x2, - CurbWeight = 7500.SI<Kilogram>(), - DynamicTyreRadius = 0.5.SI<Meter>(), - //CurbWeigthExtra = 0.SI<Kilogram>(), - Loading = 12000.SI<Kilogram>(), - GrossVehicleWeight = 16000.SI<Kilogram>(), - TrailerGrossVehicleWeight = 0.SI<Kilogram>(), - AxleData = new List<Axle> { - new Axle { - AxleType = AxleType.VehicleNonDriven, - AxleWeightShare = 0.4, - Inertia = 0.5.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.00555, - TyreTestLoad = 33000.SI<Newton>() - }, - new Axle { - AxleType = AxleType.VehicleNonDriven, - AxleWeightShare = 0.6, - Inertia = 0.5.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.00555, - TyreTestLoad = 33000.SI<Newton>() - }, - } - }; - var result = vehicleData.Validate(ExecutionMode.Engineering, null, false); - Assert.IsTrue(!result.Any(), "validation should have succeded but failed." + string.Concat(result)); - - result = vehicleData.Validate(ExecutionMode.Declaration, null, false); - Assert.IsTrue(result.Any(), "validation should have failed, but succeeded."); - } - - /// <summary> - /// VECTO-107 Check valid range of input parameters - /// </summary> - [TestMethod] - public void ValidationModeVectoRunDataTest() - { - var container = new VehicleContainer(ExecutionMode.Engineering); - var data = new DistanceRun(container); - var engineData = new CombustionEngineData { - FullLoadCurves = - new Dictionary<uint, EngineFullLoadCurve>() { - { 0, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") }, - { 1, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") }, - }, - IdleSpeed = 560.RPMtoRad() - }; - - var gearboxData = new GearboxData(); - gearboxData.Gears[1] = new GearData { - LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\Direct Gear.vtlm", 1, "1"), - Ratio = 1 - }; - - var axleGearData = new AxleGearData { - AxleGear = new GearData { - Ratio = 1, - LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\limited.vtlm", 1, "1"), - } - }; - var vehicleData = new VehicleData { - AxleConfiguration = AxleConfiguration.AxleConfig_4x2, - CurbWeight = 7500.SI<Kilogram>(), - DynamicTyreRadius = 0.5.SI<Meter>(), - //CurbWeigthExtra = 0.SI<Kilogram>(), - Loading = 12000.SI<Kilogram>(), - GrossVehicleWeight = 16000.SI<Kilogram>(), - TrailerGrossVehicleWeight = 0.SI<Kilogram>(), - AxleData = new List<Axle> { - new Axle { - AxleType = AxleType.VehicleNonDriven, - AxleWeightShare = 0.4, - Inertia = 0.5.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.00555, - TyreTestLoad = 33000.SI<Newton>() - }, - new Axle { - AxleType = AxleType.VehicleNonDriven, - AxleWeightShare = 0.6, - Inertia = 0.5.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.00555, - TyreTestLoad = 33000.SI<Newton>() - }, - } - }; - - container.RunData = new VectoRunData { - VehicleData = vehicleData, - AirdragData = new AirdragData() { - CrossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection, - CrossWindCorrectionCurve = - new CrosswindCorrectionCdxALookup(5.SI<SquareMeter>(), - CrossWindCorrectionCurveReader.GetNoCorrectionCurve(5.SI<SquareMeter>()), - CrossWindCorrectionMode.NoCorrection) - }, - GearboxData = gearboxData, - EngineData = engineData, - AxleGearData = axleGearData - }; - - var results = data.Validate(ExecutionMode.Declaration, null, false); - Assert.IsTrue(results.Any(), "Validation should have failed, but succeded."); - - results = vehicleData.Validate(ExecutionMode.Engineering, null, false); - Assert.IsTrue(!results.Any()); - } - - /// <summary> - /// VECTO-107 Check valid range of input parameters - /// </summary> - [TestMethod] - public void Validation_VectoRun() - { - var container = new VehicleContainer(ExecutionMode.Engineering); - var data = new DistanceRun(container); - var engineData = new CombustionEngineData { - FullLoadCurves = - new Dictionary<uint, EngineFullLoadCurve>() { - { 0, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") }, - { 1, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") } - }, - IdleSpeed = 560.RPMtoRad() - }; - - var gearboxData = new GearboxData(); - gearboxData.Gears[1] = new GearData { - LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\Direct Gear.vtlm", 1, "1"), - Ratio = 1, - }; - - var axleGearData = new AxleGearData { - AxleGear = new GearData { - LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\limited.vtlm", 1, "1"), - Ratio = 1, - } - }; - - container.RunData = new VectoRunData { - GearboxData = gearboxData, - EngineData = engineData, - AxleGearData = axleGearData - }; - - var results = data.Validate(ExecutionMode.Declaration, null, false); - Assert.IsTrue(results.Any(), "Validation should have failed, but succeded."); - } - - /// <summary> - /// VECTO-107 Check valid range of input parameters - /// </summary> - [TestMethod] - public void Validation_Test() - { - var results = new DataObject().Validate(ExecutionMode.Declaration, null, false); - - // every field and property should be tested except private parent fields and properties and - // (4*4+1) * 2 = 17*2= 34 - 4 private parent fields (+2 public field and property which are tested twice) = 32 - Assert.AreEqual(32, results.Count, - "Validation Error: " + string.Join("\n_eng_avg", results.Select(r => r.ErrorMessage))); - } - - [TestMethod] - public void ValidateDictionaryTest() - { - var container = new ContainerObject() { - Elements = new Dictionary<int, WrapperObject>() { - { 2, new WrapperObject() { Value = 41 } }, - { 4, new WrapperObject() { Value = -30 } } - } - }; - - var results = container.Validate(ExecutionMode.Declaration, null, false); - Assert.AreEqual(1, results.Count); - } - - /// <summary> - /// VECTO-249: check upshift is above downshift - /// </summary> - [TestMethod] - public void ShiftPolygonValidationTest() - { - var vgbs = new[] { - "-116,600,1508 ", - "0,600,1508 ", - "293,600,1508 ", - "494,806,1508 ", - "956,1278,2355 ", - }; - - var shiftPolygon = - ShiftPolygonReader.Create( - VectoCSVFile.ReadStream( - InputDataHelper.InputDataAsStream("engine torque,downshift rpm [rpm],upshift rpm [rpm] ", vgbs))); - - var results = shiftPolygon.Validate(ExecutionMode.Declaration, GearboxType.MT, false); - Assert.IsFalse(results.Any()); - - // change columns - shiftPolygon = - ShiftPolygonReader.Create( - VectoCSVFile.ReadStream( - InputDataHelper.InputDataAsStream("engine torque,upshift rpm [rpm], downshift rpm [rpm] ", vgbs))); - - results = shiftPolygon.Validate(ExecutionMode.Declaration, GearboxType.MT, false); - Assert.IsTrue(results.Any()); - } - - [TestMethod] - public void ShiftPolygonValidationATTest() - { - var vgbs = new[] { - "-116,600,1508 ", - "0,600,1508 ", - "293,600,1508 ", - "494,806,1508 ", - "956,1278,2355 ", - }; - - var shiftPolygon = - ShiftPolygonReader.Create( - VectoCSVFile.ReadStream( - InputDataHelper.InputDataAsStream("engine torque,downshift rpm [rpm],upshift rpm [rpm] ", vgbs))); - - var results = shiftPolygon.Validate(ExecutionMode.Declaration, GearboxType.ATSerial, false); - Assert.IsFalse(results.Any()); - - // change columns - shiftPolygon = - ShiftPolygonReader.Create( - VectoCSVFile.ReadStream( - InputDataHelper.InputDataAsStream("engine torque,upshift rpm [rpm], downshift rpm [rpm] ", vgbs))); - - results = shiftPolygon.Validate(ExecutionMode.Declaration, GearboxType.ATSerial, false); - Assert.IsFalse(results.Any()); - } - - public class ContainerObject - { - [Required, ValidateObject] public Dictionary<int, WrapperObject> Elements; - } - - public class WrapperObject - { - [Required, Range(0, 100)] public int Value = 0; - } - - public class DeepDataObject - { - [Required, Range(41, 42)] protected int public_field = 5; - } - - public abstract class ParentDataObject - { - #region 4 parent instance fields - - // ReSharper disable once NotAccessedField.Local - [Required, Range(1, 2)] private int private_parent_field = 7; - [Required, Range(3, 4)] protected int protected_parent_field = 7; - [Required, Range(5, 6)] internal int internal_parent_field = 7; - [Required, Range(7, 8)] public int public_parent_field = 5; - - #endregion - - #region 4 parent static field - - [Required, Range(43, 44)] private static int private_static_parent_field = 7; - [Required, Range(43, 44)] protected static int protected_static_parent_field = 7; - [Required, Range(50, 51)] internal static int internal_static_parent_field = 7; - [Required, Range(45, 46)] public static int public_static_parent_field = 7; - - #endregion - - #region 4 parent instance properties - - [Required, Range(11, 12)] - private int private_parent_property - { - get { return 7; } - } - - [Required, Range(13, 14)] - protected int protected_parent_property - { - get { return 7; } - } - - [Required, Range(15, 16)] - internal int internal_parent_property - { - get { return 7; } - } - - [Required, Range(17, 18)] - public int public_parent_property - { - get { return 7; } - } - - #endregion - - #region 4 parent static properties - - [Required, Range(19, 20)] - private static int private_static_parent_property - { - get { return 7; } - } - - [Required, Range(19, 20)] - protected static int protected_static_parent_property - { - get { return 7; } - } - - [Required, Range(19, 20)] - internal static int internal_static_parent_property - { - get { return 7; } - } - - [Required, Range(19, 20)] - public static int public_static_parent_property - { - get { return 7; } - } - - #endregion - - #region 1 parent sub objects - - [Required, ValidateObject] public DeepDataObject parent_sub_object = new DeepDataObject(); - - #endregion - - private void just_to_remove_compiler_warnings() - { - private_parent_field = private_static_parent_field; - } - } - - public class DataObject : ParentDataObject - { - #region 4 instance fields - - // ReSharper disable once NotAccessedField.Local - [Required, Range(1, 2)] private int private_field = 7; - [Required, Range(3, 4)] protected int protected_field = 7; - [Required, Range(5, 6)] internal int internal_field = 7; - [Required, Range(7, 8)] public int public_field = 5; - - #endregion - - #region 4 static field - - [Required, Range(43, 44)] private static int private_static_field = 7; - [Required, Range(43, 44)] protected static int protected_static_field = 7; - [Required, Range(50, 51)] internal static int internal_static_field = 7; - [Required, Range(45, 46)] public static int public_static_field = 7; - - #endregion - - #region 4 instance properties - - [Required, Range(11, 12)] - private int private_property - { - get { return 7; } - } - - [Required, Range(13, 14)] - protected int protected_property - { - get { return 7; } - } - - [Required, Range(15, 16)] - internal int internal_property - { - get { return 7; } - } - - [Required, Range(17, 18)] - public int public_property - { - get { return 7; } - } - - #endregion - - #region 4 static properties - - [Required, Range(19, 20)] - private static int private_static_property - { - get { return 7; } - } - - [Required, Range(19, 20)] - protected static int protected_static_property - { - get { return 7; } - } - - [Required, Range(19, 20)] - internal static int internal_static_property - { - get { return 7; } - } - - [Required, Range(19, 20)] - public static int public_static_property - { - get { return 7; } - } - - #endregion - - #region 1 sub objects - - [Required, ValidateObject] public DeepDataObject sub_object = new DeepDataObject(); - - #endregion - - private void just_to_remove_compiler_warnings() - { - private_field = private_static_field; - } - } - } - - public class DummyGearboxData : IGearboxEngineeringInputData - { - public DataSourceType SourceType { get; set; } - public string Source { get; set; } - public bool SavedInDeclarationMode { get; set; } - public string Manufacturer { get; set; } - public string Model { get; set; } - public string Creator { get; set; } - public string Date { get; set; } - public string TechnicalReportId { get; set; } - - public CertificationMethod CertificationMethod - { - get { return CertificationMethod.NotCertified; } - } - - public string CertificationNumber { get; set; } - public string DigestValue { get; set; } - public GearboxType Type { get; set; } - public IList<ITransmissionInputData> Gears { get; set; } - - ITorqueConverterDeclarationInputData IGearboxDeclarationInputData.TorqueConverter - { - get { return TorqueConverter; } - } - - public KilogramSquareMeter Inertia { get; set; } - public Second TractionInterruption { get; set; } - public Second MinTimeBetweenGearshift { get; set; } - public double TorqueReserve { get; set; } - public MeterPerSecond StartSpeed { get; set; } - public MeterPerSquareSecond StartAcceleration { get; set; } - public double StartTorqueReserve { get; set; } - public ITorqueConverterEngineeringInputData TorqueConverter { get; set; } - public Second DownshiftAfterUpshiftDelay { get; set; } - public Second UpshiftAfterDownshiftDelay { get; set; } - public MeterPerSquareSecond UpshiftMinAcceleration { get; set; } - public Second PowershiftShiftTime { get; set; } - } +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Data; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; + +#pragma warning disable 169 + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData +{ + [TestClass] + [SuppressMessage("ReSharper", "InconsistentNaming")] + [SuppressMessage("ReSharper", "UnusedMember.Local")] + public class ValidationTestClass + { + /// <summary> + /// VECTO-107 Check valid range of input parameters + /// </summary> + [TestMethod] + public void Validation_CombustionEngineData() + { + var fuelConsumption = new DataTable(); + fuelConsumption.Columns.Add(""); + fuelConsumption.Columns.Add(""); + fuelConsumption.Columns.Add(""); + fuelConsumption.Rows.Add("1", "1", "1"); + fuelConsumption.Rows.Add("2", "2", "2"); + fuelConsumption.Rows.Add("3", "3", "3"); + + var fullLoad = new DataTable(); + fullLoad.Columns.Add("Engine speed"); + fullLoad.Columns.Add("max torque"); + fullLoad.Columns.Add("drag torque"); + fullLoad.Columns.Add("PT1"); + fullLoad.Rows.Add("3", "3", "-3", "3"); + fullLoad.Rows.Add("3", "3", "-3", "3"); + + var data = new CombustionEngineData { + ModelName = "asdf", + Displacement = 6374.SI().Cubic.Centi.Meter.Cast<CubicMeter>(), + IdleSpeed = 560.RPMtoRad(), + Inertia = 1.SI<KilogramSquareMeter>(), + WHTCUrban = 1, + WHTCRural = 1, + WHTCMotorway = 1, + FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>() { { 0, FullLoadCurveReader.Create(fullLoad) } }, + ConsumptionMap = FuelConsumptionMapReader.Create(fuelConsumption) + }; + data.FullLoadCurves[0].EngineData = data; + + var results = data.Validate(ExecutionMode.Declaration, null, false); + Assert.IsFalse(results.Any(), "Validation Failed: " + string.Join("; ", results.Select(r => r.ErrorMessage))); + Assert.IsTrue(data.IsValid()); + } + + [TestMethod] + public void Validation_CombustionEngineData_Engineering() + { + var fuelConsumption = new TableData(); + fuelConsumption.Columns.Add(""); + fuelConsumption.Columns.Add(""); + fuelConsumption.Columns.Add(""); + fuelConsumption.Rows.Add("1", "1", "1"); + fuelConsumption.Rows.Add("2", "2", "2"); + fuelConsumption.Rows.Add("3", "3", "3"); + + var fullLoad = new TableData(); + fullLoad.Columns.Add("Engine speed"); + fullLoad.Columns.Add("max torque"); + fullLoad.Columns.Add("drag torque"); + fullLoad.Columns.Add("PT1"); + fullLoad.Rows.Add("3", "3", "-3", "3"); + fullLoad.Rows.Add("3", "3", "-3", "3"); + var data = new MockEngineDataProvider { + Model = "asdf", + Displacement = 6374.SI().Cubic.Centi.Meter.Cast<CubicMeter>(), + IdleSpeed = 560.RPMtoRad(), + Inertia = 1.SI<KilogramSquareMeter>(), + FullLoadCurve = fullLoad, + FuelConsumptionMap = fuelConsumption + }; + var dao = new EngineeringDataAdapter(); + + var engineData = dao.CreateEngineData(data, null, new List<ITorqueLimitInputData>()); + + var results = engineData.Validate(ExecutionMode.Declaration, null, false); + Assert.IsFalse(results.Any(), "Validation failed: " + string.Join("; ", results.Select(r => r.ErrorMessage))); + Assert.IsTrue(engineData.IsValid()); + } + + [TestMethod] + public void Validation_CombustionEngineData_Declaration() + { + var fuelConsumption = new TableData(); + fuelConsumption.Columns.Add(""); + fuelConsumption.Columns.Add(""); + fuelConsumption.Columns.Add(""); + fuelConsumption.Rows.Add("1", "1", "1"); + fuelConsumption.Rows.Add("2", "2", "2"); + fuelConsumption.Rows.Add("3", "3", "3"); + + var fullLoad = new TableData(); + fullLoad.Columns.Add("Engine speed"); + fullLoad.Columns.Add("max torque"); + fullLoad.Columns.Add("drag torque"); + fullLoad.Columns.Add("PT1"); + fullLoad.Rows.Add("3", "3", "-3", "3"); + fullLoad.Rows.Add("3", "3", "-3", "3"); + var data = new MockEngineDataProvider { + Model = "asdf", + Displacement = 6374.SI().Cubic.Centi.Meter.Cast<CubicMeter>(), + IdleSpeed = 560.RPMtoRad(), + Inertia = 1.SI<KilogramSquareMeter>(), + FullLoadCurve = fullLoad, + FuelConsumptionMap = fuelConsumption, + WHTCMotorway = 1.1, + WHTCRural = 1.1, + WHTCUrban = 1.1 + }; + var dao = new DeclarationDataAdapter(); + + var dummyGearbox = new DummyGearboxData() { + Type = GearboxType.AMT, + Gears = new List<ITransmissionInputData>() + }; + + var engineData = dao.CreateEngineData(data, null, dummyGearbox, new List<ITorqueLimitInputData>()); + + var results = engineData.Validate(ExecutionMode.Declaration, null, false); + Assert.IsFalse(results.Any(), "Validation failed: " + string.Join("; ", results.Select(r => r.ErrorMessage))); + + Assert.IsTrue(engineData.IsValid()); + } + + [TestMethod] + public void ValidationModeVehicleDataTest() + { + var vehicleData = new VehicleData { + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + CurbWeight = 7500.SI<Kilogram>(), + DynamicTyreRadius = 0.5.SI<Meter>(), + //CurbWeigthExtra = 0.SI<Kilogram>(), + Loading = 12000.SI<Kilogram>(), + GrossVehicleWeight = 16000.SI<Kilogram>(), + TrailerGrossVehicleWeight = 0.SI<Kilogram>(), + AxleData = new List<Axle> { + new Axle { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.4, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + new Axle { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.6, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + } + }; + var result = vehicleData.Validate(ExecutionMode.Engineering, null, false); + Assert.IsTrue(!result.Any(), "validation should have succeded but failed." + string.Concat(result)); + + result = vehicleData.Validate(ExecutionMode.Declaration, null, false); + Assert.IsTrue(result.Any(), "validation should have failed, but succeeded."); + } + + /// <summary> + /// VECTO-107 Check valid range of input parameters + /// </summary> + [TestMethod] + public void ValidationModeVectoRunDataTest() + { + var container = new VehicleContainer(ExecutionMode.Engineering); + var data = new DistanceRun(container); + var engineData = new CombustionEngineData { + FullLoadCurves = + new Dictionary<uint, EngineFullLoadCurve>() { + { 0, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") }, + { 1, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") }, + }, + IdleSpeed = 560.RPMtoRad() + }; + + var gearboxData = new GearboxData(); + gearboxData.Gears[1] = new GearData { + LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\Direct Gear.vtlm", 1, "1"), + Ratio = 1 + }; + + var axleGearData = new AxleGearData { + AxleGear = new GearData { + Ratio = 1, + LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\limited.vtlm", 1, "1"), + } + }; + var vehicleData = new VehicleData { + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + CurbWeight = 7500.SI<Kilogram>(), + DynamicTyreRadius = 0.5.SI<Meter>(), + //CurbWeigthExtra = 0.SI<Kilogram>(), + Loading = 12000.SI<Kilogram>(), + GrossVehicleWeight = 16000.SI<Kilogram>(), + TrailerGrossVehicleWeight = 0.SI<Kilogram>(), + AxleData = new List<Axle> { + new Axle { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.4, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + new Axle { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.6, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + } + }; + + container.RunData = new VectoRunData { + JobRunId = 0, + VehicleData = vehicleData, + AirdragData = new AirdragData() { + CrossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection, + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(5.SI<SquareMeter>(), + CrossWindCorrectionCurveReader.GetNoCorrectionCurve(5.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection) + }, + GearboxData = gearboxData, + EngineData = engineData, + AxleGearData = axleGearData + }; + + var results = data.Validate(ExecutionMode.Declaration, null, false); + Assert.IsTrue(results.Any(), "Validation should have failed, but succeded."); + + results = vehicleData.Validate(ExecutionMode.Engineering, null, false); + Assert.IsTrue(!results.Any()); + } + + /// <summary> + /// VECTO-107 Check valid range of input parameters + /// </summary> + [TestMethod] + public void Validation_VectoRun() + { + var container = new VehicleContainer(ExecutionMode.Engineering); + var data = new DistanceRun(container); + var engineData = new CombustionEngineData { + FullLoadCurves = + new Dictionary<uint, EngineFullLoadCurve>() { + { 0, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") }, + { 1, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") } + }, + IdleSpeed = 560.RPMtoRad() + }; + + var gearboxData = new GearboxData(); + gearboxData.Gears[1] = new GearData { + LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\Direct Gear.vtlm", 1, "1"), + Ratio = 1, + }; + + var axleGearData = new AxleGearData { + AxleGear = new GearData { + LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\limited.vtlm", 1, "1"), + Ratio = 1, + } + }; + + container.RunData = new VectoRunData { + JobRunId = 0, + GearboxData = gearboxData, + EngineData = engineData, + AxleGearData = axleGearData + }; + + var results = data.Validate(ExecutionMode.Declaration, null, false); + Assert.IsTrue(results.Any(), "Validation should have failed, but succeded."); + } + + /// <summary> + /// VECTO-107 Check valid range of input parameters + /// </summary> + [TestMethod] + public void Validation_Test() + { + var results = new DataObject().Validate(ExecutionMode.Declaration, null, false); + + // every field and property should be tested except private parent fields and properties and + // (4*4+1) * 2 = 17*2= 34 - 4 private parent fields (+2 public field and property which are tested twice) = 32 + Assert.AreEqual(32, results.Count, + "Validation Error: " + string.Join("\n_eng_avg", results.Select(r => r.ErrorMessage))); + } + + [TestMethod] + public void ValidateDictionaryTest() + { + var container = new ContainerObject() { + Elements = new Dictionary<int, WrapperObject>() { + { 2, new WrapperObject() { Value = 41 } }, + { 4, new WrapperObject() { Value = -30 } } + } + }; + + var results = container.Validate(ExecutionMode.Declaration, null, false); + Assert.AreEqual(1, results.Count); + } + + /// <summary> + /// VECTO-249: check upshift is above downshift + /// </summary> + [TestMethod] + public void ShiftPolygonValidationTest() + { + var vgbs = new[] { + "-116,600,1508 ", + "0,600,1508 ", + "293,600,1508 ", + "494,806,1508 ", + "956,1278,2355 ", + }; + + var shiftPolygon = + ShiftPolygonReader.Create( + VectoCSVFile.ReadStream( + InputDataHelper.InputDataAsStream("engine torque,downshift rpm [rpm],upshift rpm [rpm] ", vgbs))); + + var results = shiftPolygon.Validate(ExecutionMode.Declaration, GearboxType.MT, false); + Assert.IsFalse(results.Any()); + + // change columns + shiftPolygon = + ShiftPolygonReader.Create( + VectoCSVFile.ReadStream( + InputDataHelper.InputDataAsStream("engine torque,upshift rpm [rpm], downshift rpm [rpm] ", vgbs))); + + results = shiftPolygon.Validate(ExecutionMode.Declaration, GearboxType.MT, false); + Assert.IsTrue(results.Any()); + } + + [TestMethod] + public void ShiftPolygonValidationATTest() + { + var vgbs = new[] { + "-116,600,1508 ", + "0,600,1508 ", + "293,600,1508 ", + "494,806,1508 ", + "956,1278,2355 ", + }; + + var shiftPolygon = + ShiftPolygonReader.Create( + VectoCSVFile.ReadStream( + InputDataHelper.InputDataAsStream("engine torque,downshift rpm [rpm],upshift rpm [rpm] ", vgbs))); + + var results = shiftPolygon.Validate(ExecutionMode.Declaration, GearboxType.ATSerial, false); + Assert.IsFalse(results.Any()); + + // change columns + shiftPolygon = + ShiftPolygonReader.Create( + VectoCSVFile.ReadStream( + InputDataHelper.InputDataAsStream("engine torque,upshift rpm [rpm], downshift rpm [rpm] ", vgbs))); + + results = shiftPolygon.Validate(ExecutionMode.Declaration, GearboxType.ATSerial, false); + Assert.IsFalse(results.Any()); + } + + public class ContainerObject + { + [Required, ValidateObject] public Dictionary<int, WrapperObject> Elements; + } + + public class WrapperObject + { + [Required, Range(0, 100)] public int Value = 0; + } + + public class DeepDataObject + { + [Required, Range(41, 42)] protected int public_field = 5; + } + + public abstract class ParentDataObject + { + #region 4 parent instance fields + + // ReSharper disable once NotAccessedField.Local + [Required, Range(1, 2)] private int private_parent_field = 7; + [Required, Range(3, 4)] protected int protected_parent_field = 7; + [Required, Range(5, 6)] internal int internal_parent_field = 7; + [Required, Range(7, 8)] public int public_parent_field = 5; + + #endregion + + #region 4 parent static field + + [Required, Range(43, 44)] private static int private_static_parent_field = 7; + [Required, Range(43, 44)] protected static int protected_static_parent_field = 7; + [Required, Range(50, 51)] internal static int internal_static_parent_field = 7; + [Required, Range(45, 46)] public static int public_static_parent_field = 7; + + #endregion + + #region 4 parent instance properties + + [Required, Range(11, 12)] + private int private_parent_property + { + get { return 7; } + } + + [Required, Range(13, 14)] + protected int protected_parent_property + { + get { return 7; } + } + + [Required, Range(15, 16)] + internal int internal_parent_property + { + get { return 7; } + } + + [Required, Range(17, 18)] + public int public_parent_property + { + get { return 7; } + } + + #endregion + + #region 4 parent static properties + + [Required, Range(19, 20)] + private static int private_static_parent_property + { + get { return 7; } + } + + [Required, Range(19, 20)] + protected static int protected_static_parent_property + { + get { return 7; } + } + + [Required, Range(19, 20)] + internal static int internal_static_parent_property + { + get { return 7; } + } + + [Required, Range(19, 20)] + public static int public_static_parent_property + { + get { return 7; } + } + + #endregion + + #region 1 parent sub objects + + [Required, ValidateObject] public DeepDataObject parent_sub_object = new DeepDataObject(); + + #endregion + + private void just_to_remove_compiler_warnings() + { + private_parent_field = private_static_parent_field; + } + } + + public class DataObject : ParentDataObject + { + #region 4 instance fields + + // ReSharper disable once NotAccessedField.Local + [Required, Range(1, 2)] private int private_field = 7; + [Required, Range(3, 4)] protected int protected_field = 7; + [Required, Range(5, 6)] internal int internal_field = 7; + [Required, Range(7, 8)] public int public_field = 5; + + #endregion + + #region 4 static field + + [Required, Range(43, 44)] private static int private_static_field = 7; + [Required, Range(43, 44)] protected static int protected_static_field = 7; + [Required, Range(50, 51)] internal static int internal_static_field = 7; + [Required, Range(45, 46)] public static int public_static_field = 7; + + #endregion + + #region 4 instance properties + + [Required, Range(11, 12)] + private int private_property + { + get { return 7; } + } + + [Required, Range(13, 14)] + protected int protected_property + { + get { return 7; } + } + + [Required, Range(15, 16)] + internal int internal_property + { + get { return 7; } + } + + [Required, Range(17, 18)] + public int public_property + { + get { return 7; } + } + + #endregion + + #region 4 static properties + + [Required, Range(19, 20)] + private static int private_static_property + { + get { return 7; } + } + + [Required, Range(19, 20)] + protected static int protected_static_property + { + get { return 7; } + } + + [Required, Range(19, 20)] + internal static int internal_static_property + { + get { return 7; } + } + + [Required, Range(19, 20)] + public static int public_static_property + { + get { return 7; } + } + + #endregion + + #region 1 sub objects + + [Required, ValidateObject] public DeepDataObject sub_object = new DeepDataObject(); + + #endregion + + private void just_to_remove_compiler_warnings() + { + private_field = private_static_field; + } + } + } + + public class DummyGearboxData : IGearboxEngineeringInputData + { + public DataSourceType SourceType { get; set; } + public string Source { get; set; } + public bool SavedInDeclarationMode { get; set; } + public string Manufacturer { get; set; } + public string Model { get; set; } + public string Creator { get; set; } + public string Date { get; set; } + public string TechnicalReportId { get; set; } + + public CertificationMethod CertificationMethod + { + get { return CertificationMethod.NotCertified; } + } + + public string CertificationNumber { get; set; } + public string DigestValue { get; set; } + public GearboxType Type { get; set; } + public IList<ITransmissionInputData> Gears { get; set; } + + ITorqueConverterDeclarationInputData IGearboxDeclarationInputData.TorqueConverter + { + get { return TorqueConverter; } + } + + public KilogramSquareMeter Inertia { get; set; } + public Second TractionInterruption { get; set; } + public Second MinTimeBetweenGearshift { get; set; } + public double TorqueReserve { get; set; } + public MeterPerSecond StartSpeed { get; set; } + public MeterPerSquareSecond StartAcceleration { get; set; } + public double StartTorqueReserve { get; set; } + public ITorqueConverterEngineeringInputData TorqueConverter { get; set; } + public Second DownshiftAfterUpshiftDelay { get; set; } + public Second UpshiftAfterDownshiftDelay { get; set; } + public MeterPerSquareSecond UpshiftMinAcceleration { get; set; } + public Second PowershiftShiftTime { get; set; } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs index 47b2e9b7fa66234b79d9947f8cf65bb0004b99c3..1629bf64d7612829b97f7b37e310b185abb66dd2 100644 --- a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs @@ -29,127 +29,137 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.OutputData; - -namespace TUGraz.VectoCore.Tests.Utils -{ - /// <summary> - /// Fake Data Writer Class for Tests. - /// </summary> - internal class MockModalDataContainer : IModalDataContainer - { - public MockModalDataContainer() - { - Data = new ModalResults(); - CurrentRow = Data.NewRow(); - Auxiliaries = new Dictionary<string, DataColumn>(); - } - - public ModalResults Data { get; set; } - public DataRow CurrentRow { get; set; } - - public string ModFileName - { - get { return ""; } - } - - public object this[string auxId] - { - get { return CurrentRow[Auxiliaries[auxId]]; } - set { CurrentRow[Auxiliaries[auxId]] = value; } - } - - public bool HasTorqueConverter { get; set; } - - public void CommitSimulationStep() - { - Data.Rows.Add(CurrentRow); - CurrentRow = Data.NewRow(); - } - - public FuelData.Entry FuelData { get { return VectoCore.Models.Declaration.FuelData.Diesel; } } - - public VectoRun.Status RunStatus - { - get { return VectoRun.Status.Success; } - } - - public string Error { get { return null; } } - public string StackTrace { get { return null; } } - - public void Finish(VectoRun.Status runStatus) {} - - public bool WriteModalResults { get; set; } - - public IEnumerable<T> GetValues<T>(ModalResultField key) - { - return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>((int)key)); - } - - public IEnumerable<T> GetValues<T>(DataColumn col) - { - return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>(col)); - } - - public IEnumerable<T> GetValues<T>(Func<DataRow, T> selectorFunc) - { - throw new NotImplementedException(); - } - - public T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T> - { - throw new NotImplementedException(); - } - - public Dictionary<string, DataColumn> Auxiliaries { get; set; } - - public void SetDataValue(string fieldName, object value) - { - throw new System.NotImplementedException(); - } - - public void AddAuxiliary(string id, string columnName = null) - { - var auxColName = columnName ?? ModalResultField.P_aux_ + id; - if (!Data.Columns.Contains(auxColName)) { - Auxiliaries[id] = Data.Columns.Add(auxColName, typeof(Watt)); - } - Auxiliaries[id] = Data.Columns[auxColName]; - } - - public void Dispose() - { - throw new NotImplementedException(); - } - - public void FinishSimulation(Exception exception) - { - Data.Rows.Clear(); - } - - public string RunName { get; set; } - public string CycleName { get; set; } - public string RunSuffix { get; set; } - - public object this[ModalResultField key] - { - get { return CurrentRow[key.GetName()]; } - set { CurrentRow[key.GetName()] = value; } - } - - public void CommitSimulationStep(Second absTime, Second simulationInterval) - { - CurrentRow[ModalResultField.time.GetName()] = (absTime + simulationInterval / 2); - CurrentRow[ModalResultField.simulationInterval.GetName()] = simulationInterval; - CommitSimulationStep(); - } - } +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.OutputData; + +namespace TUGraz.VectoCore.Tests.Utils +{ + /// <summary> + /// Fake Data Writer Class for Tests. + /// </summary> + internal class MockModalDataContainer : IModalDataContainer + { + public MockModalDataContainer() + { + Data = new ModalResults(); + CurrentRow = Data.NewRow(); + Auxiliaries = new Dictionary<string, DataColumn>(); + } + + public ModalResults Data { get; set; } + public DataRow CurrentRow { get; set; } + + public string ModFileName + { + get { return ""; } + } + + public object this[string auxId] + { + get { return CurrentRow[Auxiliaries[auxId]]; } + set { CurrentRow[Auxiliaries[auxId]] = value; } + } + + public bool HasTorqueConverter { get; set; } + + public void CommitSimulationStep() + { + Data.Rows.Add(CurrentRow); + CurrentRow = Data.NewRow(); + } + + public FuelData.Entry FuelData + { + get { return VectoCore.Models.Declaration.FuelData.Diesel; } + } + + public VectoRun.Status RunStatus + { + get { return VectoRun.Status.Success; } + } + + public string Error + { + get { return null; } + } + + public string StackTrace + { + get { return null; } + } + + public void Finish(VectoRun.Status runStatus, Exception exception = null) {} + + public bool WriteModalResults { get; set; } + + public IEnumerable<T> GetValues<T>(ModalResultField key) + { + return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>((int)key)); + } + + public IEnumerable<T> GetValues<T>(DataColumn col) + { + return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>(col)); + } + + public IEnumerable<T> GetValues<T>(Func<DataRow, T> selectorFunc) + { + throw new NotImplementedException(); + } + + public T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T> + { + throw new NotImplementedException(); + } + + public Dictionary<string, DataColumn> Auxiliaries { get; set; } + + public void SetDataValue(string fieldName, object value) + { + throw new System.NotImplementedException(); + } + + public void AddAuxiliary(string id, string columnName = null) + { + var auxColName = columnName ?? ModalResultField.P_aux_ + id; + if (!Data.Columns.Contains(auxColName)) { + Auxiliaries[id] = Data.Columns.Add(auxColName, typeof(Watt)); + } + Auxiliaries[id] = Data.Columns[auxColName]; + } + + public void Dispose() + { + throw new NotImplementedException(); + } + + public void FinishSimulation() + { + Data.Rows.Clear(); + } + + public string RunName { get; set; } + public string CycleName { get; set; } + public string RunSuffix { get; set; } + + public object this[ModalResultField key] + { + get { return CurrentRow[key.GetName()]; } + set { CurrentRow[key.GetName()] = value; } + } + + public void CommitSimulationStep(Second absTime, Second simulationInterval) + { + CurrentRow[ModalResultField.time.GetName()] = (absTime + simulationInterval / 2); + CurrentRow[ModalResultField.simulationInterval.GetName()] = simulationInterval; + CommitSimulationStep(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoXML.spp b/VectoCore/VectoXML.spp index 3cecbcffd6db892bd816e1a612dcbb9348d83118..913a0ee07df23a144d822fb19eb07b1ab34e58ff 100644 --- a/VectoCore/VectoXML.spp +++ b/VectoCore/VectoXML.spp @@ -31,7 +31,6 @@ <Folder FolderName="HTML Files" ExtStr="html;htm;xhtml;asp"/> <Folder FolderName="DTD/Schemas" ExtStr="dtd;dcd;xdr;biz;xsd"> <File FilePath="VectoCore\Resources\XSD\ParameterDocumentation.xsd" HomeFolder="Yes"/> - <File FilePath="VectoCore\Resources\XSD\VectoCOC.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\VectoComponent.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\VectoDeclarationDefinitions.0.6.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\VectoDeclarationDefinitions.0.8.xsd" HomeFolder="Yes"/> @@ -41,7 +40,8 @@ <File FilePath="VectoCore\Resources\XSD\VectoEngineeringDefinitions.0.7.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\VectoEngineeringInput.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\VectoInput.xsd" HomeFolder="Yes"/> - <File FilePath="VectoCore\Resources\XSD\VectoOutput.xsd" HomeFolder="Yes"/> + <File FilePath="VectoCore\Resources\XSD\VectoOutputCustomer.xsd" HomeFolder="Yes"/> + <File FilePath="VectoCore\Resources\XSD\VectoOutputManufacturer.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\xmldsig-core-schema.xsd" HomeFolder="Yes"/> </Folder> <Folder FolderName="Entities" ExtStr="ent"/>