Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS will be completely phased out by mid-2025. To see alternatives please check here

Skip to content
Snippets Groups Projects
Commit c2de1ba0 authored by Markus Quaritsch's avatar Markus Quaritsch
Browse files

Merge pull request #48 in VECTO/vecto-sim from...

Merge pull request #48 in VECTO/vecto-sim from ~EMKRISPMI/vecto-sim:feature/VECTO-79-add-jobcontainer-or-similar to develop

* commit 'fef1a3f7':
  added fields for vehicle mass and vehicle loading in sum file
  acceleration average over seconds and 3 second running average
  V79 structurally finished. Still some changes needed (which fields in engineonly mode, correct calculation of the 3second average in sum file).
  sum file gets written. nearly all tests running.
  sum file write / changed some interfaces and testcases
  changes for sum file
  shorter vectojob tests
  tests for reading vecto job file, executing the job and writing moddata
  changed port provider interfaces, finished builder for assembling a full powertrain
  reading of job file, added methods for builder, added new auxiliary class for mapping-auxiliaries
  added test method and test files for job file
  added code comments, corrected error in IsEqual for double comparison with tolerance.
  reading job file, added builder for the powertrain
  faster job tests, all tests runable and successful
  more SI tests, easier SI units
  changed a test to run much faster. temporarily ignored job tests.
  preparings for sum file
  started with classes for reading job file and writing sum file
