Code development platform for open source projects from the European Union institutions

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

renaming ports, adding new port, reading vehicle data, test for vehicle...

renaming ports, adding new port, reading vehicle data, test for vehicle (without cross-wind correction)
parent 6eb09812
No related branches found
No related tags found
No related merge requests found
Showing
with 629 additions and 187 deletions
......@@ -20,12 +20,12 @@ namespace TUGraz.VectoCore.Models.Connector.Ports
public interface IDriverDemandOutPort
{
/// <summary>
/// Requests the Outport with the given velocity [m/s] and road gradient [rad].
/// Requests the Outport with the given accelleration [m/s] and road gradient [rad].
/// </summary>
/// <param name="absTime">[s]</param>
/// <param name="dt">[s]</param>
/// <param name="velocity">[m/s]</param>
/// <param name="accelleration">[m/s^2]</param>
/// <param name="gradient">[rad]</param>
IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSecond velocity, Radian gradient);
IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSquareSecond accelleration, Radian gradient);
}
}
\ No newline at end of file
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 InPort();
}
/// <summary>
/// Defines a method to acquire an DriverDemand out port.
/// </summary>
public interface IDriverDemandOutProvider
{
/// <summary>
/// Returns the outport to send requests to.
/// </summary>
/// <returns></returns>
IDriverDemandOutPort OutPort();
}
/// <summary>
/// Defines a method to acquire an DriverDemand out port.
/// </summary>
public interface IDriverDemandOutProvider
{
/// <summary>
/// Returns the outport to send requests to.
/// </summary>
/// <returns></returns>
IDriverDemandOutPort OutPort();
}
}
\ No newline at end of file
using System;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.Connector.Ports
{
/// <summary>
/// Defines a connect method to connect the inport to an outport.
/// </summary>
public interface IDrivingCycleDemandInPort
{
/// <summary>
/// Connects the inport to another outport.
/// </summary>
void Connect(IDrivingCycleDemandOutPort other);
}
/// <summary>
/// Defines a request method for a DriverDemand-Out-Port.
/// </summary>
public interface IDrivingCycleDemandOutPort
{
/// <summary>
/// Requests the Outport with the given velocity [m/s] and road gradient [rad].
/// </summary>
/// <param name="absTime">[s]</param>
/// <param name="dt">[s]</param>
/// <param name="velocity">[m/s]</param>
/// <param name="gradient">[rad]</param>
IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSecond velocity, Radian gradient);
}
}
\ No newline at end of file
namespace TUGraz.VectoCore.Models.Connector.Ports
{
/// <summary>
/// Defines a method to acquire an DriverDemand in port.
/// </summary>
public interface IDrivingCycleDemandInProvider
{
/// <summary>
/// Returns the inport to connect it to another outport.
/// </summary>
/// <returns></returns>
IDrivingCycleDemandInPort InPort();
}
/// <summary>
/// Defines a method to acquire an DriverDemand out port.
/// </summary>
public interface IDrivingCycleDemandOutProvider
{
/// <summary>
/// Returns the outport to send requests to.
/// </summary>
/// <returns></returns>
IDrivingCycleDemandOutPort OutPort();
}
}
\ No newline at end of file
using System;
using Common.Logging;
using Newtonsoft.Json;
namespace TUGraz.VectoCore.Models.SimulationComponent.Data
{
......@@ -11,5 +12,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
{
Log = LogManager.GetLogger(GetType());
}
protected static int GetFileVersion(string jsonStr)
{
dynamic json = JsonConvert.DeserializeObject(jsonStr);
return json.Header.FileVersion;
}
}
}
\ No newline at end of file
......@@ -40,9 +40,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
AxleConfig8x8,
}
[DataMember] private Data _data;
[DataMember] private DataV5Engineering _data;
[DataMember] private VehicleCategory _vehicleCategory;
[DataMember]
protected DataV5Engineering Data
{
get { return _data; }
set
{
_data = value;
_data.SetProperties(this);
}
}
[DataMember] private CrossWindCorrectionMode _crossWindCorrectionMode;
......@@ -52,6 +61,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
[DataMember] private AxleConfiguration _axleConfiguration;
[DataMember]
public string BasePath { get; protected set; }
protected VehicleData(string basePath)
{
BasePath = basePath;
}
public bool SavedInDeclarationMode
{
......@@ -59,28 +75,41 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
set { _data.Body.SavedInDeclarationMode = value; }
}
[DataMember] private VehicleCategory _vehicleCategory;
public VehicleCategory Category
{
get { return _vehicleCategory; }
protected set { _vehicleCategory = value; }
set
{
_vehicleCategory = value;
_data.Body.VehicleCategoryStr = value.ToString();
}
}
public double CurbWeight
public Kilogram CurbWeight
{
get { return _data.Body.CurbWeight; }
set { _data.Body.CurbWeight = value; }
get { return _data.Body.CurbWeight.SI<Kilogram>(); }
set { _data.Body.CurbWeight = value.Double(); }
}
public double CurbWeigthExtra
public Kilogram CurbWeigthExtra
{
get { return _data.Body.CurbWeightExtra; }
set { _data.Body.CurbWeightExtra = value; }
get { return _data.Body.CurbWeightExtra.SI<Kilogram>(); }
set { _data.Body.CurbWeightExtra = value.Double(); }
}
public double Loading
public Kilogram Loading
{
get { return _data.Body.Loading; }
set { _data.Body.Loading = value; }
get { return _data.Body.Loading.SI<Kilogram>(); }
set { _data.Body.Loading = value.Double(); }
}
public Kilogram TotalVehicleWeight()
{
return CurbWeight + CurbWeigthExtra + Loading;
}
public Kilogram GrossVehicleMassRating
......@@ -119,6 +148,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
set { _data.Body.DynamicTyreRadius = (double) value.ConvertTo().Milli.Meter; }
}
public Kilogram ReducedMassWheels { get; set; }
public string Rim
{
get { throw new NotImplementedException(); }
......@@ -128,7 +159,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
public CrossWindCorrectionMode CrossWindCorrection
{
get { return _crossWindCorrectionMode; }
protected set { _crossWindCorrectionMode = value; }
set { _crossWindCorrectionMode = value; }
}
public RetarderData Retarder
......@@ -142,6 +173,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
get { return _axleConfiguration; }
}
public double TotalRollResistanceCoefficient { get; protected set; }
public static VehicleData ReadFromFile(string fileName)
{
return ReadFromJson(File.ReadAllText(fileName), Path.GetDirectoryName(fileName));
......@@ -149,62 +182,86 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
public static VehicleData ReadFromJson(string json, string basePath = "")
{
var vehicleData = new VehicleData();
var d = JsonConvert.DeserializeObject<Data>(json);
if (d.Header.FileVersion > 5) {
throw new UnsupportedFileVersionException("Unsupported Version of .vveh file. Got Version " + d.Header.FileVersion);
}
var vehicleData = new VehicleData(basePath);
vehicleData._data = d;
vehicleData._retarder = new RetarderData(d.Body.Retarder, basePath);
vehicleData._axleData = new List<Axle>(d.Body.AxleConfig.Axles.Count);
foreach (var axle in d.Body.AxleConfig.Axles) {
vehicleData._axleData.Add(new Axle(axle));
}
vehicleData._axleConfiguration = AxleConfiguration.AxleConfig4x2;
switch (d.Body.VehicleCategoryStr) {
case "RigidTruck":
vehicleData._vehicleCategory = VehicleCategory.RigidTruck;
break;
case "Tractor":
vehicleData._vehicleCategory = VehicleCategory.Tractor;
break;
case "CityBus":
vehicleData._vehicleCategory = VehicleCategory.CityBus;
break;
case "InterurbanBus":
vehicleData._vehicleCategory = VehicleCategory.InterurbanBus;
break;
case "Coach":
vehicleData._vehicleCategory = VehicleCategory.Coach;
break;
}
switch (d.Body.CrossWindCorrectionModeStr) {
case "CdOfBeta":
vehicleData._crossWindCorrectionMode = CrossWindCorrectionMode.VAirBeta;
break;
case "CdOfV":
vehicleData._crossWindCorrectionMode = CrossWindCorrectionMode.SpeedDependent;
var fileVersion = GetFileVersion(json);
switch (fileVersion) {
case 5:
var data = JsonConvert.DeserializeObject<DataV5Engineering>(json);
vehicleData.Data = data;
break;
default:
vehicleData._crossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection;
break;
throw new UnsupportedFileVersionException("Unsupported Version of .vveh file. Got Version " + fileVersion);
}
return vehicleData;
}
public class Data
public class DataV5Engineering
{
[JsonProperty(Required = Required.Always)] public JsonDataHeader Header;
[JsonProperty(Required = Required.Always)] public DataBody Body;
public void SetProperties(VehicleData vehicleData)
{
vehicleData._axleConfiguration = AxleConfiguration.AxleConfig4x2;
vehicleData._retarder = new RetarderData(Body.Retarder, vehicleData.BasePath);
vehicleData._axleData = new List<Axle>(Body.AxleConfig.Axles.Count);
var RRC = 0.0;
var mRed0 = 0.SI<Kilogram>();
foreach (var axleData in Body.AxleConfig.Axles) {
var axle = new Axle(axleData);
if (axle.RollResistanceCoefficient < 0) {
throw new VectoException("Axle roll resistance coefficient < 0");
}
if (axle.TyreTestLoad <= 0) {
throw new VectoException("Axle tyre test load (FzISO) must be greater than 0!");
}
var nrWheels = axle.TwinTyres ? 4 : 2;
RRC += axle.AxleWeightShare * axle.RollResistanceCoefficient *
Math.Pow(
(axle.AxleWeightShare * vehicleData.TotalVehicleWeight() * Physics.GravityAccelleration / axle.TyreTestLoad /
nrWheels).Double(), Physics.RollResistanceExponent - 1);
mRed0 += nrWheels * (axle.Inertia / vehicleData.DynamicTyreRadius / vehicleData.DynamicTyreRadius).Cast<Kilogram>();
vehicleData._axleData.Add(axle);
}
vehicleData.TotalRollResistanceCoefficient = RRC;
vehicleData.ReducedMassWheels = mRed0;
switch (Body.VehicleCategoryStr) {
case "RigidTruck":
vehicleData.Category = VehicleCategory.RigidTruck;
break;
case "Tractor":
vehicleData.Category = VehicleCategory.Tractor;
break;
case "CityBus":
vehicleData.Category = VehicleCategory.CityBus;
break;
case "InterurbanBus":
vehicleData.Category = VehicleCategory.InterurbanBus;
break;
case "Coach":
vehicleData.Category = VehicleCategory.Coach;
break;
}
switch (Body.CrossWindCorrectionModeStr) {
case "CdOfBeta":
vehicleData._crossWindCorrectionMode = CrossWindCorrectionMode.VAirBeta;
break;
case "CdOfV":
vehicleData._crossWindCorrectionMode = CrossWindCorrectionMode.SpeedDependent;
break;
default:
vehicleData._crossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection;
break;
}
}
public class DataBody
{
[JsonProperty("SavedInDeclMode")] public bool SavedInDeclarationMode;
......@@ -258,19 +315,147 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
}
}
public class DataV5Declaration
{
[JsonProperty(Required = Required.Always)] public JsonDataHeader Header;
[JsonProperty(Required = Required.Always)] public DataBody Body;
public void SetProperties(VehicleData vehicleData)
{
vehicleData._axleConfiguration = AxleConfiguration.AxleConfig4x2;
vehicleData._retarder = new RetarderData(Body.Retarder, vehicleData.BasePath);
vehicleData._axleData = new List<Axle>(Body.AxleConfig.Axles.Count);
var RRC = 0.0;
var mRed0 = 0.SI<Kilogram>();
foreach (var axleData in Body.AxleConfig.Axles) {
var axle = new Axle(axleData);
if (axle.RollResistanceCoefficient < 0) {
throw new VectoException("Axle roll resistance coefficient < 0");
}
if (axle.TyreTestLoad <= 0) {
throw new VectoException("Axle tyre test load (FzISO) must be greater than 0!");
}
var nrWheels = axle.TwinTyres ? 4 : 2;
RRC += axle.AxleWeightShare * axle.RollResistanceCoefficient *
Math.Pow(
(axle.AxleWeightShare * vehicleData.TotalVehicleWeight() * Physics.GravityAccelleration / axle.TyreTestLoad /
nrWheels).Double(), Physics.RollResistanceExponent - 1);
mRed0 += nrWheels * (axle.Inertia / vehicleData.DynamicTyreRadius / vehicleData.DynamicTyreRadius).Cast<Kilogram>();
vehicleData._axleData.Add(axle);
}
vehicleData.TotalRollResistanceCoefficient = RRC;
vehicleData.ReducedMassWheels = mRed0;
switch (Body.VehicleCategoryStr) {
case "RigidTruck":
vehicleData.Category = VehicleCategory.RigidTruck;
break;
case "Tractor":
vehicleData.Category = VehicleCategory.Tractor;
break;
case "CityBus":
vehicleData.Category = VehicleCategory.CityBus;
break;
case "InterurbanBus":
vehicleData.Category = VehicleCategory.InterurbanBus;
break;
case "Coach":
vehicleData.Category = VehicleCategory.Coach;
break;
}
//switch (Body.CrossWindCorrectionModeStr) {
// case "CdOfBeta":
// vehicleData._crossWindCorrectionMode = CrossWindCorrectionMode.VAirBeta;
// break;
// case "CdOfV":
// vehicleData._crossWindCorrectionMode = CrossWindCorrectionMode.SpeedDependent;
// break;
// default:
// vehicleData._crossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection;
// break;
//}
}
public class DataBody
{
[JsonProperty("SavedInDeclMode", Required = Required.Always)] public bool SavedInDeclarationMode;
[JsonProperty("VehCat", Required = Required.Always)] public string VehicleCategoryStr;
[JsonProperty(Required = Required.Always)] public double CurbWeight;
//[JsonProperty]
//public double CurbWeightExtra;
//[JsonProperty]
//public double Loading;
[JsonProperty("MassMax", Required = Required.Always)] public double GrossVehicleMassRating;
[JsonProperty("Cd2")] public double DragCoefficientRigidTruck; // without trailer
[JsonProperty("CrossSecArea2")] public double CrossSectionAreaRigidTruck;
[JsonProperty("Cd", Required = Required.Always)] public double DragCoefficient;
[JsonProperty("CrossSecArea", Required = Required.Always)] public double CrossSectionArea;
//[JsonProperty("rdyn")]
//public double DynamicTyreRadius;
[JsonProperty("Rim", Required = Required.Always)] public string RimStr;
//[JsonProperty("CdCorrMode")]
//public string CrossWindCorrectionModeStr;
//[JsonProperty("CdCorrFile")]
//public string CrossWindCorrectionFile;
[JsonProperty("Retarder", Required = Required.Always)] public RetarderData.Data Retarder;
[JsonProperty(Required = Required.Always)] public AxleConfigData AxleConfig;
public class AxleConfigData
{
[JsonProperty("Type", Required = Required.Always)] public string TypeStr;
[JsonProperty(Required = Required.Always)] public IList<AxleData> Axles;
}
public class AxleData
{
//[JsonProperty]
//public double Inertia;
[JsonProperty(Required = Required.Always)] public string WheelsStr;
//[JsonProperty(Required = Required.Always)]
//public double AxleWeightShare;
[JsonProperty(Required = Required.Always)] public bool TwinTyres;
[JsonProperty("RRCISO", Required = Required.Always)] public double RollResistanceCoefficient;
[JsonProperty("FzISO", Required = Required.Always)] public double TyreTestLoad;
}
}
}
public class Axle
{
private Data.DataBody.AxleData _data;
private DataV5Engineering.DataBody.AxleData _data;
public Axle(Data.DataBody.AxleData data)
public Axle(DataV5Engineering.DataBody.AxleData data)
{
_data = data;
}
public double Inertia
public Axle(DataV5Declaration.DataBody.AxleData data) {}
public SI Inertia
{
get { return _data.Inertia; }
set { _data.Inertia = value; }
get { return _data.Inertia.SI().Kilo.Gramm.Square.Meter; }
set { _data.Inertia = value.Double(); }
}
public double RollResistanceCoefficient
......@@ -278,6 +463,24 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
get { return _data.RollResistanceCoefficient; }
set { _data.RollResistanceCoefficient = value; }
}
public Newton TyreTestLoad
{
get { return _data.TyreTestLoad.SI<Newton>(); }
set { _data.TyreTestLoad = value.Double(); }
}
public double AxleWeightShare
{
get { return _data.AxleWeightShare; }
set { _data.AxleWeightShare = value; }
}
public bool TwinTyres
{
get { return _data.TwinTyres; }
set { _data.TwinTyres = value; }
}
}
}
}
\ No newline at end of file
......@@ -5,5 +5,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
/// <summary>
/// Defines interfaces for a driver demand driving cycle.
/// </summary>
public interface IDriverDemandDrivingCycle : IDrivingCycleOutProvider, IDriverDemandInProvider {}
public interface IDrivingCycleDemandDrivingCycle : IDrivingCycleOutProvider, IDrivingCycleDemandInProvider {}
}
\ No newline at end of file
......@@ -6,67 +6,68 @@ using TUGraz.VectoCore.Models.SimulationComponent.Data;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
/// <summary>
/// Class representing one Distance Based Driving Cycle
/// </summary>
public class DistanceBasedDrivingCycle : VectoSimulationComponent, IDriverDemandDrivingCycle, IDrivingCycleOutPort,
IDriverDemandInPort
{
protected TimeSpan AbsTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0);
protected DrivingCycleData Data;
protected double Distance = 0;
protected TimeSpan Dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0);
private IDriverDemandOutPort _outPort;
/// <summary>
/// Class representing one Distance Based Driving Cycle
/// </summary>
public class DistanceBasedDrivingCycle : VectoSimulationComponent, IDrivingCycleDemandDrivingCycle,
IDrivingCycleOutPort,
IDrivingCycleDemandInPort
{
protected TimeSpan AbsTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0);
protected DrivingCycleData Data;
protected double Distance = 0;
protected TimeSpan Dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0);
private IDrivingCycleDemandOutPort _outPort;
public DistanceBasedDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) : base(container)
{
Data = cycle;
}
public DistanceBasedDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) : base(container)
{
Data = cycle;
}
#region IDriverDemandInProvider
#region IDrivingCycleDemandInProvider
public IDriverDemandInPort InPort()
{
return this;
}
public IDrivingCycleDemandInPort InPort()
{
return this;
}
#endregion
#endregion
#region IDrivingCycleOutProvider
#region IDrivingCycleOutProvider
public IDrivingCycleOutPort OutPort()
{
return this;
}
public IDrivingCycleOutPort OutPort()
{
return this;
}
#endregion
#endregion
#region IDriverDemandInPort
#region IDrivingCycleDemandInPort
void IDriverDemandInPort.Connect(IDriverDemandOutPort other)
{
_outPort = other;
}
void IDrivingCycleDemandInPort.Connect(IDrivingCycleDemandOutPort other)
{
_outPort = other;
}
#endregion
#endregion
#region IDrivingCycleOutPort
#region IDrivingCycleOutPort
IResponse IDrivingCycleOutPort.Request(TimeSpan absTime, TimeSpan dt)
{
//todo: Distance calculation and comparison!!!
throw new NotImplementedException("Distance based Cycle is not yet implemented.");
}
IResponse IDrivingCycleOutPort.Request(TimeSpan absTime, TimeSpan dt)
{
//todo: Distance calculation and comparison!!!
throw new NotImplementedException("Distance based Cycle is not yet implemented.");
}
#endregion
#endregion
#region VectoSimulationComponent
#region VectoSimulationComponent
public override void CommitSimulationStep(IModalDataWriter writer)
{
throw new NotImplementedException("Distance based Cycle is not yet implemented.");
}
public override void CommitSimulationStep(IModalDataWriter writer)
{
throw new NotImplementedException("Distance based Cycle is not yet implemented.");
}
#endregion
}
#endregion
}
}
\ No newline at end of file
......@@ -11,11 +11,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
/// <summary>
/// Class representing one Time Based Driving Cycle
/// </summary>
public class TimeBasedDrivingCycle : VectoSimulationComponent, IDriverDemandDrivingCycle, IDriverDemandInPort,
public class TimeBasedDrivingCycle : VectoSimulationComponent, IDrivingCycleDemandDrivingCycle, IDrivingCycleDemandInPort,
IDrivingCycleOutPort
{
protected DrivingCycleData Data;
private IDriverDemandOutPort _outPort;
private IDrivingCycleDemandOutPort _outPort;
public TimeBasedDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) : base(container)
{
......@@ -31,9 +31,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
#endregion
#region IDriverDemandInProvider
#region IDrivingCycleDemandInProvider
public IDriverDemandInPort InPort()
public IDrivingCycleDemandInPort InPort()
{
return this;
}
......@@ -56,9 +56,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
#endregion
#region IDriverDemandInPort
#region IDrivingCycleDemandInPort
void IDriverDemandInPort.Connect(IDriverDemandOutPort other)
void IDrivingCycleDemandInPort.Connect(IDrivingCycleDemandOutPort other)
{
_outPort = other;
}
......
using System;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.Simulation.Impl;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
public class Vehicle : IVehicle
public class Vehicle : VectoSimulationComponent, IVehicle
{
private IFvOutPort _nextInstance;
private VehicleState _previousState;
private VehicleState _currentState;
private VehicleData _data;
public Vehicle(VehicleContainer container, VehicleData data) : base(container)
{
_data = data;
_previousState = new VehicleState();
_previousState.Velocity = 0.SI<MeterPerSecond>();
_currentState = new VehicleState();
}
public Vehicle(VehicleContainer container, VehicleData data, double initialVelocity) : this(container, data)
{
_previousState.Velocity = initialVelocity.SI<MeterPerSecond>();
}
public IFvInPort InPort()
{
throw new NotImplementedException();
return this;
}
public IDriverDemandOutPort OutPort()
{
throw new NotImplementedException();
return this;
}
public void Connect(IFvOutPort other)
......@@ -24,16 +44,53 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
_nextInstance = other;
}
public override void CommitSimulationStep(IModalDataWriter writer)
{
_previousState = _currentState;
_currentState = new VehicleState();
}
public IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSquareSecond accelleration, Radian gradient)
{
var force = 0.SI<Newton>();
var velocity = 0.SI<MeterPerSecond>();
return _nextInstance.Request(absTime, dt, force, velocity);
_currentState.Velocity = _previousState.Velocity +
(accelleration * (dt.TotalSeconds / 2.0).SI<Second>()).Cast<MeterPerSecond>();
var force = RollingResistance(gradient) + AirDragResistance() + AccelerationForce(accelleration) +
SlopeResistance(gradient);
return _nextInstance.Request(absTime, dt, force, _currentState.Velocity);
}
protected Newton RollingResistance(Radian gradient)
{
return (Math.Cos(gradient.Double()) * _data.TotalVehicleWeight() *
Physics.GravityAccelleration *
_data.TotalRollResistanceCoefficient).Cast<Newton>();
}
protected Newton AirDragResistance()
{
// TODO different types of cross-wind correction...
var Cd = _data.DragCoefficient;
var vAir = _currentState.Velocity;
return (Cd * _data.CrossSectionArea * Physics.AirDensity / 2 * vAir * vAir).Cast<Newton>();
}
protected Newton AccelerationForce(MeterPerSquareSecond accelleration)
{
return ((_data.TotalVehicleWeight() + _data.ReducedMassWheels) * accelleration).Cast<Newton>();
}
protected Newton SlopeResistance(Radian gradient)
{
return (_data.TotalVehicleWeight() * Physics.GravityAccelleration * Math.Sin(gradient.Double())).Cast<Newton>();
}
public IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSecond velocity, Radian gradient)
public class VehicleState
{
throw new NotImplementedException();
public MeterPerSecond Velocity;
}
}
}
\ No newline at end of file
namespace TUGraz.VectoCore.Utils
{
public class Physics
{
public static readonly MeterPerSquareSecond GravityAccelleration = 9.81.SI<MeterPerSquareSecond>();
public static readonly SI AirDensity = 1.188.SI().Kilo.Gramm.Per.Cubic.Meter;
public static readonly double RollResistanceExponent = 0.9;
}
}
\ No newline at end of file
......@@ -34,51 +34,78 @@ namespace TUGraz.VectoCore.Utils
/// Reads a CSV file which is stored in Vecto-CSV-Format.
/// </summary>
/// <param name="fileName"></param>
/// <param name="ignoreEmptyColumns"></param>
/// <exception cref="FileIOException"></exception>
/// <returns>A DataTable which represents the CSV File.</returns>
public static DataTable Read(string fileName, bool ignoreEmptyColumns = false)
{
try {
var lines = File.ReadAllLines(fileName);
lines = RemoveComments(lines);
var validColumns = GetValidHeaderColumns(lines.First());
if (validColumns.Length > 0) {
// Valid Columns found => header was valid => skip header line
lines = lines.Skip(1).ToArray();
} else {
var log = LogManager.GetLogger(typeof (VectoCSVFile));
log.Warn("No valid Data Header found. Interpreting the first line as data line.");
// set the validColumns to: {"0", "1", "2", "3", ...} for all columns in first line.
validColumns = GetColumns(lines.First()).Select((_, index) => index.ToString()).ToArray();
}
return ReadData(File.ReadAllLines(fileName), ignoreEmptyColumns);
} catch (Exception e) {
throw new VectoException(string.Format("File {0}: {1}", fileName, e.Message));
}
}
var table = new DataTable();
foreach (var col in validColumns) {
table.Columns.Add(col);
/// <summary>
/// Reads a CSV file which is stored in Vecto-CSV-Format.
/// </summary>
/// <param name="stream"></param>
/// <param name="ignoreEmptyColumns"></param>
/// <exception cref="FileIOException"></exception>
/// <returns>A DataTable which represents the CSV File.</returns>
public static DataTable ReadStream(Stream stream, bool ignoreEmptyColumns = false)
{
try {
var lines = new List<string>();
using (StreamReader reader = new StreamReader(stream)) {
while (!reader.EndOfStream) {
lines.Add(reader.ReadLine());
}
}
return ReadData(lines.ToArray(), ignoreEmptyColumns);
} catch (Exception e) {
throw new VectoException("failed to read stream", e);
}
}
for (var i = 0; i < lines.Length; i++) {
var line = lines[i];
private static DataTable ReadData(string[] data, bool ignoreEmptyColumns = false)
{
var lines = RemoveComments(data);
var validColumns = GetValidHeaderColumns(lines.First());
if (validColumns.Length > 0) {
// Valid Columns found => header was valid => skip header line
lines = lines.Skip(1).ToArray();
} else {
var log = LogManager.GetLogger(typeof (VectoCSVFile));
log.Warn("No valid Data Header found. Interpreting the first line as data line.");
// set the validColumns to: {"0", "1", "2", "3", ...} for all columns in first line.
validColumns = GetColumns(lines.First()).Select((_, index) => index.ToString()).ToArray();
}
var cells = line.Split(Separator);
if (!ignoreEmptyColumns && cells.Length != table.Columns.Count) {
throw new CSVReadException(string.Format("Line {0}: The number of values is not correct.", i));
}
var table = new DataTable();
foreach (var col in validColumns) {
table.Columns.Add(col);
}
try {
table.Rows.Add(line.Split(Separator));
} catch (InvalidCastException e) {
throw new CSVReadException(
string.Format("Line {0}: The data format of a value is not correct. {1}", i, e.Message), e);
}
for (var i = 0; i < lines.Length; i++) {
var line = lines[i];
var cells = line.Split(Separator);
if (!ignoreEmptyColumns && cells.Length != table.Columns.Count) {
throw new CSVReadException(string.Format("Line {0}: The number of values is not correct.", i));
}
return table;
} catch (Exception e) {
throw new VectoException(string.Format("File {0}: {1}", fileName, e.Message));
try {
table.Rows.Add(line.Split(Separator));
} catch (InvalidCastException e) {
throw new CSVReadException(
string.Format("Line {0}: The data format of a value is not correct. {1}", i, e.Message), e);
}
}
return table;
}
private static string[] GetValidHeaderColumns(string line)
......
......@@ -109,14 +109,17 @@
<Compile Include="Exceptions\VectoExceptions.cs" />
<Compile Include="Exceptions\VectoSimulationException.cs" />
<Compile Include="Models\Connector\Ports\IDriverDemandPort.cs" />
<Compile Include="Models\Connector\Ports\IDrivingCycleProvider.cs" />
<Compile Include="Models\Connector\Ports\IDriverDemandProvider.cs" />
<Compile Include="Models\Connector\Ports\IDrivingCycleDemandPort.cs" />
<Compile Include="Models\Connector\Ports\IDrivingCycleProvider.cs" />
<Compile Include="Models\Connector\Ports\IDrivingCycleDemandProvider.cs" />
<Compile Include="Models\Connector\Ports\IResponse.cs" />
<Compile Include="Models\Connector\Ports\IRoadPortProvider.cs" />
<Compile Include="Models\Connector\Ports\IShaft.cs" />
<Compile Include="Models\Connector\Ports\Impl\Response.cs" />
<Compile Include="Models\Connector\Ports\IFvPort.cs" />
<Compile Include="Models\Connector\Ports\ITnPort.cs" />
<Compile Include="Models\DeclarationData\Wheels.cs" />
<Compile Include="Models\SimulationComponent\Data\AuxiliariesDemandAdapter.cs" />
<Compile Include="Models\SimulationComponent\Data\CombustionEngineData.cs" />
<Compile Include="Models\SimulationComponent\Data\DrivingCycleData.cs" />
......@@ -140,8 +143,14 @@
<Compile Include="Models\SimulationComponent\Impl\Vehicle.cs" />
<Compile Include="Models\SimulationComponent\IPowerTrainComponent.cs" />
<Compile Include="Models\SimulationComponent\IVehicle.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Utils\Formulas.cs" />
<Compile Include="Utils\IntExtensionMethods.cs" />
<Compile Include="Utils\Physics.cs" />
<Compile Include="Utils\SI.cs" />
<Compile Include="Models\SimulationComponent\Data\SimulationComponentData.cs" />
<Compile Include="Models\SimulationComponent\IAuxiliary.cs" />
......@@ -185,8 +194,15 @@
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="Resources\Rims.csv" />
<None Include="Resources\Wheels.csv" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
......
......@@ -109,7 +109,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
var cycleData = DrivingCycleData.ReadFromFileTimeBased(@"TestData\Cycles\Coach time based.vdri");
var cycle = new TimeBasedDrivingCycle(container, cycleData);
var outPort = new MockDriverDemandOutPort();
var outPort = new MockDrivingCycleDemandOutPort();
var inPort = cycle.InPort();
var cycleOut = cycle.OutPort();
......@@ -136,7 +136,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
var cycleData = DrivingCycleData.ReadFromFileTimeBased(@"TestData\Cycles\Cycle time field missing.vdri");
var cycle = new TimeBasedDrivingCycle(container, cycleData);
var outPort = new MockDriverDemandOutPort();
var outPort = new MockDrivingCycleDemandOutPort();
var inPort = cycle.InPort();
var cycleOut = cycle.OutPort();
......
......@@ -25,7 +25,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
}
}
public class MockDriverDemandOutPort : IDriverDemandOutPort
public class MockDrivingCycleDemandOutPort : IDrivingCycleDemandOutPort
{
public TimeSpan AbsTime { get; set; }
public TimeSpan Dt { get; set; }
......@@ -38,9 +38,29 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
Dt = dt;
Velocity = velocity;
Gradient = gradient;
LogManager.GetLogger(GetType()).DebugFormat("Request: absTime: {0}, dt: {1}, velocity: {3}, gradient: {4}",
LogManager.GetLogger(GetType()).DebugFormat("Request: absTime: {0}, dt: {1}, velocity: {2}, gradient: {3}",
absTime, dt, velocity, gradient);
return new ResponseSuccess();
}
}
public class MockFvOutPort : IFvOutPort
{
public TimeSpan AbsTime { get; set; }
public TimeSpan Dt { get; set; }
public Newton Force { get; set; }
public MeterPerSecond Velocity { get; set; }
public IResponse Request(TimeSpan absTime, TimeSpan dt, Newton force, MeterPerSecond velocity)
{
AbsTime = absTime;
Dt = dt;
Force = force;
Velocity = velocity;
LogManager.GetLogger(GetType())
.DebugFormat("Request: abstime: {0}, dt: {1}, force: {2}, velocity: {3}", absTime, dt, force, velocity);
return new ResponseSuccess();
}
}
}
\ No newline at end of file
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TUGraz.VectoCore.Models.Simulation.Impl;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Impl;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
{
[TestClass]
public class VehicleTest
{
private const string VehicleDataFile = @"TestData\Components\24t Coach.vveh";
[TestMethod]
public void VehiclePortTest()
{
var container = new VehicleContainer();
var vehicleData = VehicleData.ReadFromFile(VehicleDataFile);
vehicleData.CrossWindCorrection = VehicleData.CrossWindCorrectionMode.NoCorrection;
var vehicle = new Vehicle(container, vehicleData, 17.210535);
var mockPort = new MockFvOutPort();
vehicle.InPort().Connect(mockPort);
var requestPort = vehicle.OutPort();
var absTime = TimeSpan.FromSeconds(0);
var dt = TimeSpan.FromSeconds(1);
var accell = -0.256231159.SI<MeterPerSquareSecond>();
var gradient = Math.Atan(0.00366547048).SI<Radian>();
var retVal = requestPort.Request(absTime, dt, accell, gradient);
Assert.AreEqual(-2549.07832743748, mockPort.Force.Double(), 0.0001);
Assert.AreEqual(17.0824194205, mockPort.Velocity.Double(), 0.0001);
}
}
}
\ 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