diff --git a/VectoCore/Configuration/Constants.cs b/VectoCore/Configuration/Constants.cs index 748c1a022e34a9d6d9c7c6ec802b07874d018b86..6df3e913653667fea64a244aa3d39c081d5e7822 100644 --- a/VectoCore/Configuration/Constants.cs +++ b/VectoCore/Configuration/Constants.cs @@ -1,4 +1,6 @@ -namespace TUGraz.VectoCore.Configuration +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Configuration { public class Constants { @@ -14,5 +16,24 @@ public const string CycleFile = ".vdri"; } + + public class SimulationSettings + { + /// <summary> + /// base time interval for the simulation. the distance is estimated to reach this time interval as good as possible + /// </summary> + public static readonly Second TargetTimeInterval = 0.5.SI<Second>(); + + /// <summary> + /// simulation interval if the vehicle stands still + /// </summary> + public static readonly Meter DriveOffDistance = 1.SI<Meter>(); + + /// <summary> + /// threshold for changes in the road gradient. changes below this threshold will be considered to be equal for filtering out the driving cycle. + /// altitude computation is done before filtering! + /// </summary> + public static readonly double DrivingCycleRoadGradientTolerance = VectoMath.InclinationToAngle(0.25 / 100.0).Value(); + } } } \ No newline at end of file diff --git a/VectoCore/FileIO/DeclarationFile/JobFileDecl.cs b/VectoCore/FileIO/DeclarationFile/JobFileDecl.cs index 973db03907c577123937cfb73184c6a747cc9ea5..553783faca7e27d947814715b8736cebf167af4a 100644 --- a/VectoCore/FileIO/DeclarationFile/JobFileDecl.cs +++ b/VectoCore/FileIO/DeclarationFile/JobFileDecl.cs @@ -5,68 +5,81 @@ using TUGraz.VectoCore.Models.SimulationComponent.Data; namespace TUGraz.VectoCore.FileIO.DeclarationFile { /// <summary> - /// A class which represents the json data format for serializing and deserializing the Job Data files. - /// </summary> - /// <summary> - /// Represents the Vecto Job File. Fileformat: .vecto + /// A class which represents the json data format for serializing and deserializing the Job Data files. + /// Fileformat: .vecto /// </summary> /// <code> - ///{ - /// "Header": { - /// "CreatedBy": " ()", - /// "Date": "3/4/2015 2:09:13 PM", - /// "AppVersion": "2.0.4-beta3", - /// "FileVersion": 2 - /// }, - /// "Body": { - /// "SavedInDeclMode": false, - /// "VehicleData": "24t Coach.vveh", - /// "EngineData": "24t Coach.veng", - /// "GearboxData": "24t Coach.vgbx", - /// "Cycles": [ - /// "W:\\VECTO\\CITnet\\VECTO\\bin\\Debug\\Declaration\\MissionCycles\\LOT2_rural Engine Only.vdri" - /// ], - /// "Aux": [ - /// { - /// "ID": "ALT1", - /// "Type": "Alternator", - /// "Path": "24t_Coach_ALT.vaux", - /// "Technology": "" - /// }, - /// { - /// "ID": "ALT2", - /// "Type": "Alternator", - /// "Path": "24t_Coach_ALT.vaux", - /// "Technology": "" - /// }, - /// { - /// "ID": "ALT3", - /// "Type": "Alternator", - /// "Path": "24t_Coach_ALT.vaux", - /// "Technology": "" - /// } - /// ], - /// "AccelerationLimitingFile": "Coach.vacc", - /// "IsEngineOnly": true, - /// "StartStop": { - /// "Enabled": false, - /// "MaxSpeed": 5.0, - /// "MinTime": 0.0, - /// "Delay": 0 - /// }, - /// "LookAheadCoasting": { - /// "Enabled": true, - /// "Dec": -0.5, - /// "MinSpeed": 50.0 - /// }, - /// "OverSpeedEcoRoll": { - /// "Mode": "OverSpeed", - /// "MinSpeed": 70.0, - /// "OverSpeed": 5.0, - /// "UnderSpeed": 5.0 - /// } - /// } - ///} + /// { + /// "Header": { + /// "CreatedBy": " ()", + /// "Date": "3/4/2015 12:31:06 PM", + /// "AppVersion": "2.0.4-beta3", + /// "FileVersion": 2 + /// }, + /// "Body": { + /// "SavedInDeclMode": true, + /// "VehicleFile": "../Components/12t Delivery Truck.vveh", + /// "EngineFile": "../Components/12t Delivery Truck.veng", + /// "GearboxFile": "../Components/12t Delivery Truck.vgbx", + /// "Cycles": [ + /// "Long Haul", + /// "Regional Delivery", + /// "Urban Delivery" + /// ], + /// "Aux": [ + /// { + /// "ID": "FAN", + /// "Type": "Fan", + /// "Path": "<NOFILE>", + /// "Technology": "" + /// }, + /// { + /// "ID": "STP", + /// "Type": "Steering pump", + /// "Path": "<NOFILE>", + /// "Technology": "" + /// }, + /// { + /// "ID": "AC", + /// "Type": "HVAC", + /// "Path": "<NOFILE>", + /// "Technology": "" + /// }, + /// { + /// "ID": "ES", + /// "Type": "Electric System", + /// "Path": "<NOFILE>", + /// "Technology": "", + /// "TechList": [] + /// }, + /// { + /// "ID": "PS", + /// "Type": "Pneumatic System", + /// "Path": "<NOFILE>", + /// "Technology": "" + /// } + /// ], + /// "VACC": "<NOFILE>", + /// "EngineOnlyMode": true, + /// "StartStop": { + /// "Enabled": false, + /// "MaxSpeed": 5.0, + /// "MinTime": 5.0, + /// "Delay": 5 + /// }, + /// "LAC": { + /// "Enabled": true, + /// "Dec": -0.5, + /// "MinSpeed": 50.0 + /// }, + /// "OverSpeedEcoRoll": { + /// "Mode": "OverSpeed", + /// "MinSpeed": 50.0, + /// "OverSpeed": 5.0, + /// "UnderSpeed": 5.0 + /// } + /// } + /// } /// </code> public class VectoJobFileV2Declaration : VectoJobFile { @@ -91,10 +104,11 @@ namespace TUGraz.VectoCore.FileIO.DeclarationFile public class AuxDataDecl { - //[JsonProperty(Required = Required.Always)] public string ID; - //[JsonProperty(Required = Required.Always)] public string Type; + [JsonProperty(Required = Required.Always)] public string ID; + [JsonProperty(Required = Required.Always)] public string Type; //[JsonProperty(Required = Required.Always)] public string Path; [JsonProperty(Required = Required.Always)] public string Technology; + [JsonProperty] public IList<string> TechList; } public class StartStopDataDecl diff --git a/VectoCore/FileIO/EngineeringFile/JobFileEng.cs b/VectoCore/FileIO/EngineeringFile/JobFileEng.cs index 96a5440f98af2958f35ccd412c1d601f6b1a2f86..e1eb78921b04ec7b581d6733db785a4316724e1d 100644 --- a/VectoCore/FileIO/EngineeringFile/JobFileEng.cs +++ b/VectoCore/FileIO/EngineeringFile/JobFileEng.cs @@ -75,14 +75,16 @@ namespace TUGraz.VectoCore.FileIO.EngineeringFile { [JsonProperty(Required = Required.Always)] public IList<string> Cycles; [JsonProperty] public new IList<AuxDataEng> Aux = new List<AuxDataEng>(); + [JsonProperty("VACC", Required = Required.Always)] public string AccelerationCurve; + //[JsonProperty(Required = Required.Always)] public bool EngineOnlyMode; [JsonProperty(Required = Required.Always)] public new StartStopDataDeclEng StartStop; - [JsonProperty(Required = Required.Always)] public LACDataEng LAC; + [JsonProperty("LAC", Required = Required.Always)] public LACDataEng LookAheadCoasting; [JsonProperty(Required = Required.Always)] public new OverSpeedEcoRollDataEng OverSpeedEcoRoll; public class AuxDataEng : DataBodyDecl.AuxDataDecl { - [JsonProperty(Required = Required.Always)] public string ID; - [JsonProperty(Required = Required.Always)] public string Type; + //[JsonProperty(Required = Required.Always)] public string ID; + //[JsonProperty(Required = Required.Always)] public string Type; [JsonProperty(Required = Required.Always)] public string Path; } diff --git a/VectoCore/FileIO/Reader/DataObjectAdaper/AbstractSimulationDataAdapter.cs b/VectoCore/FileIO/Reader/DataObjectAdaper/AbstractSimulationDataAdapter.cs index d1c66db69eab8c063220cf87d63bc0dff4d00175..deb799e31274f60ef38ad9d24c22a1a652e5622b 100644 --- a/VectoCore/FileIO/Reader/DataObjectAdaper/AbstractSimulationDataAdapter.cs +++ b/VectoCore/FileIO/Reader/DataObjectAdaper/AbstractSimulationDataAdapter.cs @@ -25,7 +25,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper var retVal = new VehicleData { SavedInDeclarationMode = data.SavedInDeclarationMode, VehicleCategory = data.VehicleCategory(), - AxleConfiguration = EnumHelper.ParseAxleConfigurationType(data.AxleConfig.TypeStr), + AxleConfiguration = AxleConfigurationHelper.Parse(data.AxleConfig.TypeStr), CurbWeight = data.CurbWeight.SI<Kilogram>(), //CurbWeigthExtra = data.CurbWeightExtra.SI<Kilogram>(), //Loading = data.Loading.SI<Kilogram>(), @@ -40,7 +40,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper var retarder = new RetarderData() { Type = - (RetarderData.RetarderType) Enum.Parse(typeof (RetarderData.RetarderType), data.Retarder.TypeStr.ToString(), true), + (RetarderData.RetarderType)Enum.Parse(typeof(RetarderData.RetarderType), data.Retarder.TypeStr.ToString(), true), }; if (retarder.Type != RetarderData.RetarderType.None) { retarder.LossMap = RetarderLossMap.ReadFromFile(Path.Combine(basePath, data.Retarder.File)); @@ -71,8 +71,10 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper return new GearboxData() { SavedInDeclarationMode = data.SavedInDeclarationMode, ModelName = data.ModelName, - Type = (GearboxData.GearboxType) Enum.Parse(typeof (GearboxData.GearboxType), data.GearboxType, true), + Type = (GearboxData.GearboxType)Enum.Parse(typeof(GearboxData.GearboxType), data.GearboxType, true), }; } + + public abstract DriverData CreateDriverData(VectoJobFile job); } } \ No newline at end of file diff --git a/VectoCore/FileIO/Reader/DataObjectAdaper/DeclarationDataAdapter.cs b/VectoCore/FileIO/Reader/DataObjectAdaper/DeclarationDataAdapter.cs index abb2a961622cb56adf25ddcb6a2d3b790b13bcf2..c33723ecf6c2f82d4778e9433f40f57ef8956cf8 100644 --- a/VectoCore/FileIO/Reader/DataObjectAdaper/DeclarationDataAdapter.cs +++ b/VectoCore/FileIO/Reader/DataObjectAdaper/DeclarationDataAdapter.cs @@ -6,6 +6,7 @@ using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.FileIO.DeclarationFile; using TUGraz.VectoCore.FileIO.EngineeringFile; using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; @@ -51,8 +52,52 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper throw new VectoException("Unsupported GearboxData File Instance"); } + public override DriverData CreateDriverData(VectoJobFile job) + { + var fileV2Decl = job as VectoJobFileV2Declaration; + if (fileV2Decl != null) { + return CreateDriverData(fileV2Decl); + } + throw new VectoException("Unsupported Job File Instance"); + } + //========================== + + public DriverData CreateDriverData(VectoJobFileV2Declaration job) + { + var data = job.Body; + + var lookAheadData = new DriverData.LACData() { + Enabled = DeclarationData.Driver.LookAhead.Enabled, + Deceleration = DeclarationData.Driver.LookAhead.Deceleration, + MinSpeed = DeclarationData.Driver.LookAhead.MinimumSpeed + }; + var overspeedData = new DriverData.OverSpeedEcoRollData() { + Mode = DriverData.ParseDriverMode(data.OverSpeedEcoRoll.Mode), + MinSpeed = DeclarationData.Driver.OverSpeedEcoRoll.MinSpeed, + OverSpeed = DeclarationData.Driver.OverSpeedEcoRoll.OverSpeed, + UnderSpeed = DeclarationData.Driver.OverSpeedEcoRoll.UnderSpeed + }; + if (!DeclarationData.Driver.OverSpeedEcoRoll.AllowedModes.Contains(overspeedData.Mode)) { + throw new VectoSimulationException( + String.Format("Specified Overspeed/EcoRoll Mode not allowed in declaration mode! {0}", overspeedData.Mode)); + } + var startstopData = new VectoRunData.StartStopData() { + Enabled = data.StartStop.Enabled, + Delay = DeclarationData.Driver.StartStop.Delay, + MinTime = DeclarationData.Driver.StartStop.MinTime, + MaxSpeed = DeclarationData.Driver.StartStop.MaxSpeed, + }; + var retVal = new DriverData() { + LookAheadCoasting = lookAheadData, + OverSpeedEcoRoll = overspeedData, + StartStop = startstopData, + }; + return retVal; + } + + internal VehicleData CreateVehicleData(VehicleFileV5Declaration vehicle, Mission mission, Kilogram loading) { var data = vehicle.Body; @@ -134,7 +179,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper for (uint i = 0; i < gearbox.Body.Gears.Count; i++) { - var gearSettings = gearbox.Body.Gears[(int) i]; + var gearSettings = gearbox.Body.Gears[(int)i]; var lossMapPath = Path.Combine(gearbox.BasePath, gearSettings.LossMap); TransmissionLossMap lossMap = TransmissionLossMap.ReadFromFile(lossMapPath, gearSettings.Ratio); diff --git a/VectoCore/FileIO/Reader/DataObjectAdaper/EngineeringDataAdapter.cs b/VectoCore/FileIO/Reader/DataObjectAdaper/EngineeringDataAdapter.cs index 7bce183607c6846e5d2aab72def56e5b62f917ac..01880224d1eaa2c004b389a169b988d26fdfeff5 100644 --- a/VectoCore/FileIO/Reader/DataObjectAdaper/EngineeringDataAdapter.cs +++ b/VectoCore/FileIO/Reader/DataObjectAdaper/EngineeringDataAdapter.cs @@ -4,6 +4,7 @@ using System.Linq; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.FileIO.EngineeringFile; using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; @@ -46,9 +47,49 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper throw new VectoException("Unsupported GearboxData File Instance"); } + public override DriverData CreateDriverData(VectoJobFile job) + { + var filev2Eng = job as VectoJobFileV2Engineering; + if (filev2Eng != null) { + return CreateDriverData(filev2Eng); + } + throw new VectoException("Unsupported Job File Instance"); + } + //================================= + internal DriverData CreateDriverData(VectoJobFileV2Engineering job) + { + var data = job.Body; + + var accelerationData = AccelerationCurveData.ReadFromFile(data.AccelerationCurve); + var lookAheadData = new DriverData.LACData() { + Enabled = data.LookAheadCoasting.Enabled, + Deceleration = DoubleExtensionMethods.SI<MeterPerSquareSecond>(data.LookAheadCoasting.Dec), + MinSpeed = data.LookAheadCoasting.MinSpeed.KMPHtoMeterPerSecond(), + }; + var overspeedData = new DriverData.OverSpeedEcoRollData() { + Mode = DriverData.ParseDriverMode(data.OverSpeedEcoRoll.Mode), + MinSpeed = data.OverSpeedEcoRoll.MinSpeed.KMPHtoMeterPerSecond(), + OverSpeed = data.OverSpeedEcoRoll.OverSpeed.KMPHtoMeterPerSecond(), + UnderSpeed = data.OverSpeedEcoRoll.UnderSpeed.KMPHtoMeterPerSecond(), + }; + var startstopData = new VectoRunData.StartStopData() { + Enabled = data.StartStop.Enabled, + Delay = data.StartStop.Delay.SI<Second>(), + MinTime = data.StartStop.MinTime.SI<Second>(), + MaxSpeed = data.StartStop.MaxSpeed.KMPHtoMeterPerSecond(), + }; + var retVal = new DriverData() { + AccelerationCurve = accelerationData, + LookAheadCoasting = lookAheadData, + OverSpeedEcoRoll = overspeedData, + StartStop = startstopData, + }; + return retVal; + } + /// <summary> /// convert datastructure representing file-contents into internal datastructure /// Vehicle, file-format version 5 @@ -121,7 +162,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper retVal.HasTorqueConverter = data.TorqueConverter.Enabled; for (uint i = 0; i < gearbox.Body.Gears.Count; i++) { - var gearSettings = gearbox.Body.Gears[(int) i]; + var gearSettings = gearbox.Body.Gears[(int)i]; var lossMapPath = Path.Combine(gearbox.BasePath, gearSettings.LossMap); TransmissionLossMap lossMap = TransmissionLossMap.ReadFromFile(lossMapPath, gearSettings.Ratio); diff --git a/VectoCore/FileIO/Reader/Impl/AbstractSimulationDataReader.cs b/VectoCore/FileIO/Reader/Impl/AbstractSimulationDataReader.cs index ae1ecad477df820448d21ca91f32257172f3d2b4..17fa5779af7822f6c3dccd84686f6f21582b53b2 100644 --- a/VectoCore/FileIO/Reader/Impl/AbstractSimulationDataReader.cs +++ b/VectoCore/FileIO/Reader/Impl/AbstractSimulationDataReader.cs @@ -1,13 +1,5 @@ -using System; -using System.Collections.Generic; -using System.IO; -using TUGraz.VectoCore.Exceptions; -using TUGraz.VectoCore.FileIO.DeclarationFile; -using TUGraz.VectoCore.Models.Declaration; +using System.Collections.Generic; using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.FileIO.Reader.Impl { @@ -15,14 +7,15 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl { //protected string JobBasePath = ""; - protected VectoJobFile Job; + protected VectoJobFile Job { get; set; } - protected VectoVehicleFile Vehicle; + protected VectoVehicleFile Vehicle { get; set; } - protected VectoGearboxFile Gearbox; + protected VectoGearboxFile Gearbox { get; set; } - protected VectoEngineFile Engine; + protected VectoEngineFile Engine { get; set; } + protected IList<VectoRunData.AuxData> Aux { get; set; } public void SetJobFile(string filename) { @@ -38,10 +31,14 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl protected abstract void ProcessJob(VectoJobFile job); - // has to read the file string and create file-container + /// <summary> + /// has to read the file string and create file-container + /// </summary> protected abstract void ReadJobFile(string file); - // has to read the file string and create file-container + /// <summary> + /// has to read the file string and create file-container + /// </summary> protected abstract void ReadVehicle(string file); protected abstract void ReadEngine(string file); diff --git a/VectoCore/FileIO/Reader/Impl/DeclarationModeSimulationDataReader.cs b/VectoCore/FileIO/Reader/Impl/DeclarationModeSimulationDataReader.cs index ef3b6307748b80b2efb88ca60e4d83c9c8280b7b..75cb4047c513da3f8a44f76794ea152d8a686228 100644 --- a/VectoCore/FileIO/Reader/Impl/DeclarationModeSimulationDataReader.cs +++ b/VectoCore/FileIO/Reader/Impl/DeclarationModeSimulationDataReader.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Data; +using System.Collections.Generic; using System.IO; using System.Linq; using Newtonsoft.Json; @@ -10,8 +8,6 @@ using TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.FileIO.Reader.Impl @@ -34,23 +30,26 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl var tmpVehicle = dao.CreateVehicleData(Vehicle); var segment = GetVehicleClassification(tmpVehicle.VehicleCategory, tmpVehicle.AxleConfiguration, tmpVehicle.GrossVehicleMassRating, tmpVehicle.CurbWeight); + var driverdata = dao.CreateDriverData(Job); + driverdata.AccelerationCurve = AccelerationCurveData.ReadFromStream(segment.AccelerationFile); foreach (var mission in segment.Missions) { foreach (var loading in mission.Loadings) { var engineData = dao.CreateEngineData(Engine); var parser = new DrivingCycleData.DistanceBasedDataParser(); var data = VectoCSVFile.ReadStream(mission.CycleFile); var cycleEntries = parser.Parse(data).ToList(); - var simulationRunData = new VectoRunData() { + var simulationRunData = new VectoRunData { VehicleData = dao.CreateVehicleData(Vehicle, mission, loading), EngineData = engineData, GearboxData = dao.CreateGearboxData(Gearbox, engineData), - // @@@ TODO: auxiliaries + Aux = Aux, // @@@ TODO: ... - Cycle = new DrivingCycleData() { - Name = "Dummy", + Cycle = new DrivingCycleData { + Name = mission.ToString(), SavedInDeclarationMode = true, Entries = cycleEntries }, + DriverData = driverdata, IsEngineOnly = IsEngineOnly, JobFileName = Job.JobFile, }; @@ -72,6 +71,8 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl ReadEngine(Path.Combine(job.BasePath, job.Body.EngineFile)); ReadGearbox(Path.Combine(job.BasePath, job.Body.GearboxFile)); + + ReadAuxiliary(job.Body.Aux); } protected override void ReadJobFile(string file) @@ -91,7 +92,6 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl } } - protected override void ReadVehicle(string file) { var json = File.ReadAllText(file); @@ -140,6 +140,17 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl } } + private void ReadAuxiliary(IEnumerable<VectoJobFileV2Declaration.DataBodyDecl.AuxDataDecl> auxList) + { + Aux = auxList.Select(aux => + new VectoRunData.AuxData { + ID = aux.ID, + Type = aux.Type, + Technology = aux.Technology, + TechList = aux.TechList.ToArray() + }).ToArray(); + } + internal Segment GetVehicleClassification(VehicleCategory category, AxleConfiguration axles, Kilogram grossMassRating, Kilogram curbWeight) diff --git a/VectoCore/FileIO/Reader/Impl/EngineeringModeSimulationDataReader.cs b/VectoCore/FileIO/Reader/Impl/EngineeringModeSimulationDataReader.cs index e02ddfce9bdc51b1a1d0679fdcb2a827b3e784b3..bcbd0c2a3fdcd1f3b6a51500475e68e062dab9df 100644 --- a/VectoCore/FileIO/Reader/Impl/EngineeringModeSimulationDataReader.cs +++ b/VectoCore/FileIO/Reader/Impl/EngineeringModeSimulationDataReader.cs @@ -20,6 +20,8 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl { public class EngineeringModeSimulationDataReader : AbstractSimulationDataReader { + protected DriverData Driver; + internal EngineeringModeSimulationDataReader() {} @@ -74,6 +76,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl yield break; } var dao = new EngineeringDataAdapter(); + var driver = dao.CreateDriverData(job); foreach (var cycle in job.Body.Cycles) { var simulationRunData = new VectoRunData() { BasePath = job.BasePath, @@ -81,7 +84,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl EngineData = dao.CreateEngineData(Engine), GearboxData = dao.CreateGearboxData(Gearbox, null), VehicleData = dao.CreateVehicleData(Vehicle), - //DriverData = new DriverData(), + DriverData = driver, //Aux = // TODO: distance or time-based cycle! Cycle = DrivingCycleData.ReadFromFile(Path.Combine(job.BasePath, cycle), DrivingCycleData.CycleType.DistanceBased), @@ -102,6 +105,12 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl return new EngineeringDataAdapter().CreateVehicleData(data); } + public static DriverData CreateDriverDataFromFile(string file) + { + var data = DoReadJobFile(file); + return new EngineeringDataAdapter().CreateDriverData(data); + } + /// <summary> /// Create CombustionEngineData instance directly from a file /// </summary> @@ -124,25 +133,14 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl return new EngineeringDataAdapter().CreateGearboxData(data, null); } + /// <summary> - /// initialize Job member (deserialize Job-file) + /// initialize vecto job member (deserialize Vecot-file /// </summary> - /// <param name="file">file</param> + /// <param name="file"></param> protected override void ReadJobFile(string file) { - var json = File.ReadAllText(file); - var fileInfo = GetFileVersion(json); - CheckForEngineeringMode(fileInfo, "Job"); - - switch (fileInfo.Version) { - case 2: - Job = JsonConvert.DeserializeObject<VectoJobFileV2Engineering>(json); - Job.BasePath = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar; - Job.JobFile = Path.GetFileName(file); - break; - default: - throw new UnsupportedFileVersionException("Unsupported version of job-file. Got version " + fileInfo.Version); - } + Job = DoReadJobFile(file); } /// <summary> @@ -163,6 +161,29 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl Gearbox = DoReadGearboxFile(file); } + //============================================================== + + /// <summary> + /// initialize Job member (deserialize Job-file) + /// </summary> + /// <param name="file">file</param> + protected static VectoJobFile DoReadJobFile(string file) + { + var json = File.ReadAllText(file); + var fileInfo = GetFileVersion(json); + CheckForEngineeringMode(fileInfo, "Job"); + + switch (fileInfo.Version) { + case 2: + var tmp = JsonConvert.DeserializeObject<VectoJobFileV2Engineering>(json); + tmp.BasePath = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar; + tmp.JobFile = Path.GetFileName(file); + return tmp; + default: + throw new UnsupportedFileVersionException("Unsupported version of job-file. Got version " + fileInfo.Version); + } + } + /// <summary> /// De-serialize engine-file (JSON) /// </summary> diff --git a/VectoCore/FileIO/VectoFiles.cs b/VectoCore/FileIO/VectoFiles.cs index 9ee73d56f52eb896a5ec837a8a645077ce2751f2..65fd64c20ed0372f98d3e1023bdf47fdf7e52656 100644 --- a/VectoCore/FileIO/VectoFiles.cs +++ b/VectoCore/FileIO/VectoFiles.cs @@ -1,5 +1,4 @@ using System.Runtime.Serialization; -using Newtonsoft.Json; namespace TUGraz.VectoCore.FileIO { diff --git a/VectoCore/Models/Connector/Ports/IDriverDemandPort.cs b/VectoCore/Models/Connector/Ports/IDriverDemandPort.cs index b196964bdfa832a45964f919671a2a5976ccfb96..e6a7d6c7eaecf2915e13e3ac12a0b66e300f99e8 100644 --- a/VectoCore/Models/Connector/Ports/IDriverDemandPort.cs +++ b/VectoCore/Models/Connector/Ports/IDriverDemandPort.cs @@ -3,6 +3,33 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Connector.Ports { + /// <summary> + /// Defines a method to acquire an DriverDemand in port. + /// </summary> + public interface IDriverDemandInProvider + { + /// <summary> + /// Returns the inport to connect it to another outport. + /// </summary> + /// <returns></returns> + IDriverDemandInPort InPort(); + } + + /// <summary> + /// Defines a method to acquire an DriverDemand out port. + /// </summary> + public interface IDriverDemandOutProvider + { + /// <summary> + /// Returns the outport to send requests to. + /// </summary> + /// <returns></returns> + IDriverDemandOutPort OutPort(); + } + + //=============================================== + + /// <summary> /// Defines a connect method to connect the inport to an outport. /// </summary> @@ -24,8 +51,8 @@ namespace TUGraz.VectoCore.Models.Connector.Ports /// </summary> /// <param name="absTime">[s]</param> /// <param name="dt">[s]</param> - /// <param name="accelleration">[m/s^2]</param> + /// <param name="acceleration">[m/s^2]</param> /// <param name="gradient">[rad]</param> - IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSquareSecond accelleration, Radian gradient); + IResponse Request(Second absTime, Second dt, MeterPerSquareSecond acceleration, Radian gradient); } } \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/IDriverDemandProvider.cs b/VectoCore/Models/Connector/Ports/IDriverDemandProvider.cs deleted file mode 100644 index bce021607fd92a0e1aa9267e9b075f4b33b27db4..0000000000000000000000000000000000000000 --- a/VectoCore/Models/Connector/Ports/IDriverDemandProvider.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace TUGraz.VectoCore.Models.Connector.Ports -{ - /// <summary> - /// Defines a method to acquire an DriverDemand in port. - /// </summary> - public interface IDriverDemandInProvider - { - /// <summary> - /// Returns the inport to connect it to another outport. - /// </summary> - /// <returns></returns> - IDriverDemandInPort InShaft(); - } - - /// <summary> - /// Defines a method to acquire an DriverDemand out port. - /// </summary> - public interface IDriverDemandOutProvider - { - /// <summary> - /// Returns the outport to send requests to. - /// </summary> - /// <returns></returns> - IDriverDemandOutPort OutShaft(); - } -} \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/IDrivingCycleDemandPort.cs b/VectoCore/Models/Connector/Ports/IDrivingCycleDemandPort.cs deleted file mode 100644 index 815fd145a1e52493a9c2ce54a2c1581417c6fac4..0000000000000000000000000000000000000000 --- a/VectoCore/Models/Connector/Ports/IDrivingCycleDemandPort.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Connector.Ports -{ - /// <summary> - /// Defines a connect method to connect the inport to an outport. - /// </summary> - public interface IDrivingCycleDemandInPort - { - /// <summary> - /// Connects the inport to another outport. - /// </summary> - void Connect(IDrivingCycleDemandOutPort other); - } - - /// <summary> - /// Defines a request method for a DriverDemand-Out-Port. - /// </summary> - public interface IDrivingCycleDemandOutPort - { - /// <summary> - /// Requests the Outport with the given velocity [m/s] and road gradient [rad]. - /// </summary> - /// <param name="absTime">[s]</param> - /// <param name="dt">[s]</param> - /// <param name="velocity">[m/s]</param> - /// <param name="gradient">[rad]</param> - IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSecond velocity, Radian gradient); - } -} \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/IDrivingCycleDemandProvider.cs b/VectoCore/Models/Connector/Ports/IDrivingCycleDemandProvider.cs deleted file mode 100644 index c33b4f8d4d637e77f2d13c6aec57197557954e40..0000000000000000000000000000000000000000 --- a/VectoCore/Models/Connector/Ports/IDrivingCycleDemandProvider.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace TUGraz.VectoCore.Models.Connector.Ports -{ - /// <summary> - /// Defines a method to acquire an DriverDemand in port. - /// </summary> - public interface IDrivingCycleDemandInProvider - { - /// <summary> - /// Returns the inport to connect it to another outport. - /// </summary> - /// <returns></returns> - IDrivingCycleDemandInPort InShaft(); - } - - /// <summary> - /// Defines a method to acquire an DriverDemand out port. - /// </summary> - public interface IDrivingCycleDemandOutProvider - { - /// <summary> - /// Returns the outport to send requests to. - /// </summary> - /// <returns></returns> - IDrivingCycleDemandOutPort OutShaft(); - } -} \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/IDrivingCyclePort.cs b/VectoCore/Models/Connector/Ports/IDrivingCyclePort.cs index 549e9edb457335ef13ef1e4118f00c6e301a59bd..37ffe6ac786aa6fbd850cfba2b4d1664fbc6573e 100644 --- a/VectoCore/Models/Connector/Ports/IDrivingCyclePort.cs +++ b/VectoCore/Models/Connector/Ports/IDrivingCyclePort.cs @@ -1,18 +1,69 @@ -using System; +using System; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Connector.Ports { /// <summary> - /// Defines a method to request the outport. + /// Defines a method to acquire an DriverDemand in port. + /// </summary> + public interface IDrivingCycleInProvider + { + /// <summary> + /// Returns the inport to connect it to another outport. + /// </summary> + /// <returns></returns> + IDrivingCycleInPort InPort(); + } + + /// <summary> + /// Defines a method to acquire an DriverDemand out port. + /// </summary> + public interface IDrivingCycleOutProvider + { + /// <summary> + /// Returns the outport to send requests to. + /// </summary> + /// <returns></returns> + IDrivingCycleOutPort OutPort(); + } + + + //============================================================= + + + /// <summary> + /// Defines a connect method to connect the inport to an outport. + /// </summary> + public interface IDrivingCycleInPort + { + /// <summary> + /// Connects the inport to another outport. + /// </summary> + void Connect(IDrivingCycleOutPort other); + } + + /// <summary> + /// Defines a request method for a DriverDemand-Out-Port. /// </summary> public interface IDrivingCycleOutPort { /// <summary> - /// Requests a demand for a specific absolute time and a time interval dt. + /// Requests the Outport with the given velocity [m/s] and road gradient [rad]. + /// </summary> + /// <param name="absTime">[s]</param> + /// <param name="ds"></param> + /// <param name="targetVelocity">[m/s]</param> + /// <param name="gradient">[rad]</param> + IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient); + + /// <summary> + /// Requests the outport to simulate the given time interval /// </summary> - /// <param name="absTime">The absolute time of the simulation.</param> - /// <param name="dt">The current time interval.</param> + /// <param name="absTime"></param> + /// <param name="dt"></param> + /// <param name="targetVelocity"></param> + /// <param name="gradient"></param> /// <returns></returns> - IResponse Request(TimeSpan absTime, TimeSpan dt); + IResponse Request(Second absTime, Second dt, MeterPerSecond targetVelocity, Radian gradient); } } \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/IDrivingCycleProvider.cs b/VectoCore/Models/Connector/Ports/IDrivingCycleProvider.cs deleted file mode 100644 index 624b3953b626dfb320bea1028182f31816b8ab9f..0000000000000000000000000000000000000000 --- a/VectoCore/Models/Connector/Ports/IDrivingCycleProvider.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace TUGraz.VectoCore.Models.Connector.Ports -{ - /// <summary> - /// Defines a method to acquire an DriverCycle Demand out port. - /// </summary> - public interface IDrivingCycleOutProvider - { - /// <summary> - /// Returns the outport to send requests to. - /// </summary> - /// <returns></returns> - IDrivingCycleOutPort OutShaft(); - } -} \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/IFvPort.cs b/VectoCore/Models/Connector/Ports/IFvPort.cs index ac85d7d342244d4323b53d534f88cede4c20acf3..9589457820ac3a790f3efa56885efe9d68b3d32d 100644 --- a/VectoCore/Models/Connector/Ports/IFvPort.cs +++ b/VectoCore/Models/Connector/Ports/IFvPort.cs @@ -3,6 +3,33 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Connector.Ports { + /// <summary> + /// Defines a method to acquire an Fv in port. + /// </summary> + public interface IFvInProvider + { + /// <summary> + /// Returns the inport to connect it to another outport. + /// </summary> + /// <returns></returns> + IFvInPort InPort(); + } + + /// <summary> + /// Defines a method to acquire an Fv out port. + /// </summary> + public interface IFvOutProvider + { + /// <summary> + /// Returns the outport to send requests to. + /// </summary> + /// <returns></returns> + IFvOutPort OutPort(); + } + + // ================================================== + + /// <summary> /// Defines a connect method to connect the inport to an outport. /// </summary> @@ -26,6 +53,6 @@ namespace TUGraz.VectoCore.Models.Connector.Ports /// <param name="dt">[s]</param> /// <param name="force">[N]</param> /// <param name="velocity">[m/s]</param> - IResponse Request(TimeSpan absTime, TimeSpan dt, Newton force, MeterPerSecond velocity); + IResponse Request(Second absTime, Second dt, Newton force, MeterPerSecond velocity); } } \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/IResponse.cs b/VectoCore/Models/Connector/Ports/IResponse.cs index a1d76d8ca1619ea5c0725ce6c27698152213fd95..c1cf346e863b1a53c01369b83d6515732e347c80 100644 --- a/VectoCore/Models/Connector/Ports/IResponse.cs +++ b/VectoCore/Models/Connector/Ports/IResponse.cs @@ -1,7 +1,26 @@ +using System; +using System.Security.Cryptography.X509Certificates; +using TUGraz.VectoCore.Utils; + namespace TUGraz.VectoCore.Models.Connector.Ports { - /// <summary> - /// Defines an interface for a Response. - /// </summary> - public interface IResponse {} + public enum ResponseType + { + Success, + CycleFinished, + FailOverload, + FailTimeInterval, + DrivingCycleDistanceExceeded, + } + + + /// <summary> + /// Defines an interface for a Response. + /// </summary> + public interface IResponse + { + Second SimulationInterval { get; set; } + + ResponseType ResponseType { get; } + } } \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/IRoadPortProvider.cs b/VectoCore/Models/Connector/Ports/IRoadPortProvider.cs deleted file mode 100644 index 7bc3047afbcafe7f7a2bbd7ad51694e1a2d1138d..0000000000000000000000000000000000000000 --- a/VectoCore/Models/Connector/Ports/IRoadPortProvider.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace TUGraz.VectoCore.Models.Connector.Ports -{ - /// <summary> - /// Defines a method to acquire an Fv in port. - /// </summary> - public interface IRoadPortInProvider - { - /// <summary> - /// Returns the inport to connect it to another outport. - /// </summary> - /// <returns></returns> - IFvInPort InPort(); - } - - /// <summary> - /// Defines a method to acquire an Fv out port. - /// </summary> - public interface IRoadPortOutProvider - { - /// <summary> - /// Returns the outport to send requests to. - /// </summary> - /// <returns></returns> - IFvOutPort OutPort(); - } -} \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/IShaft.cs b/VectoCore/Models/Connector/Ports/IShaft.cs deleted file mode 100644 index 46a672e1db6fff6f7ec597171992c2cee681aa7b..0000000000000000000000000000000000000000 --- a/VectoCore/Models/Connector/Ports/IShaft.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace TUGraz.VectoCore.Models.Connector.Ports -{ - /// <summary> - /// Defines a method to acquire an Tn in port. - /// </summary> - public interface IInShaft - { - /// <summary> - /// Returns the inport to connect it to another outport. - /// </summary> - /// <returns></returns> - ITnInPort InShaft(); - } - - /// <summary> - /// Defines a method to acquire an Tn out port. - /// </summary> - public interface IOutShaft - { - /// <summary> - /// Returns the outport to send requests to. - /// </summary> - /// <returns></returns> - ITnOutPort OutShaft(); - } -} \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/ISimulationPort.cs b/VectoCore/Models/Connector/Ports/ISimulationPort.cs new file mode 100644 index 0000000000000000000000000000000000000000..77026657a8d436728b82122bcdd2b57c64ec6c01 --- /dev/null +++ b/VectoCore/Models/Connector/Ports/ISimulationPort.cs @@ -0,0 +1,37 @@ +using System; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Connector.Ports +{ + /// <summary> + /// Defines a method to acquire an DriverCycle Demand out port. + /// </summary> + public interface ISimulationOutProvider + { + /// <summary> + /// Returns the outport to send requests to. + /// </summary> + /// <returns></returns> + ISimulationOutPort OutPort(); + } + + //======================================================================== + + /// <summary> + /// Defines a method to request the outport. + /// </summary> + public interface ISimulationOutPort + { + /// <summary> + /// Requests a demand for a specific absolute time and a time interval dt. + /// </summary> + /// <param name="absTime">The absolute time of the simulation.</param> + /// <param name="ds"></param> + /// <returns></returns> + IResponse Request(Second absTime, Meter ds); + + IResponse Request(Second absTime, Second dt); + + IResponse Initialize(); + } +} \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/ITnOutPort.cs b/VectoCore/Models/Connector/Ports/ITnOutPort.cs deleted file mode 100644 index 66c250afedefd66af7f872b0a0f67ebe1c419590..0000000000000000000000000000000000000000 --- a/VectoCore/Models/Connector/Ports/ITnOutPort.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Connector.Ports -{ - public interface ITnOutPort : ITnPort, IOutPort - { - /// <summary> - /// Requests the Outport with the given torque [Nm] and angularVelocity [rad/s]. - /// </summary> - /// <param name="absTime">[s]</param> - /// <param name="dt">[s]</param> - /// <param name="torque">[Nm]</param> - /// <param name="angularVelocity">[rad/s]</param> - IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond angularVelocity); - } -} \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/ITnPort.cs b/VectoCore/Models/Connector/Ports/ITnPort.cs index 9c8d4d8e1a5ff1f8ede02549ba285b0c440ad328..c3d74a248578763231e774a85865c8d01c074d7c 100644 --- a/VectoCore/Models/Connector/Ports/ITnPort.cs +++ b/VectoCore/Models/Connector/Ports/ITnPort.cs @@ -3,6 +3,34 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Connector.Ports { + /// <summary> + /// Defines a method to acquire an Tn in port. + /// </summary> + public interface ITnInProvider + { + /// <summary> + /// Returns the inport to connect it to another outport. + /// </summary> + /// <returns></returns> + ITnInPort InPort(); + } + + /// <summary> + /// Defines a method to acquire an Tn out port. + /// </summary> + public interface ITnOutProvider + { + /// <summary> + /// Returns the outport to send requests to. + /// </summary> + /// <returns></returns> + ITnOutPort OutPort(); + } + + + //======================================================================== + + /// <summary> /// Defines a connect method to connect the inport to an outport. /// </summary> @@ -26,6 +54,6 @@ namespace TUGraz.VectoCore.Models.Connector.Ports /// <param name="dt">[s]</param> /// <param name="torque">[Nm]</param> /// <param name="angularVelocity">[rad/s]</param> - IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond angularVelocity); + IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity); } } \ No newline at end of file diff --git a/VectoCore/Models/Connector/Ports/Impl/Response.cs b/VectoCore/Models/Connector/Ports/Impl/Response.cs index 4931c543c7bb2ddd2235b29988e8729092ed082e..9367b94861ad9293619edbbd5a6fe04acce79e26 100644 --- a/VectoCore/Models/Connector/Ports/Impl/Response.cs +++ b/VectoCore/Models/Connector/Ports/Impl/Response.cs @@ -1,31 +1,71 @@ using System; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Connector.Ports.Impl { + public abstract class AbstractResponse : IResponse + { + public Second SimulationInterval { get; set; } + + public abstract ResponseType ResponseType { get; } + } + /// <summary> /// Response when the Cycle is finished. /// </summary> - public class ResponseCycleFinished : IResponse {} + public class ResponseCycleFinished : AbstractResponse + { + public override ResponseType ResponseType + { + get { return ResponseType.CycleFinished; } + } + } /// <summary> /// Response when a request was successful. /// </summary> - public class ResponseSuccess : IResponse {} + public class ResponseSuccess : AbstractResponse + { + public override ResponseType ResponseType + { + get { return ResponseType.Success; } + } + } /// <summary> /// Response when the request resulted in an engine overload. /// </summary> - public class ResponseFailOverload : IResponse + public class ResponseFailOverload : AbstractResponse { public double Delta { get; set; } public double Gradient { get; set; } + + public override ResponseType ResponseType + { + get { return ResponseType.FailOverload; } + } } /// <summary> /// Response when the request should have another time interval. /// </summary> - public class ResponseFailTimeInterval : IResponse + public class ResponseFailTimeInterval : AbstractResponse { - public TimeSpan DeltaT { get; set; } + public Second DeltaT { get; set; } + + public override ResponseType ResponseType + { + get { return ResponseType.FailTimeInterval; } + } + } + + public class ResponseDrivingCycleDistanceExceeded : AbstractResponse + { + public Meter MaxDistance { get; set; } + + public override ResponseType ResponseType + { + get { return ResponseType.DrivingCycleDistanceExceeded; } + } } } \ No newline at end of file diff --git a/VectoCore/Models/Declaration/AxleConfiguration.cs b/VectoCore/Models/Declaration/AxleConfiguration.cs index e8aadbbea8bf49834fdebaf53110b6b33541f243..ebac0d2c89d28864dccb0579aa3948861d37c4f0 100644 --- a/VectoCore/Models/Declaration/AxleConfiguration.cs +++ b/VectoCore/Models/Declaration/AxleConfiguration.cs @@ -1,4 +1,6 @@ using System; +using TUGraz.VectoCore.Utils; +using TUGraz.VectoCore.Models.SimulationComponent.Data; namespace TUGraz.VectoCore.Models.Declaration { @@ -15,19 +17,18 @@ namespace TUGraz.VectoCore.Models.Declaration AxleConfig_8x8, } - public static class AxleConfigurationExtensions + public static class AxleConfigurationHelper { + private const string Prefix = "AxleConfig_"; + public static string GetName(this AxleConfiguration self) { - return self.ToString().Substring(11); + return self.ToString().Replace(Prefix, ""); } - } - public static class EnumHelper - { - public static AxleConfiguration ParseAxleConfigurationType(string typeString) + public static AxleConfiguration Parse(string typeString) { - return (AxleConfiguration) Enum.Parse(typeof (AxleConfiguration), "AxleConfig_" + typeString, true); + return EnumHelper.Parse<AxleConfiguration>(Prefix + typeString); } } } \ No newline at end of file diff --git a/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/Models/Declaration/DeclarationData.cs index 9646e461840383fb41b19a72cf3ebe3ade091974..df50040d6e5192c9698fb6ea6fe718911a98c9ea 100644 --- a/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/Models/Declaration/DeclarationData.cs @@ -111,6 +111,35 @@ namespace TUGraz.VectoCore.Models.Declaration //Public Const AuxESeff As Single = 0.7 + public static class Driver + { + public static class LookAhead + { + public const Boolean Enabled = true; + public static readonly MeterPerSquareSecond Deceleration = 0.5.SI<MeterPerSquareSecond>(); + public static readonly MeterPerSecond MinimumSpeed = 50.KMPHtoMeterPerSecond(); + } + + public static class OverSpeedEcoRoll + { + public static readonly IList<DriverData.DriverMode> AllowedModes = new List<DriverData.DriverMode>() { + DriverData.DriverMode.EcoRoll, + DriverData.DriverMode.Overspeed + }; + + public static readonly MeterPerSecond MinSpeed = 50.KMPHtoMeterPerSecond(); + public static readonly MeterPerSecond OverSpeed = 5.KMPHtoMeterPerSecond(); + public static readonly MeterPerSecond UnderSpeed = 5.KMPHtoMeterPerSecond(); + } + + public static class StartStop + { + public static readonly MeterPerSecond MaxSpeed = 5.KMPHtoMeterPerSecond(); + public static readonly Second Delay = 5.SI<Second>(); + public static readonly Second MinTime = 5.SI<Second>(); + } + } + public static class Trailer { public const double RollResistanceCoefficient = 0.00555; diff --git a/VectoCore/Models/Declaration/Fan.cs b/VectoCore/Models/Declaration/Fan.cs index c82af7a4263242a213b51c34243c70cc83f90ac1..8b688d01f09f7a7df5bbd9248df55691fa19b9e0 100644 --- a/VectoCore/Models/Declaration/Fan.cs +++ b/VectoCore/Models/Declaration/Fan.cs @@ -26,7 +26,7 @@ namespace TUGraz.VectoCore.Models.Declaration _data.Clear(); foreach (DataRow row in table.Rows) { - foreach (MissionType mission in Enum.GetValues(typeof(MissionType))) { + foreach (var mission in EnumHelper.GetValues<MissionType>()) { _data[Tuple.Create(mission, row.Field<string>("Technology"))] = row.ParseDouble(mission.ToString().ToLower()).SI<Watt>(); } diff --git a/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/Models/Simulation/Data/VectoRunData.cs index 15f627cecf6355f09826ab7045eb5b93a93b5588..6ec4fd9cfaec2b80be84735ed5b454f9f508bcf0 100644 --- a/VectoCore/Models/Simulation/Data/VectoRunData.cs +++ b/VectoCore/Models/Simulation/Data/VectoRunData.cs @@ -1,13 +1,8 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; +using System.Collections.Generic; using System.Runtime.Serialization; -using Newtonsoft.Json; -using TUGraz.VectoCore.Exceptions; -using TUGraz.VectoCore.Models.SimulationComponent; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Simulation.Data { @@ -47,6 +42,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data public string Type; public string Path; public string Technology; + public string[] TechList; public AuxiliaryData Data; } @@ -54,24 +50,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Data public class StartStopData { public bool Enabled; - public double MaxSpeed; - public double MinTime; - public double Delay; - } - - public class LACData - { - public bool Enabled; - public double Dec; - public double MinSpeed; - } - - public class OverSpeedEcoRollData - { - public string Mode; - public double MinSpeed; - public double OverSpeed; - public double UnderSpeed; + public MeterPerSecond MaxSpeed; + public Second MinTime; + public Second Delay; } } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/IVehicleContainer.cs b/VectoCore/Models/Simulation/IVehicleContainer.cs index d9182acd78b7e7a6f3991be40fcdf41fbc2147a7..e7d4517f390df922d7d6fd50e1a33040f871069a 100644 --- a/VectoCore/Models/Simulation/IVehicleContainer.cs +++ b/VectoCore/Models/Simulation/IVehicleContainer.cs @@ -1,6 +1,7 @@ using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Simulation.Cockpit; using TUGraz.VectoCore.Models.SimulationComponent; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Simulation { @@ -10,7 +11,7 @@ namespace TUGraz.VectoCore.Models.Simulation /// </summary> public interface IVehicleContainer : ICockpit { - IDrivingCycleOutPort GetCycleOutPort(); + ISimulationOutPort GetCycleOutPort(); /// <summary> /// Adds a component to the vehicle container. @@ -21,7 +22,7 @@ namespace TUGraz.VectoCore.Models.Simulation /// <summary> /// Commits the current simulation step. /// </summary> - void CommitSimulationStep(double time, double simulationInterval); + void CommitSimulationStep(Second time, Second simulationInterval); /// <summary> /// Finishes the simulation. diff --git a/VectoCore/Models/Simulation/Impl/DistanceRun.cs b/VectoCore/Models/Simulation/Impl/DistanceRun.cs new file mode 100644 index 0000000000000000000000000000000000000000..ca3294473eefdbb642a734c055a6cd989e8663cb --- /dev/null +++ b/VectoCore/Models/Simulation/Impl/DistanceRun.cs @@ -0,0 +1,45 @@ +using System; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +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 Connector.Ports.IResponse DoSimulationStep() + { + //_dt = TimeSpan.FromSeconds(1) - TimeSpan.FromMilliseconds(_dt.Milliseconds); + + // estimate distance to be traveled within the next TargetTimeInterval + var ds = (Container.VehicleSpeed() * Constants.SimulationSettings.TargetTimeInterval).Cast<Meter>(); + + if (ds.IsEqual(0)) { + ds = Constants.SimulationSettings.DriveOffDistance; + } + + var response = CyclePort.Request((Second)AbsTime, ds); + + //while (response is ResponseFailTimeInterval) { + // _dt = (response as ResponseFailTimeInterval).DeltaT; + // response = CyclePort.Request(_absTime, _dt); + //} + + if (response is ResponseCycleFinished) { + return response; + } + + AbsTime = (AbsTime + response.SimulationInterval / 2); + dt = response.SimulationInterval; + return response; + } + + protected override IResponse Initialize() + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 2d8ec08b201e1b1f8df890ba81ee4bd4802e44bf..f96a671e3f1b91601c63cae414f5ebb156037501 100644 --- a/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -32,7 +32,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl private VehicleContainer BuildFullPowertrain(VectoRunData data) { - IDrivingCycleDemandDrivingCycle cycle; + IDrivingCycle cycle; if (_engineOnly) { cycle = new TimeBasedDrivingCycle(_container, data.Cycle); } else { @@ -91,19 +91,19 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl } } - protected virtual IDriver AddComponent(IDrivingCycleDemandDrivingCycle prev, IDriver next) + protected virtual IDriver AddComponent(IDrivingCycle prev, IDriver next) { - prev.InShaft().Connect(next.OutShaft()); + prev.InPort().Connect(next.OutPort()); return next; } protected virtual IVehicle AddComponent(IDriver prev, IVehicle next) { - prev.InShaft().Connect(next.OutShaft()); + prev.InPort().Connect(next.OutPort()); return next; } - protected virtual IWheels AddComponent(IRoadPortInProvider prev, IWheels next) + protected virtual IWheels AddComponent(IFvInProvider prev, IWheels next) { prev.InPort().Connect(next.OutPort()); return next; @@ -112,35 +112,35 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl protected virtual IPowerTrainComponent AddComponent(IWheels prev, IPowerTrainComponent next) { - prev.InShaft().Connect(next.OutShaft()); + prev.InPort().Connect(next.OutPort()); return next; } protected virtual IPowerTrainComponent AddComponent(IPowerTrainComponent prev, IPowerTrainComponent next) { - prev.InShaft().Connect(next.OutShaft()); + prev.InPort().Connect(next.OutPort()); return next; } - protected virtual void AddComponent(IPowerTrainComponent prev, IOutShaft next) + protected virtual void AddComponent(IPowerTrainComponent prev, ITnOutProvider next) { - prev.InShaft().Connect(next.OutShaft()); + prev.InPort().Connect(next.OutPort()); } private VehicleContainer BuildEngineOnly(VectoRunData data) { - var cycle = new EngineOnlyDrivingCycle(_container, data.Cycle); + var cycle = new EngineOnlySimulation(_container, data.Cycle); var engine = new CombustionEngine(_container, data.EngineData); var gearBox = new EngineOnlyGearbox(_container); IAuxiliary addAux = new DirectAuxiliary(_container, new AuxiliaryCycleDataAdapter(data.Cycle)); - addAux.InShaft().Connect(engine.OutShaft()); + addAux.InPort().Connect(engine.OutPort()); - gearBox.InShaft().Connect(addAux.OutShaft()); + gearBox.InPort().Connect(addAux.OutPort()); - cycle.InShaft().Connect(gearBox.OutShaft()); + cycle.InPort().Connect(gearBox.OutPort()); return _container; } diff --git a/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs index 7825484fbe7cd53e4a79d9c31ffc0aebad182abe..66fd5f748454d4b3523f1bdd00fef0e42406b338 100644 --- a/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs +++ b/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs @@ -78,7 +78,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl var sumWriterDecorator = DecorateSumWriter(data.IsEngineOnly, SumWriter, data.JobFileName, jobName, data.Cycle.Name); var builder = new PowertrainBuilder(modWriter, sumWriterDecorator, DataReader.IsEngineOnly); - yield return new VectoRun(builder.Build(data)); + yield return new DistanceRun(builder.Build(data)); } } diff --git a/VectoCore/Models/Simulation/Impl/VectoRun.cs b/VectoCore/Models/Simulation/Impl/VectoRun.cs index 7f9f75c3aec5e2b8c9042f636d4a5bf810590589..354c2d296bd3200bac64f7ce68d1ee9d1d6c7a46 100644 --- a/VectoCore/Models/Simulation/Impl/VectoRun.cs +++ b/VectoCore/Models/Simulation/Impl/VectoRun.cs @@ -3,16 +3,18 @@ using Common.Logging; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Connector.Ports.Impl; using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Simulation.Impl { /// <summary> /// Simulator for one vecto simulation job. /// </summary> - public class VectoRun : IVectoRun + public abstract class VectoRun : IVectoRun { - private TimeSpan _absTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0); - private TimeSpan _dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0); + protected Second AbsTime = 0.SI<Second>(); + + protected Second dt = 1.SI<Second>(); public VectoRun(IVehicleContainer container) { @@ -26,7 +28,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl protected string JobName { get; set; } - protected IDrivingCycleOutPort CyclePort { get; set; } + protected ISimulationOutPort CyclePort { get; set; } protected IModalDataWriter DataWriter { get; set; } protected IVehicleContainer Container { get; set; } @@ -39,31 +41,23 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl { LogManager.GetLogger(GetType()).Info("VectoJob started running."); IResponse response; - do { - response = CyclePort.Request(_absTime, _dt); - while (response is ResponseFailTimeInterval) { - _dt = (response as ResponseFailTimeInterval).DeltaT; - response = CyclePort.Request(_absTime, _dt); - } - - if (response is ResponseCycleFinished) { - break; - } - - var time = (_absTime + TimeSpan.FromTicks(_dt.Ticks / 2)).TotalSeconds; - var simulationInterval = _dt.TotalSeconds; - Container.CommitSimulationStep(time, simulationInterval); + do { + response = DoSimulationStep(); + Container.CommitSimulationStep(AbsTime, dt); // set _dt to difference to next full second. - _absTime += _dt; - _dt = TimeSpan.FromSeconds(1) - TimeSpan.FromMilliseconds(_dt.Milliseconds); + AbsTime += dt; } while (response is ResponseSuccess); Container.FinishSimulation(); LogManager.GetLogger(GetType()).Info("VectoJob finished."); } + + protected abstract IResponse DoSimulationStep(); + + protected abstract IResponse Initialize(); } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index 6628f506f27102b22970344bb701a3f3936fb7a0..0a2ea160d761ebaf7cf21190dd90e3ca37fa65e0 100644 --- a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -17,7 +17,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl internal IGearboxCockpit _gearbox; internal IVehicleCockpit _vehicle; - internal IDrivingCycleOutPort _cycle; + internal ISimulationOutPort _cycle; internal ISummaryDataWriter _sumWriter; internal IModalDataWriter _dataWriter; @@ -81,7 +81,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl #region IVehicleContainer - public IDrivingCycleOutPort GetCycleOutPort() + public ISimulationOutPort GetCycleOutPort() { return _cycle; } @@ -105,23 +105,25 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl _vehicle = vehicle; } - var cycle = component as IDrivingCycleOutPort; + var cycle = component as ISimulationOutPort; if (cycle != null) { _cycle = cycle; } } - public void CommitSimulationStep(double time, double simulationInterval) + public void CommitSimulationStep(Second time, Second simulationInterval) { _logger.Info("VehicleContainer committing simulation."); foreach (var component in _components) { component.CommitSimulationStep(_dataWriter); } - _dataWriter[ModalResultField.time] = time; - _dataWriter[ModalResultField.simulationInterval] = simulationInterval; - _dataWriter.CommitSimulationStep(); + if (_dataWriter != null) { + _dataWriter[ModalResultField.time] = time; + _dataWriter[ModalResultField.simulationInterval] = simulationInterval; + _dataWriter.CommitSimulationStep(); + } } public void FinishSimulation() diff --git a/VectoCore/Models/SimulationComponent/Data/AuxiliaryCycleDataAdapter.cs b/VectoCore/Models/SimulationComponent/Data/AuxiliaryCycleDataAdapter.cs index 3bcf89c03e8286439eabb474a390ff9d3cbabf9b..8a78c7296bac83d5797ff0745cecd787c3ed2c3b 100644 --- a/VectoCore/Models/SimulationComponent/Data/AuxiliaryCycleDataAdapter.cs +++ b/VectoCore/Models/SimulationComponent/Data/AuxiliaryCycleDataAdapter.cs @@ -31,9 +31,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data protected DrivingCycleData.DrivingCycleEntry CurrentCycleEntry { get; set; } - public Watt GetPowerDemand(TimeSpan absTime, TimeSpan dt) + public Watt GetPowerDemand(Second absTime, Second dt) { - if (_nextCycleEntry.Current.Time <= absTime.TotalSeconds) { + if (_nextCycleEntry.Current.Time <= absTime) { CurrentCycleEntry = _nextCycleEntry.Current; _nextCycleEntry.MoveNext(); } diff --git a/VectoCore/Models/SimulationComponent/Data/DriverData.cs b/VectoCore/Models/SimulationComponent/Data/DriverData.cs index 537b71fd6a96d258dfd315947adbd40bfb84f2a9..a1296388331af21095a64644bf5277c58e50c0a0 100644 --- a/VectoCore/Models/SimulationComponent/Data/DriverData.cs +++ b/VectoCore/Models/SimulationComponent/Data/DriverData.cs @@ -1,15 +1,42 @@ using System; using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Data { public class DriverData { - public DriverData(VectoRunData.StartStopData startStop, - VectoRunData.OverSpeedEcoRollData overSpeedEcoRoll, - VectoRunData.LACData lookAheadCoasting, string accelerationLimitingFile) + public enum DriverMode { - throw new NotImplementedException(); + Off, + Overspeed, + EcoRoll, + } + + + public VectoRunData.StartStopData StartStop; + public OverSpeedEcoRollData OverSpeedEcoRoll; + public LACData LookAheadCoasting; + public AccelerationCurveData AccelerationCurve; + + public static DriverMode ParseDriverMode(string mode) + { + return EnumHelper.Parse<DriverMode>(mode.Replace("-", "")); + } + + public class OverSpeedEcoRollData + { + public DriverMode Mode; + public MeterPerSecond MinSpeed; + public MeterPerSecond OverSpeed; + public MeterPerSecond UnderSpeed; + } + + public class LACData + { + public bool Enabled; + public MeterPerSquareSecond Deceleration; + public MeterPerSecond MinSpeed; } } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Data/DrivingCycleData.cs b/VectoCore/Models/SimulationComponent/Data/DrivingCycleData.cs index 997dc64d7204db63e927f8500eb75d9d473c90e4..22015239868f7de42cd10ec3ade470484ed2caaa 100644 --- a/VectoCore/Models/SimulationComponent/Data/DrivingCycleData.cs +++ b/VectoCore/Models/SimulationComponent/Data/DrivingCycleData.cs @@ -46,7 +46,30 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data var data = VectoCSVFile.Read(fileName); var entries = parser.Parse(data).ToList(); - log.Info(string.Format("Data loaded. Number of Entries: {0}", entries.Count)); + if (type == CycleType.DistanceBased) { + var filtered = new List<DrivingCycleEntry>(); + var current = entries.First(); + current.Altitude = 0.SI<Meter>(); + filtered.Add(current); + var distance = current.Distance; + var altitude = current.Altitude; + foreach (var entry in entries) { + entry.Altitude = altitude; + if (!CycleEntriesAreEqual(current, entry)) { + entry.Altitude = altitude; + filtered.Add(entry); + current = entry; + } + if (entry.StoppingTime.IsEqual(0) && !entry.VehicleTargetSpeed.IsEqual(0)) { + altitude += (entry.Distance - distance) * entry.RoadGradientPercent / 100.0; + } + distance = entry.Distance; + } + log.Info(string.Format("Data loaded. Number of Entries: {0}, filtered Entries: {1}", entries.Count, filtered.Count)); + entries = filtered; + + AdjustDistanceAfterStop(entries); + } var cycle = new DrivingCycleData { Entries = entries, @@ -55,6 +78,42 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data return cycle; } + private static void AdjustDistanceAfterStop(List<DrivingCycleEntry> entries) + { + var currentIt = entries.GetEnumerator(); + var nextIt = entries.GetEnumerator(); + nextIt.MoveNext(); + while (currentIt.MoveNext() && nextIt.MoveNext()) { + if (currentIt.Current != null && !currentIt.Current.StoppingTime.IsEqual(0)) { + if (nextIt.Current != null) { + nextIt.Current.Distance = currentIt.Current.Distance; + } + } + } + } + + private static bool CycleEntriesAreEqual(DrivingCycleEntry first, DrivingCycleEntry second) + { + if (first.Distance.IsEqual(second.Distance)) { + return true; + } + var retVal = first.VehicleTargetSpeed == second.VehicleTargetSpeed; + retVal = retVal && + first.RoadGradient.IsEqual(second.RoadGradient, Constants.SimulationSettings.DrivingCycleRoadGradientTolerance); + retVal = retVal && first.StoppingTime.IsEqual(0) && second.StoppingTime.IsEqual(0); + retVal = retVal && first.AdditionalAuxPowerDemand == second.AdditionalAuxPowerDemand; + retVal = retVal && first.AuxiliarySupplyPower.Count == second.AuxiliarySupplyPower.Count; + + foreach (var key in first.AuxiliarySupplyPower.Keys) { + if (!second.AuxiliarySupplyPower.ContainsKey(key)) { + return false; + } + retVal = retVal && first.AuxiliarySupplyPower[key] == second.AuxiliarySupplyPower[key]; + } + + return retVal; + } + private static IDataParser CreateDataParser(CycleType type) { switch (type) { @@ -149,29 +208,39 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data /// [m] Travelled distance used for distance-based cycles. If "t" /// is also defined this column will be ignored. /// </summary> - public double Distance { get; set; } + public Meter Distance { get; set; } /// <summary> /// [s] Used for time-based cycles. If neither this nor the distance /// "s" is defined the data will be interpreted as 1Hz. /// </summary> - public double Time { get; set; } + public Second Time { get; set; } /// <summary> /// [m/s] Required except for Engine Only Mode calculations. /// </summary> - public MeterPerSecond VehicleSpeed { get; set; } + public MeterPerSecond VehicleTargetSpeed { get; set; } /// <summary> - /// [%] Optional. + /// [rad] Optional. + /// </summary> + public Radian RoadGradient { get; set; } + + /// <summary> + /// [%] Optional. + /// </summary> + public double RoadGradientPercent { get; set; } + + /// <summary> + /// [m] relative altitude of the driving cycle over distance /// </summary> - public double RoadGradient { get; set; } + public Meter Altitude { get; set; } /// <summary> /// [s] Required for distance-based cycles. Not used in time based /// cycles. "stop" defines the time the vehicle spends in stop phases. /// </summary> - public double StoppingTime { get; set; } + public Second StoppingTime { get; set; } /// <summary> /// [W] Supply Power input for each auxiliary defined in the @@ -250,9 +319,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray()); return table.Rows.Cast<DataRow>().Select(row => new DrivingCycleEntry { - Distance = row.ParseDouble(Fields.Distance), - VehicleSpeed = row.ParseDouble(Fields.VehicleSpeed).SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(), - RoadGradient = row.ParseDoubleOrGetDefault(Fields.RoadGradient), + Distance = row.ParseDouble(Fields.Distance).SI<Meter>(), + VehicleTargetSpeed = row.ParseDouble(Fields.VehicleSpeed).SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(), + RoadGradientPercent = row.ParseDoubleOrGetDefault(Fields.RoadGradient), + RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0), + StoppingTime = (row.ParseDouble(Fields.StoppingTime)).SI<Second>(), AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(), EngineSpeed = @@ -311,9 +382,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray()); var entries = table.Rows.Cast<DataRow>().Select((row, index) => new DrivingCycleEntry { - Time = row.ParseDoubleOrGetDefault(Fields.Time, index), - VehicleSpeed = row.ParseDouble(Fields.VehicleSpeed).SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(), - RoadGradient = row.ParseDoubleOrGetDefault(Fields.RoadGradient), + Time = row.ParseDoubleOrGetDefault(Fields.Time, index).SI<Second>(), + VehicleTargetSpeed = row.ParseDouble(Fields.VehicleSpeed).SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(), + RoadGradientPercent = row.ParseDoubleOrGetDefault(Fields.RoadGradient), + RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0), AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(), Gear = row.ParseDoubleOrGetDefault(Fields.Gear), @@ -367,7 +439,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public IEnumerable<DrivingCycleEntry> Parse(DataTable table) { ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray()); - var absTime = new TimeSpan(0, 0, 0); + var absTime = 0.SI<Second>(); foreach (DataRow row in table.Rows) { var entry = new DrivingCycleEntry { @@ -392,8 +464,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data entry.EngineSpeed); } } - entry.Time = absTime.TotalSeconds; - absTime += new TimeSpan(0, 0, 1); + entry.Time = absTime; + absTime += 1.SI<Second>(); yield return entry; } diff --git a/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs b/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs index 1bc5286a2f6cfdcfeb89aca843b10c61e28c1bf3..5946347629890427c93a9047c2754004fa59e064 100644 --- a/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs +++ b/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs @@ -65,7 +65,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine { // delauney map needs is initialised with rpm, therefore the engineSpeed has to be converted. return - _fuelMap.Interpolate(torque.Double(), engineSpeed.ConvertTo().Rounds.Per.Minute.Double()).SI().Kilo.Gramm.Per.Second; + _fuelMap.Interpolate(torque.Value(), engineSpeed.ConvertTo().Rounds.Per.Minute.Value()).SI().Kilo.Gramm.Per.Second; } private static class Fields diff --git a/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs b/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs index 15e014396f7b12d30369da76dbbd1a1ef75e34ee..6f5e4a7e23fa6073373ff0c47c30eff820b9cbf0 100644 --- a/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs +++ b/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs @@ -270,30 +270,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine var k = (p2.TorqueFullLoad - p1.TorqueFullLoad) / (p2.EngineSpeed - p1.EngineSpeed); var d = p2.TorqueFullLoad - k * p2.EngineSpeed; - if (k.Double().IsEqual(0.0)) { + if (k.IsEqual(0.0)) { // rectangle - return (p1.EngineSpeed + (area / d.Double())); + // area = M * n + return (p1.EngineSpeed + (area / d.Value())); } - var a = k.Double() / 2.0; - var b = d.Double(); - var c = (k * p1.EngineSpeed * p1.EngineSpeed + 2 * p1.EngineSpeed * d).Double(); - - var D = b * b - 4 * a * c; - - var retVal = new List<PerSecond>(); - if (D < 0) { + // non-constant torque, M(n) = k * n + d + // area = M(n1) * (n2 - n1) + (M(n1) + M(n2))/2 * (n2 - n1) => solve for n2 + var retVal = VectoMath.QuadraticEquationSolver(k.Value() / 2.0, d.Value(), + (k * p1.EngineSpeed * p1.EngineSpeed + 2 * p1.EngineSpeed * d).Value()); + if (retVal.Count == 0) { Log.InfoFormat("No real solution found for requested area: P: {0}, p1: {1}, p2: {2}", area, p1, p2); - return null; - } else if (D > 0) { - // two solutions possible - retVal.Add((-b + Math.Sqrt(D) / (2 * a)).SI<PerSecond>()); - retVal.Add((-b - Math.Sqrt(D) / (2 * a)).SI<PerSecond>()); - } else { - // only one solution possible - retVal.Add((-b / (4 * a * c)).SI<PerSecond>()); } - return retVal.First(x => x >= p1.EngineSpeed && x <= p2.EngineSpeed); + return retVal.First(x => x >= p1.EngineSpeed.Value() && x <= p2.EngineSpeed.Value()).SI<PerSecond>(); } /// <summary> @@ -334,25 +324,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine var d = p2.TorqueFullLoad - k * p2.EngineSpeed; var retVal = new List<PerSecond>(); - if (k.Double().IsEqual(0, 0.0001)) { + if (k.IsEqual(0, 0.0001)) { // constant torque, solve linear equation - retVal.Add((power.Double() / d.Double()).SI<PerSecond>()); + // power = M * n + retVal.Add((power.Value() / d.Value()).SI<PerSecond>()); } else { - // non-constant torque, solve quadratic equation - var a = k.Double(); - var b = d.Double(); - var c = -power.Double(); - - var D = b * b - 4 * a * c; - if (D < 0) { + // non-constant torque, solve quadratic equation for engine speed (n) + // power = M(n) * n = (k * n + d) * n = k * n^2 + d * n + retVal = VectoMath.QuadraticEquationSolver(k.Value(), d.Value(), -power.Value()).SI<PerSecond>().ToList(); + if (retVal.Count == 0) { Log.InfoFormat("No real solution found for requested power demand: P: {0}, p1: {1}, p2: {2}", power, p1, p2); - } else if (D > 0) { - // two solutions possible - retVal.Add(((-b + Math.Sqrt(D)) / (2 * a)).SI<PerSecond>()); - retVal.Add(((-b - Math.Sqrt(D)) / (2 * a)).SI<PerSecond>()); - } else { - // only one solution possible - retVal.Add((-b / (2 * a)).SI<PerSecond>()); } } retVal = retVal.Where(x => x >= p1.EngineSpeed && x <= p2.EngineSpeed).ToList(); @@ -368,7 +349,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine if (lowEngineSpeed < _fullLoadEntries[startSegment].EngineSpeed) { // add part of the first segment area += ((_fullLoadEntries[startSegment].EngineSpeed - lowEngineSpeed) * - (FullLoadStationaryTorque(lowEngineSpeed) + _fullLoadEntries[startSegment].TorqueFullLoad) / 2.0).Double(); + (FullLoadStationaryTorque(lowEngineSpeed) + _fullLoadEntries[startSegment].TorqueFullLoad) / 2.0).Value(); } for (var i = startSegment + 1; i <= endSegment; i++) { var speedHigh = _fullLoadEntries[i].EngineSpeed; @@ -379,7 +360,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine torqueHigh = FullLoadStationaryTorque(highEngineSpeed); } area += ((speedHigh - _fullLoadEntries[i - 1].EngineSpeed) * - (torqueHigh + _fullLoadEntries[i - 1].TorqueFullLoad) / 2.0).Double(); + (torqueHigh + _fullLoadEntries[i - 1].TorqueFullLoad) / 2.0).Value(); } return area; } diff --git a/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs b/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs index a3665d84445df8ff0c0b22c3d2f4e6a06328c82d..bc429a3f29fc25e2aee419ad7de7010784c67a70 100644 --- a/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs +++ b/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs @@ -84,8 +84,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox _lossMap = new DelauneyMap(); //_reverseLossMap = new DelauneyMap(); foreach (var entry in _entries) { - _lossMap.AddPoint(entry.InputSpeed.Double(), (entry.InputTorque.Double() - entry.TorqueLoss.Double()) * gearRatio, - entry.InputTorque.Double()); + _lossMap.AddPoint(entry.InputSpeed.Value(), (entry.InputTorque.Value() - entry.TorqueLoss.Value()) * gearRatio, + entry.InputTorque.Value()); // @@@quam: according to Raphael, not needed for now... //_reverseLossMap.AddPoint(entry.InputSpeed.Double(), entry.InputTorque.Double(), // entry.InputTorque.Double() - entry.TorqueLoss.Double()); @@ -103,7 +103,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox public NewtonMeter GearboxInTorque(PerSecond angularVelocity, NewtonMeter gbxOutTorque) { try { - return VectoMath.Max(_lossMap.Interpolate(angularVelocity.Double(), gbxOutTorque.Double()).SI<NewtonMeter>(), + return VectoMath.Max(_lossMap.Interpolate(angularVelocity.Value(), gbxOutTorque.Value()).SI<NewtonMeter>(), 0.SI<NewtonMeter>()); } catch (Exception e) { throw new VectoSimulationException( diff --git a/VectoCore/Models/SimulationComponent/Data/IAuxiliaryCycleData.cs b/VectoCore/Models/SimulationComponent/Data/IAuxiliaryCycleData.cs index e1d731f84a10f235cf4fbe88af541498324b1e64..c0b3e098b1380e02baf6b5e628719d44ae33b84b 100644 --- a/VectoCore/Models/SimulationComponent/Data/IAuxiliaryCycleData.cs +++ b/VectoCore/Models/SimulationComponent/Data/IAuxiliaryCycleData.cs @@ -5,6 +5,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data { public interface IAuxiliaryCycleData { - Watt GetPowerDemand(TimeSpan absTime, TimeSpan dt); + Watt GetPowerDemand(Second absTime, Second dt); } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Data/VehicleData.cs b/VectoCore/Models/SimulationComponent/Data/VehicleData.cs index f592fa991c9229a336bcb91c73258aa223e30c1c..c50a3175cfea4b908ecbdf6c249dee19d75604e2 100644 --- a/VectoCore/Models/SimulationComponent/Data/VehicleData.cs +++ b/VectoCore/Models/SimulationComponent/Data/VehicleData.cs @@ -95,7 +95,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data RRC += axle.AxleWeightShare * axle.RollResistanceCoefficient * Math.Pow( (axle.AxleWeightShare * TotalVehicleWeight() * Physics.GravityAccelleration / axle.TyreTestLoad / - nrWheels).Double(), Physics.RollResistanceExponent - 1); + nrWheels).Value(), Physics.RollResistanceExponent - 1); mRed0 += nrWheels * (axle.Inertia / DynamicTyreRadius / DynamicTyreRadius).Cast<Kilogram>(); } TotalRollResistanceCoefficient = RRC; diff --git a/VectoCore/Models/SimulationComponent/Factories/EngineeringModeFactory.cs b/VectoCore/Models/SimulationComponent/Factories/EngineeringModeFactory.cs deleted file mode 100644 index af2c8e0e53b49c08a6d18eb29feea0e39f708a31..0000000000000000000000000000000000000000 --- a/VectoCore/Models/SimulationComponent/Factories/EngineeringModeFactory.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.IO; -using System.Linq; -using Newtonsoft.Json; -using TUGraz.VectoCore.Exceptions; -using TUGraz.VectoCore.FileIO; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Factories -{ - public class EngineeringModeFactory : InputFileReader - { - protected static EngineeringModeFactory _instance; - - public static EngineeringModeFactory Instance() - { - return _instance ?? (_instance = new EngineeringModeFactory()); - } - - private void CheckEngineeringMode(string fileName, VersionInfo fileInfo) - { - if (fileInfo.SavedInDeclarationMode) { - Log.WarnFormat("File {0} was saved in Declaration Mode but is used for Engineering Mode!", fileName); - } - } - - public VehicleData CreateVehicleData(string fileName) - { - var json = File.ReadAllText(fileName); - var fileInfo = GetFileVersion(json); - CheckEngineeringMode(fileName, fileInfo); - - switch (fileInfo.Version) { - case 5: - var data = JsonConvert.DeserializeObject<VehicleFileV5Engineering>(json); - return CreateVehicleData(Path.GetDirectoryName(fileName), data.Body); - default: - throw new UnsupportedFileVersionException(fileName, fileInfo.Version); - } - } - - - protected VehicleData CreateVehicleData(string basePath, VehicleFileV5Engineering.DataBodyEng data) - { - return new VehicleData { - BasePath = basePath, - SavedInDeclarationMode = data.SavedInDeclarationMode, - VehicleCategory = data.VehicleCategory(), - CurbWeight = data.CurbWeight.SI<Kilogram>(), - CurbWeigthExtra = data.CurbWeightExtra.SI<Kilogram>(), - Loading = data.Loading.SI<Kilogram>(), - GrossVehicleMassRating = data.GrossVehicleMassRating.SI().Kilo.Kilo.Gramm.Cast<Kilogram>(), - DragCoefficient = data.DragCoefficient, - CrossSectionArea = data.CrossSectionArea.SI<SquareMeter>(), - DragCoefficientRigidTruck = data.DragCoefficientRigidTruck, - CrossSectionAreaRigidTruck = data.CrossSectionAreaRigidTruck.SI<SquareMeter>(), - DynamicTyreRadius = data.DynamicTyreRadius.SI().Milli.Meter.Cast<Meter>(), - // .SI<Meter>(), - Rim = data.RimStr, - Retarder = new RetarderData(data.Retarder, basePath), - AxleData = data.AxleConfig.Axles.Select(axle => new Axle { - Inertia = axle.Inertia.SI<KilogramSquareMeter>(), - TwinTyres = axle.TwinTyres, - RollResistanceCoefficient = axle.RollResistanceCoefficient, - AxleWeightShare = axle.AxleWeightShare, - TyreTestLoad = axle.TyreTestLoad.SI<Newton>() - }).ToList() - }; - } - } -} \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/ICombustionEngine.cs b/VectoCore/Models/SimulationComponent/ICombustionEngine.cs index afb7be9d04565c5011e0449135484c32649f7e32..6ea31f7b463813aed53403b0942df68163c3436a 100644 --- a/VectoCore/Models/SimulationComponent/ICombustionEngine.cs +++ b/VectoCore/Models/SimulationComponent/ICombustionEngine.cs @@ -6,5 +6,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent /// <summary> /// Defines Interfaces for a combustion engine. /// </summary> - public interface ICombustionEngine : IOutShaft, IEngineCockpit {} + public interface ICombustionEngine : ITnOutProvider, IEngineCockpit {} } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/IDriver.cs b/VectoCore/Models/SimulationComponent/IDriver.cs index e6e019ffc7bbc670994f70711ec5fb4d7c409dde..9527fb200c8e5ea23ef2517225d8ef65aa768685 100644 --- a/VectoCore/Models/SimulationComponent/IDriver.cs +++ b/VectoCore/Models/SimulationComponent/IDriver.cs @@ -5,5 +5,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent /// <summary> /// Defines interfaces for a driver. /// </summary> - public interface IDriver : IDrivingCycleDemandOutProvider, IDriverDemandInProvider {} + public interface IDriver : IDrivingCycleOutProvider, IDriverDemandInProvider {} } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/IDriverDemandDrivingCycle.cs b/VectoCore/Models/SimulationComponent/IDrivingCycle.cs similarity index 63% rename from VectoCore/Models/SimulationComponent/IDriverDemandDrivingCycle.cs rename to VectoCore/Models/SimulationComponent/IDrivingCycle.cs index 6d8656334e67b7e0d3e7d33c36eb9f784748c6f2..647aab5838747764b9f101151afeba4118a76b2e 100644 --- a/VectoCore/Models/SimulationComponent/IDriverDemandDrivingCycle.cs +++ b/VectoCore/Models/SimulationComponent/IDrivingCycle.cs @@ -5,5 +5,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent /// <summary> /// Defines interfaces for a driver demand driving cycle. /// </summary> - public interface IDrivingCycleDemandDrivingCycle : IDrivingCycleOutProvider, IDrivingCycleDemandInProvider {} + public interface IDrivingCycle : ISimulationOutProvider, IDrivingCycleInProvider {} } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/IEngineOnlyDrivingCycle.cs b/VectoCore/Models/SimulationComponent/IEngineOnlyDrivingCycle.cs index ac196bd5fa3a0284589b41eefaf74ab871876f22..cee733a53edd52445002b11ddf0446bd277cef35 100644 --- a/VectoCore/Models/SimulationComponent/IEngineOnlyDrivingCycle.cs +++ b/VectoCore/Models/SimulationComponent/IEngineOnlyDrivingCycle.cs @@ -5,5 +5,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent /// <summary> /// Defines interfaces for a engine only driving cycle. /// </summary> - public interface IEngineOnlyDrivingCycle : IDrivingCycleOutProvider, IInShaft {} + public interface IEngineOnlySimulation : ISimulationOutProvider, ITnInProvider {} } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/IPowerTrainComponent.cs b/VectoCore/Models/SimulationComponent/IPowerTrainComponent.cs index 7c0d4202c02237dc8c618c4dbc6105c87597ee02..8841c6aaa21f7e3b5cd4b60c2110649a71bb57fc 100644 --- a/VectoCore/Models/SimulationComponent/IPowerTrainComponent.cs +++ b/VectoCore/Models/SimulationComponent/IPowerTrainComponent.cs @@ -2,5 +2,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent { - public interface IPowerTrainComponent : IInShaft, IOutShaft {} + public interface IPowerTrainComponent : ITnInProvider, ITnOutProvider {} } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/IVehicle.cs b/VectoCore/Models/SimulationComponent/IVehicle.cs index 9b5249d625380e5f17b213d58ce6e9b0dc88ff6a..f2949fac5a007d07353dbcbea2601735d00529bc 100644 --- a/VectoCore/Models/SimulationComponent/IVehicle.cs +++ b/VectoCore/Models/SimulationComponent/IVehicle.cs @@ -3,5 +3,5 @@ using TUGraz.VectoCore.Models.Simulation.Cockpit; namespace TUGraz.VectoCore.Models.SimulationComponent { - public interface IVehicle : IRoadPortInProvider, IDriverDemandOutProvider, IVehicleCockpit {} + public interface IVehicle : IFvInProvider, IDriverDemandOutProvider, IVehicleCockpit {} } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/IWheels.cs b/VectoCore/Models/SimulationComponent/IWheels.cs index 354f551e2e3c6b595fb9d487c6ad53b791778a10..62d3756c16b4a14193aed5b1eceab5a89780a5da 100644 --- a/VectoCore/Models/SimulationComponent/IWheels.cs +++ b/VectoCore/Models/SimulationComponent/IWheels.cs @@ -5,5 +5,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent /// <summary> /// Defines interfaces for a wheels component. /// </summary> - public interface IWheels : IRoadPortOutProvider, IInShaft {} + public interface IWheels : IFvOutProvider, ITnInProvider {} } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs b/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs index 1731e19655f073ad47f98a81b36fbfbbd6f4bf37..d85153b4c853ab3afb0bb74f2fca14dec5048009 100644 --- a/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs +++ b/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs @@ -17,12 +17,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _gearData = gearData; } - public ITnInPort InShaft() + public ITnInPort InPort() { return this; } - public ITnOutPort OutShaft() + public ITnOutPort OutPort() { return this; } @@ -32,14 +32,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _nextComponent = other; } - public IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond angularVelocity) + public IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity) { return _nextComponent.Request(absTime, dt, _gearData.LossMap.GearboxInTorque(angularVelocity * _gearData.Ratio, torque), angularVelocity * _gearData.Ratio); } - public override void CommitSimulationStep(IModalDataWriter writer) + protected override void DoWriteModalResults(IModalDataWriter writer) + { + // nothing to write + } + + protected override void DoCommitSimulationStep() { // nothing to commit } diff --git a/VectoCore/Models/SimulationComponent/Impl/Clutch.cs b/VectoCore/Models/SimulationComponent/Impl/Clutch.cs index 3a57e7667eae70d9b3e81cac36a043cf4a56e554..1cd9c264c06704b52b2cb9ceb5646228f54d3fba 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Clutch.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Clutch.cs @@ -35,24 +35,29 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return _clutchState; } - public override void CommitSimulationStep(IModalDataWriter writer) + protected override void DoWriteModalResults(IModalDataWriter writer) + { + throw new NotImplementedException(); + } + + protected override void DoCommitSimulationStep() { //todo: implement! - //throw new NotImplementedException(); + throw new NotImplementedException(); } - public ITnInPort InShaft() + public ITnInPort InPort() { return this; } - public ITnOutPort OutShaft() + public ITnOutPort OutPort() { return this; } - public IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond angularVelocity) + public IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity) { var torqueIn = torque; var engineSpeedIn = angularVelocity; diff --git a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 566c50af58e714ea125f1330f68309c684e865fd..1aca930d9bc122a0ee739c406ccb06a0df7ef080 100644 --- a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -32,7 +32,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private const double MaxPowerExceededThreshold = 1.05; private const double ZeroThreshold = 0.0001; private const double FullLoadMargin = 0.01; - [NonSerialized] private readonly List<TimeSpan> _enginePowerCorrections = new List<TimeSpan>(); + [NonSerialized] private readonly List<Second> _enginePowerCorrections = new List<Second>(); /// <summary> /// Current state is computed in request method @@ -50,7 +50,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _previousState.OperationMode = EngineOperationMode.Idle; _previousState.EnginePower = 0.SI<Watt>(); _previousState.EngineSpeed = _data.IdleSpeed; - _previousState.dt = TimeSpan.FromSeconds(0.1); + _previousState.dt = 1.SI<Second>(); } #region IEngineCockpit @@ -62,9 +62,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #endregion - #region IOutShaft + #region ITnOutProvider - public ITnOutPort OutShaft() + public ITnOutPort OutPort() { return this; } @@ -73,7 +73,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region ITnOutPort - IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond engineSpeed) + IResponse ITnOutPort.Request(Second absTime, Second dt, NewtonMeter torque, PerSecond engineSpeed) { _currentState.dt = dt; _currentState.EngineSpeed = engineSpeed; @@ -113,7 +113,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region VectoSimulationComponent - public override void CommitSimulationStep(IModalDataWriter writer) + protected override void DoWriteModalResults(IModalDataWriter writer) { writer[ModalResultField.PaEng] = (double)_currentState.EnginePowerLoss; writer[ModalResultField.Pe_drag] = (double)_currentState.FullDragPower; @@ -132,11 +132,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl .ConvertTo() .Gramm.Per.Hour; } catch (VectoException ex) { - Log.WarnFormat("t: {0} - {1} n: {2} Tq: {3}", _currentState.AbsTime.TotalSeconds, ex.Message, + Log.WarnFormat("t: {0} - {1} n: {2} Tq: {3}", _currentState.AbsTime, ex.Message, _currentState.EngineSpeed, _currentState.EngineTorque); writer[ModalResultField.FC] = double.NaN; } + } + protected override void DoCommitSimulationStep() + { _previousState = _currentState; _currentState = new EngineState(); } @@ -223,9 +226,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// <param name="gear"></param> /// <param name="angularVelocity">[rad/s]</param> /// <param name="dt">[s]</param> - protected void ComputeFullLoadPower(uint gear, PerSecond angularVelocity, TimeSpan dt) + protected void ComputeFullLoadPower(uint gear, PerSecond angularVelocity, Second dt) { - if (dt.Ticks == 0) { + if (dt.IsEqual(0)) { throw new VectoException("ComputeFullLoadPower cannot compute for simulation interval length 0."); } @@ -235,15 +238,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _currentState.StationaryFullLoadPower = Formulas.TorqueToPower(_currentState.StationaryFullLoadTorque, angularVelocity); - double pt1 = _data.GetFullLoadCurve(gear).PT1(angularVelocity).Double(); + double pt1 = _data.GetFullLoadCurve(gear).PT1(angularVelocity).Value(); // var dynFullPowerCalculated = (1 / (pt1 + 1)) * // (_currentState.StationaryFullLoadPower + pt1 * _previousState.EnginePower); var tStarPrev = pt1 * - Math.Log(1 / (1 - (_previousState.EnginePower / _currentState.StationaryFullLoadPower).Double()), Math.E) + Math.Log(1 / (1 - (_previousState.EnginePower / _currentState.StationaryFullLoadPower).Value()), Math.E) .SI<Second>(); - var tStar = tStarPrev + _previousState.dt.TotalSeconds.SI<Second>(); - var dynFullPowerCalculated = _currentState.StationaryFullLoadPower * (1 - Math.Exp((-tStar / pt1).Double())); + var tStar = tStarPrev + _previousState.dt; + var dynFullPowerCalculated = _currentState.StationaryFullLoadPower * (1 - Math.Exp((-tStar / pt1).Value())); _currentState.DynamicFullLoadPower = (dynFullPowerCalculated < _currentState.StationaryFullLoadPower) ? dynFullPowerCalculated : _currentState.StationaryFullLoadPower; @@ -279,7 +282,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// <summary> /// [s] /// </summary> - public TimeSpan AbsTime { get; set; } + public Second AbsTime { get; set; } /// <summary> /// [W] @@ -331,7 +334,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// </summary> public NewtonMeter EngineTorque { get; set; } - public TimeSpan dt { get; set; } + public Second dt { get; set; } #region Equality members diff --git a/VectoCore/Models/SimulationComponent/Impl/DirectAuxiliary.cs b/VectoCore/Models/SimulationComponent/Impl/DirectAuxiliary.cs index eb7a7deddf795453ff94770361ac41ed49177a14..2ea6f21c06629f08cbd8d2f884774c49e14fde5e 100644 --- a/VectoCore/Models/SimulationComponent/Impl/DirectAuxiliary.cs +++ b/VectoCore/Models/SimulationComponent/Impl/DirectAuxiliary.cs @@ -20,18 +20,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _demand = demand; } - #region IInShaft + #region ITnInProvider - public ITnInPort InShaft() + public ITnInPort InPort() { return this; } #endregion - #region IOutShaft + #region ITnOutProvider - public ITnOutPort OutShaft() + public ITnOutPort OutPort() { return this; } @@ -49,13 +49,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region ITnOutPort - IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond engineSpeed) + IResponse ITnOutPort.Request(Second absTime, Second dt, NewtonMeter torque, PerSecond engineSpeed) { if (_outPort == null) { Log.ErrorFormat("{0} cannot handle incoming request - no outport available", absTime); throw new VectoSimulationException( string.Format("{0} cannot handle incoming request - no outport available", - absTime.TotalSeconds)); + absTime)); } _powerDemand = _demand.GetPowerDemand(absTime, dt); @@ -67,11 +67,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region VectoSimulationComponent - public override void CommitSimulationStep(IModalDataWriter writer) + protected override void DoWriteModalResults(IModalDataWriter writer) { writer[ModalResultField.Paux] = (double)_powerDemand; } + protected override void DoCommitSimulationStep() {} + #endregion } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs b/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs index 2943cfd797cc15fc8fbc0ea2a3e08e5caf6f4136..9821ec7e20a6fa154547e9171363165dd9e81a51 100644 --- a/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs +++ b/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs @@ -1,73 +1,281 @@ using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net.Cache; +using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { /// <summary> /// Class representing one Distance Based Driving Cycle /// </summary> - public class DistanceBasedDrivingCycle : VectoSimulationComponent, IDrivingCycleDemandDrivingCycle, - IDrivingCycleOutPort, - IDrivingCycleDemandInPort + public class DistanceBasedDrivingCycle : VectoSimulationComponent, IDrivingCycle, + ISimulationOutPort, + IDrivingCycleInPort { - protected TimeSpan AbsTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0); protected DrivingCycleData Data; - protected double Distance = 0; - protected TimeSpan Dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0); - private IDrivingCycleDemandOutPort _outPort; + + internal DrivingCycleState PreviousState = null; + internal DrivingCycleState CurrentState = new DrivingCycleState(); + + internal readonly DrivingCycleEnumerator CycleIntervalIterator; + + private IDrivingCycleOutPort _outPort; public DistanceBasedDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) : base(container) { Data = cycle; + CycleIntervalIterator = new DrivingCycleEnumerator(Data); + CycleIntervalIterator.MoveNext(); } - #region IDrivingCycleDemandInProvider + #region IDrivingCycleInProvider - public IDrivingCycleDemandInPort InShaft() + public IDrivingCycleInPort InPort() { return this; } #endregion - #region IDrivingCycleOutProvider + #region ISimulationOutProvider - public IDrivingCycleOutPort OutShaft() + public ISimulationOutPort OutPort() { return this; } #endregion - #region IDrivingCycleDemandInPort + #region IDrivingCycleInPort - void IDrivingCycleDemandInPort.Connect(IDrivingCycleDemandOutPort other) + void IDrivingCycleInPort.Connect(IDrivingCycleOutPort other) { _outPort = other; } #endregion - #region IDrivingCycleOutPort + #region ISimulationOutPort + + IResponse ISimulationOutPort.Request(Second absTime, Meter ds) + { + var retVal = DoHandleRequest(absTime, ds); + + CurrentState.Response = retVal; + + //switch (retVal.ResponseType) {} + return retVal; + } + + private IResponse DoHandleRequest(Second absTime, Meter ds) + { + //var currentCycleEntry = Data.Entries[_previousState.CycleIndex]; + //var nextCycleEntry = Data.Entries[_previousState.CycleIndex + 1]; + + if (CycleIntervalIterator.LeftSample.Distance.IsEqual(PreviousState.Distance.Value())) { + // exactly on an entry in the cycle... + if (!CycleIntervalIterator.LeftSample.StoppingTime.IsEqual(0) + && CycleIntervalIterator.LeftSample.StoppingTime > PreviousState.WaitTime) { + // stop for certain time unless we've already waited long enough... + if (!CycleIntervalIterator.LeftSample.VehicleTargetSpeed.IsEqual(0)) { + Log.WarnFormat("Stopping Time requested in cycle but target-velocity not zero. distance: {0}, target speed: {1}", + CycleIntervalIterator.LeftSample.StoppingTime, CycleIntervalIterator.LeftSample.VehicleTargetSpeed); + throw new VectoSimulationException("Stopping Time only allowed when target speed is zero!"); + } + var dt = CycleIntervalIterator.LeftSample.StoppingTime.Value() - PreviousState.WaitTime; + return DriveTimeInterval(absTime, dt); + } + } + + if (PreviousState.Distance + ds > CycleIntervalIterator.RightSample.Distance) { + // only drive until next sample point in cycle + // only drive until next sample point in cycle + return new ResponseDrivingCycleDistanceExceeded() { + MaxDistance = CycleIntervalIterator.RightSample.Distance - PreviousState.Distance + }; + } + + + return DriveDistance(absTime, ds); + } + + private IResponse DriveTimeInterval(Second absTime, Second dt) + { + CurrentState.AbsTime = PreviousState.AbsTime + dt; + CurrentState.WaitTime = PreviousState.WaitTime + dt; + + return _outPort.Request((Second)absTime, (Second)dt, + CycleIntervalIterator.LeftSample.VehicleTargetSpeed, ComputeGradient()); + } + + private IResponse DriveDistance(Second absTime, Meter ds) + { + CurrentState.Distance = PreviousState.Distance + ds; + + CurrentState.VehicleTargetSpeed = CycleIntervalIterator.LeftSample.VehicleTargetSpeed; + + return _outPort.Request(absTime, ds, CurrentState.VehicleTargetSpeed, ComputeGradient()); + } + + private Radian ComputeGradient() + { + var leftSamplePoint = CycleIntervalIterator.LeftSample; + var rightSamplePoint = CycleIntervalIterator.RightSample; + + var gradient = leftSamplePoint.RoadGradient; + + if (!leftSamplePoint.Distance.IsEqual(rightSamplePoint.Distance)) { + CurrentState.Altitude = VectoMath.Interpolate(leftSamplePoint.Distance, rightSamplePoint.Distance, + leftSamplePoint.Altitude, rightSamplePoint.Altitude, CurrentState.Distance); + + gradient = VectoMath.InclinationToAngle(((CurrentState.Altitude - PreviousState.Altitude) / + (CurrentState.Distance - PreviousState.Distance)).Value()); + } + return gradient; + } + + IResponse ISimulationOutPort.Request(Second absTime, Second dt) + { + throw new NotImplementedException(); + } - IResponse IDrivingCycleOutPort.Request(TimeSpan absTime, TimeSpan dt) + IResponse ISimulationOutPort.Initialize() { - //todo: Distance calculation and comparison!!! - throw new NotImplementedException("Distance based Cycle is not yet implemented."); + var first = Data.Entries.First(); + PreviousState = new DrivingCycleState() { + AbsTime = 0.SI<Second>(), + WaitTime = 0.SI<Second>(), + Distance = first.Distance, + Altitude = first.Altitude, + }; + CurrentState = PreviousState.Clone(); + return new ResponseSuccess(); + //TODO: return _outPort.Initialize(); } #endregion #region VectoSimulationComponent - public override void CommitSimulationStep(IModalDataWriter writer) + protected override void DoWriteModalResults(IModalDataWriter writer) {} + + protected override void DoCommitSimulationStep() { - throw new NotImplementedException("Distance based Cycle is not yet implemented."); + if (CurrentState.Response.ResponseType != ResponseType.Success) { + throw new VectoSimulationException("Previous request did not succeed!"); + } + + PreviousState = CurrentState; + CurrentState = CurrentState.Clone(); + + if (!CycleIntervalIterator.LeftSample.StoppingTime.IsEqual(0) && + CycleIntervalIterator.LeftSample.StoppingTime.IsEqual(CurrentState.WaitTime)) { + // we needed to stop at the current interval in the cycle and have already waited enough time, move on.. + CycleIntervalIterator.MoveNext(); + } + if (CurrentState.Distance >= CycleIntervalIterator.RightSample.Distance) { + // we have reached the end of the current interval in the cycle, move on... + CycleIntervalIterator.MoveNext(); + } } #endregion + + protected void LookupCycle(Meter ds) {} + + + public class DrivingCycleEnumerator : IEnumerator<DrivingCycleData.DrivingCycleEntry> + { + protected IEnumerator<DrivingCycleData.DrivingCycleEntry> LeftSampleIt; + protected IEnumerator<DrivingCycleData.DrivingCycleEntry> RightSampleIt; + + public DrivingCycleEnumerator(DrivingCycleData data) + { + LeftSampleIt = data.Entries.GetEnumerator(); + RightSampleIt = data.Entries.GetEnumerator(); + RightSampleIt.MoveNext(); + } + + public DrivingCycleData.DrivingCycleEntry Current + { + get { return LeftSampleIt.Current; } + } + + public DrivingCycleData.DrivingCycleEntry Next + { + get { return RightSampleIt.Current; } + } + + public DrivingCycleData.DrivingCycleEntry LeftSample + { + get { return LeftSampleIt.Current; } + } + + public DrivingCycleData.DrivingCycleEntry RightSample + { + get { return RightSampleIt.Current; } + } + + public void Dispose() + { + LeftSampleIt.Dispose(); + RightSampleIt.Dispose(); + } + + object System.Collections.IEnumerator.Current + { + get { return LeftSampleIt.Current; } + } + + public bool MoveNext() + { + return LeftSampleIt.MoveNext() && RightSampleIt.MoveNext(); + } + + public void Reset() + { + LeftSampleIt.Reset(); + RightSampleIt.Reset(); + RightSampleIt.MoveNext(); + } + } + + public class DrivingCycleState + { + public DrivingCycleState() {} + + public DrivingCycleState Clone() + { + return new DrivingCycleState() { + AbsTime = AbsTime, + Distance = Distance, + VehicleTargetSpeed = VehicleTargetSpeed, + Altitude = Altitude, + // WaitTime is not cloned on purpose! + WaitTime = 0.SI<Second>(), + Response = null + }; + } + + public Second AbsTime; + + public Meter Distance; + + public Second WaitTime; + + public MeterPerSecond VehicleTargetSpeed; + + public Meter Altitude; + + public IResponse Response; + } } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/Models/SimulationComponent/Impl/Driver.cs index 1ce034eb3fe364d1292de9f7d3b0bf0fbc1e3ae6..be635b1d8da954120d9df155b643af2d77b290ce 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -1,5 +1,9 @@ using System; +using System.CodeDom; +using System.Linq; +using TUGraz.VectoCore.Exceptions; 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; @@ -8,41 +12,122 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { - public class Driver : VectoSimulationComponent, IDriver, IDrivingCycleDemandOutPort, IDriverDemandInPort + public class Driver : VectoSimulationComponent, IDriver, IDrivingCycleOutPort, IDriverDemandInPort { - protected IDriverDemandOutPort _other; + internal DriverState CurrentState = new DriverState(); + + protected IDriverDemandOutPort Next; + + protected DriverData DriverData; public Driver(VehicleContainer container, DriverData driverData) : base(container) { - //throw new NotImplementedException(); + DriverData = driverData; } - public IDriverDemandInPort InShaft() + public IDriverDemandInPort InPort() { return this; } public void Connect(IDriverDemandOutPort other) { - _other = other; + Next = other; + } + + public IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient) + { + var retVal = DoHandleRequest(absTime, ds, targetVelocity, gradient); + + CurrentState.Response = retVal; + + //switch (retVal.ResponseType) {} + return retVal; + } + + + public IResponse Request(Second absTime, Second dt, MeterPerSecond targetVelocity, Radian gradient) + { + var retVal = DoHandleRequest(absTime, dt, targetVelocity, gradient); + + CurrentState.Response = retVal; + + //switch (retVal.ResponseType) {} + return retVal; } - public IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSecond velocity, Radian gradient) + + protected IResponse DoHandleRequest(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient) { - throw new NotImplementedException(); + var currentSpeed = Cockpit.VehicleSpeed(); + + var requiredAverageSpeed = (targetVelocity + currentSpeed) / 2.0; + var requiredAcceleration = + (((targetVelocity - currentSpeed) * requiredAverageSpeed) / ds).Cast<MeterPerSquareSecond>(); + var maxAcceleration = DriverData.AccelerationCurve.Lookup(currentSpeed); + + if (requiredAcceleration > maxAcceleration.Acceleration) { + requiredAcceleration = maxAcceleration.Acceleration; + } + if (requiredAcceleration < maxAcceleration.Deceleration) { + requiredAcceleration = maxAcceleration.Deceleration; + } + + var dt = (ds / currentSpeed).Cast<Second>(); + if (!requiredAcceleration.IsEqual(0)) { + // we need to accelerate / decelerate. solve quadratic equation... + // ds = acceleration / 2 * dt^2 + currentSpeed * dt => solve for dt + var solutions = VectoMath.QuadraticEquationSolver(requiredAcceleration.Value() / 2.0, currentSpeed.Value(), + -ds.Value()); + solutions = solutions.Where(x => x >= 0).ToList(); + + if (solutions.Count == 0) { + Log.WarnFormat( + "Could not find solution for computing required time interval to drive distance {0}. currentSpeed: {1}, targetSpeed: {2}, acceleration: {3}", + ds, currentSpeed, targetVelocity, requiredAcceleration); + return new ResponseFailTimeInterval(); + } + // if there are 2 positive solutions (i.e. when decelerating), take the smaller time interval + // (the second solution means that you reach negative speed + solutions.Sort(); + dt = solutions.First().SI<Second>(); + } + var retVal = Next.Request(absTime, dt, requiredAcceleration, gradient); + retVal.SimulationInterval = dt; + return retVal; } - public IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSquareSecond accelleration, Radian gradient) + protected IResponse DoHandleRequest(Second absTime, Second dt, MeterPerSecond targetVelocity, Radian gradient) { - throw new NotImplementedException(); + if (!targetVelocity.IsEqual(0) || !Cockpit.VehicleSpeed().IsEqual(0)) { + throw new NotImplementedException("TargetVelocity or VehicleVelocity is not zero!"); + } + return Next.Request(absTime, dt, 0.SI<MeterPerSquareSecond>(), gradient); } - public IDrivingCycleDemandOutPort OutShaft() + + public IDrivingCycleOutPort OutPort() { return this; } - public override void CommitSimulationStep(IModalDataWriter writer) {} + protected override void DoWriteModalResults(IModalDataWriter writer) + { + // todo?? + } + + protected override void DoCommitSimulationStep() + { + if (CurrentState.Response.ResponseType != ResponseType.Success) { + throw new VectoSimulationException("Previois request did not succeed!"); + } + } + + + public class DriverState + { + public IResponse Response; + } } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyDrivingCycle.cs b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyDrivingCycle.cs index da14aa901d862b3ff22371b6b39475ccbc9a34f5..4417e28d1d8522f5fdb3807919431fa3dc582d38 100644 --- a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyDrivingCycle.cs +++ b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyDrivingCycle.cs @@ -1,50 +1,57 @@ using System; +using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Connector.Ports.Impl; using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { /// <summary> /// Class representing one EngineOnly Driving Cycle /// </summary> - public class EngineOnlyDrivingCycle : VectoSimulationComponent, IEngineOnlyDrivingCycle, ITnInPort, - IDrivingCycleOutPort + public class EngineOnlySimulation : VectoSimulationComponent, IEngineOnlySimulation, ITnInPort, + ISimulationOutPort { protected DrivingCycleData Data; private ITnOutPort _outPort; - public EngineOnlyDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) : base(container) + public EngineOnlySimulation(IVehicleContainer container, DrivingCycleData cycle) : base(container) { Data = cycle; } - #region IInShaft + #region ITnInProvider - public ITnInPort InShaft() + public ITnInPort InPort() { return this; } #endregion - #region IDrivingCycleOutProvider + #region ISimulationOutProvider - public IDrivingCycleOutPort OutShaft() + public ISimulationOutPort OutPort() { return this; } #endregion - #region IDrivingCycleOutPort + #region ISimulationOutPort - IResponse IDrivingCycleOutPort.Request(TimeSpan absTime, TimeSpan dt) + public IResponse Request(Second absTime, Meter ds) + { + throw new VectoSimulationException("Engine-Only Simulation can not handle distance request"); + } + + IResponse ISimulationOutPort.Request(Second absTime, Second dt) { //todo: change to variable time steps - var index = (int)Math.Floor(absTime.TotalSeconds); + var index = (int)Math.Floor(absTime.Value()); if (index >= Data.Entries.Count) { return new ResponseCycleFinished(); } @@ -52,6 +59,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return _outPort.Request(absTime, dt, Data.Entries[index].EngineTorque, Data.Entries[index].EngineSpeed); } + public IResponse Initialize() + { + // nothing to initialize here... + // TODO: _outPort.initialize(); + throw new NotImplementedException(); + } + #endregion #region ITnInPort @@ -65,7 +79,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region VectoSimulationComponent - public override void CommitSimulationStep(IModalDataWriter writer) {} + protected override void DoWriteModalResults(IModalDataWriter writer) {} + + protected override void DoCommitSimulationStep() {} #endregion } diff --git a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs index d6b997ae048d5c2a834fb8f7080cb4cddbf59274..8b50b510be505c8ddac485c94711c64998f6ce8d 100644 --- a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs +++ b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs @@ -13,18 +13,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private ITnOutPort _outPort; public EngineOnlyGearbox(IVehicleContainer cockpit) : base(cockpit) {} - #region IInShaft + #region ITnInProvider - public ITnInPort InShaft() + public ITnInPort InPort() { return this; } - #endregion IOutShaft + #endregion ITnOutProvider - #region IOutShaft + #region ITnOutProvider - public ITnOutPort OutShaft() + public ITnOutPort OutPort() { return this; } @@ -51,13 +51,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region ITnOutPort - IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond engineSpeed) + IResponse ITnOutPort.Request(Second absTime, Second dt, NewtonMeter torque, PerSecond engineSpeed) { if (_outPort == null) { Log.ErrorFormat("{0} cannot handle incoming request - no outport available", absTime); throw new VectoSimulationException( string.Format("{0} cannot handle incoming request - no outport available", - absTime.TotalSeconds)); + absTime)); } return _outPort.Request(absTime, dt, torque, engineSpeed); } @@ -66,7 +66,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region VectoSimulationComponent - public override void CommitSimulationStep(IModalDataWriter writer) {} + protected override void DoWriteModalResults(IModalDataWriter writer) {} + + protected override void DoCommitSimulationStep() {} #endregion } diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index 36823d7ee2bf8712351859a9115b185e6db214ee..5c59ce99a3450fdd70336d349a1651fc45dc5c33 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -19,18 +19,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Data = gearboxData; } - #region IInShaft + #region ITnInProvider - public ITnInPort InShaft() + public ITnInPort InPort() { return this; } #endregion - #region IOutShaft + #region ITnOutProvider - public ITnOutPort OutShaft() + public ITnOutPort OutPort() { return this; } @@ -48,7 +48,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region ITnOutPort - IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond engineSpeed) + IResponse ITnOutPort.Request(Second absTime, Second dt, NewtonMeter torque, PerSecond engineSpeed) { throw new NotImplementedException(); } @@ -66,7 +66,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region VectoSimulationComponent - public override void CommitSimulationStep(IModalDataWriter writer) + protected override void DoWriteModalResults(IModalDataWriter writer) + { + throw new NotImplementedException(); + } + + protected override void DoCommitSimulationStep() { throw new NotImplementedException(); } diff --git a/VectoCore/Models/SimulationComponent/Impl/MappingAuxiliary.cs b/VectoCore/Models/SimulationComponent/Impl/MappingAuxiliary.cs index 36425689203ff93362ad92ab08cd44948a414281..22d8eb3036d7e45a83fb9e97ab0943e547d16cca 100644 --- a/VectoCore/Models/SimulationComponent/Impl/MappingAuxiliary.cs +++ b/VectoCore/Models/SimulationComponent/Impl/MappingAuxiliary.cs @@ -39,18 +39,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _data = data; } - #region IInShaft + #region ITnInProvider - public ITnInPort InShaft() + public ITnInPort InPort() { return this; } #endregion - #region IOutShaft + #region ITnOutProvider - public ITnOutPort OutShaft() + public ITnOutPort OutPort() { return this; } @@ -68,13 +68,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region ITnOutPort - IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond angularVelocity) + IResponse ITnOutPort.Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity) { if (_outPort == null) { Log.ErrorFormat("{0} cannot handle incoming request - no outport available", absTime); throw new VectoSimulationException( string.Format("{0} cannot handle incoming request - no outport available", - absTime.TotalSeconds)); + absTime)); } var power_supply = _demand.GetPowerDemand(absTime, dt); @@ -95,11 +95,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region VectoSimulationComponent - public override void CommitSimulationStep(IModalDataWriter writer) + protected override void DoWriteModalResults(IModalDataWriter writer) { writer[ModalResultField.Paux_xxx] = (double)_powerDemand; } + protected override void DoCommitSimulationStep() {} + #endregion } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/Retarder.cs b/VectoCore/Models/SimulationComponent/Impl/Retarder.cs index 8889912ab158b2ec74b9bd51a41fdc125f9617a0..bbbc828e4d3e9167a1354a45ef99c306d9929825 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Retarder.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Retarder.cs @@ -21,17 +21,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _lossMap = lossMap; } - public override void CommitSimulationStep(IModalDataWriter writer) + protected override void DoWriteModalResults(IModalDataWriter writer) { writer[ModalResultField.PlossRetarder] = _lossMap; } - public ITnInPort InShaft() + protected override void DoCommitSimulationStep() {} + + public ITnInPort InPort() { return this; } - public ITnOutPort OutShaft() + public ITnOutPort OutPort() { return this; } @@ -41,7 +43,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _nextComponent = other; } - public IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond angularVelocity) + public IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity) { var retarderTorqueLoss = _lossMap.RetarderLoss(angularVelocity); //_retarderLoss = Formulas.TorqueToPower(torqueLoss, angularVelocity); diff --git a/VectoCore/Models/SimulationComponent/Impl/TimeBasedDrivingCycle.cs b/VectoCore/Models/SimulationComponent/Impl/TimeBasedDrivingCycle.cs index 52838a1cf5f56b4a9eb34086d7da83abd04efa4e..212f545b5b9e0bdf3185d6e53f9807eb4d0249eb 100644 --- a/VectoCore/Models/SimulationComponent/Impl/TimeBasedDrivingCycle.cs +++ b/VectoCore/Models/SimulationComponent/Impl/TimeBasedDrivingCycle.cs @@ -11,55 +11,71 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// <summary> /// Class representing one Time Based Driving Cycle /// </summary> - public class TimeBasedDrivingCycle : VectoSimulationComponent, IDrivingCycleDemandDrivingCycle, - IDrivingCycleDemandInPort, - IDrivingCycleOutPort + public class TimeBasedDrivingCycle : VectoSimulationComponent, IDrivingCycle, + IDrivingCycleInPort, + ISimulationOutPort { protected DrivingCycleData Data; - private IDrivingCycleDemandOutPort _outPort; + private IDrivingCycleOutPort _outPort; public TimeBasedDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) : base(container) { Data = cycle; } - #region IDrivingCycleOutProvider + #region ISimulationOutProvider - public IDrivingCycleOutPort OutShaft() + public ISimulationOutPort OutPort() { return this; } #endregion - #region IDrivingCycleDemandInProvider + #region IDrivingCycleInProvider - public IDrivingCycleDemandInPort InShaft() + public IDrivingCycleInPort InPort() { return this; } #endregion - #region IDrivingCycleOutPort + #region ISimulationOutPort - IResponse IDrivingCycleOutPort.Request(TimeSpan absTime, TimeSpan dt) + IResponse ISimulationOutPort.Request(Second absTime, Meter ds) + { + throw new NotImplementedException(); + } + + public IResponse Request(Second absTime, Second dt) { //todo: change to variable time steps - var index = (int)Math.Floor(absTime.TotalSeconds); + var index = (int)Math.Floor(absTime.Value()); if (index >= Data.Entries.Count) { return new ResponseCycleFinished(); } - return _outPort.Request(absTime, dt, Data.Entries[index].VehicleSpeed, - Data.Entries[index].RoadGradient.SI().GradientPercent.Cast<Radian>()); + // TODO!! + var dx = 0.SI<Meter>(); + return _outPort.Request((Second)absTime, dx, Data.Entries[index].VehicleTargetSpeed, + Data.Entries[index].RoadGradient); + } + + public IResponse Initialize() + { + // nothing to initialize here... + // TODO: _outPort.initialize(); + throw new NotImplementedException(); } #endregion - #region IDrivingCycleDemandInPort + #region IDrivingCycleInPort - void IDrivingCycleDemandInPort.Connect(IDrivingCycleDemandOutPort other) + void IDrivingCycleInPort. + Connect(IDrivingCycleOutPort + other) { _outPort = other; } @@ -68,7 +84,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region VectoSimulationComponent - public override void CommitSimulationStep(IModalDataWriter writer) {} + protected override void DoWriteModalResults(IModalDataWriter writer) + { + throw new NotImplementedException(); + } + + protected override void DoCommitSimulationStep() {} #endregion } diff --git a/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs b/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs index bbe6145774a4b67d675e9ff0aa283a1e480aa858..40d056871fe62dc20fc6ef7711e679004a5b8fc3 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs @@ -33,7 +33,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return this; } - public IDriverDemandOutPort OutShaft() + public IDriverDemandOutPort OutPort() { return this; } @@ -43,25 +43,32 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _nextInstance = other; } - public override void CommitSimulationStep(IModalDataWriter writer) + protected override void DoWriteModalResults(IModalDataWriter writer) + { + throw new NotImplementedException(); + } + + protected override void DoCommitSimulationStep() { _previousState = _currentState; _currentState = new VehicleState(); } - public IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSquareSecond accelleration, Radian gradient) + public IResponse Request(Second absTime, Second dt, MeterPerSquareSecond accelleration, Radian gradient) { - _currentState.Velocity = _previousState.Velocity + - (accelleration * (dt.TotalSeconds / 2.0).SI<Second>()).Cast<MeterPerSecond>(); - var force = RollingResistance(gradient) + AirDragResistance() + AccelerationForce(accelleration) + - SlopeResistance(gradient); + _currentState.Velocity = _previousState.Velocity + (accelleration * (dt / 2.0)).Cast<MeterPerSecond>(); + + // DriverAcceleration = vehicleAccelerationForce - RollingResistance - AirDragResistance - SlopeResistance + var vehicleAccelerationForce = DriverAcceleration(accelleration) + RollingResistance(gradient) + + AirDragResistance() + + SlopeResistance(gradient); - return _nextInstance.Request(absTime, dt, force, _currentState.Velocity); + return _nextInstance.Request(absTime, dt, vehicleAccelerationForce, _currentState.Velocity); } protected Newton RollingResistance(Radian gradient) { - return (Math.Cos(gradient.Double()) * _data.TotalVehicleWeight() * + return (Math.Cos(gradient.Value()) * _data.TotalVehicleWeight() * Physics.GravityAccelleration * _data.TotalRollResistanceCoefficient).Cast<Newton>(); } @@ -83,7 +90,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return (Cd * _data.CrossSectionArea * Physics.AirDensity / 2 * vAir * vAir).Cast<Newton>(); } - protected Newton AccelerationForce(MeterPerSquareSecond accelleration) + protected Newton DriverAcceleration(MeterPerSquareSecond accelleration) { return ((_data.TotalVehicleWeight() + _data.ReducedMassWheels) * accelleration).Cast<Newton>(); } @@ -91,7 +98,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected Newton SlopeResistance(Radian gradient) { - return (_data.TotalVehicleWeight() * Physics.GravityAccelleration * Math.Sin(gradient.Double())).Cast<Newton>(); + return (_data.TotalVehicleWeight() * Physics.GravityAccelleration * Math.Sin(gradient.Value())).Cast<Newton>(); } public MeterPerSecond VehicleSpeed() diff --git a/VectoCore/Models/SimulationComponent/Impl/Wheels.cs b/VectoCore/Models/SimulationComponent/Impl/Wheels.cs index 22312359373e9f5332b888a8f4888cadb4bb8555..1d998f4f69d14dd85aaf14a083ba760b5e20b58a 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Wheels.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Wheels.cs @@ -17,7 +17,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _dynamicWheelRadius = rdyn; } - #region IRoadPortOutProvider + #region IFvOutProvider public IFvOutPort OutPort() { @@ -26,9 +26,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #endregion - #region IInShaft + #region ITnInProvider - public ITnInPort InShaft() + public ITnInPort InPort() { return this; } @@ -37,7 +37,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region IFvOutPort - IResponse IFvOutPort.Request(TimeSpan absTime, TimeSpan dt, Newton force, MeterPerSecond velocity) + IResponse IFvOutPort.Request(Second absTime, Second dt, Newton force, MeterPerSecond velocity) { var torque = force * _dynamicWheelRadius; var angularVelocity = velocity / _dynamicWheelRadius; @@ -57,7 +57,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region VectoSimulationComponent - public override void CommitSimulationStep(IModalDataWriter writer) + protected override void DoWriteModalResults(IModalDataWriter writer) + { + throw new NotImplementedException(); + } + + protected override void DoCommitSimulationStep() { throw new NotImplementedException(); } diff --git a/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs b/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs index 85ae6769dd5bdf764ed13b236619d741a343fcb0..81008eb3d0eab9b2dcff8538150dd80510933cd5 100644 --- a/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs +++ b/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs @@ -26,12 +26,21 @@ namespace TUGraz.VectoCore.Models.SimulationComponent cockpit.AddComponent(this); } + public void CommitSimulationStep(IModalDataWriter writer) + { + if (writer != null) { + DoWriteModalResults(writer); + } + DoCommitSimulationStep(); + } + + protected abstract void DoWriteModalResults(IModalDataWriter writer); + /// <summary> /// Commits the simulation step. /// Writes the moddata into the data writer. /// Commits the internal state of the object if needed. /// </summary> - /// <param name="writer">a data writer to write the data into.</param> - public abstract void CommitSimulationStep(IModalDataWriter writer); + protected abstract void DoCommitSimulationStep(); } } \ No newline at end of file diff --git a/VectoCore/Utils/DoubleExtensionMethods.cs b/VectoCore/Utils/DoubleExtensionMethods.cs index 813c467d955da1a563f6c49f501a2c6d97f62b80..967cbe8c9c823799f57b06647d262f11545ceb7d 100644 --- a/VectoCore/Utils/DoubleExtensionMethods.cs +++ b/VectoCore/Utils/DoubleExtensionMethods.cs @@ -95,6 +95,11 @@ namespace TUGraz.VectoCore.Utils return self.SI().Rounds.Per.Minute.ConvertTo().Radian.Per.Second.Cast<PerSecond>(); } + public static MeterPerSecond KMPHtoMeterPerSecond(this double self) + { + return self.SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(); + } + /// <summary> /// Creates an SI object for the number (unit-less: [-]). /// </summary> @@ -102,7 +107,7 @@ namespace TUGraz.VectoCore.Utils /// <returns></returns> public static SI SI(this double self) { - return (SI) self; + return (SI)self; } /// <summary> diff --git a/VectoCore/Utils/EnumHelper.cs b/VectoCore/Utils/EnumHelper.cs new file mode 100644 index 0000000000000000000000000000000000000000..000a04b68c3901e6f8e5f297b10ae947115ea619 --- /dev/null +++ b/VectoCore/Utils/EnumHelper.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace TUGraz.VectoCore.Utils +{ + public static class EnumHelper + { + public static T Parse<T>(this string s, bool ignoreCase = true) + { + return (T)Enum.Parse(typeof(T), s, ignoreCase); + } + + public static IEnumerable<T> GetValues<T>() + { + return Enum.GetValues(typeof(T)).Cast<T>(); + } + } +} \ No newline at end of file diff --git a/VectoCore/Utils/Formulas.cs b/VectoCore/Utils/Formulas.cs index 91debb47ea3ee1a000e9e11a9e1310ca52e2ce8a..5ec60523d3a3d9eabb2f4465a38a1849767bc556 100644 --- a/VectoCore/Utils/Formulas.cs +++ b/VectoCore/Utils/Formulas.cs @@ -24,7 +24,7 @@ namespace TUGraz.VectoCore.Utils /// <returns>torque [Nm]</returns> public static NewtonMeter PowerToTorque(Watt power, PerSecond angularVelocity) { - if (Math.Abs(angularVelocity.Double()) < 1E-10) { + if (Math.Abs(angularVelocity.Value()) < 1E-10) { throw new VectoSimulationException("Can not compute Torque for 0 angular Velocity!"); } return power / angularVelocity; diff --git a/VectoCore/Utils/IntExtensionMethods.cs b/VectoCore/Utils/IntExtensionMethods.cs index 265ed5e69eecbca12827e41652640f781eb57e84..e133f778fbbb8dcc299608ff7791c5573a190f47 100644 --- a/VectoCore/Utils/IntExtensionMethods.cs +++ b/VectoCore/Utils/IntExtensionMethods.cs @@ -12,6 +12,12 @@ namespace TUGraz.VectoCore.Utils return d.SI().Rounds.Per.Minute.ConvertTo().Radian.Per.Second.Cast<PerSecond>(); } + public static MeterPerSecond KMPHtoMeterPerSecond(this int d) + { + return d.SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(); + } + + /// <summary> /// Gets the SI representation of the number (unit-less). /// </summary> @@ -32,15 +38,15 @@ namespace TUGraz.VectoCore.Utils return SIBase<T>.Create(d); } - /// <summary> - /// Modulo functions which also works on negative Numbers (not like the built-in %-operator which just returns the remainder). - /// </summary> - /// <param name="a"></param> - /// <param name="b"></param> - /// <returns></returns> - public static int Mod(this int a, int b) - { - return (a %= b) < 0 ? a + b : a; - } + /// <summary> + /// Modulo functions which also works on negative Numbers (not like the built-in %-operator which just returns the remainder). + /// </summary> + /// <param name="a"></param> + /// <param name="b"></param> + /// <returns></returns> + public static int Mod(this int a, int b) + { + return (a %= b) < 0 ? a + b : a; + } } } \ No newline at end of file diff --git a/VectoCore/Utils/SI.cs b/VectoCore/Utils/SI.cs index b5e21f5c96720378b4a1c8b7357dc1c0562747f5..78fd5de489d7ec439e15bd9a12c57f9a93d9c432 100644 --- a/VectoCore/Utils/SI.cs +++ b/VectoCore/Utils/SI.cs @@ -15,7 +15,7 @@ namespace TUGraz.VectoCore.Utils { static Newton() { - Constructors.Add(typeof (Newton), val => new Newton(val)); + Constructors.Add(typeof(Newton), val => new Newton(val)); } [JsonConstructor] @@ -31,7 +31,7 @@ namespace TUGraz.VectoCore.Utils { static Radian() { - Constructors.Add(typeof (Radian), val => new Radian(val)); + Constructors.Add(typeof(Radian), val => new Radian(val)); } [JsonConstructor] @@ -43,7 +43,7 @@ namespace TUGraz.VectoCore.Utils { static MeterPerSquareSecond() { - Constructors.Add(typeof (MeterPerSquareSecond), val => new MeterPerSquareSecond(val)); + Constructors.Add(typeof(MeterPerSquareSecond), val => new MeterPerSquareSecond(val)); } protected MeterPerSquareSecond(double val) : base(new SI(val).Meter.Per.Square.Second) {} @@ -53,7 +53,7 @@ namespace TUGraz.VectoCore.Utils { static Second() { - Constructors.Add(typeof (Second), val => new Second(val)); + Constructors.Add(typeof(Second), val => new Second(val)); } [JsonConstructor] @@ -64,7 +64,7 @@ namespace TUGraz.VectoCore.Utils { static Meter() { - Constructors.Add(typeof (Meter), val => new Meter(val)); + Constructors.Add(typeof(Meter), val => new Meter(val)); } protected Meter(double val) : base(new SI(val).Meter) {} @@ -74,7 +74,7 @@ namespace TUGraz.VectoCore.Utils { static Ton() { - Constructors.Add(typeof (Ton), val => new Ton(val)); + Constructors.Add(typeof(Ton), val => new Ton(val)); } [JsonConstructor] @@ -86,7 +86,7 @@ namespace TUGraz.VectoCore.Utils { static Kilogram() { - Constructors.Add(typeof (Kilogram), val => new Kilogram(val)); + Constructors.Add(typeof(Kilogram), val => new Kilogram(val)); } [JsonConstructor] @@ -97,7 +97,7 @@ namespace TUGraz.VectoCore.Utils { static SquareMeter() { - Constructors.Add(typeof (SquareMeter), val => new SquareMeter(val)); + Constructors.Add(typeof(SquareMeter), val => new SquareMeter(val)); } [JsonConstructor] @@ -108,7 +108,7 @@ namespace TUGraz.VectoCore.Utils { static CubicMeter() { - Constructors.Add(typeof (CubicMeter), val => new CubicMeter(val)); + Constructors.Add(typeof(CubicMeter), val => new CubicMeter(val)); } [JsonConstructor] @@ -119,7 +119,7 @@ namespace TUGraz.VectoCore.Utils { static KilogramSquareMeter() { - Constructors.Add(typeof (KilogramSquareMeter), val => new KilogramSquareMeter(val)); + Constructors.Add(typeof(KilogramSquareMeter), val => new KilogramSquareMeter(val)); } [JsonConstructor] @@ -130,7 +130,7 @@ namespace TUGraz.VectoCore.Utils { static KilogramPerWattSecond() { - Constructors.Add(typeof (KilogramPerWattSecond), val => new KilogramPerWattSecond(val)); + Constructors.Add(typeof(KilogramPerWattSecond), val => new KilogramPerWattSecond(val)); } [JsonConstructor] @@ -141,7 +141,7 @@ namespace TUGraz.VectoCore.Utils { static Watt() { - Constructors.Add(typeof (Watt), val => new Watt(val)); + Constructors.Add(typeof(Watt), val => new Watt(val)); } [JsonConstructor] @@ -162,7 +162,7 @@ namespace TUGraz.VectoCore.Utils { static PerSecond() { - Constructors.Add(typeof (PerSecond), val => new PerSecond(val)); + Constructors.Add(typeof(PerSecond), val => new PerSecond(val)); } [JsonConstructor] @@ -173,7 +173,7 @@ namespace TUGraz.VectoCore.Utils { static MeterPerSecond() { - Constructors.Add(typeof (MeterPerSecond), val => new MeterPerSecond(val)); + Constructors.Add(typeof(MeterPerSecond), val => new MeterPerSecond(val)); } [JsonConstructor] @@ -191,7 +191,7 @@ namespace TUGraz.VectoCore.Utils { static RoundsPerMinute() { - Constructors.Add(typeof (RoundsPerMinute), val => new RoundsPerMinute(val)); + Constructors.Add(typeof(RoundsPerMinute), val => new RoundsPerMinute(val)); } [JsonConstructor] @@ -203,7 +203,7 @@ namespace TUGraz.VectoCore.Utils { static NewtonMeter() { - Constructors.Add(typeof (NewtonMeter), val => new NewtonMeter(val)); + Constructors.Add(typeof(NewtonMeter), val => new NewtonMeter(val)); } [JsonConstructor] @@ -237,8 +237,8 @@ namespace TUGraz.VectoCore.Utils public static T Create(double val) { - RuntimeHelpers.RunClassConstructor(typeof (T).TypeHandle); - return Constructors[typeof (T)](val); + RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle); + return Constructors[typeof(T)](val); } protected SIBase(Type type, Func<double, T> constructor) @@ -535,12 +535,12 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// Gets the basic double value. /// </summary> - public double Double() + public double Value() { return Val; } - public SI Value() + public SI Clone() { return new SI(Val, Numerator, Denominator); } @@ -655,10 +655,6 @@ namespace TUGraz.VectoCore.Utils get { return new SI(this); } } - public SI GradientPercent - { - get { return new SI(this, factor: Math.Atan(Val) / Val, fromUnit: Unit.Percent); } - } /// <summary> /// Converts to/from Radiant @@ -971,6 +967,16 @@ namespace TUGraz.VectoCore.Utils return other != null && Val.Equals(other.Val) && HasEqualUnit(other); } + public bool IsEqual(SI si, double tolerance = DoubleExtensionMethods.Tolerance) + { + return HasEqualUnit(si) && Val.IsEqual(si.Val, tolerance); + } + + public bool IsEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsEqual(val, tolerance); + } + public override int GetHashCode() { unchecked { diff --git a/VectoCore/Utils/VectoMath.cs b/VectoCore/Utils/VectoMath.cs index 09a9a33de195a3761a0f2202047a9430d692726b..0538c4555a56c2983bed989c50f5a1842856e762 100644 --- a/VectoCore/Utils/VectoMath.cs +++ b/VectoCore/Utils/VectoMath.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace TUGraz.VectoCore.Utils { @@ -55,5 +56,33 @@ namespace TUGraz.VectoCore.Utils { return c1.CompareTo(c2) >= 0 ? c1 : c2; } + + /// <summary> + /// converts the given inclination in percent (0-1+) into Radians + /// </summary> + /// <param name="inclinationPercent"></param> + /// <returns></returns> + public static Radian InclinationToAngle(double inclinationPercent) + { + return Math.Atan(inclinationPercent).SI<Radian>(); + } + + public static List<double> QuadraticEquationSolver(double a, double b, double c) + { + var retVal = new List<double>(); + var D = b * b - 4 * a * c; + + if (D < 0) { + return retVal; + } else if (D > 0) { + // two solutions possible + retVal.Add((-b + Math.Sqrt(D)) / (2 * a)); + retVal.Add((-b - Math.Sqrt(D)) / (2 * a)); + } else { + // only one solution possible + retVal.Add((-b / (2 * a))); + } + return retVal; + } } } \ No newline at end of file diff --git a/VectoCore/VectoCore.csproj b/VectoCore/VectoCore.csproj index c61527e774ef8e409942450c1c8cf4294cd71182..a9ffb8a21c8cff079c42f4629deb47b1b4783eae 100644 --- a/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore.csproj @@ -129,13 +129,8 @@ <Compile Include="FileIO\Reader\ISimulationDataReader.cs" /> <Compile Include="FileIO\VectoFiles.cs" /> <Compile Include="Models\Connector\Ports\IDriverDemandPort.cs" /> - <Compile Include="Models\Connector\Ports\IDriverDemandProvider.cs" /> - <Compile Include="Models\Connector\Ports\IDrivingCycleDemandPort.cs" /> - <Compile Include="Models\Connector\Ports\IDrivingCycleProvider.cs" /> - <Compile Include="Models\Connector\Ports\IDrivingCycleDemandProvider.cs" /> + <Compile Include="Models\Connector\Ports\IDrivingCyclePort.cs" /> <Compile Include="Models\Connector\Ports\IResponse.cs" /> - <Compile Include="Models\Connector\Ports\IRoadPortProvider.cs" /> - <Compile Include="Models\Connector\Ports\IShaft.cs" /> <Compile Include="Models\Connector\Ports\Impl\Response.cs" /> <Compile Include="Models\Connector\Ports\IFvPort.cs" /> <Compile Include="Models\Connector\Ports\ITnPort.cs" /> @@ -156,8 +151,10 @@ <Compile Include="Models\Declaration\Mission.cs" /> <Compile Include="Models\Declaration\MissionType.cs" /> <Compile Include="Models\SimulationComponent\Data\Engine\PT1Curve.cs" /> + <Compile Include="Models\Simulation\Impl\DistanceRun.cs" /> <Compile Include="Models\Simulation\Impl\PowertrainBuilder.cs" /> <Compile Include="Utils\DataTableExtensionMethods.cs" /> + <Compile Include="Utils\EnumHelper.cs" /> <Compile Include="Utils\RessourceHelper.cs" /> <Compile Include="Models\Declaration\Segment.cs" /> <Compile Include="Models\SimulationComponent\Data\AuxiliaryCycleDataAdapter.cs" /> @@ -180,7 +177,7 @@ <Compile Include="Models\SimulationComponent\Data\VehicleData.cs" /> <Compile Include="Models\SimulationComponent\IClutch.cs" /> <Compile Include="Models\SimulationComponent\IEngineOnlyDrivingCycle.cs" /> - <Compile Include="Models\SimulationComponent\IDriverDemandDrivingCycle.cs" /> + <Compile Include="Models\SimulationComponent\IDrivingCycle.cs" /> <Compile Include="Models\SimulationComponent\IDriver.cs" /> <Compile Include="Models\SimulationComponent\Impl\MappingAuxiliary.cs" /> <Compile Include="Models\SimulationComponent\Impl\Vehicle.cs" /> @@ -203,7 +200,7 @@ <Compile Include="Models\SimulationComponent\IAuxiliary.cs" /> <Compile Include="Models\SimulationComponent\ICombustionEngine.cs" /> <Compile Include="Models\SimulationComponent\IGearbox.cs" /> - <Compile Include="Models\Connector\Ports\IDrivingCyclePort.cs" /> + <Compile Include="Models\Connector\Ports\ISimulationPort.cs" /> <Compile Include="Models\SimulationComponent\Impl\DistanceBasedDrivingCycle.cs" /> <Compile Include="Models\SimulationComponent\Impl\DirectAuxiliary.cs" /> <Compile Include="Models\SimulationComponent\Impl\TimeBasedDrivingCycle.cs" /> @@ -260,8 +257,10 @@ <EmbeddedResource Include="Resources\Declaration\VAUX\PS-Table.csv" /> <EmbeddedResource Include="Resources\Declaration\VAUX\SP-Table.csv" /> <EmbeddedResource Include="Resources\Declaration\VAUX\SP-Tech.csv" /> + <EmbeddedResource Include="Resources\Declaration\DefaultTC.vtcc" /> <None Include="Resources\Declaration\VCDV\parameters.csv" /> <EmbeddedResource Include="Resources\Declaration\WHTC-Weighting-Factors.csv" /> + <EmbeddedResource Include="Resources\Declaration\WHTC.csv" /> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. diff --git a/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs b/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs index aef1232210951a464c18f8c7daa20a6d87682291..5d1148a29280adcbb58e91339d0a24c1566287ba 100644 --- a/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs +++ b/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs @@ -34,15 +34,15 @@ namespace TUGraz.VectoCore.Tests.Integration.EngineOnlyCycle var engine = new CombustionEngine(vehicle, engineData); - aux.InShaft().Connect(engine.OutShaft()); - gearbox.InShaft().Connect(aux.OutShaft()); - var port = aux.OutShaft(); + aux.InPort().Connect(engine.OutPort()); + gearbox.InPort().Connect(aux.OutPort()); + var port = aux.OutPort(); // IVectoJob job = SimulationFactory.CreateTimeBasedEngineOnlyRun(TestContext.DataRow["EngineFile"].ToString(), // TestContext.DataRow["CycleFile"].ToString(), "test2.csv"); - var absTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0); - var dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); var dataWriter = new TestModalDataWriter(); @@ -98,15 +98,15 @@ namespace TUGraz.VectoCore.Tests.Integration.EngineOnlyCycle var engine = new CombustionEngine(vehicleContainer, EngineeringModeSimulationDataReader.CreateEngineDataFromFile(EngineFile)); - gearbox.InShaft().Connect(engine.OutShaft()); + gearbox.InPort().Connect(engine.OutPort()); - var absTime = new TimeSpan(); - var dt = TimeSpan.FromSeconds(1); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); var angularVelocity = 644.4445.RPMtoRad(); var power = 2329.973.SI<Watt>(); - gearbox.OutShaft().Request(absTime, dt, Formulas.PowerToTorque(power, angularVelocity), angularVelocity); + gearbox.OutPort().Request(absTime, dt, Formulas.PowerToTorque(power, angularVelocity), angularVelocity); foreach (var sc in vehicleContainer.SimulationComponents()) { sc.CommitSimulationStep(dataWriter); diff --git a/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs b/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs new file mode 100644 index 0000000000000000000000000000000000000000..89c6c41155db10326c4f255c2b32f6bd4706a975 --- /dev/null +++ b/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCore.FileIO.Reader.Impl; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Declaration; +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.Tests.Utils; +using TUGraz.VectoCore.Utils; +using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; + +namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns +{ + [TestClass] + public class MinimalPowertrain + { + public const string CycleFile = @"TestData\Cycles\Coach_24t_xshort.vdri"; + public const string EngineFile = @"TestData\Components\24t Coach.veng"; + + [TestMethod] + public void TestWheelsAndEngine() + { + var engineData = EngineeringModeSimulationDataReader.CreateEngineDataFromFile(EngineFile); + var cycleData = DrivingCycleData.ReadFromFileDistanceBased(CycleFile); + + var vehicleData = new VehicleData() { + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + CrossSectionArea = 0.SI<SquareMeter>(), + CrossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection, + CurbWeight = 1000.SI<Kilogram>(), + CurbWeigthExtra = 0.SI<Kilogram>(), + Loading = 0.SI<Kilogram>(), + DynamicTyreRadius = 0.56.SI<Meter>(), + Retarder = new RetarderData() { Type = RetarderData.RetarderType.None }, + AxleData = new List<Axle>(), + SavedInDeclarationMode = false, + }; + + var vehicleContainer = new VehicleContainer(); + + var cycle = new DistanceBasedDrivingCycle(vehicleContainer, cycleData); + + dynamic tmp = AddComponent(cycle, new MockDriver(vehicleContainer)); + tmp = AddComponent(tmp, new Vehicle(vehicleContainer, vehicleData)); + tmp = AddComponent(tmp, new Wheels(vehicleContainer, vehicleData.DynamicTyreRadius)); + AddComponent(tmp, new CombustionEngine(vehicleContainer, engineData)); + + var run = new DistanceRun(vehicleContainer); + + run.Run(); + } + + + // ======================== + + 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 void 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/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs b/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs index f8babfb301d8c82ff54e57a7b21fb2ed5c0a5d5f..63d229b29581f37a74f1cac4f7686a5c545fd305 100644 --- a/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs +++ b/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs @@ -24,8 +24,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var tmp = wheels.Lookup("285/70 R19.5"); - Assert.AreEqual(7.9, tmp.Inertia.Double(), Tolerance); - Assert.AreEqual(0.8943, tmp.DynamicTyreRadius.Double(), Tolerance); + Assert.AreEqual(7.9, tmp.Inertia.Value(), Tolerance); + Assert.AreEqual(0.8943, tmp.DynamicTyreRadius.Value(), Tolerance); Assert.AreEqual("b", tmp.SizeClass); } @@ -46,31 +46,31 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var pt1 = DeclarationData.PT1; // FIXED POINTS - Assert.AreEqual(0, pt1.Lookup(400.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.47, pt1.Lookup(800.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.58, pt1.Lookup(1000.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.53, pt1.Lookup(1200.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.46, pt1.Lookup(1400.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.43, pt1.Lookup(1500.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.22, pt1.Lookup(1750.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.2, pt1.Lookup(1800.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.11, pt1.Lookup(2000.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.11, pt1.Lookup(2500.RPMtoRad()).Double(), Tolerance); + Assert.AreEqual(0, pt1.Lookup(400.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.47, pt1.Lookup(800.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.58, pt1.Lookup(1000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.53, pt1.Lookup(1200.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.46, pt1.Lookup(1400.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.43, pt1.Lookup(1500.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.22, pt1.Lookup(1750.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.2, pt1.Lookup(1800.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.11, pt1.Lookup(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.11, pt1.Lookup(2500.RPMtoRad()).Value(), Tolerance); // INTERPOLATE - Assert.AreEqual(0.235, pt1.Lookup(600.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.525, pt1.Lookup(900.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.555, pt1.Lookup(1100.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.495, pt1.Lookup(1300.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.445, pt1.Lookup(1450.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.325, pt1.Lookup(1625.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.21, pt1.Lookup(1775.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.155, pt1.Lookup(1900.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.11, pt1.Lookup(2250.RPMtoRad()).Double(), Tolerance); + Assert.AreEqual(0.235, pt1.Lookup(600.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.525, pt1.Lookup(900.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.555, pt1.Lookup(1100.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.495, pt1.Lookup(1300.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.445, pt1.Lookup(1450.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.325, pt1.Lookup(1625.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.21, pt1.Lookup(1775.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.155, pt1.Lookup(1900.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.11, pt1.Lookup(2250.RPMtoRad()).Value(), Tolerance); // EXTRAPOLATE - Assert.AreEqual(0.11, pt1.Lookup(3000.RPMtoRad()).Double(), Tolerance); + Assert.AreEqual(0.11, pt1.Lookup(3000.RPMtoRad()).Value(), Tolerance); AssertHelper.Exception<VectoException>(() => pt1.Lookup(200.RPMtoRad())); AssertHelper.Exception<VectoException>(() => pt1.Lookup(0.RPMtoRad())); } @@ -139,8 +139,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var baseConsumption = es.Lookup(expectation.Mission, technologies: new string[] { }); var leds = es.Lookup(expectation.Mission, technologies: new[] { "LED lights" }); - Assert.AreEqual(expectation.Base, baseConsumption.Double(), Tolerance); - Assert.AreEqual(expectation.LED, leds.Double(), Tolerance); + Assert.AreEqual(expectation.Base, baseConsumption.Value(), Tolerance); + Assert.AreEqual(expectation.LED, leds.Value(), Tolerance); } } @@ -190,12 +190,12 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration for (var i = 0; i < missions.Length; i++) { // default tech Watt defaultValue = fan.Lookup(missions[i], ""); - Assert.AreEqual(expected[defaultFan][i], defaultValue.Double(), Tolerance); + Assert.AreEqual(expected[defaultFan][i], defaultValue.Value(), Tolerance); // all fan techs foreach (var expect in expected) { Watt value = fan.Lookup(missions[i], expect.Key); - Assert.AreEqual(expect.Value[i], value.Double(), Tolerance); + Assert.AreEqual(expect.Value[i], value.Value(), Tolerance); } } } @@ -223,7 +223,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration for (var i = 0; i < missions.Length; i++) { foreach (var expect in expected) { Watt value = hvac.Lookup(missions[i], expect.Key); - Assert.AreEqual(expect.Value[i], value.Double(), Tolerance); + Assert.AreEqual(expect.Value[i], value.Value(), Tolerance); } } } @@ -251,7 +251,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration for (var i = 0; i < missions.Length; i++) { foreach (var expect in expected) { Watt value = ps.Lookup(missions[i], expect.Key); - Assert.AreEqual(expect.Value[i], value.Double(), Tolerance); + Assert.AreEqual(expect.Value[i], value.Value(), Tolerance); } } } @@ -310,7 +310,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var hdvClass = hdvClasses.Key; for (var i = 0; i < missions.Length; i++) { Watt value = sp.Lookup(missions[i], hdvClass, technology); - Assert.AreEqual(hdvClasses.Value[i], value.Double(), Tolerance); + Assert.AreEqual(hdvClasses.Value[i], value.Value(), Tolerance); } } } @@ -412,7 +412,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration // var gearboxData = factory.ReadGearboxData(job.GearboxFile); // var gearbox = new Gearbox(container, gearboxData); - // gearbox.InShaft().Connect(engine.OutShaft()); + // gearbox.InPort().Connect(engine.OutPort()); // // todo axleGear @@ -424,11 +424,11 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration // var driverData = new DriverData(); // var driver = new Driver(driverData); - // driver.InShaft().Connect(vehicle.OutShaft()); + // driver.InPort().Connect(vehicle.OutPort()); // var cycleData = DrivingCycleData.ReadFromFileEngineOnly(mission.CycleFile); - // var cycle = new DistanceBasedDrivingCycle(container, cycleData); - // cycle.InShaft().Connect(driver.OutShaft()); + // var cycle = new DistanceBasedSimulation(container, cycleData); + // cycle.InPort().Connect(driver.OutPort()); // var simulator = new VectoRun(container, cycle); // runs.Add(simulator); @@ -439,8 +439,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration public void EqualAcceleration(AccelerationCurveData data, double velocity, double acceleration, double deceleration) { var entry = data.Lookup(velocity.SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>()); - Assert.AreEqual(entry.Acceleration.Double(), acceleration, Tolerance); - Assert.AreEqual(entry.Deceleration.Double(), deceleration, Tolerance); + Assert.AreEqual(entry.Acceleration.Value(), acceleration, Tolerance); + Assert.AreEqual(entry.Deceleration.Value(), deceleration, Tolerance); } public void TestAcceleration(AccelerationCurveData data) diff --git a/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs b/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs index 8937390ef9fbe32cdaeecd696fab71333952df47..25b0266dbd856c7f08be5f698dd62091495f8216 100644 --- a/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs +++ b/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs @@ -20,22 +20,22 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var container = new VehicleContainer(dataWriter, sumWriter); var cycleData = DrivingCycleData.ReadFromFileEngineOnly(@"TestData\Cycles\Coach Engine Only.vdri"); - var cycle = new EngineOnlyDrivingCycle(container, cycleData); + var cycle = new EngineOnlySimulation(container, cycleData); var outPort = new MockTnOutPort(); - var inPort = cycle.InShaft(); - var cycleOut = cycle.OutShaft(); + var inPort = cycle.InPort(); + var cycleOut = cycle.OutPort(); inPort.Connect(outPort); - var absTime = new TimeSpan(); - var dt = TimeSpan.FromSeconds(1); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); var response = cycleOut.Request(absTime, dt); Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - var time = (absTime + TimeSpan.FromTicks(dt.Ticks / 2)).TotalSeconds; - var simulationInterval = dt.TotalSeconds; + var time = absTime + dt / 2; + var simulationInterval = dt; container.CommitSimulationStep(time, simulationInterval); Assert.AreEqual(absTime, outPort.AbsTime); @@ -50,25 +50,25 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var container = new VehicleContainer(); var cycleData = DrivingCycleData.ReadFromFileEngineOnly(@"TestData\Cycles\Coach Engine Only Paux_var-dt.vdri"); - var cycle = new EngineOnlyDrivingCycle(container, cycleData); + var cycle = new EngineOnlySimulation(container, cycleData); var outPort = new MockTnOutPort(); - var inPort = cycle.InShaft(); + var inPort = cycle.InPort(); inPort.Connect(outPort); - var absTime = TimeSpan.FromSeconds(10); - var dt = TimeSpan.FromSeconds(1); + var absTime = 10.SI<Second>(); + var dt = 1.SI<Second>(); - var response = cycle.OutShaft().Request(absTime, dt); + var response = cycle.OutPort().Request(absTime, dt); Assert.IsInstanceOfType(response, typeof(ResponseFailTimeInterval)); - dt = TimeSpan.FromSeconds(0.25); - response = cycle.OutShaft().Request(absTime, dt); + dt = 0.25.SI<Second>(); + response = cycle.OutPort().Request(absTime, dt); Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); var dataWriter = new TestModalDataWriter(); - container.CommitSimulationStep(absTime.TotalSeconds, dt.TotalSeconds); + container.CommitSimulationStep(absTime, dt); Assert.AreEqual(absTime, outPort.AbsTime); Assert.AreEqual(dt, outPort.Dt); @@ -77,19 +77,19 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation // ======================== - dt = TimeSpan.FromSeconds(1); - absTime = TimeSpan.FromSeconds(500); - response = cycle.OutShaft().Request(absTime, dt); + dt = 1.SI<Second>(); + absTime = 500.SI<Second>(); + response = cycle.OutPort().Request((Second)absTime, (Second)dt); Assert.IsInstanceOfType(response, typeof(ResponseFailTimeInterval)); - dt = TimeSpan.FromSeconds(0.25); + dt = 0.25.SI<Second>(); for (int i = 0; i < 2; i++) { - response = cycle.OutShaft().Request(absTime, dt); + response = cycle.OutPort().Request((Second)absTime, (Second)dt); Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); dataWriter = new TestModalDataWriter(); - container.CommitSimulationStep(absTime.TotalSeconds, dt.TotalSeconds); + container.CommitSimulationStep(absTime, dt); Assert.AreEqual(absTime, outPort.AbsTime); Assert.AreEqual(dt, outPort.Dt); @@ -111,23 +111,23 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var cycleData = DrivingCycleData.ReadFromFileTimeBased(@"TestData\Cycles\Coach First Cycle only.vdri"); var cycle = new TimeBasedDrivingCycle(container, cycleData); - var outPort = new MockDrivingCycleDemandOutPort(); + var outPort = new MockDrivingCycleOutPort(); - var inPort = cycle.InShaft(); - var cycleOut = cycle.OutShaft(); + var inPort = cycle.InPort(); + var cycleOut = cycle.OutPort(); inPort.Connect(outPort); - var absTime = new TimeSpan(); - var dt = TimeSpan.FromSeconds(1); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); var response = cycleOut.Request(absTime, dt); Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); Assert.AreEqual(absTime, outPort.AbsTime); - Assert.AreEqual(dt, outPort.Dt); + //Assert.AreEqual(dt, outPort.Ds); Assert.AreEqual(0.SI<MeterPerSecond>(), outPort.Velocity); - Assert.AreEqual((-0.020237973).SI().GradientPercent.Cast<Radian>(), outPort.Gradient); + Assert.AreEqual(-0.000202379727237.SI<Radian>().Value(), outPort.Gradient.Value(), 1E-15); } [TestMethod] @@ -138,23 +138,23 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var cycleData = DrivingCycleData.ReadFromFileTimeBased(@"TestData\Cycles\Cycle time field missing.vdri"); var cycle = new TimeBasedDrivingCycle(container, cycleData); - var outPort = new MockDrivingCycleDemandOutPort(); + var outPort = new MockDrivingCycleOutPort(); - var inPort = cycle.InShaft(); - var cycleOut = cycle.OutShaft(); + var inPort = cycle.InPort(); + var cycleOut = cycle.OutPort(); inPort.Connect(outPort); var dataWriter = new TestModalDataWriter(); - var absTime = new TimeSpan(); - var dt = TimeSpan.FromSeconds(1); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); while (cycleOut.Request(absTime, dt) is ResponseSuccess) { Assert.AreEqual(absTime, outPort.AbsTime); - Assert.AreEqual(dt, outPort.Dt); + Assert.AreEqual(dt, outPort.Ds); - var time = (absTime + TimeSpan.FromTicks(dt.Ticks / 2)).TotalSeconds; - var simulationInterval = dt.TotalSeconds; + var time = absTime + dt / 2; + var simulationInterval = dt; container.CommitSimulationStep(time, simulationInterval); absTime += dt; diff --git a/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs b/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs index 66d3a71c4c83821964084c278a181d99d34b2f91..964f96cb773f009669d72aee19fc35d63513c479 100644 --- a/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs @@ -24,33 +24,33 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var clutch = new Clutch(vehicle, engineData); - var inPort = clutch.InShaft(); + var inPort = clutch.InPort(); var outPort = new MockTnOutPort(); inPort.Connect(outPort); - var clutchOutPort = clutch.OutShaft(); + var clutchOutPort = clutch.OutPort(); //Test - Clutch slipping gearbox.CurrentGear = 1; - clutchOutPort.Request(new TimeSpan(), new TimeSpan(), 100.SI<NewtonMeter>(), 30.SI<PerSecond>()); + clutchOutPort.Request(0.SI<Second>(), 0.SI<Second>(), 100.SI<NewtonMeter>(), 30.SI<PerSecond>()); - Assert.AreEqual(48.293649, (double) outPort.Torque, 0.001); - Assert.AreEqual(62.119969, (double) outPort.AngularVelocity, 0.001); + Assert.AreEqual(48.293649, (double)outPort.Torque, 0.001); + Assert.AreEqual(62.119969, (double)outPort.AngularVelocity, 0.001); //Test - Clutch opened gearbox.CurrentGear = 0; - clutchOutPort.Request(new TimeSpan(), new TimeSpan(), 100.SI<NewtonMeter>(), 30.SI<PerSecond>()); + clutchOutPort.Request(0.SI<Second>(), 0.SI<Second>(), 100.SI<NewtonMeter>(), 30.SI<PerSecond>()); - Assert.AreEqual(0, (double) outPort.Torque, 0.001); - Assert.AreEqual((double) engineData.IdleSpeed, (double) outPort.AngularVelocity, 0.001); + Assert.AreEqual(0, (double)outPort.Torque, 0.001); + Assert.AreEqual((double)engineData.IdleSpeed, (double)outPort.AngularVelocity, 0.001); //Test - Clutch closed gearbox.CurrentGear = 1; - clutchOutPort.Request(new TimeSpan(), new TimeSpan(), 100.SI<NewtonMeter>(), 80.SI<PerSecond>()); + clutchOutPort.Request(0.SI<Second>(), 0.SI<Second>(), 100.SI<NewtonMeter>(), 80.SI<PerSecond>()); - Assert.AreEqual(100.0, (double) outPort.Torque, 0.001); - Assert.AreEqual(80.0, (double) outPort.AngularVelocity, 0.001); + Assert.AreEqual(100.0, (double)outPort.Torque, 0.001); + Assert.AreEqual(80.0, (double)outPort.AngularVelocity, 0.001); } } } \ No newline at end of file diff --git a/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs b/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs index d94e883ceb8aa3e21f3e81a9116378e8efe995ac..59edcaf7f454834c2d1e4d9de0bc66d83a8ea26e 100644 --- a/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs @@ -36,7 +36,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent { try { func(); - Assert.Fail("Expected Exception {0}, but no exception occured.", typeof (T)); + Assert.Fail("Expected Exception {0}, but no exception occured.", typeof(T)); } catch (T ex) { if (message != null) { Assert.AreEqual(message, ex.Message); @@ -51,7 +51,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var engineData = EngineeringModeSimulationDataReader.CreateEngineDataFromFile(CoachEngine); var engine = new CombustionEngine(vehicle, engineData); - var port = engine.OutShaft(); + var port = engine.OutPort(); Assert.IsNotNull(port); } @@ -64,10 +64,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent new EngineOnlyGearbox(vehicle); - var port = engine.OutShaft(); + var port = engine.OutPort(); - var absTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0); - var dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); var torque = 400.SI<NewtonMeter>(); var engineSpeed = 1500.RPMtoRad(); @@ -81,10 +81,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var engineData = EngineeringModeSimulationDataReader.CreateEngineDataFromFile(CoachEngine); var engine = new CombustionEngine(vehicle, engineData); var gearbox = new EngineOnlyGearbox(vehicle); - var port = engine.OutShaft(); + var port = engine.OutPort(); - var absTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0); - var dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); var torque = 0.SI<NewtonMeter>(); var engineSpeed = 600.RPMtoRad(); @@ -150,11 +150,11 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent TestContext.DataRow["EngineFile"].ToString()); var engine = new CombustionEngine(vehicleContainer, engineData); - gearbox.InShaft().Connect(engine.OutShaft()); + gearbox.InPort().Connect(engine.OutPort()); var expectedResults = VectoCSVFile.Read(TestContext.DataRow["ResultFile"].ToString()); - var requestPort = gearbox.OutShaft(); + var requestPort = gearbox.OutPort(); //var modalData = new ModalDataWriter(string.Format("load_jump_{0}.csv", TestContext.DataRow["TestName"].ToString())); var modalData = new TestModalDataWriter(); @@ -163,10 +163,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var angularSpeed = Double.Parse(TestContext.DataRow["rpm"].ToString()).RPMtoRad(); - var t = TimeSpan.FromSeconds(0); - var dt = TimeSpan.FromSeconds(0.1); + var t = 0.SI<Second>(); + var dt = 0.1.SI<Second>(); - for (; t.TotalSeconds < 2; t += dt) { + for (; t < 2; t += dt) { requestPort.Request(t, dt, Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); engine.CommitSimulationStep(modalData); } @@ -176,17 +176,17 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent // dt = TimeSpan.FromSeconds(expectedResults.Rows[i].ParseDouble(0)) - t; var engineLoadPower = engineData.GetFullLoadCurve(0).FullLoadStationaryPower(angularSpeed); idlePower = Double.Parse(TestContext.DataRow["finalIdleLoad"].ToString()).SI<Watt>(); - for (; t.TotalSeconds < 25; t += dt, i++) { - dt = TimeSpan.FromSeconds(expectedResults.Rows[i + 1].ParseDouble(0) - expectedResults.Rows[i].ParseDouble(0)); - if (t >= TimeSpan.FromSeconds(10)) { + 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.TotalSeconds; - modalData[ModalResultField.simulationInterval] = dt.TotalSeconds; + modalData[ModalResultField.time] = t.Value(); + modalData[ModalResultField.simulationInterval] = dt.Value(); engine.CommitSimulationStep(modalData); // todo: compare results... - Assert.AreEqual(expectedResults.Rows[i].ParseDouble(0), t.TotalSeconds, 0.001, "Time"); + Assert.AreEqual(expectedResults.Rows[i].ParseDouble(0), t.Value(), 0.001, "Time"); Assert.AreEqual(expectedResults.Rows[i].ParseDouble(1), modalData.GetDouble(ModalResultField.Pe_full), 0.1, String.Format("Load in timestep {0}", t)); modalData.CommitSimulationStep(); @@ -210,27 +210,27 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent { var engineData = EngineeringModeSimulationDataReader.CreateEngineDataFromFile(CoachEngine); var motorway = engineData.WHTCMotorway; - Assert.AreEqual(motorway.Double(), 0); + Assert.AreEqual(motorway.Value(), 0); Assert.IsTrue(motorway.HasEqualUnit(new SI().Kilo.Gramm.Per.Watt.Second.ConvertTo())); var rural = engineData.WHTCRural; - Assert.AreEqual(rural.Double(), 0); + Assert.AreEqual(rural.Value(), 0); Assert.IsTrue(rural.HasEqualUnit(new SI().Kilo.Gramm.Per.Watt.Second.ConvertTo())); var urban = engineData.WHTCUrban; - Assert.AreEqual(urban.Double(), 0); + Assert.AreEqual(urban.Value(), 0); Assert.IsTrue(urban.HasEqualUnit(new SI().Kilo.Gramm.Per.Watt.Second.ConvertTo())); var displace = engineData.Displacement; - Assert.AreEqual(0.01273, displace.Double()); + Assert.AreEqual(0.01273, displace.Value()); Assert.IsTrue(displace.HasEqualUnit(new SI().Cubic.Meter)); var inert = engineData.Inertia; - Assert.AreEqual(3.8, inert.Double(), 0.00001); + 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.Double(), 0.000001); + Assert.AreEqual(58.6430628670095, idle.Value(), 0.000001); Assert.IsTrue(idle.HasEqualUnit(0.SI<PerSecond>())); var flc0 = engineData.GetFullLoadCurve(0); diff --git a/VectoCoreTest/Models/SimulationComponent/DistanceBasedDrivingCycleTest.cs b/VectoCoreTest/Models/SimulationComponent/DistanceBasedDrivingCycleTest.cs new file mode 100644 index 0000000000000000000000000000000000000000..e6185d855d03df7d8f7d3bb9e175a8389318c1bb --- /dev/null +++ b/VectoCoreTest/Models/SimulationComponent/DistanceBasedDrivingCycleTest.cs @@ -0,0 +1,101 @@ +using System; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCore.Exceptions; +using TUGraz.VectoCore.FileIO.Reader.Impl; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponent +{ + [TestClass] + public class DistanceBasedDrivingCycleTest + { + public const string ShortCycle = @"TestData\Cycles\Coach_24t_xshort.vdri"; + + public const double Tolerance = 0.0001; + + [TestMethod] + public void TestDistanceRequest() + { + var cycleData = DrivingCycleData.ReadFromFile(ShortCycle, DrivingCycleData.CycleType.DistanceBased); + + var vehicleContainer = new VehicleContainer(); + var cycle = new DistanceBasedDrivingCycle(vehicleContainer, cycleData); + + var driver = new MockDriver(vehicleContainer); + cycle.InPort().Connect(driver.OutPort()); + + cycle.OutPort().Initialize(); + + var startDistance = cycleData.Entries.First().Distance.Value(); + var absTime = 0.SI<Second>(); + var response = cycle.OutPort().Request(absTime, 1.SI<Meter>()); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + + Assert.AreEqual(0, driver.LastRequest.TargetVelocity.Value(), Tolerance); + Assert.AreEqual(0.028416069495827, driver.LastRequest.Gradient.Value(), 1E-12); + Assert.AreEqual(40, driver.LastRequest.dt.Value(), Tolerance); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + + + response = cycle.OutPort().Request((Second)absTime, 1.SI<Meter>()); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + + Assert.AreEqual(5.SI<MeterPerSecond>().Value(), driver.LastRequest.TargetVelocity.Value(), Tolerance); + Assert.AreEqual(0.02667562971628240, driver.LastRequest.Gradient.Value(), 1E-12); + Assert.AreEqual(1 + startDistance, cycle.CurrentState.Distance.Value(), Tolerance); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + + + response = cycle.OutPort().Request((Second)absTime, 1.SI<Meter>()); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + + Assert.AreEqual(5.SI<MeterPerSecond>().Value(), driver.LastRequest.TargetVelocity.Value(), Tolerance); + Assert.AreEqual(0.02667562971628240, driver.LastRequest.Gradient.Value(), 1E-12); + Assert.AreEqual(2 + startDistance, cycle.CurrentState.Distance.Value(), Tolerance); + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + + + response = cycle.OutPort().Request((Second)absTime, 300.SI<Meter>()); + + Assert.IsInstanceOfType(response, typeof(ResponseDrivingCycleDistanceExceeded)); + var tmp = response as ResponseDrivingCycleDistanceExceeded; + Assert.AreEqual(36, tmp.MaxDistance.Value(), Tolerance); + + Assert.AreEqual(5.SI<MeterPerSecond>().Value(), driver.LastRequest.TargetVelocity.Value(), Tolerance); + Assert.AreEqual(0.02667562971628240, driver.LastRequest.Gradient.Value(), 1E-12); + Assert.AreEqual(2 + startDistance, cycle.CurrentState.Distance.Value(), Tolerance); + + try { + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + Assert.Fail(); + } catch (VectoSimulationException e) { + Assert.AreEqual("Previous request did not succeed!", e.Message); + } + response = cycle.OutPort().Request((Second)absTime, tmp.MaxDistance); + + Assert.AreEqual(5.SI<MeterPerSecond>().Value(), driver.LastRequest.TargetVelocity.Value(), Tolerance); + Assert.AreEqual(0.02667562971628240, driver.LastRequest.Gradient.Value(), 1E-12); + Assert.AreEqual(38 + startDistance, cycle.CurrentState.Distance.Value(), Tolerance); + + + vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + } + } +} \ No newline at end of file diff --git a/VectoCoreTest/Models/SimulationComponent/DriverTest.cs b/VectoCoreTest/Models/SimulationComponent/DriverTest.cs new file mode 100644 index 0000000000000000000000000000000000000000..410e35fa7fe45c003af1f102d04601c8afc4f5c6 --- /dev/null +++ b/VectoCoreTest/Models/SimulationComponent/DriverTest.cs @@ -0,0 +1,144 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCore.FileIO.Reader.Impl; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponent +{ + [TestClass] + public class DriverTest + { + public const string JobFile = @"TestData\Jobs\24t Coach.vecto"; + + public const double Tolerance = 0.001; + + [TestMethod] + public void DriverAccelerationTest() + { + var vehicleContainer = new VehicleContainer(); + var vehicle = new MockVehicle(vehicleContainer); + + var driverData = EngineeringModeSimulationDataReader.CreateDriverDataFromFile(JobFile); + var driver = new Driver(vehicleContainer, driverData); + + 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(); + var vehicle = new MockVehicle(vehicleContainer); + + var driverData = EngineeringModeSimulationDataReader.CreateDriverDataFromFile(JobFile); + var driver = new Driver(vehicleContainer, driverData); + + 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); + } + } +} \ No newline at end of file diff --git a/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs b/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs index c8922b7c49bac3a69481b85cd0a26a1bdddc1d7d..1b93b951bb9d547e7710916af0cc0bba576bc661 100644 --- a/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs @@ -25,10 +25,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var axleGear = new AxleGear(vehicle, gbxData.AxleGearData); var mockPort = new MockTnOutPort(); - axleGear.InShaft().Connect(mockPort); + axleGear.InPort().Connect(mockPort); - var absTime = TimeSpan.FromSeconds(0); - var dt = TimeSpan.FromSeconds(1); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); var rdyn = 520; var speed = 20.320; @@ -45,11 +45,11 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var loss = 9401.44062.SI<Watt>(); - Assert.AreEqual(Formulas.PowerToTorque(PvD + loss, angSpeed * gbxData.AxleGearData.Ratio).Double(), - mockPort.Torque.Double(), 0.01, + Assert.AreEqual(Formulas.PowerToTorque(PvD + loss, angSpeed * gbxData.AxleGearData.Ratio).Value(), + mockPort.Torque.Value(), 0.01, "Torque Engine Side") ; - Assert.AreEqual((angSpeed * gbxData.AxleGearData.Ratio).Double(), mockPort.AngularVelocity.Double(), 0.01, + Assert.AreEqual((angSpeed * gbxData.AxleGearData.Ratio).Value(), mockPort.AngularVelocity.Value(), 0.01, "Torque Engine Side"); } diff --git a/VectoCoreTest/Models/SimulationComponent/RetarderTest.cs b/VectoCoreTest/Models/SimulationComponent/RetarderTest.cs index 281c443f8edce7e245b7813092a6cd5bbce0bfe0..0adcb3e64171a6bb6b1e1e11225d96c4c8894c8d 100644 --- a/VectoCoreTest/Models/SimulationComponent/RetarderTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/RetarderTest.cs @@ -23,29 +23,29 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var nextRequest = new MockTnOutPort(); - retarder.InShaft().Connect(nextRequest); - var outPort = retarder.OutShaft(); + retarder.InPort().Connect(nextRequest); + var outPort = retarder.OutPort(); - var absTime = TimeSpan.FromSeconds(0); - var dt = TimeSpan.FromSeconds(0); + var absTime = 0.SI<Second>(); + var dt = 0.SI<Second>(); // -------- outPort.Request(absTime, dt, 0.SI<NewtonMeter>(), 10.RPMtoRad()); - Assert.AreEqual(10.RPMtoRad().Double(), (double)nextRequest.AngularVelocity, Delta); + Assert.AreEqual(10.RPMtoRad().Value(), (double)nextRequest.AngularVelocity, Delta); Assert.AreEqual(10.002, (double)nextRequest.Torque, Delta); // -------- outPort.Request(absTime, dt, 100.SI<NewtonMeter>(), 1000.RPMtoRad()); - Assert.AreEqual(1000.RPMtoRad().Double(), (double)nextRequest.AngularVelocity, Delta); + Assert.AreEqual(1000.RPMtoRad().Value(), (double)nextRequest.AngularVelocity, Delta); Assert.AreEqual(112, (double)nextRequest.Torque, Delta); // -------- outPort.Request(absTime, dt, 50.SI<NewtonMeter>(), 1550.RPMtoRad()); - Assert.AreEqual(1550.RPMtoRad().Double(), (double)nextRequest.AngularVelocity, Delta); + Assert.AreEqual(1550.RPMtoRad().Value(), (double)nextRequest.AngularVelocity, Delta); Assert.AreEqual(50 + 14.81, (double)nextRequest.Torque, Delta); } } diff --git a/VectoCoreTest/Models/SimulationComponent/VehicleTest.cs b/VectoCoreTest/Models/SimulationComponent/VehicleTest.cs index ba91afff4bc0cab54ac3d23b84279781400cb595..b046f240518a452273cee0b9de8d299cc3a21684 100644 --- a/VectoCoreTest/Models/SimulationComponent/VehicleTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/VehicleTest.cs @@ -28,18 +28,18 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent vehicle.InPort().Connect(mockPort); - var requestPort = vehicle.OutShaft(); + var requestPort = vehicle.OutPort(); - var absTime = TimeSpan.FromSeconds(0); - var dt = TimeSpan.FromSeconds(1); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); var accell = -0.256231159.SI<MeterPerSquareSecond>(); var gradient = Math.Atan(0.00366547048).SI<Radian>(); var retVal = requestPort.Request(absTime, dt, accell, gradient); - Assert.AreEqual(-2549.07832743748, mockPort.Force.Double(), 0.0001); - Assert.AreEqual(17.0824194205, mockPort.Velocity.Double(), 0.0001); + Assert.AreEqual(-2549.07832743748, mockPort.Force.Value(), 0.0001); + Assert.AreEqual(17.0824194205, mockPort.Velocity.Value(), 0.0001); } } } \ No newline at end of file diff --git a/VectoCoreTest/Models/SimulationComponent/WheelsTest.cs b/VectoCoreTest/Models/SimulationComponent/WheelsTest.cs index 6898e6f147ff7002d9a6a933f9a95cfd853d855c..b5176c1f8835c2785d19aeb799aa20564373f3d8 100644 --- a/VectoCoreTest/Models/SimulationComponent/WheelsTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/WheelsTest.cs @@ -24,20 +24,20 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent IWheels wheels = new Wheels(container, vehicleData.DynamicTyreRadius); var mockPort = new MockTnOutPort(); - wheels.InShaft().Connect(mockPort); + wheels.InPort().Connect(mockPort); var requestPort = wheels.OutPort(); - var absTime = TimeSpan.FromSeconds(0); - var dt = TimeSpan.FromSeconds(1); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); var force = 5000.SI<Newton>(); var velocity = 20.SI<MeterPerSecond>(); var retVal = requestPort.Request(absTime, dt, force, velocity); - Assert.AreEqual(2600.0, mockPort.Torque.Double(), 0.0001); - Assert.AreEqual(38.4615384615, mockPort.AngularVelocity.Double(), 0.0001); + Assert.AreEqual(2600.0, mockPort.Torque.Value(), 0.0001); + Assert.AreEqual(38.4615384615, mockPort.AngularVelocity.Value(), 0.0001); } } } \ No newline at end of file diff --git a/VectoCoreTest/Models/SimulationComponentData/AccelerationCurveTest.cs b/VectoCoreTest/Models/SimulationComponentData/AccelerationCurveTest.cs index 7519b6863fc4fdd98f69560d2a5adf84153b4555..8b4a72ee2c626628be489104f47a4e7730f14b1c 100644 --- a/VectoCoreTest/Models/SimulationComponentData/AccelerationCurveTest.cs +++ b/VectoCoreTest/Models/SimulationComponentData/AccelerationCurveTest.cs @@ -13,8 +13,8 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData public void EqualAcceleration(double velocity, double acceleration, double deceleration) { var entry = Data.Lookup(velocity.SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>()); - Assert.AreEqual(entry.Acceleration.Double(), acceleration, Tolerance); - Assert.AreEqual(entry.Deceleration.Double(), deceleration, Tolerance); + Assert.AreEqual(entry.Acceleration.Value(), acceleration, Tolerance); + Assert.AreEqual(entry.Deceleration.Value(), deceleration, Tolerance); } [TestMethod] diff --git a/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs b/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs index 6fd37e3f8da440676134d7f94abe2685916bf337..79d610acec527ff143eb1946bd2cfd006d825338 100644 --- a/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs +++ b/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs @@ -17,9 +17,9 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData { var fldCurve = FullLoadCurve.ReadFromFile(CoachEngineFLD); - Assert.AreEqual(1180, fldCurve.FullLoadStationaryTorque(560.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(1352, fldCurve.FullLoadStationaryTorque(2000.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(1231, fldCurve.FullLoadStationaryTorque(580.RPMtoRad()).Double(), Tolerance); + Assert.AreEqual(1180, fldCurve.FullLoadStationaryTorque(560.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(1352, fldCurve.FullLoadStationaryTorque(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(1231, fldCurve.FullLoadStationaryTorque(580.RPMtoRad()).Value(), Tolerance); } [TestMethod] @@ -34,9 +34,9 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData { var fldCurve = FullLoadCurve.ReadFromFile(CoachEngineFLD); - Assert.AreEqual(69198.814183, fldCurve.FullLoadStationaryPower(560.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(283162.218372, fldCurve.FullLoadStationaryPower(2000.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(74767.810760, fldCurve.FullLoadStationaryPower(580.RPMtoRad()).Double(), Tolerance); + Assert.AreEqual(69198.814183, fldCurve.FullLoadStationaryPower(560.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(283162.218372, fldCurve.FullLoadStationaryPower(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(74767.810760, fldCurve.FullLoadStationaryPower(580.RPMtoRad()).Value(), Tolerance); } [TestMethod] @@ -44,11 +44,11 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData { var fldCurve = FullLoadCurve.ReadFromFile(CoachEngineFLD); - Assert.AreEqual(-149, fldCurve.DragLoadStationaryTorque(560.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(-301, fldCurve.DragLoadStationaryTorque(2000.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(-148.5, fldCurve.DragLoadStationaryTorque(580.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(-150, fldCurve.DragLoadStationaryTorque(520.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(-339, fldCurve.DragLoadStationaryTorque(2200.RPMtoRad()).Double(), Tolerance); + Assert.AreEqual(-149, fldCurve.DragLoadStationaryTorque(560.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-301, fldCurve.DragLoadStationaryTorque(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-148.5, fldCurve.DragLoadStationaryTorque(580.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-150, fldCurve.DragLoadStationaryTorque(520.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-339, fldCurve.DragLoadStationaryTorque(2200.RPMtoRad()).Value(), Tolerance); } [TestMethod] @@ -56,9 +56,9 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData { var fldCurve = FullLoadCurve.ReadFromFile(CoachEngineFLD); - Assert.AreEqual(-8737.81636, fldCurve.DragLoadStationaryPower(560.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(-63041.29254, fldCurve.DragLoadStationaryPower(2000.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(-9019.51251, fldCurve.DragLoadStationaryPower(580.RPMtoRad()).Double(), Tolerance); + Assert.AreEqual(-8737.81636, fldCurve.DragLoadStationaryPower(560.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-63041.29254, fldCurve.DragLoadStationaryPower(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-9019.51251, fldCurve.DragLoadStationaryPower(580.RPMtoRad()).Value(), Tolerance); } [TestMethod] @@ -66,9 +66,9 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData { var fldCurve = FullLoadCurve.ReadFromFile(CoachEngineFLD); - Assert.AreEqual(0.6, fldCurve.PT1(560.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.25, fldCurve.PT1(2000.RPMtoRad()).Double(), Tolerance); - Assert.AreEqual(0.37, fldCurve.PT1(1700.RPMtoRad()).Double(), Tolerance); + Assert.AreEqual(0.6, fldCurve.PT1(560.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.25, fldCurve.PT1(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(0.37, fldCurve.PT1(1700.RPMtoRad()).Value(), Tolerance); } /// <summary> @@ -100,7 +100,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData { var curve = FullLoadCurve.ReadFromFile(@"TestData\Components\FullLoadCurve no header.vfld"); var result = curve.FullLoadStationaryTorque(1.SI<PerSecond>()); - Assert.AreNotEqual(result.Double(), 0.0); + Assert.AreNotEqual(result.Value(), 0.0); } /// <summary> diff --git a/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs b/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs index 7c8b8bd21f292f707bb5946256b71f87905ed3ce..3b44f37b1fdc8d80122c8671c078ea6ca9158da7 100644 --- a/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs +++ b/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs @@ -21,19 +21,19 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData var gbxData = EngineeringModeSimulationDataReader.CreateGearboxDataFromFile(GearboxFile); Assert.AreEqual(GearboxData.GearboxType.AMT, gbxData.Type); - Assert.AreEqual(1.0, gbxData.TractionInterruption.Double(), 0.0001); + Assert.AreEqual(1.0, gbxData.TractionInterruption.Value(), 0.0001); Assert.AreEqual(8, gbxData.GearsCount()); Assert.AreEqual(3.240355, gbxData.AxleGearData.Ratio, 0.0001); Assert.AreEqual(1.0, gbxData[7].Ratio, 0.0001); - Assert.AreEqual(-400, gbxData[1].ShiftPolygon.Downshift[0].Torque.Double(), 0.0001); - Assert.AreEqual(560.RPMtoRad().Double(), gbxData[1].ShiftPolygon.Downshift[0].AngularSpeed.Double(), 0.0001); - Assert.AreEqual(1289.RPMtoRad().Double(), gbxData[1].ShiftPolygon.Upshift[0].AngularSpeed.Double(), 0.0001); + Assert.AreEqual(-400, gbxData[1].ShiftPolygon.Downshift[0].Torque.Value(), 0.0001); + Assert.AreEqual(560.RPMtoRad().Value(), gbxData[1].ShiftPolygon.Downshift[0].AngularSpeed.Value(), 0.0001); + Assert.AreEqual(1289.RPMtoRad().Value(), gbxData[1].ShiftPolygon.Upshift[0].AngularSpeed.Value(), 0.0001); - Assert.AreEqual(200.RPMtoRad().Double(), gbxData[1].LossMap[15].InputSpeed.Double(), 0.0001); - Assert.AreEqual(-350, gbxData[1].LossMap[15].InputTorque.Double(), 0.0001); - Assert.AreEqual(13.072, gbxData[1].LossMap[15].TorqueLoss.Double(), 0.0001); + Assert.AreEqual(200.RPMtoRad().Value(), gbxData[1].LossMap[15].InputSpeed.Value(), 0.0001); + Assert.AreEqual(-350, gbxData[1].LossMap[15].InputTorque.Value(), 0.0001); + Assert.AreEqual(13.072, gbxData[1].LossMap[15].TorqueLoss.Value(), 0.0001); } [TestMethod] @@ -63,7 +63,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData var loss = powerEngine - PvD; Assert.AreEqual(Double.Parse(TestContext.DataRow["GbxPowerLoss"].ToString(), CultureInfo.InvariantCulture), - loss.Double(), 0.1, + loss.Value(), 0.1, TestContext.DataRow["TestName"].ToString()); } @@ -71,8 +71,6 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData public void TestInputOutOfRange() { var gbxData = EngineeringModeSimulationDataReader.CreateGearboxDataFromFile(GearboxFile); - - } protected PerSecond SpeedToAngularSpeed(double v, double r) diff --git a/VectoCoreTest/Utils/DoubleExtensionMethodTest.cs b/VectoCoreTest/Utils/DoubleExtensionMethodTest.cs index aba3daa14437402ec31a2b6c5deda74168f33747..6ba744238c711f9246adad2f9861e8b8ce226fcc 100644 --- a/VectoCoreTest/Utils/DoubleExtensionMethodTest.cs +++ b/VectoCoreTest/Utils/DoubleExtensionMethodTest.cs @@ -11,7 +11,7 @@ namespace TUGraz.VectoCore.Tests.Utils public void DoubleExtensions_SI() { var val = 600.RPMtoRad(); - Assert.AreEqual(600 / 60 * 2 * Math.PI, val.Double()); + Assert.AreEqual(600 / 60 * 2 * Math.PI, val.Value()); Assert.IsTrue(0.SI<PerSecond>().HasEqualUnit(val)); @@ -23,7 +23,7 @@ namespace TUGraz.VectoCore.Tests.Utils val = val / 2; Assert.AreEqual(val, val2); Assert.AreEqual(600.SI().Rounds.Per.Minute.Cast<PerSecond>(), val2); - Assert.AreEqual(600.SI().Rounds.Per.Minute.Cast<PerSecond>().Double(), val2.Double()); + Assert.AreEqual(600.SI().Rounds.Per.Minute.Cast<PerSecond>().Value(), val2.Value()); } [TestMethod] diff --git a/VectoCoreTest/Utils/DummyGearbox.cs b/VectoCoreTest/Utils/DummyGearbox.cs index e1e361018671d4a4e5e2f302c80707a4c81e06bf..cdd3e105bc0f2f463742521c98404f0283657667 100644 --- a/VectoCoreTest/Utils/DummyGearbox.cs +++ b/VectoCoreTest/Utils/DummyGearbox.cs @@ -15,12 +15,12 @@ namespace TUGraz.VectoCore.Tests.Utils public DummyGearbox(IVehicleContainer cockpit) : base(cockpit) {} - public ITnInPort InShaft() + public ITnInPort InPort() { return this; } - public ITnOutPort OutShaft() + public ITnOutPort OutPort() { return this; } @@ -35,12 +35,17 @@ namespace TUGraz.VectoCore.Tests.Utils _outPort = other; } - public IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond engineSpeed) + public IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond engineSpeed) { throw new NotImplementedException(); } - public override void CommitSimulationStep(IModalDataWriter writer) {} + protected override void DoWriteModalResults(IModalDataWriter writer) + { + throw new NotImplementedException(); + } + + protected override void DoCommitSimulationStep() {} } } \ No newline at end of file diff --git a/VectoCoreTest/Utils/MockDriver.cs b/VectoCoreTest/Utils/MockDriver.cs new file mode 100644 index 0000000000000000000000000000000000000000..26d22e38499ecee4d745103bd6ecf1708e9f7f80 --- /dev/null +++ b/VectoCoreTest/Utils/MockDriver.cs @@ -0,0 +1,67 @@ +using System; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Tests.Utils +{ + public class MockDriver : VectoSimulationComponent, IDriver, IDrivingCycleOutPort, IDriverDemandInPort + { + private IDriverDemandOutPort _next; + + public RequestData LastRequest; + + public MockDriver(IVehicleContainer container) : base(container) {} + + protected override void DoWriteModalResults(IModalDataWriter writer) + { + throw new NotImplementedException(); + } + + protected override void DoCommitSimulationStep() {} + + + public IDrivingCycleOutPort OutPort() + { + return this; + } + + public IDriverDemandInPort InPort() + { + return this; + } + + public IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient) + { + LastRequest = new RequestData() { AbsTime = absTime, ds = ds, Gradient = gradient, TargetVelocity = targetVelocity }; + var acc = 0.SI<MeterPerSquareSecond>(); + var dt = 1.SI<Second>(); + return new ResponseSuccess() { SimulationInterval = dt }; + //_next.Request(absTime, TimeSpan.FromSeconds(0), acc, 0.SI<Radian>()); + } + + public IResponse Request(Second absTime, Second dt, MeterPerSecond targetVelocity, Radian gradient) + { + LastRequest = new RequestData() { AbsTime = absTime, dt = dt, Gradient = gradient, TargetVelocity = targetVelocity }; + var acc = 0.SI<MeterPerSquareSecond>(); + return new ResponseSuccess() { SimulationInterval = dt }; //_next.Request(absTime, dt, acc, gradient); + } + + public void Connect(IDriverDemandOutPort other) + { + _next = other; + } + + public class RequestData + { + public Second AbsTime; + public Meter ds; + public Second dt; + public MeterPerSecond TargetVelocity; + public Radian Gradient; + } + } +} \ No newline at end of file diff --git a/VectoCoreTest/Utils/MockPorts.cs b/VectoCoreTest/Utils/MockPorts.cs index eeea54f924bc7ef78d162a44cfcb6f750b2a175b..ea50b025d8b53ed208c63b53fb4893533ba0e934 100644 --- a/VectoCoreTest/Utils/MockPorts.cs +++ b/VectoCoreTest/Utils/MockPorts.cs @@ -8,12 +8,12 @@ namespace TUGraz.VectoCore.Tests.Utils { public class MockTnOutPort : ITnOutPort { - public TimeSpan AbsTime { get; set; } - public TimeSpan Dt { get; set; } + public Second AbsTime { get; set; } + public Second Dt { get; set; } public NewtonMeter Torque { get; set; } public PerSecond AngularVelocity { get; set; } - public IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond angularVelocity) + public IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity) { AbsTime = absTime; Dt = dt; @@ -25,34 +25,47 @@ namespace TUGraz.VectoCore.Tests.Utils } } - public class MockDrivingCycleDemandOutPort : IDrivingCycleDemandOutPort + public class MockDrivingCycleOutPort : IDrivingCycleOutPort { - public TimeSpan AbsTime { get; set; } - public TimeSpan Dt { get; set; } + public Second AbsTime { get; set; } + public Meter Ds { get; set; } + + public Second Dt { get; set; } public MeterPerSecond Velocity { get; set; } public Radian Gradient { get; set; } - public IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSecond velocity, Radian gradient) + public IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient) + { + AbsTime = absTime; + Ds = ds; + Velocity = targetVelocity; + Gradient = gradient; + LogManager.GetLogger(GetType()).DebugFormat("Request: absTime: {0}, ds: {1}, velocity: {2}, gradient: {3}", + absTime, ds, targetVelocity, gradient); + return new ResponseSuccess(); + } + + public IResponse Request(Second absTime, Second dt, MeterPerSecond targetVelocity, Radian gradient) { AbsTime = absTime; Dt = dt; - Velocity = velocity; + Velocity = targetVelocity; Gradient = gradient; - LogManager.GetLogger(GetType()).DebugFormat("Request: absTime: {0}, dt: {1}, velocity: {2}, gradient: {3}", - absTime, dt, velocity, gradient); + LogManager.GetLogger(GetType()).DebugFormat("Request: absTime: {0}, ds: {1}, velocity: {2}, gradient: {3}", + absTime, dt, targetVelocity, gradient); return new ResponseSuccess(); } } public class MockFvOutPort : IFvOutPort { - public TimeSpan AbsTime { get; set; } - public TimeSpan Dt { get; set; } + public Second AbsTime { get; set; } + public Second Dt { get; set; } public Newton Force { get; set; } public MeterPerSecond Velocity { get; set; } - public IResponse Request(TimeSpan absTime, TimeSpan dt, Newton force, MeterPerSecond velocity) + public IResponse Request(Second absTime, Second dt, Newton force, MeterPerSecond velocity) { AbsTime = absTime; Dt = dt; diff --git a/VectoCoreTest/Utils/MockVehicle.cs b/VectoCoreTest/Utils/MockVehicle.cs new file mode 100644 index 0000000000000000000000000000000000000000..c49232b881b01a96b65a9df7839f90ed7874c132 --- /dev/null +++ b/VectoCoreTest/Utils/MockVehicle.cs @@ -0,0 +1,77 @@ +using System; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Tests.Utils +{ + public class MockVehicle : VectoSimulationComponent, IVehicle, IFvInPort, IDriverDemandOutPort + { + internal MeterPerSecond MyVehicleSpeed; + internal IFvOutPort NextComponent; + + internal RequestData LastRequest = new RequestData(); + + public MockVehicle(IVehicleContainer cockpit) : base(cockpit) {} + protected override void DoWriteModalResults(IModalDataWriter writer) {} + + protected override void DoCommitSimulationStep() {} + + public IFvInPort InPort() + { + return this; + } + + public IDriverDemandOutPort OutPort() + { + return this; + } + + public MeterPerSecond VehicleSpeed() + { + return MyVehicleSpeed; + } + + public Kilogram VehicleMass() + { + return 7500.SI<Kilogram>(); + } + + public Kilogram VehicleLoading() + { + return 0.SI<Kilogram>(); + } + + public Kilogram TotalMass() + { + return VehicleMass(); + } + + public void Connect(IFvOutPort other) + { + NextComponent = other; + } + + public IResponse Request(Second absTime, Second dt, MeterPerSquareSecond acceleration, Radian gradient) + { + LastRequest = new RequestData() { + abstime = absTime, + dt = dt, + acceleration = acceleration, + gradient = gradient + }; + return new ResponseSuccess(); + } + + public class RequestData + { + public Second abstime; + public Second dt; + public MeterPerSquareSecond acceleration; + public Radian gradient; + } + } +} \ No newline at end of file diff --git a/VectoCoreTest/Utils/SITest.cs b/VectoCoreTest/Utils/SITest.cs index 69f33eab2458c3d7e69bb9b0009cfb9b02aa53a7..0d816f0fcff956079d097df0d16cfdb2fdb1e682 100644 --- a/VectoCoreTest/Utils/SITest.cs +++ b/VectoCoreTest/Utils/SITest.cs @@ -35,40 +35,40 @@ namespace TUGraz.VectoCore.Tests.Utils var torque = 1500.SI<NewtonMeter>(); var power = angularVelocity * torque; Assert.IsInstanceOfType(power, typeof(Watt)); - Assert.AreEqual(600.0 / 60 * 2 * Math.PI * 1500, power.Double()); + Assert.AreEqual(600.0 / 60 * 2 * Math.PI * 1500, power.Value()); var siStandardMult = power * torque; Assert.IsInstanceOfType(siStandardMult, typeof(SI)); - Assert.AreEqual(600.0 / 60 * 2 * Math.PI * 1500 * 1500, siStandardMult.Double()); + Assert.AreEqual(600.0 / 60 * 2 * Math.PI * 1500 * 1500, siStandardMult.Value()); Assert.IsTrue(siStandardMult.HasEqualUnit(new SI().Watt.Newton.Meter)); //div var torque2 = power / angularVelocity; Assert.IsInstanceOfType(torque2, typeof(NewtonMeter)); - Assert.AreEqual(1500, torque2.Double()); + Assert.AreEqual(1500, torque2.Value()); var siStandardDiv = power / power; Assert.IsInstanceOfType(siStandardMult, typeof(SI)); Assert.IsTrue(siStandardDiv.HasEqualUnit(new SI())); - Assert.AreEqual(600.0 / 60 * 2 * Math.PI * 1500 * 1500, siStandardMult.Double()); + Assert.AreEqual(600.0 / 60 * 2 * Math.PI * 1500 * 1500, siStandardMult.Value()); //add var angularVelocity2 = 400.SI<RoundsPerMinute>().Cast<PerSecond>(); var angVeloSum = angularVelocity + angularVelocity2; Assert.IsInstanceOfType(angVeloSum, typeof(PerSecond)); - Assert.AreEqual((400.0 + 600) / 60 * 2 * Math.PI, angVeloSum.Double(), 0.0000001); + Assert.AreEqual((400.0 + 600) / 60 * 2 * Math.PI, angVeloSum.Value(), 0.0000001); AssertException<VectoException>(() => { var x = 500.SI().Watt + 300.SI().Newton; }); //subtract var angVeloDiff = angularVelocity - angularVelocity2; Assert.IsInstanceOfType(angVeloDiff, typeof(PerSecond)); - Assert.AreEqual((600.0 - 400) / 60 * 2 * Math.PI, angVeloDiff.Double(), 0.0000001); + Assert.AreEqual((600.0 - 400) / 60 * 2 * Math.PI, angVeloDiff.Value(), 0.0000001); //general si unit var generalSIUnit = 3600000000.0.SI().Gramm.Per.Kilo.Watt.Hour.ConvertTo().Kilo.Gramm.Per.Watt.Second; Assert.IsInstanceOfType(generalSIUnit, typeof(SI)); - Assert.AreEqual(1, generalSIUnit.Double()); + Assert.AreEqual(1, generalSIUnit.Value()); //type conversion @@ -81,7 +81,7 @@ namespace TUGraz.VectoCore.Tests.Utils // cast SI to specialized unit classes. var angularVelocity5 = angularVelocity4.Cast<PerSecond>(); Assert.AreEqual(angularVelocity3, angularVelocity5); - Assert.AreEqual(angularVelocity3.Double(), angularVelocity4.Double()); + Assert.AreEqual(angularVelocity3.Value(), angularVelocity4.Value()); Assert.IsInstanceOfType(angularVelocity3, typeof(PerSecond)); Assert.IsInstanceOfType(angularVelocity5, typeof(PerSecond)); Assert.IsInstanceOfType(angularVelocity4, typeof(SI)); @@ -101,7 +101,7 @@ namespace TUGraz.VectoCore.Tests.Utils public void SI_Test() { var si = new SI(); - Assert.AreEqual(0.0, si.Double()); + Assert.AreEqual(0.0, si.Value()); Assert.AreEqual("0 [-]", si.ToString()); Assert.IsTrue(si.HasEqualUnit(new SI())); @@ -118,15 +118,15 @@ namespace TUGraz.VectoCore.Tests.Utils var kg = 5.SI().Kilo.Gramm; - Assert.AreEqual(5.0, kg.Double()); + Assert.AreEqual(5.0, kg.Value()); Assert.AreEqual("5 [kg]", kg.ToString()); - kg = kg.ConvertTo().Kilo.Gramm.Value(); - Assert.AreEqual(5.0, kg.Double()); + kg = kg.ConvertTo().Kilo.Gramm.Clone(); + Assert.AreEqual(5.0, kg.Value()); Assert.AreEqual("5 [kg]", kg.ToString()); - kg = kg.ConvertTo().Gramm.Value(); - Assert.AreEqual(5000, kg.Double()); + kg = kg.ConvertTo().Gramm.Clone(); + Assert.AreEqual(5000, kg.Value()); Assert.AreEqual("5000 [g]", kg.ToString()); var x = 5.SI(); @@ -141,12 +141,14 @@ namespace TUGraz.VectoCore.Tests.Utils Assert.AreEqual((5 * 2).SI(), x * 2.0); - var y = 2.SI(); - Assert.AreEqual((2 * 5).SI(), y * x); + //var y = 2.SI(); + //Assert.AreEqual((2 * 5).SI(), y * x); - var percent = 10.SI<Radian>().ConvertTo().GradientPercent; - Assert.AreEqual(67.975.ToString("F3") + " [Percent]", percent.ToString("F3")); - Assert.AreEqual(67.975, percent.Double(), 0.001); + //var percent = 10.SI<Radian>().ConvertTo().GradientPercent; + //Assert.AreEqual(67.975.ToString("F3") + " [Percent]", percent.ToString("F3")); + //Assert.AreEqual(67.975, percent.Value(), 0.001); + + Assert.AreEqual(45.0 / 180.0 * Math.PI, VectoMath.InclinationToAngle(1).Value(), 0.000001); } [TestMethod] @@ -182,11 +184,11 @@ namespace TUGraz.VectoCore.Tests.Utils var v5 = v1 * v2; Assert.IsTrue(v5.HasEqualUnit(0.SI().Square.Newton.Meter)); - Assert.AreEqual(v1.Double() * v2.Double(), v5.Double()); + Assert.AreEqual(v1.Value() * v2.Value(), v5.Value()); var v6 = v1 / v2; Assert.IsTrue(v6.HasEqualUnit(0.SI())); - Assert.AreEqual(v1.Double() / v2.Double(), v6.Double()); + Assert.AreEqual(v1.Value() / v2.Value(), v6.Value()); var t = 10.SI<NewtonMeter>(); var angVelo = 5.SI<PerSecond>(); diff --git a/VectoCoreTest/Utils/TestModalDataWriter.cs b/VectoCoreTest/Utils/TestModalDataWriter.cs index a9e4d8ccc6f0de77b9b61d9e2889ce1886b54c78..a4805e878c9e3544d6b2e2850057c0063d556108 100644 --- a/VectoCoreTest/Utils/TestModalDataWriter.cs +++ b/VectoCoreTest/Utils/TestModalDataWriter.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Tests.Utils { @@ -46,11 +47,10 @@ namespace TUGraz.VectoCore.Tests.Utils set { CurrentRow[key.GetName()] = value; } } - public void CommitSimulationStep(TimeSpan absTime, TimeSpan simulationInterval) + public void CommitSimulationStep(Second absTime, Second simulationInterval) { - CurrentRow[ModalResultField.time.GetName()] = - (absTime + TimeSpan.FromTicks(simulationInterval.Ticks / 2)).TotalSeconds; - CurrentRow[ModalResultField.simulationInterval.GetName()] = simulationInterval.TotalSeconds; + CurrentRow[ModalResultField.time.GetName()] = (absTime + simulationInterval / 2).Value(); + CurrentRow[ModalResultField.simulationInterval.GetName()] = simulationInterval.Value(); CommitSimulationStep(); } diff --git a/VectoCoreTest/VectoCoreTest.csproj b/VectoCoreTest/VectoCoreTest.csproj index f94e5325f72a6d521171429457c1e19981bec3db..87c2195928c7744b51e7fe7286c48f77d0c96e92 100644 --- a/VectoCoreTest/VectoCoreTest.csproj +++ b/VectoCoreTest/VectoCoreTest.csproj @@ -46,6 +46,7 @@ <Reference Include="Common.Logging.NLog31"> <HintPath>..\packages\Common.Logging.NLog31.3.0.0\lib\net40\Common.Logging.NLog31.dll</HintPath> </Reference> + <Reference Include="Microsoft.CSharp" /> <Reference Include="NLog"> <HintPath>..\packages\NLog.3.2.0.0\lib\net45\NLog.dll</HintPath> </Reference> @@ -70,6 +71,7 @@ <ItemGroup> <Compile Include="Exceptions\ExceptionTests.cs" /> <Compile Include="Integration\EngineOnlyCycle\EngineOnlyCycleTest.cs" /> + <Compile Include="Integration\SimulationRuns\MinimalPowertrain.cs" /> <Compile Include="Models\Declaration\DeclarationDataTest.cs" /> <Compile Include="Models\SimulationComponentData\AccelerationCurveTest.cs" /> <Compile Include="Models\SimulationComponentData\FuelConsumptionMapTest.cs" /> @@ -78,12 +80,16 @@ <Compile Include="Models\SimulationComponentData\VehicleDataTest.cs" /> <Compile Include="Models\SimulationComponent\ClutchTest.cs" /> <Compile Include="Models\SimulationComponent\CombustionEngineTest.cs" /> + <Compile Include="Models\SimulationComponent\DistanceBasedDrivingCycleTest.cs" /> + <Compile Include="Models\SimulationComponent\DriverTest.cs" /> <Compile Include="Models\SimulationComponent\GearboxTest.cs" /> <Compile Include="Models\SimulationComponent\RetarderTest.cs" /> <Compile Include="Models\SimulationComponent\WheelsTest.cs" /> <Compile Include="Models\SimulationComponent\VehicleTest.cs" /> <Compile Include="Models\Simulation\DrivingCycleTests.cs" /> <Compile Include="Utils\AssertHelper.cs" /> + <Compile Include="Utils\MockDriver.cs" /> + <Compile Include="Utils\MockVehicle.cs" /> <Compile Include="Utils\ResultFileHelper.cs" /> <Compile Include="Utils\MockPorts.cs" /> <Compile Include="Models\Simulation\SimulationTests.cs" />