parents dfc7420d fef1a3f7
No related branches found
No related tags found
No related merge requests found
Showing
with 1019 additions and 290 deletions
......@@ -16,6 +16,7 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AROUND_MULTIPLICATIVE_OP/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RP/@EntryIndexedValue">RP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SI/@EntryIndexedValue">SI</s:String>
<s:Boolean x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=2BF7A1E51991F2458D2D1F0B29CF888B/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=2BF7A1E51991F2458D2D1F0B29CF888B/AbsolutePath/@EntryValue">C:\Workspaces\VisualStudio\VECTO_quam\VECTO.sln.DotSettings</s:String>
......
namespace TUGraz.VectoCore.Models.Connector.Ports
{
/// <summary>
/// Defines a method to acquire an DriverDemand in port.
/// </summary>
public interface IDriverDemandInProvider
{
/// <summary>
/// Returns the inport to connect it to another outport.
/// </summary>
/// <returns></returns>
IDriverDemandInPort InPort();
}
/// <summary>
/// Defines a method to acquire an DriverDemand in port.
/// </summary>
public interface IDriverDemandInProvider
{
/// <summary>
/// Returns the inport to connect it to another outport.
/// </summary>
/// <returns></returns>
IDriverDemandInPort InShaft();
}
/// <summary>
/// Defines a method to acquire an DriverDemand out port.
/// </summary>
public interface IDriverDemandOutProvider
{
/// <summary>
/// Returns the outport to send requests to.
/// </summary>
/// <returns></returns>
IDriverDemandOutPort OutPort();
}
/// <summary>
/// Defines a method to acquire an DriverDemand out port.
/// </summary>
public interface IDriverDemandOutProvider
{
/// <summary>
/// Returns the outport to send requests to.
/// </summary>
/// <returns></returns>
IDriverDemandOutPort OutShaft();
}
}
\ No newline at end of file
......@@ -2,17 +2,17 @@ using System;
namespace TUGraz.VectoCore.Models.Connector.Ports
{
/// <summary>
/// Defines a method to request the outport.
/// </summary>
public interface IDrivingCycleOutPort
{
/// <summary>
/// Requests a demand for a specific absolute time and a time interval dt.
/// </summary>
/// <param name="absTime">The absolute time of the simulation.</param>
/// <param name="dt">The current time interval.</param>
/// <returns></returns>
IResponse Request(TimeSpan absTime, TimeSpan dt);
}
/// <summary>
/// Defines a method to request the outport.
/// </summary>
public interface IDrivingCycleOutPort
{
/// <summary>
/// Requests a demand for a specific absolute time and a time interval dt.
/// </summary>
/// <param name="absTime">The absolute time of the simulation.</param>
/// <param name="dt">The current time interval.</param>
/// <returns></returns>
IResponse Request(TimeSpan absTime, TimeSpan dt);
}
}
\ No newline at end of file
namespace TUGraz.VectoCore.Models.Connector.Ports
{
/// <summary>
/// Defines a method to acquire an DriverCycle Demand out port.
/// </summary>
public interface IDrivingCycleOutProvider
{
/// <summary>
/// Returns the outport to send requests to.
/// </summary>
/// <returns></returns>
IDrivingCycleOutPort OutPort();
}
/// <summary>
/// Defines a method to acquire an DriverCycle Demand out port.
/// </summary>
public interface IDrivingCycleOutProvider
{
/// <summary>
/// Returns the outport to send requests to.
/// </summary>
/// <returns></returns>
IDrivingCycleOutPort OutShaft();
}
}
\ No newline at end of file
namespace TUGraz.VectoCore.Models.Connector.Ports
{
/// <summary>
/// Defines a method to acquire an Fv in port.
/// </summary>
public interface IRoadPortInProvider
{
/// <summary>
/// Returns the inport to connect it to another outport.
/// </summary>
/// <returns></returns>
IFvInPort InPort();
}
/// <summary>
/// Defines a method to acquire an Fv in port.
/// </summary>
public interface IRoadPortInProvider
{
/// <summary>
/// Returns the inport to connect it to another outport.
/// </summary>
/// <returns></returns>
IFvInPort InShaft();
}
/// <summary>
/// Defines a method to acquire an Fv out port.
/// </summary>
public interface IRoadPortOutProvider
{
/// <summary>
/// Returns the outport to send requests to.
/// </summary>
/// <returns></returns>
IFvOutPort OutPort();
}
/// <summary>
/// Defines a method to acquire an Fv out port.
/// </summary>
public interface IRoadPortOutProvider
{
/// <summary>
/// Returns the outport to send requests to.
/// </summary>
/// <returns></returns>
IFvOutPort OutShaft();
}
}
\ No newline at end of file
......@@ -2,15 +2,19 @@
namespace TUGraz.VectoCore.Models.Simulation.Cockpit
{
/// <summary>
/// Defines a method to access shared data of the vehicle.
/// </summary>
public interface IVehicleCockpit
{
/// <summary>
/// Returns the current vehicle speed.
/// </summary>
/// <returns></returns>
MeterPerSecond VehicleSpeed();
}
/// <summary>
/// Defines a method to access shared data of the vehicle.
/// </summary>
public interface IVehicleCockpit
{
/// <summary>
/// Returns the current vehicle speed.
/// </summary>
/// <returns></returns>
MeterPerSecond VehicleSpeed();
double VehicleMass();
double VehicleLoading();
}
}
\ No newline at end of file
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<T> GetValues<T>(ModalResultField key);
}
}
\ No newline at end of file
namespace TUGraz.VectoCore.Models.Simulation.Data
{
public interface ISummaryDataWriter
{
/// <summary>
/// Writes a single sum entry for the given modaldata of the job.
/// </summary>
/// <param name="data">The modal data.</param>
/// <param name="jobFileName">Name of the job file.</param>
/// <param name="jobName">Name of the job.</param>
/// <param name="cycleFileName">Name of the cycle file.</param>
/// <param name="vehicleMass">The vehicle mass.</param>
/// <param name="vehicleLoading">The vehicle loading.</param>
void Write(IModalDataWriter data, string jobFileName, string jobName, string cycleFileName, double vehicleMass,
double vehicleLoading);
/// <summary>
/// Writes the data to the sum file.
/// </summary>
void Finish();
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.Data;
using System.Linq;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.Simulation.Data
{
public class ModalDataWriter : IModalDataWriter
{
public ModalDataWriter(string fileName)
private ModalResults Data { get; set; }
private DataRow CurrentRow { get; set; }
private string ModFileName { get; set; }
public ModalDataWriter(string modFileName)
{
FileName = fileName;
ModFileName = modFileName;
Data = new ModalResults();
CurrentRow = Data.NewRow();
}
private ModalResults Data { get; set; }
private DataRow CurrentRow { get; set; }
public string FileName { get; set; }
public void CommitSimulationStep()
{
Data.Rows.Add(CurrentRow);
......@@ -24,13 +27,63 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
public void Finish()
{
VectoCSVFile.Write(FileName, Data);
VectoCSVFile.Write(ModFileName, Data);
}
public object Compute(string expression, string filter)
{
return Data.Compute(expression, filter);
}
public IEnumerable<T> GetValues<T>(ModalResultField key)
{
return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>((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*
*/
}
\ No newline at end of file
......@@ -14,7 +14,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
{
public ModalResults()
{
foreach (ModalResultField value in Enum.GetValues(typeof (ModalResultField))) {
foreach (ModalResultField value in Enum.GetValues(typeof(ModalResultField))) {
var col = new DataColumn(value.GetName(), value.GetDataType()) { Caption = value.GetCaption() };
Columns.Add(col);
}
......@@ -66,188 +66,188 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
/// Time step [s].
/// Midpoint of the simulated interval.
/// </summary>
[ModalResultField(typeof (double), caption: "time [s]")] time,
[ModalResultField(typeof(double), caption: "time [s]")] time,
/// <summary>
/// Simulation interval around the current time step. [s]
/// </summary>
[ModalResultField(typeof (double), "simulation_interval", "simulation_interval [s]")] simulationInterval,
[ModalResultField(typeof(double), "simulation_interval", "simulation_interval [s]")] simulationInterval,
/// <summary>
/// Engine speed [1/min].
/// </summary>
[ModalResultField(typeof (double), caption: "n [1/min]")] n,
[ModalResultField(typeof(double), caption: "n [1/min]")] n,
/// <summary>
/// [Nm] Engine torque.
/// </summary>
[ModalResultField(typeof (double), caption: "Tq_eng [Nm]")] Tq_eng,
[ModalResultField(typeof(double), caption: "Tq_eng [Nm]")] Tq_eng,
/// <summary>
/// [Nm] Torque at clutch (before clutch, engine-side)
/// </summary>
[ModalResultField(typeof (double), caption: "Tq_clutch [Nm]")] Tq_clutch,
[ModalResultField(typeof(double), caption: "Tq_clutch [Nm]")] Tq_clutch,
/// <summary>
/// [Nm] Full load torque
/// </summary>
[ModalResultField(typeof (double), caption: "Tq_full [Nm]")] Tq_full,
[ModalResultField(typeof(double), caption: "Tq_full [Nm]")] Tq_full,
/// <summary>
/// [Nm] Motoring torque
/// </summary>
[ModalResultField(typeof (double), caption: "Tq_drag [Nm]")] Tq_drag,
[ModalResultField(typeof(double), caption: "Tq_drag [Nm]")] Tq_drag,
/// <summary>
/// [kW] Engine power.
/// </summary>
[ModalResultField(typeof (double), caption: "Pe_eng [kW]")] Pe_eng,
[ModalResultField(typeof(double), caption: "Pe_eng [kW]")] Pe_eng,
/// <summary>
/// [kW] Engine full load power.
/// </summary>
[ModalResultField(typeof (double), caption: "Pe_full [kW]")] Pe_full,
[ModalResultField(typeof(double), caption: "Pe_full [kW]")] Pe_full,
/// <summary>
/// [kW] Engine drag power.
/// </summary>
[ModalResultField(typeof (double), caption: "Pe_drag [kW]")] Pe_drag,
[ModalResultField(typeof(double), caption: "Pe_drag [kW]")] Pe_drag,
/// <summary>
/// [kW] Engine power at clutch (equals Pe minus loss due to rotational inertia Pa Eng).
/// </summary>
[ModalResultField(typeof (double), caption: "Pe_clutch [kW]")] Pe_clutch,
[ModalResultField(typeof(double), caption: "Pe_clutch [kW]")] Pe_clutch,
/// <summary>
/// [kW] Rotational acceleration power: Engine.
/// </summary>
[ModalResultField(typeof (double), "Pa", "Pa [Eng]")] PaEng,
[ModalResultField(typeof(double), "Pa", "Pa [Eng]")] PaEng,
/// <summary>
/// [kW] Total auxiliary power demand .
/// </summary>
[ModalResultField(typeof (double), caption: "Paux [kW]")] Paux,
[ModalResultField(typeof(double), caption: "Paux [kW]")] Paux,
/// <summary>
/// [g/h] Fuel consumption from FC map..
/// </summary>
[ModalResultField(typeof (double), caption: "FC [g/h]")] FC,
[ModalResultField(typeof(double), caption: "FC [g/h]")] FC,
/// <summary>
/// [g/h] Fuel consumption after Auxiliary-Start/Stop Correction. (Based on FC.)
/// </summary>
[ModalResultField(typeof (double), "FC-AUXc", "FC-AUXc [g/h]")] FCAUXc,
[ModalResultField(typeof(double), "FC-AUXc", "FC-AUXc [g/h]")] FCAUXc,
/// <summary>
/// [g/h] Fuel consumption after WHTC Correction. (Based on FC-AUXc.)
/// </summary>
[ModalResultField(typeof (double), "FC-WHTCc", "FC-WHTCc [g/h]")] FCWHTCc,
[ModalResultField(typeof(double), "FC-WHTCc", "FC-WHTCc [g/h]")] FCWHTCc,
/// <summary>
/// [km] Travelled distance.
/// </summary>
[ModalResultField(typeof (double))] dist,
[ModalResultField(typeof(double))] dist,
/// <summary>
/// [km/h] Actual vehicle speed.
/// </summary>
[ModalResultField(typeof (double))] v_act,
[ModalResultField(typeof(double))] v_act,
/// <summary>
/// [km/h] Target vehicle speed.
/// </summary>
[ModalResultField(typeof (double))] v_targ,
[ModalResultField(typeof(double))] v_targ,
/// <summary>
/// [m/s2] Vehicle acceleration.
/// </summary>
[ModalResultField(typeof (double))] acc,
[ModalResultField(typeof(double))] acc,
/// <summary>
/// [%] Road gradient.
/// </summary>
[ModalResultField(typeof (double))] grad,
[ModalResultField(typeof(double))] grad,
/// <summary>
/// [-] GearData. "0" = clutch opened / neutral. "0.5" = lock-up clutch is open (AT with torque converter only, see
/// Gearbox)
/// </summary>
[ModalResultField(typeof (double))] Gear,
[ModalResultField(typeof(double))] Gear,
/// <summary>
/// [kW] Gearbox losses.
/// </summary>
[ModalResultField(typeof (double), "Ploss GB")] PlossGB,
[ModalResultField(typeof(double), "Ploss GB")] PlossGB,
/// <summary>
/// [kW] Losses in differential / axle transmission.
/// </summary>
[ModalResultField(typeof (double), "Ploss Diff")] PlossDiff,
[ModalResultField(typeof(double), "Ploss Diff")] PlossDiff,
/// <summary>
/// [kW] Retarder losses.
/// </summary>
[ModalResultField(typeof (double), "Ploss Retarder")] PlossRetarder,
[ModalResultField(typeof(double), "Ploss Retarder")] PlossRetarder,
/// <summary>
/// [kW] Rotational acceleration power: Gearbox.
/// </summary>
[ModalResultField(typeof (double), "Pa GB")] PaGB,
[ModalResultField(typeof(double), "Pa GB")] PaGB,
/// <summary>
/// [kW] Vehicle acceleration power.
/// </summary>
[ModalResultField(typeof (double), "Pa Veh")] PaVeh,
[ModalResultField(typeof(double), "Pa Veh")] PaVeh,
/// <summary>
/// [kW] Rolling resistance power demand.
/// </summary>
[ModalResultField(typeof (double))] Proll,
[ModalResultField(typeof(double))] Proll,
/// <summary>
/// [kW] Air resistance power demand.
/// </summary>
[ModalResultField(typeof (double))] Pair,
[ModalResultField(typeof(double))] Pair,
/// <summary>
/// [kW] Power demand due to road gradient.
/// </summary>
[ModalResultField(typeof (double))] Pgrad,
[ModalResultField(typeof(double))] Pgrad,
/// <summary>
/// [kW] Total power demand at wheel = sum of rolling, air, acceleration and road gradient resistance.
/// </summary>
[ModalResultField(typeof (double))] Pwheel,
[ModalResultField(typeof(double))] Pwheel,
/// <summary>
/// [kW] Brake power. Drag power is included in Pe.
/// </summary>
[ModalResultField(typeof (double))] Pbrake,
[ModalResultField(typeof(double))] Pbrake,
/// <summary>
/// [kW] Power demand of Auxiliary with ID xxx. See also Aux Dialog and Driving Cycle.
/// </summary>
[ModalResultField(typeof (double))] Paux_xxx,
[ModalResultField(typeof(double))] Paux_xxx,
/// <summary>
/// [-] Torque converter speed ratio
/// </summary>
[ModalResultField(typeof (double))] TCν,
[ModalResultField(typeof(double))] TCν,
/// <summary>
/// [-] Torque converter torque ratio
/// </summary>
[ModalResultField(typeof (double), "TCµ")] TCmu,
[ModalResultField(typeof(double), "TCµ")] TCmu,
/// <summary>
/// [Nm] Torque converter output torque
/// </summary>
[ModalResultField(typeof (double))] TC_M_Out,
[ModalResultField(typeof(double))] TC_M_Out,
/// <summary>
/// [1/min] Torque converter output speed
/// </summary>
[ModalResultField(typeof (double))] TC_n_Out
[ModalResultField(typeof(double))] TC_n_Out
}
......@@ -280,17 +280,17 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
public static string GetCaption(this ModalResultField field)
{
return GetAttr(field).Caption ?? field.GetName() ?? field.ToString();
return GetAttr(field).Caption ?? field.GetName();
}
private static ModalResultFieldAttribute GetAttr(ModalResultField field)
{
return (ModalResultFieldAttribute) Attribute.GetCustomAttribute(ForValue(field), typeof (ModalResultFieldAttribute));
return (ModalResultFieldAttribute)Attribute.GetCustomAttribute(ForValue(field), typeof(ModalResultFieldAttribute));
}
private static MemberInfo ForValue(ModalResultField field)
{
return typeof (ModalResultField).GetField(Enum.GetName(typeof (ModalResultField), field));
return typeof(ModalResultField).GetField(Enum.GetName(typeof(ModalResultField), field));
}
}
}
\ No newline at end of file
using System.Collections.Generic;
using TUGraz.VectoCore.Utils;
using System.Linq;
using System.Data;
namespace TUGraz.VectoCore.Models.Simulation.Data
{
public class SummaryFileWriter : ISummaryDataWriter
{
private readonly DataTable _table;
private readonly string _sumFileName;
/// <summary>
/// Initializes a new instance of the <see cref="SummaryFileWriter"/> class.
/// </summary>
/// <param name="sumFileName">Name of the sum file.</param>
public SummaryFileWriter(string sumFileName)
{
_sumFileName = sumFileName;
_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 jobFileName, string jobName, string cycleFileName, double vehicleMass,
double vehicleLoading)
{
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(Pe_eng)", "Pe_eng > 0");
row["Pneg [kw]"] = data.Compute("Avg(Pe_eng)", "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(Pe_eng)", "Pe_eng > 0");
row["EnegICE [kwh]"] = data.Compute("Avg(Pe_eng)", "Pe_eng < 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(Pbrake)", "");
row["Etransm [kwh]"] = data.Compute("Sum([Ploss Diff]) + Sum([Ploss GB])", "");
row["Eretarder [kwh]"] = data.Compute("Sum([Ploss Retarder])", "");
row["Eacc [kwh]"] = data.Compute("Sum(Pa)+Sum([Pa GB])", ""); // TODO +PaEng?
//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]"] = vehicleMass;
row["Loading [kg]"] = vehicleLoading;
var dtValues = data.GetValues<double>(ModalResultField.simulationInterval).ToList();
var accValues = data.GetValues<double?>(ModalResultField.acc);
var accelerations = CalculateAverageOverSeconds(dtValues, accValues).ToList();
row["a [m/s2]"] = accelerations.Average();
var acceleration3SecondAverage = Calculate3SecondAverage(accelerations).ToList();
row["a_pos [m/s2]"] = acceleration3SecondAverage.Where(x => x > 0.125).DefaultIfEmpty(0).Average();
row["a_neg [m/s2]"] = acceleration3SecondAverage.Where(x => x < -0.125).DefaultIfEmpty(0).Average();
row["pAcc [%]"] = 100.0 * acceleration3SecondAverage.Count(x => x > 0.125) / acceleration3SecondAverage.Count;
row["pDec [%]"] = 100.0 * acceleration3SecondAverage.Count(x => x < -0.125) / acceleration3SecondAverage.Count;
row["pCruise [%]"] = 100.0 * acceleration3SecondAverage.Count(x => x < 0.125 && x > -0.125) /
acceleration3SecondAverage.Count;
var pStopTime = data.GetValues<double?>(ModalResultField.v_act)
.Zip(dtValues, (velocity, dt) => new { velocity, dt })
.Where(x => x.velocity < 0.1)
.Sum(x => x.dt);
row["pStop [%]"] = 100.0 * pStopTime / dtValues.Sum();
_table.Rows.Add(row);
}
private static IEnumerable<double> Calculate3SecondAverage(List<double> accelerations)
{
if (accelerations.Count >= 3) {
var runningAverage = (accelerations[0] + accelerations[1] + accelerations[2]) / 3.0;
for (var i = 2; i < accelerations.Count() - 1; i++) {
runningAverage -= accelerations[i - 2] / 3.0;
runningAverage += accelerations[i + 1] / 3.0;
yield return runningAverage;
}
}
}
private static IEnumerable<double> CalculateAverageOverSeconds(IEnumerable<double> dtValues,
IEnumerable<double?> accValues)
{
var dtSum = 0.0;
var accSum = 0.0;
var acceleration = dtValues.Zip(accValues, (dt, acc) => new { dt, acc }).ToList();
foreach (var x in acceleration.ToList()) {
var currentX = x;
while (dtSum + currentX.dt >= 1) {
var splitX = new { dt = 1 - dtSum, currentX.acc };
yield return accSum;
accSum = 0.0;
dtSum = 0.0;
currentX = new { dt = currentX.dt - splitX.dt, currentX.acc };
}
if (currentX.dt > 0) {
accSum += currentX.dt * currentX.acc ?? 0.0;
dtSum += currentX.dt;
}
}
// return remaining data. acts like extrapolation to next whole second.
if (dtSum > 0) {
yield return accSum;
}
}
public void Finish()
{
VectoCSVFile.Write(_sumFileName, _table);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
namespace TUGraz.VectoCore.Models.Simulation.Data
{
/// <summary>
/// Represents the Vecto Job File. Fileformat: .vecto
/// </summary>
/// <code>
///{
/// "Header": {
/// "CreatedBy": " ()",
/// "Date": "3/4/2015 2:09:13 PM",
/// "AppVersion": "2.0.4-beta3",
/// "FileVersion": 2
/// },
/// "Body": {
/// "SavedInDeclMode": false,
/// "VehicleFile": "24t Coach.vveh",
/// "EngineFile": "24t Coach.veng",
/// "GearboxFile": "24t Coach.vgbx",
/// "Cycles": [
/// "W:\\VECTO\\CITnet\\VECTO\\bin\\Debug\\Declaration\\MissionCycles\\LOT2_rural Engine Only.vdri"
/// ],
/// "Aux": [
/// {
/// "ID": "ALT1",
/// "Type": "Alternator",
/// "Path": "24t_Coach_ALT.vaux",
/// "Technology": ""
/// },
/// {
/// "ID": "ALT2",
/// "Type": "Alternator",
/// "Path": "24t_Coach_ALT.vaux",
/// "Technology": ""
/// },
/// {
/// "ID": "ALT3",
/// "Type": "Alternator",
/// "Path": "24t_Coach_ALT.vaux",
/// "Technology": ""
/// }
/// ],
/// "AccelerationLimitingFile": "Coach.vacc",
/// "IsEngineOnly": true,
/// "StartStop": {
/// "Enabled": false,
/// "MaxSpeed": 5.0,
/// "MinTime": 0.0,
/// "Delay": 0
/// },
/// "LookAheadCoasting": {
/// "Enabled": true,
/// "Dec": -0.5,
/// "MinSpeed": 50.0
/// },
/// "OverSpeedEcoRoll": {
/// "Mode": "OverSpeed",
/// "MinSpeed": 70.0,
/// "OverSpeed": 5.0,
/// "UnderSpeed": 5.0
/// }
/// }
///}
/// </code>
[DataContract]
public class VectoJobData : SimulationComponentData
{
/// <summary>
/// A class which represents the json data format for serializing and deserializing the Job Data files.
/// </summary>
public class Data
{
[JsonProperty(Required = Required.Always)] public DataHeader Header;
[JsonProperty(Required = Required.Always)] public DataBody Body;
public class DataHeader
{
[JsonProperty(Required = Required.Always)] public string CreatedBy;
[JsonProperty(Required = Required.Always)] public DateTime Date;
[JsonProperty(Required = Required.Always)] public string AppVersion;
[JsonProperty(Required = Required.Always)] public double FileVersion;
}
public class DataBody
{
[JsonProperty("SavedInDeclMode")] public bool SavedInDeclarationMode;
[JsonProperty(Required = Required.Always)] public string VehicleFile;
[JsonProperty(Required = Required.Always)] public string EngineFile;
[JsonProperty(Required = Required.Always)] public string GearboxFile;
[JsonProperty(Required = Required.Always)] public IList<string> Cycles;
[JsonProperty] public IList<AuxData> Aux = new List<AuxData>();
[JsonProperty(Required = Required.Always)] public string VACC;
[JsonProperty(Required = Required.Always)] public bool EngineOnlyMode;
[JsonProperty(Required = Required.Always)] public StartStopData StartStop;
[JsonProperty(Required = Required.Always)] public LACData LAC;
[JsonProperty(Required = Required.Always)] public OverSpeedEcoRollData OverSpeedEcoRoll;
public class AuxData
{
[JsonProperty(Required = Required.Always)] public string ID;
[JsonProperty(Required = Required.Always)] public string Type;
[JsonProperty(Required = Required.Always)] public string Path;
[JsonProperty(Required = Required.Always)] public string Technology;
}
public class StartStopData
{
[JsonProperty(Required = Required.Always)] public bool Enabled;
[JsonProperty(Required = Required.Always)] public double MaxSpeed;
[JsonProperty(Required = Required.Always)] public double MinTime;
[JsonProperty(Required = Required.Always)] public double Delay;
}
public class LACData
{
[JsonProperty(Required = Required.Always)] public bool Enabled;
[JsonProperty(Required = Required.Always)] public double Dec;
[JsonProperty(Required = Required.Always)] public double MinSpeed;
}
public class OverSpeedEcoRollData
{
[JsonProperty(Required = Required.Always)] public string Mode;
[JsonProperty(Required = Required.Always)] public double MinSpeed;
[JsonProperty(Required = Required.Always)] public double OverSpeed;
[JsonProperty(Required = Required.Always)] public double UnderSpeed;
}
}
}
[DataMember] private Data _data;
public string VehicleFile
{
get { return _data.Body.VehicleFile; }
}
public string EngineFile
{
get { return _data.Body.EngineFile; }
}
public string GearboxFile
{
get { return _data.Body.GearboxFile; }
}
public IList<string> Cycles
{
get { return _data.Body.Cycles; }
}
public IList<Data.DataBody.AuxData> Aux
{
get { return _data.Body.Aux; }
}
public string AccelerationLimitingFile
{
get { return _data.Body.VACC; }
}
public bool IsEngineOnly
{
get { return _data.Body.EngineOnlyMode; }
}
public Data.DataBody.StartStopData StartStop
{
get { return _data.Body.StartStop; }
}
public Data.DataBody.LACData LookAheadCoasting
{
get { return _data.Body.LAC; }
}
public Data.DataBody.OverSpeedEcoRollData OverSpeedEcoRoll
{
get { return _data.Body.OverSpeedEcoRoll; }
}
public string JobFileName { get; set; }
public static VectoJobData ReadFromFile(string fileName)
{
return ReadFromJson(File.ReadAllText(fileName), Path.GetDirectoryName(fileName), fileName);
}
public static VectoJobData ReadFromJson(string json, string basePath = "", string fileName = "")
{
var data = new VectoJobData();
data.JobFileName = fileName;
//todo handle conversion errors
var d = JsonConvert.DeserializeObject<Data>(json);
data._data = d;
if (d.Header.FileVersion > 2) {
throw new UnsupportedFileVersionException("Unsupported Version of .vecto file. Got Version: " + d.Header.FileVersion);
}
return data;
}
public void WriteToFile(string fileName)
{
//todo handle file exceptions
File.WriteAllText(fileName, ToJson());
}
public string ToJson()
{
_data.Header.Date = DateTime.Now;
_data.Header.FileVersion = 2;
_data.Header.AppVersion = "3.0.0"; // todo: get current app version!
_data.Header.CreatedBy = ""; // todo: get current user
_data.Body.SavedInDeclarationMode = false; //todo: get declaration mode setting
return JsonConvert.SerializeObject(_data, Formatting.Indented);
}
}
}
\ No newline at end of file
using TUGraz.VectoCore.Models.Simulation.Cockpit;
using TUGraz.VectoCore.Models.Simulation.Data;
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(double time, double simulationInterval);
/// <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
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Common.Logging;
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)
/// <summary>
/// Container for simulation jobs.
/// </summary>
public class JobContainer
{
private readonly List<IVectoSimulator> _simulators = new List<IVectoSimulator>();
private readonly ISummaryDataWriter _sumWriter;
private static int _jobNumber;
public JobContainer(ISummaryDataWriter sumWriter)
{
_sumWriter = sumWriter;
}
public JobContainer(VectoJobData data)
{
var sumFileName = Path.GetFileNameWithoutExtension(data.JobFileName);
var sumFilePath = Path.GetDirectoryName(data.JobFileName);
_sumWriter = new SummaryFileWriter(string.Format("{0}.vsum", Path.Combine(sumFilePath, sumFileName)));
AddJobs(data);
}
public void AddJobs(VectoJobData data)
{
_jobNumber++;
_simulators.AddRange(SimulatorFactory.CreateJobs(data, _sumWriter, _jobNumber));
}
public void AddJob(IVectoSimulator sim)
{
_jobNumber++;
_simulators.Add(sim);
}
public void RunSimulation()
/// <summary>
/// Runs all jobs, waits until finished.
/// </summary>
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
using System;
using Common.Logging;
using System.Collections.Generic;
using System.IO;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.SimulationComponent;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Impl;
namespace TUGraz.VectoCore.Models.Simulation.Impl
{
public class SimulatorFactory
{
/// <summary>
/// Creates a time based engine only powertrain and simulation job for the given files.
/// </summary>
/// <param name="engineFile"></param>
/// <param name="cycleFile"></param>
/// <param name="resultFile"></param>
/// <returns></returns>
public static IVectoSimulator CreateTimeBasedEngineOnlyJob(string engineFile, string cycleFile,
string resultFile)
{
Action<string> debug = LogManager.GetLogger<SimulatorFactory>().Debug;
debug("Creating VehicleContainer.");
var container = new VehicleContainer();
debug("SimulationFactory creating cycle.");
var cycleData = DrivingCycleData.ReadFromFileEngineOnly(cycleFile);
var cycle = new EngineOnlyDrivingCycle(container, cycleData);
debug("SimulationFactory creating engine.");
var engineData = CombustionEngineData.ReadFromFile(engineFile);
var engine = new CombustionEngine(container, engineData);
debug("Creating gearbox.");
var gearBox = new EngineOnlyGearbox(container);
debug("SimulationFactory creating auxiliary");
var aux = new EngineOnlyAuxiliary(container, new AuxiliariesDemandAdapter(cycleData));
debug("SimulationFactory connecting auxiliary with engine.");
aux.InShaft().Connect(engine.OutShaft());
debug("SimulationFactory connecting gearbox with auxiliary.");
gearBox.InShaft().Connect(aux.OutShaft());
debug("SimulationFactory connecting cycle with gearbox.");
cycle.InShaft().Connect(gearBox.OutShaft());
var dataWriter = new ModalDataWriter(resultFile);
debug("Creating Simulator.");
var simulator = new VectoSimulator(container, cycle, dataWriter);
return simulator;
}
}
public class SimulatorFactory
{
private static IModalDataWriter _dataWriter;
/// <summary>
/// Creates a simulation job for time based engine only powertrain.
/// </summary>
public static IVectoSimulator CreateTimeBasedEngineOnlyJob(string engineFile, string cycleFile,
IModalDataWriter dataWriter, SummaryFileWriter sumWriter)
{
var builder = new SimulatorBuilder(dataWriter, sumWriter, "", "", cycleFile, engineOnly: true);
builder.AddEngine(engineFile);
var simulator = builder.Build(cycleFile);
return simulator;
}
public static IEnumerable<IVectoSimulator> CreateJobs(VectoJobData data, ISummaryDataWriter sumWriter, int jobNumber)
{
for (var i = 0; i < data.Cycles.Count; i++) {
var cycleFile = data.Cycles[i];
var jobName = string.Format("{0}-{1}", jobNumber, i);
var modFileName = string.Format("{0}_{1}.vmod", Path.GetFileNameWithoutExtension(data.JobFileName),
Path.GetFileNameWithoutExtension(cycleFile));
_dataWriter = new ModalDataWriter(modFileName);
var builder = new SimulatorBuilder(_dataWriter, sumWriter, data.JobFileName, jobName, cycleFile, data.IsEngineOnly);
builder.AddEngine(data.EngineFile);
if (!data.IsEngineOnly) {
builder.AddVehicle(data.VehicleFile);
builder.AddGearbox(data.GearboxFile);
foreach (var aux in data.Aux) {
builder.AddAuxiliary(aux.Path, aux.ID);
}
builder.AddDriver(data.StartStop, data.OverSpeedEcoRoll, data.LookAheadCoasting,
data.AccelerationLimitingFile);
}
var job = builder.Build(cycleFile);
yield return job;
}
}
public class SimulatorBuilder
{
private readonly bool _engineOnly;
private readonly VehicleContainer _container;
private ICombustionEngine _engine;
private IGearbox _gearBox;
private IVehicle _vehicle;
private IWheels _wheels;
private IDriver _driver;
private readonly Dictionary<string, AuxiliaryData> _auxDict = new Dictionary<string, AuxiliaryData>();
private IPowerTrainComponent _retarder;
private IClutch _clutch;
private IPowerTrainComponent _axleGear;
public SimulatorBuilder(IModalDataWriter dataWriter, ISummaryDataWriter sumWriter, string jobFileName, string jobName,
string cycleFile, bool engineOnly)
{
_engineOnly = engineOnly;
_container = new VehicleContainer(dataWriter, sumWriter, jobFileName, jobName, cycleFile);
}
public IVectoSimulator Build(string cycleFile)
{
if (_engineOnly) {
return BuildEngineOnly(cycleFile);
}
return BuildFullPowertrain(cycleFile);
}
private IVectoSimulator BuildFullPowertrain(string cycleFile)
{
//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);
return simulator;
}
private IVectoSimulator BuildEngineOnly(string cycleFile)
{
var cycleData = DrivingCycleData.ReadFromFileEngineOnly(cycleFile);
var cycle = new EngineOnlyDrivingCycle(_container, cycleData);
IAuxiliary addAux = new DirectAuxiliary(_container, new AuxiliaryCycleDataAdapter(cycleData));
addAux.InShaft().Connect(_engine.OutShaft());
if (_gearBox == null) {
_gearBox = new EngineOnlyGearbox(_container);
}
_gearBox.InShaft().Connect(addAux.OutShaft());
cycle.InShaft().Connect(_gearBox.OutShaft());
var simulator = new VectoSimulator(_container, cycle);
return simulator;
}
public void AddCycle(string cycleFile) {}
public void AddEngine(string engineFile)
{
var engineData = CombustionEngineData.ReadFromFile(engineFile);
_engine = new CombustionEngine(_container, engineData);
AddClutch(engineFile);
}
public void AddClutch(string engineFile)
{
var engineData = CombustionEngineData.ReadFromFile(engineFile);
_clutch = new Clutch(_container, engineData);
}
public void AddGearbox(string gearboxFile)
{
_gearBox = new Gearbox(_container);
}
public void AddAuxiliary(string auxFileName, string auxID)
{
_auxDict[auxID] = AuxiliaryData.ReadFromFile(auxFileName);
}
public void AddDriver(VectoJobData.Data.DataBody.StartStopData startStop,
VectoJobData.Data.DataBody.OverSpeedEcoRollData overSpeedEcoRoll,
VectoJobData.Data.DataBody.LACData lookAheadCoasting, string accelerationLimitingFile)
{
if (_engineOnly) {
return;
}
var driverData = new DriverData(startStop, overSpeedEcoRoll, lookAheadCoasting, accelerationLimitingFile);
_driver = new Driver(driverData);
}
public void AddVehicle(string vehicleFile)
{
if (_engineOnly) {
return;
}
var vehicleData = VehicleData.ReadFromFile(vehicleFile);
_vehicle = new Vehicle(_container, vehicleData);
}
public void AddRetarder(string retarderFile)
{
var retarderData = RetarderLossMap.ReadFromFile(retarderFile);
_retarder = new Retarder(_container, retarderData);
}
}
}
}
\ No newline at end of file
using System;
using System;
using System.Data;
using System.IO;
using Common.Logging;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
......@@ -6,58 +8,64 @@ using TUGraz.VectoCore.Models.Simulation.Data;
namespace TUGraz.VectoCore.Models.Simulation.Impl
{
public class VectoSimulator : IVectoSimulator
{
private TimeSpan _absTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0);
private TimeSpan _dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0);
public VectoSimulator(IVehicleContainer container, IDrivingCycleOutPort cycle, IModalDataWriter dataWriter)
{
Container = container;
Cycle = cycle;
DataWriter = dataWriter;
}
protected IDrivingCycleOutPort Cycle { get; set; }
protected IModalDataWriter DataWriter { get; set; }
protected IVehicleContainer Container { get; set; }
public IVehicleContainer GetContainer()
{
return Container;
}
public void Run()
{
LogManager.GetLogger(GetType()).Info("VectoJob started running.");
IResponse response;
do {
response = Cycle.Request(_absTime, _dt);
while (response is ResponseFailTimeInterval) {
_dt = (response as ResponseFailTimeInterval).DeltaT;
response = Cycle.Request(_absTime, _dt);
}
if (response is ResponseCycleFinished) {
break;
}
DataWriter[ModalResultField.time] = (_absTime + TimeSpan.FromTicks(_dt.Ticks / 2)).TotalSeconds;
DataWriter[ModalResultField.simulationInterval] = _dt.TotalSeconds;
Container.CommitSimulationStep(DataWriter);
// 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: write vsum file
LogManager.GetLogger(GetType()).Info("VectoJob finished.");
}
}
/// <summary>
/// Simulator for one vecto simulation job.
/// </summary>
public class VectoSimulator : IVectoSimulator
{
private TimeSpan _absTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0);
private TimeSpan _dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0);
public VectoSimulator(IVehicleContainer container, IDrivingCycleOutPort cyclePort)
{
Container = container;
CyclePort = cyclePort;
}
protected SummaryFileWriter SumWriter { get; set; }
protected string JobFileName { get; set; }
protected string JobName { get; set; }
protected IDrivingCycleOutPort CyclePort { get; set; }
protected IModalDataWriter DataWriter { get; set; }
protected IVehicleContainer Container { get; set; }
public IVehicleContainer GetContainer()
{
return Container;
}
public void Run()
{
LogManager.GetLogger(GetType()).Info("VectoJob started running.");
IResponse response;
do {
response = CyclePort.Request(_absTime, _dt);
while (response is ResponseFailTimeInterval) {
_dt = (response as ResponseFailTimeInterval).DeltaT;
response = CyclePort.Request(_absTime, _dt);
}
if (response is ResponseCycleFinished) {
break;
}
var time = (_absTime + TimeSpan.FromTicks(_dt.Ticks / 2)).TotalSeconds;
var simulationInterval = _dt.TotalSeconds;
Container.CommitSimulationStep(time, simulationInterval);
// set _dt to difference to next full second.
_absTime += _dt;
_dt = TimeSpan.FromSeconds(1) - TimeSpan.FromMilliseconds(_dt.Milliseconds);
} while (response is ResponseSuccess);
Container.FinishSimulation();
LogManager.GetLogger(GetType()).Info("VectoJob finished.");
}
}
}
\ No newline at end of file
......@@ -14,6 +14,13 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
private readonly IList<VectoSimulationComponent> _components = new List<VectoSimulationComponent>();
private IEngineCockpit _engine;
private IGearboxCockpit _gearbox;
private IVehicleCockpit _vehicle;
private ILog _logger;
private ISummaryDataWriter _sumWriter;
private IModalDataWriter _dataWriter;
private string _jobName;
private string _cycleFileName;
private string _jobFileName;
#region IGearCockpit
......@@ -29,7 +36,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
#region IEngineCockpit
public PerSecond EngineSpeed()
public PerSecond EngineSpeed()
{
if (_engine == null) {
throw new VectoException("no engine available!");
......@@ -43,18 +50,40 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
public MeterPerSecond VehicleSpeed()
{
throw new VectoException("no vehicle available!");
return _vehicle != null ? _vehicle.VehicleSpeed() : 0.SI<MeterPerSecond>();
}
public double VehicleMass()
{
return _vehicle != null ? _vehicle.VehicleMass() : 0;
}
public double VehicleLoading()
{
return _vehicle != null ? _vehicle.VehicleLoading() : 0;
}
#endregion
public VehicleContainer(IModalDataWriter dataWriter = null, ISummaryDataWriter sumWriter = null,
string jobFileName = "",
string jobName = "",
string cycleFileName = "")
{
_logger = LogManager.GetLogger(GetType());
_dataWriter = dataWriter;
_sumWriter = sumWriter;
_jobFileName = jobFileName;
_jobName = jobName;
_cycleFileName = cycleFileName;
}
#region IVehicleContainer
public virtual void AddComponent(VectoSimulationComponent component)
{
_components.Add(component);
// TODO: refactor the following to use polymorphism?
var engine = component as IEngineCockpit;
if (engine != null) {
_engine = engine;
......@@ -64,22 +93,32 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
if (gearbox != null) {
_gearbox = gearbox;
}
var vehicle = component as IVehicleCockpit;
if (vehicle != null) {
_vehicle = vehicle;
}
}
public void CommitSimulationStep(IModalDataWriter dataWriter)
public void CommitSimulationStep(double time, double simulationInterval)
{
LogManager.GetLogger(GetType()).Info("VehicleContainer committing simulation.");
_logger.Info("VehicleContainer committing simulation.");
foreach (var component in _components) {
component.CommitSimulationStep(dataWriter);
component.CommitSimulationStep(_dataWriter);
}
dataWriter.CommitSimulationStep();
_dataWriter[ModalResultField.time] = time;
_dataWriter[ModalResultField.simulationInterval] = simulationInterval;
_dataWriter.CommitSimulationStep();
}
public void FinishSimulation(IModalDataWriter dataWriter)
public void FinishSimulation()
{
LogManager.GetLogger(GetType()).Info("VehicleContainer finishing simulation.");
dataWriter.Finish();
_logger.Info("VehicleContainer finishing simulation.");
_dataWriter.Finish();
_sumWriter.Write(_dataWriter, _jobFileName, _jobName, _cycleFileName, VehicleMass(), VehicleLoading());
}
#endregion
......
......@@ -7,16 +7,15 @@ using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Data
{
public class AuxiliariesDemandAdapter
public class AuxiliaryCycleDataAdapter : IAuxiliaryCycleData
{
private readonly string _auxiliaryId;
private readonly DrivingCycleData _drivingCycle;
private readonly IEnumerator<DrivingCycleData.DrivingCycleEntry> _nextCycleEntry;
//protected DrivingCycleData.DrivingCycleEntry NextCycleEntry { get { return _nextCycleEntry.Current; } }
private readonly ILog Log;
public AuxiliariesDemandAdapter(DrivingCycleData inputData, string column = null)
public AuxiliaryCycleDataAdapter(DrivingCycleData inputData, string column = null)
{
Log = LogManager.GetLogger(GetType());
_drivingCycle = inputData;
......
......@@ -69,7 +69,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
public SI Displacement
{
get { return _data.Body.Displacement.SI().Cubic.Centi.Meter.ConvertTo().Cubic.Meter.Value(); }
protected set { _data.Body.Displacement = (double) value.ConvertTo().Cubic.Centi.Meter; }
protected set { _data.Body.Displacement = (double)value.ConvertTo().Cubic.Centi.Meter; }
}
/// <summary>
......@@ -78,7 +78,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
public PerSecond IdleSpeed
{
get { return _data.Body.IdleSpeed.RPMtoRad(); }
protected set { _data.Body.IdleSpeed = (double) value.ConvertTo().Rounds.Per.Minute; }
protected set { _data.Body.IdleSpeed = (double)value.ConvertTo().Rounds.Per.Minute; }
}
/// <summary>
......@@ -87,7 +87,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
public SI Inertia
{
get { return _data.Body.Inertia.SI().Kilo.Gramm.Square.Meter; }
protected set { _data.Body.Inertia = (double) value.ConvertTo().Kilo.Gramm.Square.Meter; }
protected set { _data.Body.Inertia = (double)value.ConvertTo().Kilo.Gramm.Square.Meter; }
}
/// <summary>
......@@ -96,7 +96,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
public SI WHTCUrban
{
get { return _data.Body.WHTCUrban.SI().Gramm.Per.Kilo.Watt.Hour.ConvertTo().Kilo.Gramm.Per.Watt.Second.Value(); }
protected set { _data.Body.WHTCUrban = (double) value.ConvertTo().Gramm.Per.Kilo.Watt.Hour; }
protected set { _data.Body.WHTCUrban = (double)value.ConvertTo().Gramm.Per.Kilo.Watt.Hour; }
}
/// <summary>
......@@ -105,16 +105,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
public SI WHTCRural
{
get { return _data.Body.WHTCRural.SI().Gramm.Per.Kilo.Watt.Hour.ConvertTo().Kilo.Gramm.Per.Watt.Second.Value(); }
protected set { _data.Body.WHTCRural = (double) value.ConvertTo().Gramm.Per.Kilo.Watt.Hour; }
protected set { _data.Body.WHTCRural = (double)value.ConvertTo().Gramm.Per.Kilo.Watt.Hour; }
}
/// <summary>
/// [g/Ws]
/// [kg/Ws]
/// </summary>
public SI WHTCMotorway
{
get { return _data.Body.WHTCMotorway.SI().Gramm.Per.Kilo.Watt.Hour.ConvertTo().Kilo.Gramm.Per.Watt.Second.Value(); }
protected set { _data.Body.WHTCMotorway = (double) value.ConvertTo().Gramm.Per.Kilo.Watt.Hour; }
protected set { _data.Body.WHTCMotorway = (double)value.ConvertTo().Gramm.Per.Kilo.Watt.Hour; }
}
[DataMember]
......@@ -168,7 +168,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
public FullLoadCurve GetFullLoadCurve(uint gear)
{
var curve = _fullLoadCurves.FirstOrDefault(kv => kv.Key.Contains(gear));
if (curve.Key.Equals(null)) {
if (curve.Key == null) {
throw new KeyNotFoundException(string.Format("GearData '{0}' was not found in the FullLoadCurves.", gear));
}
......@@ -260,7 +260,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
if (obj.GetType() != GetType()) {
return false;
}
return Equals((DataFullLoadCurve) obj);
return Equals((DataFullLoadCurve)obj);
}
public override int GetHashCode()
......@@ -301,7 +301,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
if (obj.GetType() != GetType()) {
return false;
}
return Equals((DataBody) obj);
return Equals((DataBody)obj);
}
public override int GetHashCode()
......@@ -342,7 +342,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
if (obj.GetType() != GetType()) {
return false;
}
return Equals((Data) obj);
return Equals((Data)obj);
}
public override int GetHashCode()
......@@ -359,18 +359,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof (string) || base.CanConvertFrom(context, sourceType);
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return value.GetType() == typeof (string)
? new Range((string) value)
return value.GetType() == typeof(string)
? new Range((string)value)
: base.ConvertFrom(context, culture, value);
}
}
[TypeConverter(typeof (RangeConverter))]
[TypeConverter(typeof(RangeConverter))]
private class Range
{
private readonly uint _end;
......@@ -413,13 +413,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
if (obj.GetType() != GetType()) {
return false;
}
return Equals((Range) obj);
return Equals((Range)obj);
}
public override int GetHashCode()
{
unchecked {
return (int) ((_start * 397) ^ _end);
return (int)((_start * 397) ^ _end);
}
}
......@@ -447,7 +447,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
if (obj.GetType() != GetType()) {
return false;
}
return Equals((CombustionEngineData) obj);
return Equals((CombustionEngineData)obj);
}
public override int GetHashCode()
......
using System;
using TUGraz.VectoCore.Models.Simulation.Data;
namespace TUGraz.VectoCore.Models.SimulationComponent.Data
{
public class DriverData
{
public DriverData(VectoJobData.Data.DataBody.StartStopData startStop,
VectoJobData.Data.DataBody.OverSpeedEcoRollData overSpeedEcoRoll,
VectoJobData.Data.DataBody.LACData lookAheadCoasting, string accelerationLimitingFile)
{
throw new NotImplementedException();
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment