From e11799bdf5a2cc2752feb64be0c6b004871eb022 Mon Sep 17 00:00:00 2001 From: Michael Krisper <michael.krisper@tugraz.at> Date: Tue, 28 Apr 2015 09:44:00 +0200 Subject: [PATCH] changes for sum file --- .../Simulation/Data/IModalDataWriter.cs | 8 + .../Models/Simulation/Data/ModalDataWriter.cs | 207 +++++++++++++++++- .../Models/Simulation/IVehicleContainer.cs | 42 ++-- .../Models/Simulation/Impl/JobContainer.cs | 10 +- .../Simulation/Impl/SimulatorFactory.cs | 133 +++++------ .../Models/Simulation/Impl/VectoSimulator.cs | 161 +------------- .../Simulation/Impl/VehicleContainer.cs | 22 +- .../Models/Simulation/SimulationTests.cs | 6 +- 8 files changed, 329 insertions(+), 260 deletions(-) diff --git a/VectoCore/Models/Simulation/Data/IModalDataWriter.cs b/VectoCore/Models/Simulation/Data/IModalDataWriter.cs index cd7ad3baa3..81eb386117 100644 --- a/VectoCore/Models/Simulation/Data/IModalDataWriter.cs +++ b/VectoCore/Models/Simulation/Data/IModalDataWriter.cs @@ -1,3 +1,7 @@ +using System; +using System.Collections.Generic; +using System.Data; + namespace TUGraz.VectoCore.Models.Simulation.Data { public interface IModalDataWriter @@ -15,5 +19,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Data void CommitSimulationStep(); void Finish(); + + Object Compute(string expression, string filter); + + IEnumerable<object> GetValues(ModalResultField key); } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Data/ModalDataWriter.cs b/VectoCore/Models/Simulation/Data/ModalDataWriter.cs index cfb75f2132..c658012cfe 100644 --- a/VectoCore/Models/Simulation/Data/ModalDataWriter.cs +++ b/VectoCore/Models/Simulation/Data/ModalDataWriter.cs @@ -1,21 +1,32 @@ +using System.Collections.Generic; using System.Data; +using System.IO; +using System.Linq; using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Simulation.Data { public class ModalDataWriter : IModalDataWriter { - public ModalDataWriter(string fileName) + private string JobName { get; set; } + private SummaryFileWriter SumWriter { get; set; } + private string CycleFileName { get; set; } + private string JobFileName { get; set; } + private ModalResults Data { get; set; } + private DataRow CurrentRow { get; set; } + private string FileName { get; set; } + + + public ModalDataWriter(string fileName, string jobName, string cycleFileName, SummaryFileWriter sumWriter) { FileName = fileName; Data = new ModalResults(); CurrentRow = Data.NewRow(); + SumWriter = sumWriter; + JobName = jobName; + CycleFileName = cycleFileName; } - private ModalResults Data { get; set; } - private DataRow CurrentRow { get; set; } - public string FileName { get; set; } - public void CommitSimulationStep() { Data.Rows.Add(CurrentRow); @@ -25,12 +36,194 @@ namespace TUGraz.VectoCore.Models.Simulation.Data public void Finish() { VectoCSVFile.Write(FileName, Data); + SumWriter.Write(this, jobName, cycleFileName); + } + + public object Compute(string expression, string filter) + { + return Data.Compute(expression, filter); } + public IEnumerable<object> GetValues(ModalResultField key) + { + return Data.Rows.Cast<DataRow>().Select(x => x[(int)key]); + } + + public object this[ModalResultField key] { - get { return CurrentRow[(int) key]; } - set { CurrentRow[(int) key] = value; } + get { return CurrentRow[(int)key]; } + set { CurrentRow[(int)key] = value; } + } + } + + + /* + jobName Unit Description + Job [-] Job number. Format is "x-y" with x = file number and y = cycle number + Input File [-] jobName of the input file + Cycle [-] jobName of the cycle file + time [s] Total simulation time + distance [km] Total travelled distance + speed [km/h] Average vehicle speed + ∆altitude [m] Altitude difference between start and end of cycle + Ppos [kW] Average positive engine power + Pneg [kW] Average negative engine power + FC [g/km] Average fuel consumption + FC-AUXc [g/km] Fuel consumption after Auxiliary-Start/Stop Correction. (Based on FC.) + FC-WHTCc [g/km] Fuel consumption after WHTC Correction. (Based on FC-AUXc.) + Pbrake [kW] Average brake power (not including engine drag) + EposICE [kWh] Total positive engine work + EnegICE [kWh] Total negative engine work (engine brake) + Eair [kWh] Total work of air resistance + Eroll [kWh] Total work of rolling resistance + Egrad [kWh] Total work of gradient resistance + Eacc [kWh] Total work from accelerations (<0) / decelerations (>0) + Eaux [kWh] Total energy demand of auxiliaries + Eaux_xxx [kWh] Energy demand of auxiliary with ID xxx. See also Aux Dialog and Driving Cycle. + Ebrake [kWh] Total work dissipated in mechanical braking (sum of service brakes, retader and additional engine exhaust brakes) + Etransm [kWh] Total work of transmission losses + Eretarder [kWh] Total retarder losses + Mass [kg] Vehicle mass (equals Curb Weight Vehicle plus Curb Weight Extra Trailer/Body, see Vehicle Editor) + Loading [kg] Vehicle loading (see Vehicle Editor) + a [m/s2] Average acceleration + a_pos [m/s2] Average acceleration in acceleration phases* + a_neg [m/s2] Average deceleration in deceleration phases* + Acc.Noise [m/s2] Acceleration noise + pAcc [%] Time share of acceleration phases* + pDec [%] Time share of deceleration phases* + pCruise [%] Time share of cruise phases* + pStop [%] Time share of stop phases* + */ + + public class SummaryFileWriter + { + private readonly DataTable _table; + private readonly string _jobFileName; + private readonly string _sumFileName; + + public SummaryFileWriter(string sumFileName, string jobFileName) + { + _sumFileName = sumFileName; + _jobFileName = jobFileName; + + _table = new DataTable(); + _table.Columns.Add("Job [-]", typeof(string)); + _table.Columns.Add("Input File [-]", typeof(string)); + _table.Columns.Add("Cycle [-]", typeof(string)); + _table.Columns.Add("Time [s]", typeof(double)); + _table.Columns.Add("distance [km]", typeof(double)); + _table.Columns.Add("speed [km/h]", typeof(double)); + _table.Columns.Add("∆altitude [m]", typeof(double)); + _table.Columns.Add("Ppos [kw]", typeof(double)); + _table.Columns.Add("Pneg [kw]", typeof(double)); + _table.Columns.Add("FC [g/km]", typeof(double)); + _table.Columns.Add("FC-AUXc [g/km]", typeof(double)); + _table.Columns.Add("FC-WHTCc [g/km]", typeof(double)); + _table.Columns.Add("Pbrake [kw]", typeof(double)); + _table.Columns.Add("EposICE [kwh]", typeof(double)); + _table.Columns.Add("EnegICE [kwh]", typeof(double)); + _table.Columns.Add("Eair [kwh]", typeof(double)); + _table.Columns.Add("Eroll [kwh]", typeof(double)); + _table.Columns.Add("Egrad [kwh]", typeof(double)); + _table.Columns.Add("Eacc [kwh]", typeof(double)); + _table.Columns.Add("Eaux [kwh]", typeof(double)); + _table.Columns.Add("Eaux_xxx [kwh]", typeof(double)); + _table.Columns.Add("Ebrake [kwh]", typeof(double)); + _table.Columns.Add("Etransm [kwh]", typeof(double)); + _table.Columns.Add("Eretarder [kwh]", typeof(double)); + _table.Columns.Add("Mass [kg]", typeof(double)); + _table.Columns.Add("Loading [kg]", typeof(double)); + _table.Columns.Add("a [m/s2]", typeof(double)); + _table.Columns.Add("a_pos [m/s2]", typeof(double)); + _table.Columns.Add("a_neg [m/s2]", typeof(double)); + _table.Columns.Add("pAcc [%]", typeof(double)); + _table.Columns.Add("pDec [%]", typeof(double)); + _table.Columns.Add("pCruise [%]", typeof(double)); + _table.Columns.Add("pStop [%]", typeof(double)); + } + + + public void Write(IModalDataWriter data, string jobName, string cycleFileName) + { + var row = _table.NewRow(); + row["Job [-]"] = jobName; + row["Input File [-]"] = _jobFileName; + row["Cycle [-]"] = cycleFileName; + row["time [s]"] = data.Compute("Max(time)", ""); + row["distance [km]"] = data.Compute("Max(dist)", ""); + row["speed [km/h]"] = data.Compute("Avg(v_act)", ""); + + + row["Ppos [kw]"] = data.Compute("Avg(Peng)", "Pe_eng > 0"); + row["Pneg [kw]"] = data.Compute("Avg(Peng)", "Pe_eng < 0"); + row["FC [g/km]"] = data.Compute("Avg(FC)", ""); + row["FC-AUXc [g/km]"] = data.Compute("Avg(FC-AUXc)", ""); + row["FC-WHTCc [g/km]"] = data.Compute("Avg(FC-WHTCc)", ""); + row["Pbrake [kw]"] = data.Compute("Avg(Pbrake)", ""); + row["EposICE [kwh]"] = data.Compute("Avg(pos)", "pos > 0"); + row["EnegICE [kwh]"] = data.Compute("Avg(pos)", "pos < 0"); + row["Eair [kwh]"] = data.Compute("Sum(Pair)", ""); + row["Eroll [kwh]"] = data.Compute("Sum(Proll)", ""); + row["Egrad [kwh]"] = data.Compute("Sum(Pgrad)", ""); + row["Eaux [kwh]"] = data.Compute("Sum(Paux)", ""); + row["Ebrake [kwh]"] = data.Compute("Sum(brake)", ""); + row["Etransm [kwh]"] = data.Compute("Sum(transm)", ""); + row["Eretarder [kwh]"] = data.Compute("Sum(retarder)", ""); + row["Eacc [kwh]"] = data.Compute("Sum(Pa+PaGB+PaEng)", ""); + row["a [m/s2]"] = data.Compute("Avg(a)", ""); + + + //todo altitude - calculate when reading the cycle file, add column for altitude + //row["∆altitude [m]"] = Data.Rows[Data.Rows.Count - 1].Field<double>("altitude") - + // Data.Rows[0].Field<double>("altitude"); + + //todo auxiliaries + //foreach (var auxCol in data.Auxiliaries) { + // row["Eaux_" + auxCol.jobName + " [kwh]"] = data.Compute("Sum(aux_" + auxCol.jobName + ")", ""); + //} + + //todo get data from vehicle file + //row["Mass [kg]"] = Container.VehicleMass(); + //row["Loading [kg]"] = Container.LoadingMass(); + + var acceleration = data.GetValues(ModalResultField.acc).Cast<double>().ToList(); + var simInterval = data.GetValues(ModalResultField.simulationInterval).Cast<double>().ToList(); + + //todo dynamic time steps!!! + var runningAverage = (acceleration[0] + acceleration[1] + acceleration[2]) / 3; + var accelerationAvg = new List<double>(); + + for (var i = 2; i < acceleration.Count() - 1; i++) { + runningAverage -= acceleration[i - 2] / 3; + runningAverage += acceleration[i + 1] / 3; + accelerationAvg.Add(runningAverage); + } + + row["a_pos [m/s2]"] = accelerationAvg.Where(x => x > 0.125).Average(); + row["a_neg [m/s2]"] = accelerationAvg.Where(x => x < -0.125).Average(); + + + row["pAcc [%]"] = 100.0 * accelerationAvg.Count(x => x > 0.125) / accelerationAvg.Count; + row["pDec [%]"] = 100.0 * accelerationAvg.Count(x => x < -0.125) / accelerationAvg.Count; + row["pCruise [%]"] = 100.0 * accelerationAvg.Count(x => x < 0.125 && x > -0.125) / accelerationAvg.Count; + + + var velocity = data.GetValues(ModalResultField.v_act).Cast<double>().ToList(); + var timeSum = 0.0; + for (var i = 0; i < velocity.Count; i++) { + if (velocity[i] < 0.1) { + timeSum += simInterval[i]; + } + } + row["pStop [%]"] = 100.0 * timeSum / (double)data.Compute("Max(v_act)", ""); + + _table.ImportRow(row); + } + + public void Finish() + { + VectoCSVFile.Write(_sumFileName, _table); } } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/IVehicleContainer.cs b/VectoCore/Models/Simulation/IVehicleContainer.cs index 16a89af63a..e68e3838f6 100644 --- a/VectoCore/Models/Simulation/IVehicleContainer.cs +++ b/VectoCore/Models/Simulation/IVehicleContainer.cs @@ -4,28 +4,26 @@ using TUGraz.VectoCore.Models.SimulationComponent; namespace TUGraz.VectoCore.Models.Simulation { - /// <summary> - /// Defines Methods for adding components, commiting a simulation step and finishing the simulation. - /// Also defines interfaces for all cockpit access to data. - /// </summary> - public interface IVehicleContainer : ICockpit - { - /// <summary> - /// Adds a component to the vehicle container. - /// </summary> - /// <param name="component"></param> - void AddComponent(VectoSimulationComponent component); + /// <summary> + /// Defines Methods for adding components, commiting a simulation step and finishing the simulation. + /// Also defines interfaces for all cockpit access to data. + /// </summary> + public interface IVehicleContainer : ICockpit + { + /// <summary> + /// Adds a component to the vehicle container. + /// </summary> + /// <param name="component"></param> + void AddComponent(VectoSimulationComponent component); - /// <summary> - /// Commits the current simulation step. - /// </summary> - /// <param name="dataWriter"></param> - void CommitSimulationStep(IModalDataWriter dataWriter); + /// <summary> + /// Commits the current simulation step. + /// </summary> + void CommitSimulationStep(); - /// <summary> - /// Finishes the simulation. - /// </summary> - /// <param name="dataWriter"></param> - void FinishSimulation(IModalDataWriter dataWriter); - } + /// <summary> + /// Finishes the simulation. + /// </summary> + void FinishSimulation(); + } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/JobContainer.cs b/VectoCore/Models/Simulation/Impl/JobContainer.cs index 8a3df18985..f6b420a28c 100644 --- a/VectoCore/Models/Simulation/Impl/JobContainer.cs +++ b/VectoCore/Models/Simulation/Impl/JobContainer.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; using Common.Logging; @@ -6,7 +7,7 @@ using TUGraz.VectoCore.Models.Simulation.Data; namespace TUGraz.VectoCore.Models.Simulation.Impl { - //todo: add job tracking (state of jobs, iteration, ...) + //todo: add job tracking (state of jobs, ...) //todo: add job control (pause, stop) @@ -16,12 +17,14 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public class JobContainer { private readonly List<IVectoSimulator> _simulators = new List<IVectoSimulator>(); + private readonly SummaryFileWriter _sumWriter; public JobContainer() {} public JobContainer(VectoJobData data) { - _simulators.AddRange(SimulatorFactory.CreateJobs(data)); + _sumWriter = new SummaryFileWriter(Path.GetFileNameWithoutExtension(data.FileName) + ".vsum", data.FileName); + _simulators.AddRange(SimulatorFactory.CreateJobs(data, _sumWriter)); } @@ -36,7 +39,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public void RunJobs() { LogManager.GetLogger(GetType()).Info("VectoSimulator started running. Starting Jobs."); + Task.WaitAll(_simulators.Select(job => Task.Factory.StartNew(job.Run)).ToArray()); + + _sumWriter.Finish(); } } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs index d333e246cd..ad748df543 100644 --- a/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs +++ b/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs @@ -24,7 +24,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl return simulator; } - public static IEnumerable<IVectoSimulator> CreateJobs(VectoJobData data) + public static IEnumerable<IVectoSimulator> CreateJobs(VectoJobData data, SummaryFileWriter sumWriter) { foreach (var cycle in data.Cycles) { var builder = new SimulatorBuilder(data.IsEngineOnly); @@ -38,7 +38,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl builder.AddDriver(data.StartStop, data.OverSpeedEcoRoll, data.LookAheadCoasting, data.AccelerationLimitingFile); - var job = builder.Build(cycle, data.FileName); + var job = builder.Build(cycle, data.FileName, sumWriter); yield return job; } @@ -64,14 +64,76 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl _container = new VehicleContainer(); } - public IVectoSimulator Build(string cycleFile, string jobFile) + public IVectoSimulator Build(string cycleFile, string jobFile, SummaryFileWriter sumWriter) { + var modFileName = string.Format("{0}_{1}.vmod", Path.GetFileNameWithoutExtension(jobFile), + Path.GetFileNameWithoutExtension(cycleFile)); + var dataWriter = new ModalDataWriter(modFileName, sumWriter); + + if (_engineOnly) { - return BuildEngineOnly(cycleFile, jobFile); + return BuildEngineOnly(cycleFile, dataWriter, sumWriter); } - return BuildFullPowertrain(cycleFile, jobFile); + return BuildFullPowertrain(cycleFile, dataWriter, sumWriter); + } + + private IVectoSimulator BuildFullPowertrain(string cycleFile, IModalDataWriter dataWriter, + SummaryFileWriter sumWriter) + { + //throw new NotImplementedException("FullPowertrain is not fully implemented yet."); + var cycleData = DrivingCycleData.ReadFromFileEngineOnly(cycleFile); + //todo: make distinction between time based and distance based driving cycle! + var cycle = new TimeBasedDrivingCycle(_container, cycleData); + + _axleGear = null; + _wheels = null; + + // connect cycle --> driver --> vehicle --> wheels --> axleGear --> gearBox --> retarder --> clutch + cycle.InShaft().Connect(_driver.OutShaft()); + _driver.InShaft().Connect(_vehicle.OutShaft()); + _vehicle.InShaft().Connect(_wheels.OutShaft()); + _wheels.InShaft().Connect(_axleGear.OutShaft()); + _axleGear.InShaft().Connect(_gearBox.OutShaft()); + _gearBox.InShaft().Connect(_retarder.OutShaft()); + _retarder.InShaft().Connect(_clutch.OutShaft()); + + // connect directAux --> engine + IAuxiliary directAux = new DirectAuxiliary(_container, new AuxiliaryCycleDataAdapter(cycleData)); + directAux.InShaft().Connect(_engine.OutShaft()); + + // connect aux --> ... --> aux_XXX --> directAux + var previousAux = directAux; + foreach (var auxData in _auxDict) { + var auxCycleData = new AuxiliaryCycleDataAdapter(cycleData, auxData.Key); + IAuxiliary auxiliary = new MappingAuxiliary(_container, auxCycleData, auxData.Value); + auxiliary.InShaft().Connect(previousAux.OutShaft()); + previousAux = auxiliary; + } + + // connect clutch --> aux + _clutch.InShaft().Connect(previousAux.OutShaft()); + + var simulator = new VectoSimulator(_container, cycle, dataWriter, sumWriter); + return simulator; + } + + private IVectoSimulator BuildEngineOnly(string cycleFile, IModalDataWriter dataWriter, SummaryFileWriter sumWriter) + { + var cycleData = DrivingCycleData.ReadFromFileEngineOnly(cycleFile); + var cycle = new EngineOnlyDrivingCycle(_container, cycleData); + + IAuxiliary addAux = new DirectAuxiliary(_container, new AuxiliaryCycleDataAdapter(cycleData)); + addAux.InShaft().Connect(_engine.OutShaft()); + + _gearBox.InShaft().Connect(addAux.OutShaft()); + + cycle.InShaft().Connect(_gearBox.OutShaft()); + + var simulator = new VectoSimulator(_container, cycle); + return simulator; } + public void AddEngine(string engineFile) { var engineData = CombustionEngineData.ReadFromFile(engineFile); @@ -126,67 +188,6 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl var retarderData = RetarderLossMap.ReadFromFile(retarderFile); _retarder = new Retarder(_container, retarderData); } - - private IVectoSimulator BuildFullPowertrain(string cycleFile, string jobFile) - { - //throw new NotImplementedException("FullPowertrain is not fully implemented yet."); - var cycleData = DrivingCycleData.ReadFromFileEngineOnly(cycleFile); - //todo: make distinction between time based and distance based driving cycle! - var cycle = new TimeBasedDrivingCycle(_container, cycleData); - - _axleGear = null; - _wheels = null; - - // connect cycle --> driver --> vehicle --> wheels --> axleGear --> gearBox --> retarder --> clutch - cycle.InShaft().Connect(_driver.OutShaft()); - _driver.InShaft().Connect(_vehicle.OutShaft()); - _vehicle.InShaft().Connect(_wheels.OutShaft()); - _wheels.InShaft().Connect(_axleGear.OutShaft()); - _axleGear.InShaft().Connect(_gearBox.OutShaft()); - _gearBox.InShaft().Connect(_retarder.OutShaft()); - _retarder.InShaft().Connect(_clutch.OutShaft()); - - // connect directAux --> engine - IAuxiliary directAux = new DirectAuxiliary(_container, new AuxiliaryCycleDataAdapter(cycleData)); - directAux.InShaft().Connect(_engine.OutShaft()); - - // connect aux --> ... --> aux_XXX --> directAux - var previousAux = directAux; - foreach (var auxData in _auxDict) { - var auxCycleData = new AuxiliaryCycleDataAdapter(cycleData, auxData.Key); - IAuxiliary auxiliary = new MappingAuxiliary(_container, auxCycleData, auxData.Value); - auxiliary.InShaft().Connect(previousAux.OutShaft()); - previousAux = auxiliary; - } - - // connect clutch --> aux - _clutch.InShaft().Connect(previousAux.OutShaft()); - - var dataWriter = - new ModalDataWriter(string.Format("{0}_{1}.vmod", Path.GetFileNameWithoutExtension(jobFile), - Path.GetFileNameWithoutExtension(cycleFile))); - var simulator = new VectoSimulator(Path.GetFileNameWithoutExtension(jobFile), jobFile, _container, cycle, dataWriter); - return simulator; - } - - private IVectoSimulator BuildEngineOnly(string cycleFile, string jobFile) - { - var cycleData = DrivingCycleData.ReadFromFileEngineOnly(cycleFile); - var cycle = new EngineOnlyDrivingCycle(_container, cycleData); - - IAuxiliary addAux = new DirectAuxiliary(_container, new AuxiliaryCycleDataAdapter(cycleData)); - addAux.InShaft().Connect(_engine.OutShaft()); - - _gearBox.InShaft().Connect(addAux.OutShaft()); - - cycle.InShaft().Connect(_gearBox.OutShaft()); - - var dataWriter = - new ModalDataWriter(string.Format("{0}_{1}.vmod", Path.GetFileNameWithoutExtension(jobFile), - Path.GetFileNameWithoutExtension(cycleFile))); - var simulator = new VectoSimulator(Path.GetFileNameWithoutExtension(jobFile), jobFile, _container, cycle, dataWriter); - return simulator; - } } } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/VectoSimulator.cs b/VectoCore/Models/Simulation/Impl/VectoSimulator.cs index e1bb0f6755..7a260f5b85 100644 --- a/VectoCore/Models/Simulation/Impl/VectoSimulator.cs +++ b/VectoCore/Models/Simulation/Impl/VectoSimulator.cs @@ -1,5 +1,6 @@ using System; using System.Data; +using System.IO; using Common.Logging; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Connector.Ports.Impl; @@ -15,17 +16,15 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl private TimeSpan _absTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0); private TimeSpan _dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0); - public VectoSimulator(string jobName, string jobFileName, IVehicleContainer container, IDrivingCycleOutPort cyclePort, - IModalDataWriter dataWriter) + public VectoSimulator(IVehicleContainer container, IDrivingCycleOutPort cyclePort) { - JobName = jobName; - JobFileName = jobFileName; Container = container; CyclePort = cyclePort; - DataWriter = dataWriter; } - public string JobFileName { get; set; } + protected SummaryFileWriter SumWriter { get; set; } + + protected string JobFileName { get; set; } protected string JobName { get; set; } @@ -56,162 +55,16 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl DataWriter[ModalResultField.time] = (_absTime + TimeSpan.FromTicks(_dt.Ticks / 2)).TotalSeconds; DataWriter[ModalResultField.simulationInterval] = _dt.TotalSeconds; - Container.CommitSimulationStep(DataWriter); + Container.CommitSimulationStep(); // set _dt to difference to next full second. _absTime += _dt; _dt = TimeSpan.FromSeconds(1) - TimeSpan.FromMilliseconds(_dt.Milliseconds); } while (response is ResponseSuccess); - Container.FinishSimulation(DataWriter); - - - //todo: WriteSummary(); + Container.FinishSimulation(); LogManager.GetLogger(GetType()).Info("VectoJob finished."); } - - - /* - jobName Unit Description - Job [-] Job number. Format is "x-y" with x = file number and y = cycle number - Input File [-] jobName of the input file - Cycle [-] jobName of the cycle file - time [s] Total simulation time - distance [km] Total travelled distance - speed [km/h] Average vehicle speed - ∆altitude [m] Altitude difference between start and end of cycle - Ppos [kW] Average positive engine power - Pneg [kW] Average negative engine power - FC [g/km] Average fuel consumption - FC-AUXc [g/km] Fuel consumption after Auxiliary-Start/Stop Correction. (Based on FC.) - FC-WHTCc [g/km] Fuel consumption after WHTC Correction. (Based on FC-AUXc.) - Pbrake [kW] Average brake power (not including engine drag) - EposICE [kWh] Total positive engine work - EnegICE [kWh] Total negative engine work (engine brake) - Eair [kWh] Total work of air resistance - Eroll [kWh] Total work of rolling resistance - Egrad [kWh] Total work of gradient resistance - Eacc [kWh] Total work from accelerations (<0) / decelerations (>0) - Eaux [kWh] Total energy demand of auxiliaries - Eaux_xxx [kWh] Energy demand of auxiliary with ID xxx. See also Aux Dialog and Driving Cycle. - Ebrake [kWh] Total work dissipated in mechanical braking (sum of service brakes, retader and additional engine exhaust brakes) - Etransm [kWh] Total work of transmission losses - Eretarder [kWh] Total retarder losses - Mass [kg] Vehicle mass (equals Curb Weight Vehicle plus Curb Weight Extra Trailer/Body, see Vehicle Editor) - Loading [kg] Vehicle loading (see Vehicle Editor) - a [m/s2] Average acceleration - a_pos [m/s2] Average acceleration in acceleration phases* - a_neg [m/s2] Average deceleration in deceleration phases* - Acc.Noise [m/s2] Acceleration noise - pAcc [%] Time share of acceleration phases* - pDec [%] Time share of deceleration phases* - pCruise [%] Time share of cruise phases* - pStop [%] Time share of stop phases* - */ - - private static class SummaryFile - { - private static DataTable table; - - static SummaryFile() - { - table = new DataTable(); - table.Columns.Add("Job [-]", typeof(string)); - table.Columns.Add("Input File [-]", typeof(string)); - table.Columns.Add("Cycle [-]", typeof(string)); - table.Columns.Add("Time [s]", typeof(double)); - table.Columns.Add("distance [km]", typeof(double)); - table.Columns.Add("speed [km/h]", typeof(double)); - table.Columns.Add("∆altitude [m]", typeof(double)); - table.Columns.Add("Ppos [kw]", typeof(double)); - table.Columns.Add("Pneg [kw]", typeof(double)); - table.Columns.Add("FC [g/km]", typeof(double)); - table.Columns.Add("FC-AUXc [g/km]", typeof(double)); - table.Columns.Add("FC-WHTCc [g/km]", typeof(double)); - table.Columns.Add("Pbrake [kw]", typeof(double)); - table.Columns.Add("EposICE [kwh]", typeof(double)); - table.Columns.Add("EnegICE [kwh]", typeof(double)); - table.Columns.Add("Eair [kwh]", typeof(double)); - table.Columns.Add("Eroll [kwh]", typeof(double)); - table.Columns.Add("Egrad [kwh]", typeof(double)); - table.Columns.Add("Eacc [kwh]", typeof(double)); - table.Columns.Add("Eaux [kwh]", typeof(double)); - table.Columns.Add("Eaux_xxx [kwh]", typeof(double)); - table.Columns.Add("Ebrake [kwh]", typeof(double)); - table.Columns.Add("Etransm [kwh]", typeof(double)); - table.Columns.Add("Eretarder [kwh]", typeof(double)); - table.Columns.Add("Mass [kg]", typeof(double)); - table.Columns.Add("Loading [kg]", typeof(double)); - table.Columns.Add("a [m/s2]", typeof(double)); - table.Columns.Add("a_pos [m/s2]", typeof(double)); - table.Columns.Add("a_neg [m/s2]", typeof(double)); - table.Columns.Add("Acc.Noise [m/s2]", typeof(double)); - table.Columns.Add("pAcc [%]", typeof(double)); - table.Columns.Add("pDec [%]", typeof(double)); - table.Columns.Add("pCruise [%]", typeof(double)); - table.Columns.Add("pStop [%]", typeof(double)); - } - - - private static void WriteSummary(ModalResults modData) - { - //var data = new ModalResults(); - - var row = table.NewRow(); - //row["Job [-]"] = jobName; - //row["Input File [-]"] = jobFileName; - //row["Cycle [-]"] = Container.CycleFileName(); - //row["time [s]"] = data.Compute("Max(time)", ""); - //row["distance [km]"] = data.Compute("Max(distance)", ""); - //row["speed [km/h]"] = data.Compute("Avg(speed)", ""); - //row["∆altitude [m]"] = data.Rows[data.Rows.Count-1].Field<double>("altitude") - data.Rows[0].Field<double>("altitude"); - //row["Ppos [kw]"] = data.Compute("Avg(Peng)", "Peng > 0"); - //row["Pneg [kw]"] = data.Compute("Avg(Peng)", "Peng < 0"); - //row["FC [g/km]"] = data.Compute("Avg(FC)", ""); - //row["FC-AUXc [g/km]"] = data.Compute("Avg(FC-AUXc)", ""); - //row["FC-WHTCc [g/km]"] = data.Compute("Avg(FC-WHTCc)", ""); - //row["Pbrake [kw]"] = data.Compute("Avg(Pbrake)", ""); - //row["EposICE [kwh]"] = data.Compute("Avg(pos)", "pos > 0"); - //row["EnegICE [kwh]"] = data.Compute("Avg(pos)", "pos < 0"); - //row["Eair [kwh]"] = data.Compute("Sum(air)", ""); - //row["Eroll [kwh]"] = data.Compute("Sum(roll)", ""); - //row["Egrad [kwh]"] = data.Compute("Sum(grad)", ""); - //row["Eacc [kwh]"] = data.Compute("Sum(acc)", ""); - //row["Eaux [kwh]"] = data.Compute("Sum(aux)", ""); - - //todo auxiliaries - //foreach (var auxCol in data.Auxiliaries) { - // row["Eaux_" + auxCol.jobName + " [kwh]"] = data.Compute("Sum(aux_" + auxCol.jobName + ")", ""); - //} - - - //row["Ebrake [kwh]"] = data.Compute("Sum(brake)", ""); - //row["Etransm [kwh]"] = data.Compute("Sum(transm)", ""); - //row["Eretarder [kwh]"] = data.Compute("Sum(retarder)", ""); - //row["Mass [kg]"] = Container.VehicleMass(); - //row["Loading [kg]"] = Container.LoadingMass(); - //row["a [m/s2]"] = data.Compute("Avg(a)", ""); - - ////todo: a3s = average over 3 seconds!!! - //row["a_pos [m/s2]"] = data.Compute("Avg(a)", "a > 0.125"); - //row["a_neg [m/s2]"] = data.Compute("Avg(a)", "a < -0.125"); - - //// todo: is this really acc.noise? - //row["Acc.Noise [m/s2]"] = data.Compute("Sum(a)", "a < 0.125 and a > -0.125"); - - //row["pAcc [%]"] = (double) data.Compute("Sum(time_interval)", "a > 0.125") / - // (double) data.Compute("Sum(time_interval)", ""); - //row["pDec [%]"] = (double) data.Compute("Sum(time_interval)", "a > 0.125") / - // (double) data.Compute("Sum(time_interval)", ""); - //row["pCruise [%]"] = (double) data.Compute("Sum(time_interval)", "a > 0.125") / - // (double) data.Compute("Sum(time_interval)", ""); - //row["pStop [%]"] = (double) data.Compute("Sum(time_interval)", "a < 0.125 and a > -0.125") / - // (double) data.Compute("Sum(time_interval)", ""); - - table.ImportRow(row); - //VectoCSVFile.Write(jobFileName, table); - } - } } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index 7013a40b5a..597269ddc0 100644 --- a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -15,6 +15,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl private IEngineCockpit _engine; private IGearboxCockpit _gearbox; private ILog _logger; + private SummaryFileWriter _sumWriter; + private IModalDataWriter _dataWriter; + private string _jobName; + private string _cycleFileName; #region IGearCockpit @@ -49,9 +53,13 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl #endregion - public VehicleContainer() + public VehicleContainer(IModalDataWriter dataWriter, SummaryFileWriter sumWriter, string jobName, string cycleFileName) { _logger = LogManager.GetLogger(GetType()); + _dataWriter = dataWriter; + _sumWriter = sumWriter; + _jobName = jobName; + _cycleFileName = cycleFileName; } #region IVehicleContainer @@ -73,19 +81,21 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl } - public void CommitSimulationStep(IModalDataWriter dataWriter) + public void CommitSimulationStep() { _logger.Info("VehicleContainer committing simulation."); foreach (var component in _components) { - component.CommitSimulationStep(dataWriter); + component.CommitSimulationStep(_dataWriter); } - dataWriter.CommitSimulationStep(); + _dataWriter.CommitSimulationStep(); } - public void FinishSimulation(IModalDataWriter dataWriter) + public void FinishSimulation() { _logger.Info("VehicleContainer finishing simulation."); - dataWriter.Finish(); + _dataWriter.Finish(); + + _sumWriter.Write(_dataWriter, _jobName, _cycleFileName); } #endregion diff --git a/VectoCoreTest/Models/Simulation/SimulationTests.cs b/VectoCoreTest/Models/Simulation/SimulationTests.cs index a11a76fb64..8655c0ecd4 100644 --- a/VectoCoreTest/Models/Simulation/SimulationTests.cs +++ b/VectoCoreTest/Models/Simulation/SimulationTests.cs @@ -118,12 +118,12 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation @"TestData\Results\EngineOnlyCycles\24t Coach_Engine Only2.vmod", @"TestData\Results\EngineOnlyCycles\24t Coach_Engine Only3.vmod" }; - var sumFile = @"24t Coach.vsum"; - var expectedSumFile = "24t Coach-expected.vsum"; + var expectedSumFile = @"TestData\Results\EngineOnlyCycles\24t Coach.vsum"; + var sumFile = @"24t Coach.vsum"; var resultFiles = expectedResultFiles.Select(x => Path.GetFileName(x)); - //Assert.IsTrue(File.Exists(sumFile), "sum file is missing: " + sumFile); + Assert.IsTrue(File.Exists(sumFile), "sum file is missing: " + sumFile); foreach (var result in resultFiles) { Assert.IsTrue(File.Exists(result), "vmod file is missing: " + result); } -- GitLab