diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs index 201451de671cc15783395728810412506986e909..75d495f288d41927c7a0715de7138c1a106f1c14 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs @@ -131,7 +131,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl _segment.VehicleClass), InputDataHash = InputDataProvider.XMLHash }; - Report.InitializeReport(powertrainConfig, _segment); + Report.InitializeReport(powertrainConfig); } public IEnumerable<VectoRunData> NextRun() diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs index 1ff25c1668c908e7c0e325d3b5cb9c910eaf5937..ca76f42a5e23ddc60eab616008b978639420bd1c 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs @@ -137,11 +137,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public void WaitFinished() { - try { - Task.WaitAll(Runs.Select(r => r.RunTask).ToArray()); - } catch (Exception) { - // ignored - } + Task.WaitAll(Runs.Select(r => r.RunTask).ToArray()); } [MethodImpl(MethodImplOptions.Synchronized)] @@ -178,16 +174,27 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public class ProgressEntry { + // unique identifier of the simulation run public int RunId; + // job-local identifier of the simulation run public int JobRunId; + public string RunName; + public double Progress; + public double ExecTime; + public Exception Error; + public bool Canceled; + public bool Success; + public bool Done; + public string CycleName; + public string RunSuffix; } @@ -214,11 +221,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl ExecException = ex; throw; } finally { - stopWatch.Stop(); - Success = Run.FinishedWithoutErrors && ExecException == null; - Done = true; - ExecTime = stopWatch.Elapsed.TotalMilliseconds; - JobContainer.JobCompleted(); + stopWatch.Stop(); + Success = Run.FinishedWithoutErrors && ExecException == null; + Done = true; + ExecTime = stopWatch.Elapsed.TotalMilliseconds; + JobContainer.JobCompleted(); } }); } diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs index d1a063f45387a94c8575982708222229240ae698..044834a701c44473ff16645ed27c67fcec90cff3 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs @@ -29,178 +29,178 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.ComponentModel.DataAnnotations; -using System.Threading; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Simulation.Impl -{ - /// <summary> - /// Simulator for one vecto simulation job. - /// </summary> - public abstract class VectoRun : LoggingObject, IVectoRun - { - private static int _runIdCounter; - - protected Second AbsTime = 0.SI<Second>(); - // ReSharper disable once InconsistentNaming - protected Second dt = 1.SI<Second>(); - private bool _cancelled; - protected ISimulationOutPort CyclePort { get; set; } - - [Required, ValidateObject] - protected IVehicleContainer Container { get; set; } - - public bool FinishedWithoutErrors { get; protected set; } - - public int RunIdentifier { get; protected set; } - - public string RunName - { - get { return Container.RunData.JobName; } - } - - public string CycleName - { - get { return Container.RunData.Cycle.Name; } - } - - public string RunSuffix - { - get { return Container.RunData.ModFileSuffix; } - } - +using System; +using System.ComponentModel.DataAnnotations; +using System.Threading; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + /// <summary> + /// Simulator for one vecto simulation job. + /// </summary> + public abstract class VectoRun : LoggingObject, IVectoRun + { + private static int _runIdCounter; + + protected Second AbsTime = 0.SI<Second>(); + // ReSharper disable once InconsistentNaming + protected Second dt = 1.SI<Second>(); + private bool _cancelled; + protected ISimulationOutPort CyclePort { get; set; } + + [Required, ValidateObject] + protected IVehicleContainer Container { get; set; } + + public bool FinishedWithoutErrors { get; protected set; } + + public int RunIdentifier { get; protected set; } + + public string RunName + { + get { return Container.RunData.JobName; } + } + + public string CycleName + { + get { return Container.RunData.Cycle.Name; } + } + + public string RunSuffix + { + get { return Container.RunData.ModFileSuffix; } + } + public int JobRunIdentifier { get { return Container.RunData.JobRunId; } } - public double Progress - { - get { return CyclePort.Progress; } - } - - protected VectoRun(IVehicleContainer container) - { - Container = container; - RunIdentifier = Interlocked.Increment(ref _runIdCounter); - Container.RunStatus = Status.Pending; - CyclePort = container.GetCycleOutPort(); - } - - public IVehicleContainer GetContainer() - { - return Container; - } - - public void Run() - { - var debug = new DebugData(); - - Log.Info("VectoJob started running."); - - Container.AbsTime = AbsTime; - - Initialize(); - try { - IResponse response; - do { - response = DoSimulationStep(); - debug.Add(response); - if (response is ResponseSuccess) { - Container.CommitSimulationStep(AbsTime, dt); - AbsTime += dt; - if (_cancelled) { - Log.Error("Run canceled!"); - Container.RunStatus = Status.Canceled; - Container.FinishSimulationRun(); - return; - } - Container.AbsTime = AbsTime; - } - } while (response is ResponseSuccess); - } catch (VectoSimulationException vse) { - Log.Error("SIMULATION RUN ABORTED! ========================"); - Log.Error(vse); - Container.RunStatus = Status.Aborted; - var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", - vse,AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), - vse.Message, RunIdentifier, CycleName, RunSuffix); - Container.FinishSimulationRun(ex); - throw ex; - } catch (VectoException ve) { - Log.Error("SIMULATION RUN ABORTED! ========================"); - Log.Error(ve); - Container.RunStatus = Status.Aborted; - var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", - ve, - AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), ve.Message, - RunIdentifier, CycleName, RunSuffix); - try { - Container.FinishSimulationRun(ex); - } catch (Exception ve2) { - ve = new VectoException("Multiple Exceptions occured.", - new AggregateException(ve, new VectoException("Exception during finishing Simulation.", ve2))); - throw ve; - } - throw ex; - } catch (Exception e) { - Log.Error("SIMULATION RUN ABORTED! ========================"); - Log.Error(e); - Container.RunStatus = Status.Aborted; - - var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", - e, AbsTime, - Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), e.Message, - RunIdentifier, CycleName, RunSuffix); - Container.FinishSimulationRun(ex); - throw ex; - } - Container.RunStatus = Progress < 1 ? Status.Aborted : Status.Success; - Container.FinishSimulationRun(); - if (Progress.IsSmaller(1, 1e-9)) { - throw new VectoSimulationException( - "{5} ({6} {7}) Progress: {8} - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4}", - AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), RunIdentifier, CycleName, - RunSuffix, Progress); - } - IterationStatistics.FinishSimulation(RunName + CycleName + RunSuffix + RunIdentifier); - - Log.Info("VectoJob finished."); - } - - public void Cancel() - { - _cancelled = true; - } - - private static object TryCatch(Func<object> action) - { - try { - return action(); - } catch (VectoException e) { - LogManager.GetLogger(typeof(VectoRun).FullName).Info(e); - return null; - } - } - - protected abstract IResponse DoSimulationStep(); - - protected abstract IResponse Initialize(); - - public enum Status - { - Pending, - Running, - Success, - Canceled, - Aborted, - } - } + public double Progress + { + get { return CyclePort.Progress; } + } + + protected VectoRun(IVehicleContainer container) + { + Container = container; + RunIdentifier = Interlocked.Increment(ref _runIdCounter); + Container.RunStatus = Status.Pending; + CyclePort = container.GetCycleOutPort(); + } + + public IVehicleContainer GetContainer() + { + return Container; + } + + public void Run() + { + var debug = new DebugData(); + + Log.Info("VectoJob started running."); + + Container.AbsTime = AbsTime; + + Initialize(); + try { + IResponse response; + do { + response = DoSimulationStep(); + debug.Add(response); + if (response is ResponseSuccess) { + Container.CommitSimulationStep(AbsTime, dt); + AbsTime += dt; + if (_cancelled) { + Log.Error("Run canceled!"); + Container.RunStatus = Status.Canceled; + Container.FinishSimulationRun(); + return; + } + Container.AbsTime = AbsTime; + } + } while (response is ResponseSuccess); + } catch (VectoSimulationException vse) { + Log.Error("SIMULATION RUN ABORTED! ========================"); + Log.Error(vse); + Container.RunStatus = Status.Aborted; + var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", + vse, AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), + vse.Message, RunIdentifier, CycleName, RunSuffix); + Container.FinishSimulationRun(ex); + throw ex; + } catch (VectoException ve) { + Log.Error("SIMULATION RUN ABORTED! ========================"); + Log.Error(ve); + Container.RunStatus = Status.Aborted; + var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", + ve, + AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), ve.Message, + RunIdentifier, CycleName, RunSuffix); + try { + Container.FinishSimulationRun(ex); + } catch (Exception ve2) { + ve = new VectoException("Multiple Exceptions occured.", + new AggregateException(ve, new VectoException("Exception during finishing Simulation.", ve2))); + throw ve; + } + throw ex; + } catch (Exception e) { + Log.Error("SIMULATION RUN ABORTED! ========================"); + Log.Error(e); + Container.RunStatus = Status.Aborted; + + var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}", + e, AbsTime, + Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), e.Message, + RunIdentifier, CycleName, RunSuffix); + Container.FinishSimulationRun(ex); + throw ex; + } + Container.RunStatus = Progress < 1 ? Status.Aborted : Status.Success; + Container.FinishSimulationRun(); + if (Progress.IsSmaller(1, 1e-9)) { + throw new VectoSimulationException( + "{5} ({6} {7}) Progress: {8} - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4}", + AbsTime, Container.Distance, dt, Container.VehicleSpeed, TryCatch(() => Container.Gear), RunIdentifier, CycleName, + RunSuffix, Progress); + } + IterationStatistics.FinishSimulation(RunName + CycleName + RunSuffix + RunIdentifier); + + Log.Info("VectoJob finished."); + } + + public void Cancel() + { + _cancelled = true; + } + + private static object TryCatch(Func<object> action) + { + try { + return action(); + } catch (VectoException e) { + LogManager.GetLogger(typeof(VectoRun).FullName).Info(e); + return null; + } + } + + protected abstract IResponse DoSimulationStep(); + + protected abstract IResponse Initialize(); + + public enum Status + { + Pending, + Running, + Success, + Canceled, + Aborted, + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index cec819de6162c578d8e46676ff8749a42f299553..a0968b24da150ad4e5d34e35fb3e8245bd159230 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -325,11 +325,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public void FinishSimulationRun(Exception e = null) { Log.Info("VehicleContainer finishing simulation."); - ModData.Finish(RunStatus); + ModData.Finish(RunStatus, e); WriteSumData(ModData); - ModData.FinishSimulation(e); + ModData.FinishSimulation(); DrivingCycle.FinishSimulation(); } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 02152d10f148ffa1f50bd06011d4a593f7cb2c18..a7cb1b718bb728f9a39c7cf50a9ac28aff0f988f 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -590,9 +590,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl angularSpeed = angularSpeed.LimitTo(_engine.ModelData.IdleSpeed, _engine.EngineRatedSpeed); retVal = RequestPort.Request(absTime, dt, 0.SI<NewtonMeter>(), angularSpeed); }). - Default(r => { - throw new UnexpectedResponseException("searching Idling point", r); - }); + Default(r => { throw new UnexpectedResponseException("searching Idling point", r); }); return retVal; } @@ -649,9 +647,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl 0.SI<NewtonMeter>(), angularSpeed); retVal = RequestPort.Request(absTime, dt, 0.SI<NewtonMeter>(), angularSpeed); }). - Default(r => { - throw new UnexpectedResponseException("searching Idling point", r); - }); + Default(r => { throw new UnexpectedResponseException("searching Idling point", r); }); return retVal; } diff --git a/VectoCore/VectoCore/OutputData/DeclarationReport.cs b/VectoCore/VectoCore/OutputData/DeclarationReport.cs index 1167eee4a5069514f9a6e12fc19c8e3ef17ac702..b70bbb0ffbf4cd50bd90761afc0318c64a1737fc 100644 --- a/VectoCore/VectoCore/OutputData/DeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/DeclarationReport.cs @@ -34,16 +34,32 @@ using System.Runtime.CompilerServices; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; namespace TUGraz.VectoCore.OutputData { public interface IDeclarationReport { + /** + * allow to initialize the report + * read the configuration of the powertrain to be used during the simulation. + * This methodd is called once befor creating the simulation runs with a temporary + * VectoRunData instance + */ + void InitializeReport(VectoRunData modelData); + + /** + * called when creating the simulation run (before starting the simulations) + * Hence, the report class knows which and how many results to expect after the simulation + * (calls to AddResult) + */ void PrepareResult(LoadingType loading, Mission mission, VectoRunData runData); + + /** + * called after the simulation run providing the modal data of the simulation + * for the given configuration + */ void AddResult(LoadingType loadingType, Mission mission, VectoRunData runData, IModalDataContainer modData); - void InitializeReport(VectoRunData modelData, Segment segment); } /// <summary> @@ -58,20 +74,6 @@ namespace TUGraz.VectoCore.OutputData public Dictionary<LoadingType, TEntry> ModData; } - //public class MissionProfile - //{ - // public readonly IList<double> DistanceKm; - // public readonly IList<double> TargetSpeed; - // public readonly IList<double> Altitude; - - // public MissionProfile(IModalDataContainer m) - // { - // DistanceKm = m.GetValues<Meter>(ModalResultField.dist).Select(v => v.ConvertTo().Kilo.Meter).ToDouble(); - // TargetSpeed = - // m.GetValues<MeterPerSecond>(ModalResultField.v_targ).Select(v => v.ConvertTo().Kilo.Meter.Per.Hour).ToDouble(); - // Altitude = m.GetValues<Meter>(ModalResultField.altitude).ToDouble(); - // } - //} /// <summary> /// Dictionary of MissionTypes and their corresponding results. @@ -84,10 +86,10 @@ namespace TUGraz.VectoCore.OutputData /// </summary> internal Dictionary<uint, EngineFullLoadCurve> Flc { get; set; } - /// <summary> - /// The declaration segment from the segment table - /// </summary> - internal Segment? Segment { get; set; } + ///// <summary> + ///// The declaration segment from the segment table + ///// </summary> + //internal Segment? Segment { get; set; } /// <summary> @@ -113,19 +115,12 @@ namespace TUGraz.VectoCore.OutputData public void AddResult(LoadingType loadingType, Mission mission, VectoRunData runData, IModalDataContainer modData) { - if (modData.RunStatus != VectoRun.Status.Success) { - //Missions.Clear(); - return; - } if (!Missions.ContainsKey(mission.MissionType)) { throw new VectoException("Unknown mission type {0} for generating declaration report", mission.MissionType); } if (!Missions[mission.MissionType].ModData.ContainsKey(loadingType)) { throw new VectoException("Unknown loading type {0} for mission {1}", loadingType, mission.MissionType); } - //if (Missions[mission.MissionType].MissionProfile == null) { - // Missions[mission.MissionType].MissionProfile = new MissionProfile(modData); - //} _resultCount--; DoAddResult(Missions[mission.MissionType].ModData[loadingType], runData, modData); @@ -133,7 +128,6 @@ namespace TUGraz.VectoCore.OutputData if (_resultCount == 0) { DoWriteReport(); Flc = null; - Segment = null; } } @@ -150,13 +144,6 @@ namespace TUGraz.VectoCore.OutputData protected internal abstract void DoWriteReport(); - public void InitializeReport(VectoRunData modelData, Segment segment) - { - Segment = segment; - - DoInitializeReport(modelData, segment); - } - - protected abstract void DoInitializeReport(VectoRunData modelData, Segment segment); + public abstract void InitializeReport(VectoRunData modelData); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs index d58d0a42cb7b122f4016ac40b118223eb777387f..b48aec3d79efaca6804a215991feccbe0c834f83 100644 --- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs @@ -78,11 +78,6 @@ namespace TUGraz.VectoCore.OutputData string StackTrace { get; } - /// <summary> - /// Finishes the writing of the DataWriter. - /// </summary> - void Finish(VectoRun.Status runStatus); - IEnumerable<T> GetValues<T>(ModalResultField key); IEnumerable<T> GetValues<T>(DataColumn col); @@ -97,12 +92,16 @@ namespace TUGraz.VectoCore.OutputData void AddAuxiliary(string id, string columnName = null); + /// <summary> + /// Finishes the writing of the DataWriter. + /// </summary> + void Finish(VectoRun.Status runStatus, Exception exception = null); + /// <summary> /// clear the modal data after the simulation /// called after the simulation is finished and the sum-entries have been written /// </summary> - /// <param name="exception"></param> - void FinishSimulation(Exception exception = null); + void FinishSimulation(); } public static class ModalDataContainerExtensions diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index 9f20751ac6d637fd5af16aaea8d92f83f8a6b7fe..6e235c440260496e4fe3a8fb8e70f3d7f5a0b48e 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -63,8 +63,19 @@ namespace TUGraz.VectoCore.OutputData public VectoRun.Status RunStatus { get; protected set; } - public string Error { get { return SimException == null ? null : SimException.Message; } } - public string StackTrace { get { return SimException == null ? null : SimException.StackTrace; } } + public string Error + { + get { return SimException == null ? null : SimException.Message; } + } + + public string StackTrace + { + get { + return SimException == null + ? null + : (SimException.StackTrace ?? (SimException.InnerException != null ? SimException.InnerException.StackTrace : null)); + } + } public bool WriteAdvancedAux { get; set; } @@ -74,7 +85,8 @@ namespace TUGraz.VectoCore.OutputData public ModalDataContainer(VectoRunData runData, IModalDataWriter writer, Action<ModalDataContainer> addReportResult, bool writeEngineOnly, params IModalDataFilter[] filter) : this( - runData.JobRunId, runData.JobName, runData.Cycle.Name, runData.EngineData.FuelType, runData.ModFileSuffix, writer, addReportResult, + runData.JobRunId, runData.JobName, runData.Cycle.Name, runData.EngineData.FuelType, runData.ModFileSuffix, writer, + addReportResult, writeEngineOnly, filter) {} protected ModalDataContainer(int jobRunId, string runName, string cycleName, FuelType fuelType, string runSuffix, @@ -111,11 +123,12 @@ namespace TUGraz.VectoCore.OutputData public FuelData.Entry FuelData { get; internal set; } - public void Finish(VectoRun.Status runStatus) + public void Finish(VectoRun.Status runStatus, Exception exception = null) { var dataColumns = new List<ModalResultField> { ModalResultField.time }; RunStatus = runStatus; + SimException = exception; if (!_writeEngineOnly) { dataColumns.AddRange(new[] { @@ -238,7 +251,8 @@ namespace TUGraz.VectoCore.OutputData RunSuffix += "_" + filter.ID; filteredData = filter.Filter(filteredData); } - _writer.WriteModData(JobRunId, RunName, CycleName, RunSuffix, new DataView(filteredData).ToTable(false, strCols.ToArray())); + _writer.WriteModData(JobRunId, RunName, CycleName, RunSuffix, + new DataView(filteredData).ToTable(false, strCols.ToArray())); } _addReportResult(this); @@ -323,9 +337,8 @@ namespace TUGraz.VectoCore.OutputData } } - public void FinishSimulation(Exception exception) + public void FinishSimulation() { - SimException = exception; //Data.Clear(); //.Rows.Clear(); Data = null; CurrentRow = null; diff --git a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs index e430fd531535fd6d736f92a572368bb59921b283..889b2a9e704d7a4072cbd56eef1b7821f2378e45 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs @@ -62,12 +62,12 @@ namespace TUGraz.VectoCore.OutputData.XML public XMLCustomerReport() { di = "http://www.w3.org/2000/09/xmldsig#"; - tns = "urn:tugraz:ivt:VectoAPI:COCOutput:v0.4"; + tns = "urn:tugraz:ivt:VectoAPI:CustomerOutput:v0.4"; VehiclePart = new XElement(tns + XMLNames.Component_Vehicle); Results = new XElement(tns + "Results"); } - public void Initialize(VectoRunData modelData, Segment segment) + public void Initialize(VectoRunData modelData) { VehiclePart.Add( new XElement(tns + XMLNames.Component_Model, modelData.VehicleData.ModelName), @@ -75,7 +75,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + XMLNames.Component_ManufacturerAddress, modelData.VehicleData.ManufacturerAddress), new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), new XElement(tns + XMLNames.Vehicle_LegislativeClass, modelData.VehicleData.LegislativeClass.ToXMLFormat()), - new XElement(tns + "VehicleGroup", segment.VehicleClass.GetClassNumber()), + new XElement(tns + "VehicleGroup", modelData.VehicleData.VehicleClass.GetClassNumber()), new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), new XElement(tns + XMLNames.Vehicle_CurbMassChassis, modelData.VehicleData.CurbWeight.ToXMLFormat(0)), @@ -108,7 +108,7 @@ namespace TUGraz.VectoCore.OutputData.XML foreach (var resultEntry in entry.ModData) { allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success; Results.Add(new XElement(tns + "Result", - new XAttribute("status", resultEntry.Value.Status.ToString().ToLower()), + new XAttribute("status", resultEntry.Value.Status == VectoRun.Status.Success ? "success" : "error"), new XElement(tns + "Mission", entry.Mission.ToXMLFormat()), GetResults(resultEntry))); } @@ -125,7 +125,7 @@ namespace TUGraz.VectoCore.OutputData.XML case VectoRun.Status.Canceled: case VectoRun.Status.Aborted: return new object[] { - new XElement("Error", resultEntry.Value.Error) + new XElement(tns + "Error", resultEntry.Value.Error) }; default: throw new ArgumentOutOfRangeException(); @@ -164,7 +164,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XAttribute("xmlns", tns), new XAttribute(XNamespace.Xmlns + "di", di), new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoCOC.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), + string.Format("{0} {1}VectoOutputCustomer.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), new XElement(tns + "Data", vehicle, new XElement(tns + "ResultDataSignature", resultSignature), diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs index 55e2886548cf618ac8d84a556cffefa5b41b2f25..79a575703bb299fb6fc8757c71b7ca889b839abe 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs @@ -162,10 +162,10 @@ namespace TUGraz.VectoCore.OutputData.XML } - protected override void DoInitializeReport(VectoRunData modelData, Segment segment) + public override void InitializeReport(VectoRunData modelData) { - _manufacturerReport.Initialize(modelData, segment); - _customerReport.Initialize(modelData, segment); + _manufacturerReport.Initialize(modelData); + _customerReport.Initialize(modelData); } diff --git a/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs index db83185b1411b7081a48dd061b681c5a2bc901e9..d2c3ea2e8c1823d4904a3ac92ebc8999e3c9cbfa 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs @@ -69,12 +69,12 @@ namespace TUGraz.VectoCore.OutputData.XML Results = new XElement(tns + "Results"); } - public void Initialize(VectoRunData modelData, Segment segment) + public void Initialize(VectoRunData modelData) { VehiclePart.Add( new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), new XElement(tns + XMLNames.Vehicle_LegislativeClass, modelData.VehicleData.LegislativeClass.ToXMLFormat()), - new XElement(tns + "VehicleGroup", segment.VehicleClass.GetClassNumber()), + new XElement(tns + "VehicleGroup", modelData.VehicleData.VehicleClass.GetClassNumber()), new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), new XElement(tns + XMLNames.Vehicle_CurbMassChassis, modelData.VehicleData.CurbWeight.ToXMLFormat(0)), @@ -269,7 +269,7 @@ namespace TUGraz.VectoCore.OutputData.XML foreach (var resultEntry in entry.ModData) { allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success; Results.Add(new XElement(tns + "Result", - new XAttribute("status", resultEntry.Value.Status.ToString().ToLower()), + new XAttribute("status", resultEntry.Value.Status == VectoRun.Status.Success?"success" : "error"), new XElement(tns + "Mission", entry.Mission.ToXMLFormat()), GetResults(resultEntry))); } @@ -286,8 +286,8 @@ namespace TUGraz.VectoCore.OutputData.XML case VectoRun.Status.Canceled: case VectoRun.Status.Aborted: return new object[] { - new XElement("Error", resultEntry.Value.Error), - new XElement("ErrorDetails", resultEntry.Value.StackTrace), + new XElement(tns+"Error", resultEntry.Value.Error), + new XElement(tns+"ErrorDetails", resultEntry.Value.StackTrace), }; default: throw new ArgumentOutOfRangeException(); @@ -339,7 +339,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XAttribute("xmlns", tns), new XAttribute(XNamespace.Xmlns + "di", di), new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoOutput.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), + string.Format("{0} {1}VectoOutputManufacturer.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), new XElement(tns + "Data", vehicle, results, diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs index cef987e2b8cf9c2e5d7eb0cb65559359d44176e9..3ce0723f68e2b7eb4797349a4181f0d497cf1223 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs @@ -29,537 +29,537 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using System.Data; -using System.Diagnostics; -using System.Linq; -using NUnit.Framework; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; - -// ReSharper disable UnusedVariable -// ReSharper disable NotAccessedVariable -// ReSharper disable CollectionNeverQueried.Local -// ReSharper disable RedundantAssignment - -namespace TUGraz.VectoCore.Tests.Models.SimulationComponent -{ - [TestFixture] - public class CombustionEngineTest - { - protected double Tolerance = 1E-3; - - private const string CoachEngine = @"TestData\Components\24t Coach.veng"; - - private const string TruckEngine = @"TestData\Components\40t_Long_Haul_Truck.veng"; - - [TestCase] - public void TestEngineHasOutPort() - { - var vehicle = new VehicleContainer(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); - var engine = new CombustionEngine(vehicle, engineData); - - var port = engine.OutPort(); - Assert.IsNotNull(port); - } - - [TestCase] - public void TestOutPortRequestNotFailing() - { - var vehicle = new VehicleContainer(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); - var engine = new CombustionEngine(vehicle, engineData); - var gearbox = new MockGearbox(vehicle) { Gear = 0 }; - - var port = engine.OutPort(); - - var absTime = 0.SI<Second>(); - var dt = 1.SI<Second>(); - var torque = 400.SI<NewtonMeter>(); - var engineSpeed = 1500.RPMtoRad(); - - port.Initialize(torque, engineSpeed); - port.Request(absTime, dt, torque, engineSpeed); - } - - [TestCase] - public void TestSimpleModalData() - { - var vehicle = new VehicleContainer(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); - var engine = new CombustionEngine(vehicle, engineData); - var gearbox = new MockGearbox(vehicle) { Gear = 0 }; - var port = engine.OutPort(); - - var absTime = 0.SI<Second>(); - var dt = 1.SI<Second>(); - - var torque = 0.SI<NewtonMeter>(); - var engineSpeed = 600.RPMtoRad(); - var dataWriter = new MockModalDataContainer(); - - port.Initialize(torque, engineSpeed); - for (var i = 0; i < 21; i++) { - port.Request(absTime, dt, torque, engineSpeed); - engine.CommitSimulationStep(dataWriter); - if (i > 0) { - dataWriter.CommitSimulationStep(absTime, dt); - } - absTime += dt; - } - - engineSpeed = 644.4445.RPMtoRad(); - port.Request(absTime, dt, Formulas.PowerToTorque(2329.973.SI<Watt>(), engineSpeed), engineSpeed); - engine.CommitSimulationStep(dataWriter); - - AssertHelper.AreRelativeEqual(1152.40304, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value()); - - dataWriter.CommitSimulationStep(absTime, dt); - absTime += dt; - - var power = new[] { 569.3641, 4264.177 }; - for (var i = 0; i < 2; i++) { - port.Request(absTime, dt, Formulas.PowerToTorque(power[i].SI<Watt>(), engineSpeed), engineSpeed); - engine.CommitSimulationStep(dataWriter); - dataWriter.CommitSimulationStep(absTime, dt); - absTime += dt; - } - - engineSpeed = 869.7512.RPMtoRad(); - port.Request(absTime, dt, Formulas.PowerToTorque(7984.56.SI<Watt>(), engineSpeed), engineSpeed); - engine.CommitSimulationStep(dataWriter); - - Assert.AreEqual(7108.32, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value(), 0.001); - dataWriter.CommitSimulationStep(absTime, dt); - absTime += dt; - - engineSpeed = 644.4445.RPMtoRad(); - port.Request(absTime, dt, Formulas.PowerToTorque(1351.656.SI<Watt>(), engineSpeed), engineSpeed); - engine.CommitSimulationStep(dataWriter); - - Assert.AreEqual(-7108.32, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value(), 0.001); - dataWriter.CommitSimulationStep(absTime, dt); - - VectoCSVFile.Write(@"test1.csv", dataWriter.Data, true); - } - - [TestCase("Test1Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_1Hz.csv")] - [TestCase("Test10Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz.csv")] - [TestCase("TestvarHz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_varHz.csv")] - [TestCase("Test10Hz", @"TestData\Components\24t Coach_IncPT1.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz_IncPT1.csv")] - public void TestEngineOnlyEngineFullLoadJump(string testName, string engineFile, double rpm, double initialIdleLoad, - double finalIdleLoad, string resultFile) - { - var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 0); - var engine = new EngineOnlyCombustionEngine(vehicleContainer, engineData); - - var expectedResults = VectoCSVFile.Read(resultFile); - - var requestPort = engine.OutPort(); - - //var modalData = new ModalDataWriter(string.Format("load_jump_{0}.csv", TestContext.DataRow["TestName"].ToString())); - var modalData = new MockModalDataContainer(); - - var idlePower = initialIdleLoad.SI<Watt>(); - - var angularSpeed = rpm.RPMtoRad(); - - var t = 0.SI<Second>(); - var dt = 0.1.SI<Second>(); - requestPort.Initialize(Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); - for (; t < 2; t += dt) { - requestPort.Request(t, dt, Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); - engine.CommitSimulationStep(modalData); - } - - var i = 0; - // dt = TimeSpan.FromSeconds(double.Parse(TestContext.DataRow["dt"].ToString(), CultureInfo.InvariantCulture)); - // dt = TimeSpan.FromSeconds(expectedResults.Rows[i].ParseDouble(0)) - t; - var engineLoadPower = engineData.FullLoadCurves[0].FullLoadStationaryPower(angularSpeed); - idlePower = finalIdleLoad.SI<Watt>(); - for (; t < 25; t += dt, i++) { - dt = (expectedResults.Rows[i + 1].ParseDouble(0) - expectedResults.Rows[i].ParseDouble(0)).SI<Second>(); - if (t >= 10.SI<Second>()) { - engineLoadPower = idlePower; - } - requestPort.Request(t, dt, Formulas.PowerToTorque(engineLoadPower, angularSpeed), angularSpeed); - modalData[ModalResultField.time] = t; - modalData[ModalResultField.simulationInterval] = dt; - engine.CommitSimulationStep(modalData); - Assert.AreEqual(expectedResults.Rows[i].ParseDouble(0), t.Value(), 0.001, "Time"); - Assert.AreEqual(expectedResults.Rows[i].ParseDouble(1), ((SI)modalData[ModalResultField.P_eng_full]).Value(), 0.1, - string.Format("Load in timestep {0}", t)); - modalData.CommitSimulationStep(); - } - modalData.Finish(VectoRun.Status.Success); - } - - [TestCase("Test1Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_1Hz.csv")] - [TestCase("Test10Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz.csv")] - [TestCase("TestvarHz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_varHz.csv")] - [TestCase("Test10Hz", @"TestData\Components\24t Coach_IncPT1.veng", 1000, 50, 50, - @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz_IncPT1.csv")] - public void TestEngineFullLoadJump(string testName, string engineFile, double rpm, double initialIdleLoad, - double finalIdleLoad, string resultFile) - { - var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 0); - var engine = new CombustionEngine(vehicleContainer, engineData); - var gearbox = new MockGearbox(vehicleContainer) { Gear = 0 }; - - var expectedResults = VectoCSVFile.Read(resultFile); - - var requestPort = engine.OutPort(); - - //var modalData = new ModalDataWriter(string.Format("load_jump_{0}.csv", TestName)); - var modalData = new MockModalDataContainer(); - - var idlePower = initialIdleLoad.SI<Watt>(); - - var angularSpeed = rpm.RPMtoRad(); - - var t = 0.SI<Second>(); - var dt = 0.1.SI<Second>(); - requestPort.Initialize(Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); - for (; t < 2; t += dt) { - requestPort.Request(t, dt, Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); - engine.CommitSimulationStep(modalData); - } - - var i = 0; - // dt = TimeSpan.FromSeconds(double.Parse(TestContext.DataRow["dt"].ToString(), CultureInfo.InvariantCulture)); - // dt = TimeSpan.FromSeconds(expectedResults.Rows[i].ParseDouble(0)) - t; - var engineLoadPower = engineData.FullLoadCurves[0].FullLoadStationaryPower(angularSpeed); - idlePower = finalIdleLoad.SI<Watt>(); - for (; t < 25; t += dt, i++) { - dt = (expectedResults.Rows[i + 1].ParseDouble(0) - expectedResults.Rows[i].ParseDouble(0)).SI<Second>(); - if (t >= 10.SI<Second>()) { - engineLoadPower = idlePower; - } - requestPort.Request(t, dt, Formulas.PowerToTorque(engineLoadPower, angularSpeed), angularSpeed); - modalData[ModalResultField.time] = t; - modalData[ModalResultField.simulationInterval] = dt; - engine.CommitSimulationStep(modalData); - Assert.AreEqual(expectedResults.Rows[i].ParseDouble(0), t.Value(), 0.001, "Time"); - Assert.AreEqual(expectedResults.Rows[i].ParseDouble(1), ((SI)modalData[ModalResultField.P_eng_full]).Value(), 0.1, - string.Format("Load in timestep {0}", t)); - modalData.CommitSimulationStep(); - } - modalData.Finish(VectoRun.Status.Success); - } - - [TestCase] - public void EngineIdleJump() - { - var container = new VehicleContainer(ExecutionMode.Engineering); - var gearbox = new MockGearbox(container); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 1); - var vehicle = new MockVehicle(container); - vehicle.MyVehicleSpeed = 0.SI<MeterPerSecond>(); - var engine = new CombustionEngine(container, engineData); - var clutch = new Clutch(container, engineData); - - var d = new MockDriver(container); - - var aux = new EngineAuxiliary(container); - aux.AddConstant("CONST", 5000.SI<Watt>()); - - gearbox.Gear = 1; - - //gearbox.InPort().Connect(engine.OutPort()); - gearbox.InPort().Connect(clutch.OutPort()); - clutch.InPort().Connect(engine.OutPort()); - engine.Connect(aux.Port()); - clutch.IdleController = engine.IdleController; - - // var expectedResults = VectoCSVFile.Read(TestContext.DataRow["ResultFile"].ToString()); - - var requestPort = gearbox.OutPort(); - - //vehicleContainer.DataWriter = new ModalDataWriter("engine_idle_test.csv"); - var dataWriter = new MockModalDataContainer(); - container.ModData = dataWriter; - container.ModalData.AddAuxiliary("CONST"); - - var torque = 1200.SI<NewtonMeter>(); - var angularVelocity = 800.RPMtoRad(); - - // initialize engine... - - gearbox.Initialize(torque, angularVelocity); - - var absTime = 0.SI<Second>(); - var dt = Constants.SimulationSettings.TargetTimeInterval; - - var response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - - container.CommitSimulationStep(absTime, dt); - var row = dataWriter.Data.Rows.Cast<DataRow>().Last(); - Assert.AreEqual(100530.96491487339.SI<Watt>().Value(), ((SI)row[ModalResultField.P_eng_out.GetName()]).Value()); - Assert.AreEqual(105530.96491487339.SI<Watt>().Value(), ((SI)row[ModalResultField.P_eng_fcmap.GetName()]).Value()); - Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.P_aux.GetName()]); - Assert.AreEqual(800.RPMtoRad(), row[ModalResultField.n_eng_avg.GetName()]); - - absTime += dt; - - // actual test... - - gearbox.Gear = 0; - gearbox.SetClutch(false); - torque = 0.SI<NewtonMeter>(); - - response = (ResponseSuccess)gearbox.Request(absTime, dt, torque, angularVelocity); - - container.CommitSimulationStep(absTime, dt); - row = dataWriter.Data.Rows.Cast<DataRow>().Last(); - - Assert.AreEqual(0.SI<Watt>(), row[ModalResultField.P_eng_out.GetName()]); - Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.P_aux.GetName()]); - Assert.AreEqual(680.RPMtoRad(), row[ModalResultField.n_eng_avg.GetName()]); - } - - [TestCase] - public void EngineIdleControllerTestCoach() - { - VehicleContainer container; - CombustionEngine engine; - ITnOutPort requestPort; - MockGearbox gearbox; - VehicleContainer(CoachEngine, out container, out engine, out requestPort, out gearbox); - - var absTime = 0.SI<Second>(); - var dt = Constants.SimulationSettings.TargetTimeInterval; - - var angularVelocity = 800.RPMtoRad(); - var torque = 100000.SI<Watt>() / angularVelocity; - - var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); - - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - Assert.AreEqual(105000, response.EnginePowerRequest.Value(), Tolerance); - container.CommitSimulationStep(absTime, dt); - absTime += dt; - - var engineSpeed = new[] { 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad() }; - var enginePower = new[] { -8601.6308.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>() }; - - gearbox.SetClutch(false); - for (var i = 0; i < engineSpeed.Length; i++) { - torque = 0.SI<NewtonMeter>(); - - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); - container.CommitSimulationStep(absTime, dt); - absTime += dt; - - Assert.AreEqual(engineSpeed[i].Value(), engine.PreviousState.EngineSpeed.Value(), Tolerance, "i: {0}", i); - Assert.AreEqual(enginePower[i].Value(), engine.PreviousState.EnginePower.Value(), Tolerance, "i: {0}", i); - } - } - - /* - * VECTO 2.2 - | time [s] | P_eng_out [kW] | n_eng_avg [1/min] | T_eng_fcmap [Nm] | Gear [-] | - | 59.5 | 349.981 | 1679.281 | 1990.181 | 8 | - | 60.5 | 5 | 1679.281 | 28.43269 | 0 | - | 61.5 | -19.47213 | 1397.271 | -133.0774 | 0 | - | 62.5 | -18.11888 | 1064.296 | -162.5699 | 0 | - | 63.5 | -11.11163 | 714.1923 | -148.571 | 0 | - | 64.5 | -0.5416708 | 560 | -9.236741 | 0 | - | 65.5 | 5 | 560 | 85.26157 | 0 | - | 66.5 | 5 | 560 | 85.26157 | 0 | - | 67.5 | 5 | 560 | 85.26157 | 0 | - | 68.5 | 5 | 560 | 85.26157 | 0 | - | 69.5 | 5 | 560 | 85.26157 | 0 | - | 70.5 | 308.729 | 1284.139 | 2295.815 | 9 | - */ - - [TestCase] - public void EngineIdleControllerTestTruck() - { - VehicleContainer container; - CombustionEngine engine; - ITnOutPort requestPort; - MockGearbox gearbox; - VehicleContainer(TruckEngine, out container, out engine, out requestPort, out gearbox); - - //var dataWriter = new ModalDataWriter("EngineIdle.vmod"); - //container.DataWriter = dataWriter; - - var absTime = 0.SI<Second>(); - var dt = Constants.SimulationSettings.TargetTimeInterval; - - var angularVelocity = 1680.RPMtoRad(); - var torque = 345000.SI<Watt>() / angularVelocity; - - var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); - - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - Assert.AreEqual(350000, response.EnginePowerRequest.Value(), Tolerance); - container.CommitSimulationStep(absTime, dt); - absTime += dt; - - var engineSpeed = new[] { - 1439.5773, 1225.5363, 1026.6696, 834.1936, 641.1360, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, - 560, 560 - }; - - var enginePower = new[] { - -37334.1588, -27198.2777, -20280.7550, -15216.7221, -11076.6656, -500.7991, 5000, 5000, 5000, 5000, 5000, 5000, 5000, - 5000, 5000, 5000, 5000, 5000, 5000, 5000 - }; - - var fld = engine.ModelData.FullLoadCurves; - - gearbox.SetClutch(false); - var engSpeedResults = new List<dynamic>(); - for (var i = 0; i < 20; i++) { - torque = 0.SI<NewtonMeter>(); - - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); - - container.CommitSimulationStep(absTime, dt); - - engSpeedResults.Add(new { absTime, engine.PreviousState.EngineSpeed, engine.PreviousState.EnginePower }); - Assert.AreEqual(engineSpeed[i], engine.PreviousState.EngineSpeed.AsRPM, Tolerance, string.Format("entry {0}", i)); - Assert.AreEqual(enginePower[i], engine.PreviousState.EnginePower.Value(), Tolerance, string.Format("entry {0}", i)); - absTime += dt; - } - //dataWriter.Finish(); - } - - [TestCase] - public void EngineIdleControllerTest2Truck() - { - VehicleContainer container; - CombustionEngine engine; - ITnOutPort requestPort; - MockGearbox gearbox; - VehicleContainer(TruckEngine, out container, out engine, out requestPort, out gearbox); - - //var dataWriter = new ModalDataWriter("EngienIdle.vmod"); - //container.DataWriter = dataWriter; - - var absTime = 0.SI<Second>(); - var dt = Constants.SimulationSettings.TargetTimeInterval; - - var angularVelocity = 95.5596.SI<PerSecond>(); - - var torque = (engine.ModelData.FullLoadCurves[0].DragLoadStationaryPower(angularVelocity) - 5000.SI<Watt>()) / - angularVelocity; - - var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); - - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - Assert.AreEqual(-14829.79713, response.EnginePowerRequest.Value(), Tolerance); - container.CommitSimulationStep(absTime, dt); - absTime += dt; - - var engineSpeed = new[] { - 1680.RPMtoRad(), 1680.RPMtoRad(), 1467.014.RPMtoRad(), 1272.8658.RPMtoRad(), 1090.989.RPMtoRad(), - 915.3533.RPMtoRad(), 738.599.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), - 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), - 560.RPMtoRad() - }; - - //var enginePower = new[] { - // 5000.SI<Watt>(), 5000.SI<Watt>(), -32832.8834.SI<Watt>(), -25025.1308.SI<Watt>(), -19267.0360.SI<Watt>(), - // -14890.1962.SI<Watt>(), -11500.7991.SI<Watt>(), -8091.0577.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), - // 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), - // 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>() - //}; - - gearbox.SetClutch(false); - var engSpeedResults = new List<dynamic>(); - torque = 0.SI<NewtonMeter>(); - for (var i = 0; i < engineSpeed.Length; i++) { - response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); - - container.CommitSimulationStep(absTime, dt); - - engSpeedResults.Add(new { absTime, engine.PreviousState.EngineSpeed, engine.PreviousState.EnginePower }); - //Assert.AreEqual(engineSpeed[i].Value(), engine.PreviousState.EngineSpeed.Value(), Tolerance); - //Assert.AreEqual(enginePower[i].Value(), engine.PreviousState.EnginePower.Value(), Tolerance); - - absTime += dt; - } - //dataWriter.Finish(); - } - - [TestCase] - public void Test_EngineData() - { - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); - var motorway = engineData.WHTCMotorway; - Assert.AreEqual(motorway, 1); - - var rural = engineData.WHTCRural; - Assert.AreEqual(rural, 1); - - var urban = engineData.WHTCUrban; - Assert.AreEqual(urban, 1); - - var displace = engineData.Displacement; - Assert.AreEqual(0.01273, displace.Value()); - Assert.IsTrue(displace.HasEqualUnit(new SI().Cubic.Meter)); - - var inert = engineData.Inertia; - Assert.AreEqual(3.8, inert.Value(), 0.00001); - Assert.IsTrue(inert.HasEqualUnit(new SI().Kilo.Gramm.Square.Meter)); - - var idle = engineData.IdleSpeed; - Assert.AreEqual(58.6430628670095, idle.Value(), 0.000001); - Assert.IsTrue(idle.HasEqualUnit(0.SI<PerSecond>())); - } - - private static void VehicleContainer(string engineFile, out VehicleContainer container, out CombustionEngine engine, - out ITnOutPort requestPort, out MockGearbox gearbox) - { - container = new VehicleContainer(ExecutionMode.Engineering); - gearbox = new MockGearbox(container); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 1); - - engine = new CombustionEngine(container, engineData); - var clutch = new Clutch(container, engineData); - - var d = new MockDriver(container); - - var aux = new EngineAuxiliary(container); - aux.AddConstant("CONST", 5000.SI<Watt>()); - - gearbox.Gear = 1; - var vehicle = new MockVehicle(container); - vehicle.MyVehicleSpeed = 0.SI<MeterPerSecond>(); - //gearbox.InPort().Connect(engine.OutPort()); - gearbox.InPort().Connect(clutch.OutPort()); - clutch.InPort().Connect(engine.OutPort()); - engine.Connect(aux.Port()); - - // has to be done after connecting components! - clutch.IdleController = engine.IdleController; - - requestPort = gearbox.OutPort(); - - //vehicleContainer.DataWriter = new ModalDataWriter("engine_idle_test.csv"); - var dataWriter = new MockModalDataContainer(); - container.ModData = dataWriter; - container.ModalData.AddAuxiliary("CONST"); - } - } +using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.Linq; +using NUnit.Framework; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; + +// ReSharper disable UnusedVariable +// ReSharper disable NotAccessedVariable +// ReSharper disable CollectionNeverQueried.Local +// ReSharper disable RedundantAssignment + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponent +{ + [TestFixture] + public class CombustionEngineTest + { + protected double Tolerance = 1E-3; + + private const string CoachEngine = @"TestData\Components\24t Coach.veng"; + + private const string TruckEngine = @"TestData\Components\40t_Long_Haul_Truck.veng"; + + [TestCase] + public void TestEngineHasOutPort() + { + var vehicle = new VehicleContainer(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); + var engine = new CombustionEngine(vehicle, engineData); + + var port = engine.OutPort(); + Assert.IsNotNull(port); + } + + [TestCase] + public void TestOutPortRequestNotFailing() + { + var vehicle = new VehicleContainer(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); + var engine = new CombustionEngine(vehicle, engineData); + var gearbox = new MockGearbox(vehicle) { Gear = 0 }; + + var port = engine.OutPort(); + + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); + var torque = 400.SI<NewtonMeter>(); + var engineSpeed = 1500.RPMtoRad(); + + port.Initialize(torque, engineSpeed); + port.Request(absTime, dt, torque, engineSpeed); + } + + [TestCase] + public void TestSimpleModalData() + { + var vehicle = new VehicleContainer(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); + var engine = new CombustionEngine(vehicle, engineData); + var gearbox = new MockGearbox(vehicle) { Gear = 0 }; + var port = engine.OutPort(); + + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); + + var torque = 0.SI<NewtonMeter>(); + var engineSpeed = 600.RPMtoRad(); + var dataWriter = new MockModalDataContainer(); + + port.Initialize(torque, engineSpeed); + for (var i = 0; i < 21; i++) { + port.Request(absTime, dt, torque, engineSpeed); + engine.CommitSimulationStep(dataWriter); + if (i > 0) { + dataWriter.CommitSimulationStep(absTime, dt); + } + absTime += dt; + } + + engineSpeed = 644.4445.RPMtoRad(); + port.Request(absTime, dt, Formulas.PowerToTorque(2329.973.SI<Watt>(), engineSpeed), engineSpeed); + engine.CommitSimulationStep(dataWriter); + + AssertHelper.AreRelativeEqual(1152.40304, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value()); + + dataWriter.CommitSimulationStep(absTime, dt); + absTime += dt; + + var power = new[] { 569.3641, 4264.177 }; + for (var i = 0; i < 2; i++) { + port.Request(absTime, dt, Formulas.PowerToTorque(power[i].SI<Watt>(), engineSpeed), engineSpeed); + engine.CommitSimulationStep(dataWriter); + dataWriter.CommitSimulationStep(absTime, dt); + absTime += dt; + } + + engineSpeed = 869.7512.RPMtoRad(); + port.Request(absTime, dt, Formulas.PowerToTorque(7984.56.SI<Watt>(), engineSpeed), engineSpeed); + engine.CommitSimulationStep(dataWriter); + + Assert.AreEqual(7108.32, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value(), 0.001); + dataWriter.CommitSimulationStep(absTime, dt); + absTime += dt; + + engineSpeed = 644.4445.RPMtoRad(); + port.Request(absTime, dt, Formulas.PowerToTorque(1351.656.SI<Watt>(), engineSpeed), engineSpeed); + engine.CommitSimulationStep(dataWriter); + + Assert.AreEqual(-7108.32, ((SI)dataWriter[ModalResultField.P_eng_inertia]).Value(), 0.001); + dataWriter.CommitSimulationStep(absTime, dt); + + VectoCSVFile.Write(@"test1.csv", dataWriter.Data, true); + } + + [TestCase("Test1Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_1Hz.csv")] + [TestCase("Test10Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz.csv")] + [TestCase("TestvarHz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_varHz.csv")] + [TestCase("Test10Hz", @"TestData\Components\24t Coach_IncPT1.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz_IncPT1.csv")] + public void TestEngineOnlyEngineFullLoadJump(string testName, string engineFile, double rpm, double initialIdleLoad, + double finalIdleLoad, string resultFile) + { + var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 0); + var engine = new EngineOnlyCombustionEngine(vehicleContainer, engineData); + + var expectedResults = VectoCSVFile.Read(resultFile); + + var requestPort = engine.OutPort(); + + //var modalData = new ModalDataWriter(string.Format("load_jump_{0}.csv", TestContext.DataRow["TestName"].ToString())); + var modalData = new MockModalDataContainer(); + + var idlePower = initialIdleLoad.SI<Watt>(); + + var angularSpeed = rpm.RPMtoRad(); + + var t = 0.SI<Second>(); + var dt = 0.1.SI<Second>(); + requestPort.Initialize(Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); + for (; t < 2; t += dt) { + requestPort.Request(t, dt, Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); + engine.CommitSimulationStep(modalData); + } + + var i = 0; + // dt = TimeSpan.FromSeconds(double.Parse(TestContext.DataRow["dt"].ToString(), CultureInfo.InvariantCulture)); + // dt = TimeSpan.FromSeconds(expectedResults.Rows[i].ParseDouble(0)) - t; + var engineLoadPower = engineData.FullLoadCurves[0].FullLoadStationaryPower(angularSpeed); + idlePower = finalIdleLoad.SI<Watt>(); + for (; t < 25; t += dt, i++) { + dt = (expectedResults.Rows[i + 1].ParseDouble(0) - expectedResults.Rows[i].ParseDouble(0)).SI<Second>(); + if (t >= 10.SI<Second>()) { + engineLoadPower = idlePower; + } + requestPort.Request(t, dt, Formulas.PowerToTorque(engineLoadPower, angularSpeed), angularSpeed); + modalData[ModalResultField.time] = t; + modalData[ModalResultField.simulationInterval] = dt; + engine.CommitSimulationStep(modalData); + Assert.AreEqual(expectedResults.Rows[i].ParseDouble(0), t.Value(), 0.001, "Time"); + Assert.AreEqual(expectedResults.Rows[i].ParseDouble(1), ((SI)modalData[ModalResultField.P_eng_full]).Value(), 0.1, + string.Format("Load in timestep {0}", t)); + modalData.CommitSimulationStep(); + } + modalData.Finish(VectoRun.Status.Success); + } + + [TestCase("Test1Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_1Hz.csv")] + [TestCase("Test10Hz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz.csv")] + [TestCase("TestvarHz", @"TestData\Components\24t Coach.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_varHz.csv")] + [TestCase("Test10Hz", @"TestData\Components\24t Coach_IncPT1.veng", 1000, 50, 50, + @"TestData\Results\EngineFullLoadJumps\EngineFLJ_1000rpm_10Hz_IncPT1.csv")] + public void TestEngineFullLoadJump(string testName, string engineFile, double rpm, double initialIdleLoad, + double finalIdleLoad, string resultFile) + { + var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 0); + var engine = new CombustionEngine(vehicleContainer, engineData); + var gearbox = new MockGearbox(vehicleContainer) { Gear = 0 }; + + var expectedResults = VectoCSVFile.Read(resultFile); + + var requestPort = engine.OutPort(); + + //var modalData = new ModalDataWriter(string.Format("load_jump_{0}.csv", TestName)); + var modalData = new MockModalDataContainer(); + + var idlePower = initialIdleLoad.SI<Watt>(); + + var angularSpeed = rpm.RPMtoRad(); + + var t = 0.SI<Second>(); + var dt = 0.1.SI<Second>(); + requestPort.Initialize(Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); + for (; t < 2; t += dt) { + requestPort.Request(t, dt, Formulas.PowerToTorque(idlePower, angularSpeed), angularSpeed); + engine.CommitSimulationStep(modalData); + } + + var i = 0; + // dt = TimeSpan.FromSeconds(double.Parse(TestContext.DataRow["dt"].ToString(), CultureInfo.InvariantCulture)); + // dt = TimeSpan.FromSeconds(expectedResults.Rows[i].ParseDouble(0)) - t; + var engineLoadPower = engineData.FullLoadCurves[0].FullLoadStationaryPower(angularSpeed); + idlePower = finalIdleLoad.SI<Watt>(); + for (; t < 25; t += dt, i++) { + dt = (expectedResults.Rows[i + 1].ParseDouble(0) - expectedResults.Rows[i].ParseDouble(0)).SI<Second>(); + if (t >= 10.SI<Second>()) { + engineLoadPower = idlePower; + } + requestPort.Request(t, dt, Formulas.PowerToTorque(engineLoadPower, angularSpeed), angularSpeed); + modalData[ModalResultField.time] = t; + modalData[ModalResultField.simulationInterval] = dt; + engine.CommitSimulationStep(modalData); + Assert.AreEqual(expectedResults.Rows[i].ParseDouble(0), t.Value(), 0.001, "Time"); + Assert.AreEqual(expectedResults.Rows[i].ParseDouble(1), ((SI)modalData[ModalResultField.P_eng_full]).Value(), 0.1, + string.Format("Load in timestep {0}", t)); + modalData.CommitSimulationStep(); + } + modalData.Finish(VectoRun.Status.Success); + } + + [TestCase] + public void EngineIdleJump() + { + var container = new VehicleContainer(ExecutionMode.Engineering); + var gearbox = new MockGearbox(container); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 1); + var vehicle = new MockVehicle(container); + vehicle.MyVehicleSpeed = 0.SI<MeterPerSecond>(); + var engine = new CombustionEngine(container, engineData); + var clutch = new Clutch(container, engineData); + + var d = new MockDriver(container); + + var aux = new EngineAuxiliary(container); + aux.AddConstant("CONST", 5000.SI<Watt>()); + + gearbox.Gear = 1; + + //gearbox.InPort().Connect(engine.OutPort()); + gearbox.InPort().Connect(clutch.OutPort()); + clutch.InPort().Connect(engine.OutPort()); + engine.Connect(aux.Port()); + clutch.IdleController = engine.IdleController; + + // var expectedResults = VectoCSVFile.Read(TestContext.DataRow["ResultFile"].ToString()); + + var requestPort = gearbox.OutPort(); + + //vehicleContainer.DataWriter = new ModalDataWriter("engine_idle_test.csv"); + var dataWriter = new MockModalDataContainer(); + container.ModData = dataWriter; + container.ModalData.AddAuxiliary("CONST"); + + var torque = 1200.SI<NewtonMeter>(); + var angularVelocity = 800.RPMtoRad(); + + // initialize engine... + + gearbox.Initialize(torque, angularVelocity); + + var absTime = 0.SI<Second>(); + var dt = Constants.SimulationSettings.TargetTimeInterval; + + var response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); + + container.CommitSimulationStep(absTime, dt); + var row = dataWriter.Data.Rows.Cast<DataRow>().Last(); + Assert.AreEqual(100530.96491487339.SI<Watt>().Value(), ((SI)row[ModalResultField.P_eng_out.GetName()]).Value()); + Assert.AreEqual(105530.96491487339.SI<Watt>().Value(), ((SI)row[ModalResultField.P_eng_fcmap.GetName()]).Value()); + Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.P_aux.GetName()]); + Assert.AreEqual(800.RPMtoRad(), row[ModalResultField.n_eng_avg.GetName()]); + + absTime += dt; + + // actual test... + + gearbox.Gear = 0; + gearbox.SetClutch(false); + torque = 0.SI<NewtonMeter>(); + + response = (ResponseSuccess)gearbox.Request(absTime, dt, torque, angularVelocity); + + container.CommitSimulationStep(absTime, dt); + row = dataWriter.Data.Rows.Cast<DataRow>().Last(); + + Assert.AreEqual(0.SI<Watt>(), row[ModalResultField.P_eng_out.GetName()]); + Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.P_aux.GetName()]); + Assert.AreEqual(680.RPMtoRad(), row[ModalResultField.n_eng_avg.GetName()]); + } + + [TestCase] + public void EngineIdleControllerTestCoach() + { + VehicleContainer container; + CombustionEngine engine; + ITnOutPort requestPort; + MockGearbox gearbox; + VehicleContainer(CoachEngine, out container, out engine, out requestPort, out gearbox); + + var absTime = 0.SI<Second>(); + var dt = Constants.SimulationSettings.TargetTimeInterval; + + var angularVelocity = 800.RPMtoRad(); + var torque = 100000.SI<Watt>() / angularVelocity; + + var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); + + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); + Assert.AreEqual(105000, response.EnginePowerRequest.Value(), Tolerance); + container.CommitSimulationStep(absTime, dt); + absTime += dt; + + var engineSpeed = new[] { 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad() }; + var enginePower = new[] { -8601.6308.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>() }; + + gearbox.SetClutch(false); + for (var i = 0; i < engineSpeed.Length; i++) { + torque = 0.SI<NewtonMeter>(); + + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); + container.CommitSimulationStep(absTime, dt); + absTime += dt; + + Assert.AreEqual(engineSpeed[i].Value(), engine.PreviousState.EngineSpeed.Value(), Tolerance, "i: {0}", i); + Assert.AreEqual(enginePower[i].Value(), engine.PreviousState.EnginePower.Value(), Tolerance, "i: {0}", i); + } + } + + /* + * VECTO 2.2 + | time [s] | P_eng_out [kW] | n_eng_avg [1/min] | T_eng_fcmap [Nm] | Gear [-] | + | 59.5 | 349.981 | 1679.281 | 1990.181 | 8 | + | 60.5 | 5 | 1679.281 | 28.43269 | 0 | + | 61.5 | -19.47213 | 1397.271 | -133.0774 | 0 | + | 62.5 | -18.11888 | 1064.296 | -162.5699 | 0 | + | 63.5 | -11.11163 | 714.1923 | -148.571 | 0 | + | 64.5 | -0.5416708 | 560 | -9.236741 | 0 | + | 65.5 | 5 | 560 | 85.26157 | 0 | + | 66.5 | 5 | 560 | 85.26157 | 0 | + | 67.5 | 5 | 560 | 85.26157 | 0 | + | 68.5 | 5 | 560 | 85.26157 | 0 | + | 69.5 | 5 | 560 | 85.26157 | 0 | + | 70.5 | 308.729 | 1284.139 | 2295.815 | 9 | + */ + + [TestCase] + public void EngineIdleControllerTestTruck() + { + VehicleContainer container; + CombustionEngine engine; + ITnOutPort requestPort; + MockGearbox gearbox; + VehicleContainer(TruckEngine, out container, out engine, out requestPort, out gearbox); + + //var dataWriter = new ModalDataWriter("EngineIdle.vmod"); + //container.DataWriter = dataWriter; + + var absTime = 0.SI<Second>(); + var dt = Constants.SimulationSettings.TargetTimeInterval; + + var angularVelocity = 1680.RPMtoRad(); + var torque = 345000.SI<Watt>() / angularVelocity; + + var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); + + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); + Assert.AreEqual(350000, response.EnginePowerRequest.Value(), Tolerance); + container.CommitSimulationStep(absTime, dt); + absTime += dt; + + var engineSpeed = new[] { + 1439.5773, 1225.5363, 1026.6696, 834.1936, 641.1360, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560 + }; + + var enginePower = new[] { + -37334.1588, -27198.2777, -20280.7550, -15216.7221, -11076.6656, -500.7991, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000 + }; + + var fld = engine.ModelData.FullLoadCurves; + + gearbox.SetClutch(false); + var engSpeedResults = new List<dynamic>(); + for (var i = 0; i < 20; i++) { + torque = 0.SI<NewtonMeter>(); + + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); + + container.CommitSimulationStep(absTime, dt); + + engSpeedResults.Add(new { absTime, engine.PreviousState.EngineSpeed, engine.PreviousState.EnginePower }); + Assert.AreEqual(engineSpeed[i], engine.PreviousState.EngineSpeed.AsRPM, Tolerance, string.Format("entry {0}", i)); + Assert.AreEqual(enginePower[i], engine.PreviousState.EnginePower.Value(), Tolerance, string.Format("entry {0}", i)); + absTime += dt; + } + //dataWriter.Finish(); + } + + [TestCase] + public void EngineIdleControllerTest2Truck() + { + VehicleContainer container; + CombustionEngine engine; + ITnOutPort requestPort; + MockGearbox gearbox; + VehicleContainer(TruckEngine, out container, out engine, out requestPort, out gearbox); + + //var dataWriter = new ModalDataWriter("EngienIdle.vmod"); + //container.DataWriter = dataWriter; + + var absTime = 0.SI<Second>(); + var dt = Constants.SimulationSettings.TargetTimeInterval; + + var angularVelocity = 95.5596.SI<PerSecond>(); + + var torque = (engine.ModelData.FullLoadCurves[0].DragLoadStationaryPower(angularVelocity) - 5000.SI<Watt>()) / + angularVelocity; + + var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); + + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); + Assert.AreEqual(-14829.79713, response.EnginePowerRequest.Value(), Tolerance); + container.CommitSimulationStep(absTime, dt); + absTime += dt; + + var engineSpeed = new[] { + 1680.RPMtoRad(), 1680.RPMtoRad(), 1467.014.RPMtoRad(), 1272.8658.RPMtoRad(), 1090.989.RPMtoRad(), + 915.3533.RPMtoRad(), 738.599.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), + 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), + 560.RPMtoRad() + }; + + //var enginePower = new[] { + // 5000.SI<Watt>(), 5000.SI<Watt>(), -32832.8834.SI<Watt>(), -25025.1308.SI<Watt>(), -19267.0360.SI<Watt>(), + // -14890.1962.SI<Watt>(), -11500.7991.SI<Watt>(), -8091.0577.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), + // 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), + // 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>() + //}; + + gearbox.SetClutch(false); + var engSpeedResults = new List<dynamic>(); + torque = 0.SI<NewtonMeter>(); + for (var i = 0; i < engineSpeed.Length; i++) { + response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, 0.RPMtoRad()); + + container.CommitSimulationStep(absTime, dt); + + engSpeedResults.Add(new { absTime, engine.PreviousState.EngineSpeed, engine.PreviousState.EnginePower }); + //Assert.AreEqual(engineSpeed[i].Value(), engine.PreviousState.EngineSpeed.Value(), Tolerance); + //Assert.AreEqual(enginePower[i].Value(), engine.PreviousState.EnginePower.Value(), Tolerance); + + absTime += dt; + } + //dataWriter.Finish(); + } + + [TestCase] + public void Test_EngineData() + { + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); + var motorway = engineData.WHTCMotorway; + Assert.AreEqual(motorway, 1); + + var rural = engineData.WHTCRural; + Assert.AreEqual(rural, 1); + + var urban = engineData.WHTCUrban; + Assert.AreEqual(urban, 1); + + var displace = engineData.Displacement; + Assert.AreEqual(0.01273, displace.Value()); + Assert.IsTrue(displace.HasEqualUnit(new SI().Cubic.Meter)); + + var inert = engineData.Inertia; + Assert.AreEqual(3.8, inert.Value(), 0.00001); + Assert.IsTrue(inert.HasEqualUnit(new SI().Kilo.Gramm.Square.Meter)); + + var idle = engineData.IdleSpeed; + Assert.AreEqual(58.6430628670095, idle.Value(), 0.000001); + Assert.IsTrue(idle.HasEqualUnit(0.SI<PerSecond>())); + } + + private static void VehicleContainer(string engineFile, out VehicleContainer container, out CombustionEngine engine, + out ITnOutPort requestPort, out MockGearbox gearbox) + { + container = new VehicleContainer(ExecutionMode.Engineering); + gearbox = new MockGearbox(container); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineFile, 1); + + engine = new CombustionEngine(container, engineData); + var clutch = new Clutch(container, engineData); + + var d = new MockDriver(container); + + var aux = new EngineAuxiliary(container); + aux.AddConstant("CONST", 5000.SI<Watt>()); + + gearbox.Gear = 1; + var vehicle = new MockVehicle(container); + vehicle.MyVehicleSpeed = 0.SI<MeterPerSecond>(); + //gearbox.InPort().Connect(engine.OutPort()); + gearbox.InPort().Connect(clutch.OutPort()); + clutch.InPort().Connect(engine.OutPort()); + engine.Connect(aux.Port()); + + // has to be done after connecting components! + clutch.IdleController = engine.IdleController; + + requestPort = gearbox.OutPort(); + + //vehicleContainer.DataWriter = new ModalDataWriter("engine_idle_test.csv"); + var dataWriter = new MockModalDataContainer(); + container.ModData = dataWriter; + container.ModalData.AddAuxiliary("CONST"); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs index 47b2e9b7fa66234b79d9947f8cf65bb0004b99c3..1629bf64d7612829b97f7b37e310b185abb66dd2 100644 --- a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs @@ -29,127 +29,137 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.OutputData; - -namespace TUGraz.VectoCore.Tests.Utils -{ - /// <summary> - /// Fake Data Writer Class for Tests. - /// </summary> - internal class MockModalDataContainer : IModalDataContainer - { - public MockModalDataContainer() - { - Data = new ModalResults(); - CurrentRow = Data.NewRow(); - Auxiliaries = new Dictionary<string, DataColumn>(); - } - - public ModalResults Data { get; set; } - public DataRow CurrentRow { get; set; } - - public string ModFileName - { - get { return ""; } - } - - public object this[string auxId] - { - get { return CurrentRow[Auxiliaries[auxId]]; } - set { CurrentRow[Auxiliaries[auxId]] = value; } - } - - public bool HasTorqueConverter { get; set; } - - public void CommitSimulationStep() - { - Data.Rows.Add(CurrentRow); - CurrentRow = Data.NewRow(); - } - - public FuelData.Entry FuelData { get { return VectoCore.Models.Declaration.FuelData.Diesel; } } - - public VectoRun.Status RunStatus - { - get { return VectoRun.Status.Success; } - } - - public string Error { get { return null; } } - public string StackTrace { get { return null; } } - - public void Finish(VectoRun.Status runStatus) {} - - public bool WriteModalResults { get; set; } - - public IEnumerable<T> GetValues<T>(ModalResultField key) - { - return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>((int)key)); - } - - public IEnumerable<T> GetValues<T>(DataColumn col) - { - return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>(col)); - } - - public IEnumerable<T> GetValues<T>(Func<DataRow, T> selectorFunc) - { - throw new NotImplementedException(); - } - - public T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T> - { - throw new NotImplementedException(); - } - - public Dictionary<string, DataColumn> Auxiliaries { get; set; } - - public void SetDataValue(string fieldName, object value) - { - throw new System.NotImplementedException(); - } - - public void AddAuxiliary(string id, string columnName = null) - { - var auxColName = columnName ?? ModalResultField.P_aux_ + id; - if (!Data.Columns.Contains(auxColName)) { - Auxiliaries[id] = Data.Columns.Add(auxColName, typeof(Watt)); - } - Auxiliaries[id] = Data.Columns[auxColName]; - } - - public void Dispose() - { - throw new NotImplementedException(); - } - - public void FinishSimulation(Exception exception) - { - Data.Rows.Clear(); - } - - public string RunName { get; set; } - public string CycleName { get; set; } - public string RunSuffix { get; set; } - - public object this[ModalResultField key] - { - get { return CurrentRow[key.GetName()]; } - set { CurrentRow[key.GetName()] = value; } - } - - public void CommitSimulationStep(Second absTime, Second simulationInterval) - { - CurrentRow[ModalResultField.time.GetName()] = (absTime + simulationInterval / 2); - CurrentRow[ModalResultField.simulationInterval.GetName()] = simulationInterval; - CommitSimulationStep(); - } - } +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.OutputData; + +namespace TUGraz.VectoCore.Tests.Utils +{ + /// <summary> + /// Fake Data Writer Class for Tests. + /// </summary> + internal class MockModalDataContainer : IModalDataContainer + { + public MockModalDataContainer() + { + Data = new ModalResults(); + CurrentRow = Data.NewRow(); + Auxiliaries = new Dictionary<string, DataColumn>(); + } + + public ModalResults Data { get; set; } + public DataRow CurrentRow { get; set; } + + public string ModFileName + { + get { return ""; } + } + + public object this[string auxId] + { + get { return CurrentRow[Auxiliaries[auxId]]; } + set { CurrentRow[Auxiliaries[auxId]] = value; } + } + + public bool HasTorqueConverter { get; set; } + + public void CommitSimulationStep() + { + Data.Rows.Add(CurrentRow); + CurrentRow = Data.NewRow(); + } + + public FuelData.Entry FuelData + { + get { return VectoCore.Models.Declaration.FuelData.Diesel; } + } + + public VectoRun.Status RunStatus + { + get { return VectoRun.Status.Success; } + } + + public string Error + { + get { return null; } + } + + public string StackTrace + { + get { return null; } + } + + public void Finish(VectoRun.Status runStatus, Exception exception = null) {} + + public bool WriteModalResults { get; set; } + + public IEnumerable<T> GetValues<T>(ModalResultField key) + { + return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>((int)key)); + } + + public IEnumerable<T> GetValues<T>(DataColumn col) + { + return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>(col)); + } + + public IEnumerable<T> GetValues<T>(Func<DataRow, T> selectorFunc) + { + throw new NotImplementedException(); + } + + public T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T> + { + throw new NotImplementedException(); + } + + public Dictionary<string, DataColumn> Auxiliaries { get; set; } + + public void SetDataValue(string fieldName, object value) + { + throw new System.NotImplementedException(); + } + + public void AddAuxiliary(string id, string columnName = null) + { + var auxColName = columnName ?? ModalResultField.P_aux_ + id; + if (!Data.Columns.Contains(auxColName)) { + Auxiliaries[id] = Data.Columns.Add(auxColName, typeof(Watt)); + } + Auxiliaries[id] = Data.Columns[auxColName]; + } + + public void Dispose() + { + throw new NotImplementedException(); + } + + public void FinishSimulation() + { + Data.Rows.Clear(); + } + + public string RunName { get; set; } + public string CycleName { get; set; } + public string RunSuffix { get; set; } + + public object this[ModalResultField key] + { + get { return CurrentRow[key.GetName()]; } + set { CurrentRow[key.GetName()] = value; } + } + + public void CommitSimulationStep(Second absTime, Second simulationInterval) + { + CurrentRow[ModalResultField.time.GetName()] = (absTime + simulationInterval / 2); + CurrentRow[ModalResultField.simulationInterval.GetName()] = simulationInterval; + CommitSimulationStep(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoXML.spp b/VectoCore/VectoXML.spp index 3cecbcffd6db892bd816e1a612dcbb9348d83118..913a0ee07df23a144d822fb19eb07b1ab34e58ff 100644 --- a/VectoCore/VectoXML.spp +++ b/VectoCore/VectoXML.spp @@ -31,7 +31,6 @@ <Folder FolderName="HTML Files" ExtStr="html;htm;xhtml;asp"/> <Folder FolderName="DTD/Schemas" ExtStr="dtd;dcd;xdr;biz;xsd"> <File FilePath="VectoCore\Resources\XSD\ParameterDocumentation.xsd" HomeFolder="Yes"/> - <File FilePath="VectoCore\Resources\XSD\VectoCOC.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\VectoComponent.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\VectoDeclarationDefinitions.0.6.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\VectoDeclarationDefinitions.0.8.xsd" HomeFolder="Yes"/> @@ -41,7 +40,8 @@ <File FilePath="VectoCore\Resources\XSD\VectoEngineeringDefinitions.0.7.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\VectoEngineeringInput.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\VectoInput.xsd" HomeFolder="Yes"/> - <File FilePath="VectoCore\Resources\XSD\VectoOutput.xsd" HomeFolder="Yes"/> + <File FilePath="VectoCore\Resources\XSD\VectoOutputCustomer.xsd" HomeFolder="Yes"/> + <File FilePath="VectoCore\Resources\XSD\VectoOutputManufacturer.xsd" HomeFolder="Yes"/> <File FilePath="VectoCore\Resources\XSD\xmldsig-core-schema.xsd" HomeFolder="Yes"/> </Folder> <Folder FolderName="Entities" ExtStr="ent"/>