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

Skip to content
Snippets Groups Projects
Commit 3e06cff0 authored by Michael KRISPER's avatar Michael KRISPER
Browse files

Merge branch 'develop' into feature/VECTO-110-documentation

parents 01ea3be6 b952a5eb
No related branches found
No related tags found
No related merge requests found
Showing
with 912 additions and 154 deletions
#!/usr/bin/env python
"""
1) Copies the declaration files into the project resource directory.
2) Renames the mission files accordingly
3) Scales Pneumatic System from KW to W.
4) Renames the VCDV paramerters.csv to parameters.csv
5) Scales the WHTC-Weighting percentage values from 0-100 to 0-1
Prerequisites:
* Original declaration files accessible in "root/Declaration"
Usage:
python DeclarationConverter.py
"""
import os
import shutil
__author__ = "Michael Krisper"
__email__ = "michael.krisper@tugraz.at"
__date__ = "2015-07-15"
__version__ = "1.0.0"
SOURCE = "../Declaration"
DESTINATION = os.path.abspath("../VectoCore/Resources/Declaration")
def main(source_path, destination_path):
# Copy files from source to resource dir
shutil.rmtree(destination_path, onerror=lambda dir, path, err: print(dir, path, err))
shutil.copytree(source_path, destination_path, ignore=lambda src, names: names if "Reports" in src else [])
# Rename mission cycles
os.chdir(os.path.join(destination_path, "MissionCycles"))
for file in os.listdir():
os.rename(file, file.replace("_", "").replace(" ", "").replace("Citybus", "").replace("Bus", ""))
# Adjust PS table
os.chdir(os.path.join(destination_path, "VAUX"))
with open("PS-Table.csv", "r") as f:
lines = f.readlines()
with open("PS-Table.csv", "w") as f:
f.write(lines[0])
for line in lines[1:]:
values = line.split(",")
f.write("{},{}\n".format(values[0], ",".join(str(float(v)*1000) for v in values[1:])))
#VCDV
os.chdir(os.path.join(destination_path, "VCDV"))
os.rename("paramerters.csv", "parameters.csv")
# WHTC Weighting Factors
os.chdir(os.path.join(destination_path))
with open("WHTC-Weighting-Factors.csv", "r") as f:
lines = f.readlines()
with open("WHTC-Weighting-Factors.csv", "w") as f:
f.write(lines[0])
for line in lines[1:]:
values = line.split(",")
f.write("{},{}\n".format(values[0], ",".join(str(float(v) / 100) for v in values[1:])))
if __name__ == "__main__":
main(SOURCE, DESTINATION)
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>e23b3a9b-62e7-4476-849e-eef1c3804a2f</ProjectGuid>
<ProjectHome>.</ProjectHome>
<StartupFile>DeclarationConverter.py</StartupFile>
<SearchPath>
</SearchPath>
<WorkingDirectory>.</WorkingDirectory>
<OutputPath>.</OutputPath>
<Name>DeclarationConverter</Name>
<RootNamespace>DeclarationConverter</RootNamespace>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>true</DebugSymbols>
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
<ItemGroup>
<Compile Include="DeclarationConverter.py" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<PtvsTargetsFile>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets</PtvsTargetsFile>
</PropertyGroup>
<Import Condition="Exists($(PtvsTargetsFile))" Project="$(PtvsTargetsFile)" />
<Import Condition="!Exists($(PtvsTargetsFile))" Project="$(MSBuildToolsPath)\Microsoft.Common.targets" />
<!-- Uncomment the CoreCompile target to enable the Build command in
Visual Studio and specify your pre- and post-build commands in
the BeforeBuild and AfterBuild targets below. -->
<!--<Target Name="CoreCompile" />-->
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
</Project>
\ No newline at end of file

\ No newline at end of file
......@@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VectoCore", "VectoCore\Vect
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VectoCoreTest", "VectoCoreTest\VectoCoreTest.csproj", "{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}"
EndProject
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "DeclarationConverter", "DeclarationConverter\DeclarationConverter.pyproj", "{E23B3A9B-62E7-4476-849E-EEF1C3804A2F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......@@ -55,6 +57,12 @@ Global
{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Release|Any CPU.Build.0 = Release|Any CPU
{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Release|x64.ActiveCfg = Release|Any CPU
{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Release|x86.ActiveCfg = Release|Any CPU
{E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug|x64.ActiveCfg = Debug|Any CPU
{E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug|x86.ActiveCfg = Debug|Any CPU
{E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Release|x64.ActiveCfg = Release|Any CPU
{E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
......@@ -24,6 +24,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PT/@EntryIndexedValue">PT</s:String>
<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:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WHTC/@EntryIndexedValue">WHTC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FCONSTANT/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FVARIABLE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FCONSTRUCTOR/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
......
namespace TUGraz.VectoCore.Configuration
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Configuration
{
public class Constants
public static class Constants
{
public class FileExtensions
public static class Auxiliaries
{
public static class IDs
{
public const string Fan = "FAN";
public const string SteeringPump = "STP";
public const string ElectricSystem = "ES";
public const string HeatingVentilationAirCondition = "AC";
public const string PneumaticSystem = "PS";
}
public static class Names
{
public const string Fan = "Fan";
public const string SteeringPump = "Steering pump";
public const string ElectricSystem = "Electric System";
public const string HeatingVentilationAirCondition = "HVAC";
public const string PneumaticSystem = "Pneumatic System";
}
}
public static class FileExtensions
{
public const string ModDataFile = ".vmod";
......@@ -14,5 +37,24 @@
public const string CycleFile = ".vdri";
}
public static class SimulationSettings
{
/// <summary>
/// base time interval for the simulation. the distance is estimated to reach this time interval as good as possible
/// </summary>
public static readonly Second TargetTimeInterval = 0.5.SI<Second>();
/// <summary>
/// simulation interval if the vehicle stands still
/// </summary>
public static readonly Meter DriveOffDistance = 1.SI<Meter>();
/// <summary>
/// threshold for changes in the road gradient. changes below this threshold will be considered to be equal for filtering out the driving cycle.
/// altitude computation is done before filtering!
/// </summary>
public static readonly double DrivingCycleRoadGradientTolerance = VectoMath.InclinationToAngle(0.25 / 100.0).Value();
}
}
}
\ No newline at end of file
......@@ -34,7 +34,7 @@ namespace TUGraz.VectoCore.FileIO.DeclarationFile
/// }
/// }
/// </code>
internal class EngineFileV2Declaration : VectoEngineFile
internal class EngineFileV3Declaration : VectoEngineFile
{
[JsonProperty(Required = Required.Always)] public JsonDataHeader Header;
[JsonProperty(Required = Required.Always)] public DataBodyDecl Body;
......@@ -60,7 +60,8 @@ namespace TUGraz.VectoCore.FileIO.DeclarationFile
/// </summary>
[JsonProperty("IdlingSpeed", Required = Required.Always)] public double IdleSpeed;
[JsonProperty(Required = Required.Always)] public IList<DataFullLoadCurve> FullLoadCurves;
//[JsonProperty(Required = Required.Always)] public IList<DataFullLoadCurve> FullLoadCurves;
[JsonProperty(Required = Required.Always)] public string FullLoadCurve;
/// <summary>
/// The Fuel Consumption Map is used to calculate the base Fuel Consumption (FC) value.
......
......@@ -30,7 +30,7 @@ namespace TUGraz.VectoCore.FileIO.DeclarationFile
/// ...
/// ]
/// }
public class GearboxFileV4Declaration : VectoGearboxFile
public class GearboxFileV5Declaration : VectoGearboxFile
{
[JsonProperty(Required = Required.Always)] public JsonDataHeader Header;
[JsonProperty(Required = Required.Always)] public DataBodyDecl Body;
......@@ -53,6 +53,7 @@ namespace TUGraz.VectoCore.FileIO.DeclarationFile
{
[JsonProperty(Required = Required.Always)] public double Ratio;
[JsonProperty(Required = Required.Always)] public string LossMap;
[JsonProperty] public string FullLoadCurve;
}
}
}
\ No newline at end of file
......@@ -5,68 +5,81 @@ using TUGraz.VectoCore.Models.SimulationComponent.Data;
namespace TUGraz.VectoCore.FileIO.DeclarationFile
{
/// <summary>
/// A class which represents the json data format for serializing and deserializing the Job Data files.
/// </summary>
/// <summary>
/// Represents the Vecto Job File. Fileformat: .vecto
/// A class which represents the json data format for serializing and deserializing the Job Data files.
/// Fileformat: .vecto
/// </summary>
/// <code>
///{
/// "Header": {
/// "CreatedBy": " ()",
/// "Date": "3/4/2015 2:09:13 PM",
/// "AppVersion": "2.0.4-beta3",
/// "FileVersion": 2
/// },
/// "Body": {
/// "SavedInDeclMode": false,
/// "VehicleData": "24t Coach.vveh",
/// "EngineData": "24t Coach.veng",
/// "GearboxData": "24t Coach.vgbx",
/// "Cycles": [
/// "W:\\VECTO\\CITnet\\VECTO\\bin\\Debug\\Declaration\\MissionCycles\\LOT2_rural Engine Only.vdri"
/// ],
/// "Aux": [
/// {
/// "ID": "ALT1",
/// "Type": "Alternator",
/// "Path": "24t_Coach_ALT.vaux",
/// "Technology": ""
/// },
/// {
/// "ID": "ALT2",
/// "Type": "Alternator",
/// "Path": "24t_Coach_ALT.vaux",
/// "Technology": ""
/// },
/// {
/// "ID": "ALT3",
/// "Type": "Alternator",
/// "Path": "24t_Coach_ALT.vaux",
/// "Technology": ""
/// }
/// ],
/// "AccelerationLimitingFile": "Coach.vacc",
/// "IsEngineOnly": true,
/// "StartStop": {
/// "Enabled": false,
/// "MaxSpeed": 5.0,
/// "MinTime": 0.0,
/// "Delay": 0
/// },
/// "LookAheadCoasting": {
/// "Enabled": true,
/// "Dec": -0.5,
/// "MinSpeed": 50.0
/// },
/// "OverSpeedEcoRoll": {
/// "Mode": "OverSpeed",
/// "MinSpeed": 70.0,
/// "OverSpeed": 5.0,
/// "UnderSpeed": 5.0
/// }
/// }
///}
/// {
/// "Header": {
/// "CreatedBy": " ()",
/// "Date": "3/4/2015 12:31:06 PM",
/// "AppVersion": "2.0.4-beta3",
/// "FileVersion": 2
/// },
/// "Body": {
/// "SavedInDeclMode": true,
/// "VehicleFile": "../Components/12t Delivery Truck.vveh",
/// "EngineFile": "../Components/12t Delivery Truck.veng",
/// "GearboxFile": "../Components/12t Delivery Truck.vgbx",
/// "Cycles": [
/// "Long Haul",
/// "Regional Delivery",
/// "Urban Delivery"
/// ],
/// "Aux": [
/// {
/// "ID": "FAN",
/// "Type": "Fan",
/// "Path": "<NOFILE>",
/// "Technology": ""
/// },
/// {
/// "ID": "STP",
/// "Type": "Steering pump",
/// "Path": "<NOFILE>",
/// "Technology": ""
/// },
/// {
/// "ID": "AC",
/// "Type": "HVAC",
/// "Path": "<NOFILE>",
/// "Technology": ""
/// },
/// {
/// "ID": "ES",
/// "Type": "Electric System",
/// "Path": "<NOFILE>",
/// "Technology": "",
/// "TechList": []
/// },
/// {
/// "ID": "PS",
/// "Type": "Pneumatic System",
/// "Path": "<NOFILE>",
/// "Technology": ""
/// }
/// ],
/// "VACC": "<NOFILE>",
/// "EngineOnlyMode": true,
/// "StartStop": {
/// "Enabled": false,
/// "MaxSpeed": 5.0,
/// "MinTime": 5.0,
/// "Delay": 5
/// },
/// "LAC": {
/// "Enabled": true,
/// "Dec": -0.5,
/// "MinSpeed": 50.0
/// },
/// "OverSpeedEcoRoll": {
/// "Mode": "OverSpeed",
/// "MinSpeed": 50.0,
/// "OverSpeed": 5.0,
/// "UnderSpeed": 5.0
/// }
/// }
/// }
/// </code>
public class VectoJobFileV2Declaration : VectoJobFile
{
......@@ -91,10 +104,11 @@ namespace TUGraz.VectoCore.FileIO.DeclarationFile
public class AuxDataDecl
{
//[JsonProperty(Required = Required.Always)] public string ID;
//[JsonProperty(Required = Required.Always)] public string Type;
[JsonProperty(Required = Required.Always)] public string ID;
[JsonProperty(Required = Required.Always)] public string Type;
//[JsonProperty(Required = Required.Always)] public string Path;
[JsonProperty(Required = Required.Always)] public string Technology;
[JsonProperty] public IList<string> TechList;
}
public class StartStopDataDecl
......
......@@ -3,7 +3,7 @@ using TUGraz.VectoCore.FileIO.DeclarationFile;
namespace TUGraz.VectoCore.FileIO.EngineeringFile
{
internal class EngineFileV2Engineering : EngineFileV2Declaration
internal class EngineFileV3Engineering : EngineFileV3Declaration
{
[JsonProperty(Required = Required.Always)] public new DataBodyEng Body;
......
......@@ -48,7 +48,7 @@ namespace TUGraz.VectoCore.FileIO.EngineeringFile
/// ...
/// ]
/// }
public class GearboxFileV4Engineering : GearboxFileV4Declaration
public class GearboxFileV5Engineering : GearboxFileV5Declaration
{
[JsonProperty(Required = Required.Always)] public new DataBodyEng Body;
......
......@@ -75,14 +75,14 @@ namespace TUGraz.VectoCore.FileIO.EngineeringFile
{
[JsonProperty(Required = Required.Always)] public IList<string> Cycles;
[JsonProperty] public new IList<AuxDataEng> Aux = new List<AuxDataEng>();
[JsonProperty("VACC", Required = Required.Always)] public string AccelerationCurve;
[JsonProperty] public bool EngineOnlyMode;
[JsonProperty(Required = Required.Always)] public new StartStopDataDeclEng StartStop;
[JsonProperty(Required = Required.Always)] public LACDataEng LAC;
[JsonProperty("LAC", Required = Required.Always)] public LACDataEng LookAheadCoasting;
[JsonProperty(Required = Required.Always)] public new OverSpeedEcoRollDataEng OverSpeedEcoRoll;
public class AuxDataEng : DataBodyDecl.AuxDataDecl
{
[JsonProperty(Required = Required.Always)] public string ID;
[JsonProperty(Required = Required.Always)] public string Type;
[JsonProperty(Required = Required.Always)] public string Path;
}
......
......@@ -24,10 +24,5 @@ namespace TUGraz.VectoCore.FileIO
data = JsonConvert.DeserializeAnonymousType(jsonStr, data);
return new VersionInfo { SavedInDeclarationMode = data.Body.SavedInDeclMode, Version = data.Header.FileVersion };
}
protected T Deserialize<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json);
}
}
}
\ No newline at end of file
......@@ -7,7 +7,7 @@ namespace TUGraz.VectoCore.FileIO
[JsonProperty(Required = Required.Always)] public string AppVersion;
[JsonProperty(Required = Required.Always)] public string CreatedBy;
[JsonProperty(Required = Required.Always)] public string Date;
[JsonProperty(Required = Required.Always)] public double FileVersion;
[JsonProperty(Required = Required.Always)] public uint FileVersion;
#region Equality members
......@@ -28,7 +28,7 @@ namespace TUGraz.VectoCore.FileIO
if (obj.GetType() != GetType()) {
return false;
}
return Equals((JsonDataHeader) obj);
return Equals((JsonDataHeader)obj);
}
public override int GetHashCode()
......
......@@ -25,7 +25,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
var retVal = new VehicleData {
SavedInDeclarationMode = data.SavedInDeclarationMode,
VehicleCategory = data.VehicleCategory(),
AxleConfiguration = EnumHelper.ParseAxleConfigurationType(data.AxleConfig.TypeStr),
AxleConfiguration = AxleConfigurationHelper.Parse(data.AxleConfig.TypeStr),
CurbWeight = data.CurbWeight.SI<Kilogram>(),
//CurbWeigthExtra = data.CurbWeightExtra.SI<Kilogram>(),
//Loading = data.Loading.SI<Kilogram>(),
......@@ -40,7 +40,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
var retarder = new RetarderData() {
Type =
(RetarderData.RetarderType) Enum.Parse(typeof (RetarderData.RetarderType), data.Retarder.TypeStr.ToString(), true),
(RetarderData.RetarderType)Enum.Parse(typeof(RetarderData.RetarderType), data.Retarder.TypeStr.ToString(), true),
};
if (retarder.Type != RetarderData.RetarderType.None) {
retarder.LossMap = RetarderLossMap.ReadFromFile(Path.Combine(basePath, data.Retarder.File));
......@@ -51,7 +51,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
return retVal;
}
internal CombustionEngineData SetCommonCombustionEngineData(EngineFileV2Declaration.DataBodyDecl data, string basePath)
internal CombustionEngineData SetCommonCombustionEngineData(EngineFileV3Declaration.DataBodyDecl data, string basePath)
{
var retVal = new CombustionEngineData() {
SavedInDeclarationMode = data.SavedInDeclarationMode,
......@@ -66,13 +66,15 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
return retVal;
}
internal GearboxData SetCommonGearboxData(GearboxFileV4Declaration.DataBodyDecl data)
internal GearboxData SetCommonGearboxData(GearboxFileV5Declaration.DataBodyDecl data)
{
return new GearboxData() {
SavedInDeclarationMode = data.SavedInDeclarationMode,
ModelName = data.ModelName,
Type = (GearboxData.GearboxType) Enum.Parse(typeof (GearboxData.GearboxType), data.GearboxType, true),
Type = (GearboxData.GearboxType)Enum.Parse(typeof(GearboxData.GearboxType), data.GearboxType, true),
};
}
public abstract DriverData CreateDriverData(VectoJobFile job);
}
}
\ No newline at end of file
......@@ -2,10 +2,11 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.FileIO.DeclarationFile;
using TUGraz.VectoCore.FileIO.EngineeringFile;
using TUGraz.VectoCore.Models.Declaration;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
......@@ -35,7 +36,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
public override CombustionEngineData CreateEngineData(VectoEngineFile engine)
{
var fileV2Decl = engine as EngineFileV2Declaration;
var fileV2Decl = engine as EngineFileV3Declaration;
if (fileV2Decl != null) {
return CreateEngineData(fileV2Decl);
}
......@@ -44,15 +45,59 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
public override GearboxData CreateGearboxData(VectoGearboxFile gearbox, CombustionEngineData engine)
{
var fileV5Decl = gearbox as GearboxFileV4Declaration;
var fileV5Decl = gearbox as GearboxFileV5Declaration;
if (fileV5Decl != null) {
return CreateGearboxData(fileV5Decl, engine);
}
throw new VectoException("Unsupported GearboxData File Instance");
}
public override DriverData CreateDriverData(VectoJobFile job)
{
var fileV2Decl = job as VectoJobFileV2Declaration;
if (fileV2Decl != null) {
return CreateDriverData(fileV2Decl);
}
throw new VectoException("Unsupported Job File Instance");
}
//==========================
public DriverData CreateDriverData(VectoJobFileV2Declaration job)
{
var data = job.Body;
var lookAheadData = new DriverData.LACData() {
Enabled = DeclarationData.Driver.LookAhead.Enabled,
Deceleration = DeclarationData.Driver.LookAhead.Deceleration,
MinSpeed = DeclarationData.Driver.LookAhead.MinimumSpeed
};
var overspeedData = new DriverData.OverSpeedEcoRollData() {
Mode = DriverData.ParseDriverMode(data.OverSpeedEcoRoll.Mode),
MinSpeed = DeclarationData.Driver.OverSpeedEcoRoll.MinSpeed,
OverSpeed = DeclarationData.Driver.OverSpeedEcoRoll.OverSpeed,
UnderSpeed = DeclarationData.Driver.OverSpeedEcoRoll.UnderSpeed
};
if (!DeclarationData.Driver.OverSpeedEcoRoll.AllowedModes.Contains(overspeedData.Mode)) {
throw new VectoSimulationException(
string.Format("Specified Overspeed/EcoRoll Mode not allowed in declaration mode! {0}", overspeedData.Mode));
}
var startstopData = new VectoRunData.StartStopData() {
Enabled = data.StartStop.Enabled,
Delay = DeclarationData.Driver.StartStop.Delay,
MinTime = DeclarationData.Driver.StartStop.MinTime,
MaxSpeed = DeclarationData.Driver.StartStop.MaxSpeed,
};
var retVal = new DriverData() {
LookAheadCoasting = lookAheadData,
OverSpeedEcoRoll = overspeedData,
StartStop = startstopData,
};
return retVal;
}
internal VehicleData CreateVehicleData(VehicleFileV5Declaration vehicle, Mission mission, Kilogram loading)
{
var data = vehicle.Body;
......@@ -69,7 +114,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
if (data.AxleConfig.Axles.Count < mission.AxleWeightDistribution.Length) {
throw new VectoException(
String.Format("Vehicle does not contain sufficient axles. {0} axles defined, {1} axles required",
string.Format("Vehicle does not contain sufficient axles. {0} axles defined, {1} axles required",
data.AxleConfig.Axles.Count, mission.AxleWeightDistribution.Count()));
}
retVal.AxleData = new List<Axle>();
......@@ -80,7 +125,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
TwinTyres = axleInput.TwinTyres,
RollResistanceCoefficient = axleInput.RollResistanceCoefficient,
TyreTestLoad = axleInput.TyreTestLoad.SI<Newton>(),
Inertia = DeclarationData.Wheels.Lookup(axleInput.WheelsStr).Inertia,
Inertia = DeclarationData.Wheels.Lookup(axleInput.WheelsStr.Replace(" ", "")).Inertia,
};
retVal.AxleData.Add(axle);
}
......@@ -98,18 +143,17 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
return retVal;
}
internal CombustionEngineData CreateEngineData(EngineFileV2Declaration engine)
internal CombustionEngineData CreateEngineData(EngineFileV3Declaration engine)
{
var retVal = SetCommonCombustionEngineData(engine.Body, engine.BasePath);
retVal.Inertia = DeclarationData.Engine.EngineInertia(retVal.Displacement);
foreach (var entry in engine.Body.FullLoadCurves) {
retVal.AddFullLoadCurve(entry.Gears, FullLoadCurve.ReadFromFile(Path.Combine(engine.BasePath, entry.Path), true));
}
retVal.FullLoadCurve = EngineFullLoadCurve.ReadFromFile(Path.Combine(engine.BasePath, engine.Body.FullLoadCurve),
true);
retVal.FullLoadCurve.EngineData = retVal;
return retVal;
}
internal GearboxData CreateGearboxData(GearboxFileV4Declaration gearbox, CombustionEngineData engine)
internal GearboxData CreateGearboxData(GearboxFileV5Declaration gearbox, CombustionEngineData engine)
{
var retVal = SetCommonGearboxData(gearbox.Body);
......@@ -134,20 +178,64 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
for (uint i = 0; i < gearbox.Body.Gears.Count; i++) {
var gearSettings = gearbox.Body.Gears[(int) i];
var gearSettings = gearbox.Body.Gears[(int)i];
var lossMapPath = Path.Combine(gearbox.BasePath, gearSettings.LossMap);
TransmissionLossMap lossMap = TransmissionLossMap.ReadFromFile(lossMapPath, gearSettings.Ratio);
var lossMap = TransmissionLossMap.ReadFromFile(lossMapPath, gearSettings.Ratio);
if (i == 0) {
retVal.AxleGearData = new GearData(lossMap, null, gearSettings.Ratio, false);
retVal.AxleGearData = new GearData() {
LossMap = lossMap,
Ratio = gearSettings.Ratio,
TorqueConverterActive = false
};
} else {
var shiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(engine, i);
retVal._gearData.Add(i, new GearData(lossMap, shiftPolygon, gearSettings.Ratio, false));
var fullLoad = !string.IsNullOrEmpty(gearSettings.FullLoadCurve) && !gearSettings.FullLoadCurve.Equals("<NOFILE>")
? GearFullLoadCurve.ReadFromFile(Path.Combine(gearbox.BasePath, gearSettings.FullLoadCurve))
: null;
var shiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(fullLoad, engine);
retVal._gearData.Add(i, new GearData() {
LossMap = lossMap,
ShiftPolygon = shiftPolygon,
Ratio = gearSettings.Ratio,
TorqueConverterActive = false
});
}
}
return retVal;
}
public IEnumerable<VectoRunData.AuxData> CreateAuxiliaryData(IEnumerable<VectoRunData.AuxData> auxList,
MissionType mission, VehicleClass hvdClass)
{
foreach (var auxData in auxList) {
var aux = new VectoRunData.AuxData { DemandType = AuxiliaryDemandType.Constant };
switch (aux.Type) {
case AuxiliaryType.Fan:
aux.PowerDemand = DeclarationData.Fan.Lookup(mission, auxData.Technology);
aux.ID = Constants.Auxiliaries.IDs.Fan;
break;
case AuxiliaryType.SteeringPump:
aux.PowerDemand = DeclarationData.SteeringPump.Lookup(mission, hvdClass, auxData.Technology);
aux.ID = Constants.Auxiliaries.IDs.SteeringPump;
break;
case AuxiliaryType.HeatingVentilationAirCondition:
aux.PowerDemand = DeclarationData.HeatingVentilationAirConditioning.Lookup(mission, hvdClass);
aux.ID = Constants.Auxiliaries.IDs.HeatingVentilationAirCondition;
break;
case AuxiliaryType.PneumaticSystem:
aux.PowerDemand = DeclarationData.PneumaticSystem.Lookup(mission, hvdClass);
aux.ID = Constants.Auxiliaries.IDs.PneumaticSystem;
break;
case AuxiliaryType.ElectricSystem:
aux.PowerDemand = DeclarationData.ElectricSystem.Lookup(mission, auxData.TechList);
aux.ID = Constants.Auxiliaries.IDs.ElectricSystem;
break;
}
yield return aux;
}
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.FileIO.EngineeringFile;
using TUGraz.VectoCore.Models.Declaration;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
using TUGraz.VectoCore.Models.SimulationComponent.Impl;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
......@@ -30,7 +34,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
public override CombustionEngineData CreateEngineData(VectoEngineFile engine)
{
var fileV2Eng = engine as EngineFileV2Engineering;
var fileV2Eng = engine as EngineFileV3Engineering;
if (fileV2Eng != null) {
return CreateEngineData(fileV2Eng);
}
......@@ -39,16 +43,56 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
public override GearboxData CreateGearboxData(VectoGearboxFile gearbox, CombustionEngineData engine)
{
var fileV5Eng = gearbox as GearboxFileV4Engineering;
var fileV5Eng = gearbox as GearboxFileV5Engineering;
if (fileV5Eng != null) {
return CreateGearboxData(fileV5Eng);
}
throw new VectoException("Unsupported GearboxData File Instance");
}
public override DriverData CreateDriverData(VectoJobFile job)
{
var filev2Eng = job as VectoJobFileV2Engineering;
if (filev2Eng != null) {
return CreateDriverData(filev2Eng);
}
throw new VectoException("Unsupported Job File Instance");
}
//=================================
internal DriverData CreateDriverData(VectoJobFileV2Engineering job)
{
var data = job.Body;
var accelerationData = AccelerationCurveData.ReadFromFile(Path.Combine(job.BasePath, data.AccelerationCurve));
var lookAheadData = new DriverData.LACData() {
Enabled = data.LookAheadCoasting.Enabled,
Deceleration = data.LookAheadCoasting.Dec.SI<MeterPerSquareSecond>(),
MinSpeed = data.LookAheadCoasting.MinSpeed.KMPHtoMeterPerSecond(),
};
var overspeedData = new DriverData.OverSpeedEcoRollData() {
Mode = DriverData.ParseDriverMode(data.OverSpeedEcoRoll.Mode),
MinSpeed = data.OverSpeedEcoRoll.MinSpeed.KMPHtoMeterPerSecond(),
OverSpeed = data.OverSpeedEcoRoll.OverSpeed.KMPHtoMeterPerSecond(),
UnderSpeed = data.OverSpeedEcoRoll.UnderSpeed.KMPHtoMeterPerSecond(),
};
var startstopData = new VectoRunData.StartStopData() {
Enabled = data.StartStop.Enabled,
Delay = data.StartStop.Delay.SI<Second>(),
MinTime = data.StartStop.MinTime.SI<Second>(),
MaxSpeed = data.StartStop.MaxSpeed.KMPHtoMeterPerSecond(),
};
var retVal = new DriverData() {
AccelerationCurve = accelerationData,
LookAheadCoasting = lookAheadData,
OverSpeedEcoRoll = overspeedData,
StartStop = startstopData,
};
return retVal;
}
/// <summary>
/// convert datastructure representing file-contents into internal datastructure
/// Vehicle, file-format version 5
......@@ -67,7 +111,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
retVal.DynamicTyreRadius = data.DynamicTyreRadius.SI().Milli.Meter.Cast<Meter>();
retVal.AxleData = data.AxleConfig.Axles.Select(axle => new Axle {
Inertia = DoubleExtensionMethods.SI<KilogramSquareMeter>(axle.Inertia),
Inertia = axle.Inertia.SI<KilogramSquareMeter>(),
TwinTyres = axle.TwinTyres,
RollResistanceCoefficient = axle.RollResistanceCoefficient,
AxleWeightShare = axle.AxleWeightShare,
......@@ -84,14 +128,13 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
/// </summary>
/// <param name="engine">Engin-Data file (Engineering mode)</param>
/// <returns></returns>
internal CombustionEngineData CreateEngineData(EngineFileV2Engineering engine)
internal CombustionEngineData CreateEngineData(EngineFileV3Engineering engine)
{
var retVal = SetCommonCombustionEngineData(engine.Body, engine.BasePath);
retVal.Inertia = engine.Body.Inertia.SI<KilogramSquareMeter>();
foreach (var entry in engine.Body.FullLoadCurves) {
retVal.AddFullLoadCurve(entry.Gears, FullLoadCurve.ReadFromFile(Path.Combine(engine.BasePath, entry.Path), false));
}
retVal.FullLoadCurve = EngineFullLoadCurve.ReadFromFile(Path.Combine(engine.BasePath, engine.Body.FullLoadCurve),
false);
retVal.FullLoadCurve.EngineData = retVal;
return retVal;
}
......@@ -102,7 +145,7 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
/// </summary>
/// <param name="gearbox"></param>
/// <returns></returns>
internal GearboxData CreateGearboxData(GearboxFileV4Engineering gearbox)
internal GearboxData CreateGearboxData(GearboxFileV5Engineering gearbox)
{
var retVal = SetCommonGearboxData(gearbox.Body);
......@@ -121,15 +164,24 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
retVal.HasTorqueConverter = data.TorqueConverter.Enabled;
for (uint i = 0; i < gearbox.Body.Gears.Count; i++) {
var gearSettings = gearbox.Body.Gears[(int) i];
var gearSettings = gearbox.Body.Gears[(int)i];
var lossMapPath = Path.Combine(gearbox.BasePath, gearSettings.LossMap);
TransmissionLossMap lossMap = TransmissionLossMap.ReadFromFile(lossMapPath, gearSettings.Ratio);
var shiftPolygon = !String.IsNullOrEmpty(gearSettings.ShiftPolygon)
var shiftPolygon = !string.IsNullOrEmpty(gearSettings.ShiftPolygon)
? ShiftPolygon.ReadFromFile(Path.Combine(gearbox.BasePath, gearSettings.ShiftPolygon))
: null;
var fullLoad = !string.IsNullOrEmpty(gearSettings.FullLoadCurve) && !gearSettings.FullLoadCurve.Equals("<NOFILE>")
? GearFullLoadCurve.ReadFromFile(Path.Combine(gearbox.BasePath, gearSettings.FullLoadCurve))
: null;
var gear = new GearData(lossMap, shiftPolygon, gearSettings.Ratio, gearSettings.TCactive);
var gear = new GearData() {
LossMap = lossMap,
ShiftPolygon = shiftPolygon,
FullLoadCurve = fullLoad,
Ratio = gearSettings.Ratio,
TorqueConverterActive = gearSettings.TCactive
};
if (i == 0) {
retVal.AxleGearData = gear;
} else {
......
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using Common.Logging;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.FileIO.Reader
{
public class DrivingCycleDataReader
{
// --- Factory Methods
public static DrivingCycleData ReadFromStream(Stream stream, DrivingCycleData.CycleType type)
{
return DoReadCycleData(type, VectoCSVFile.ReadStream(stream));
}
public static DrivingCycleData ReadFromFileEngineOnly(string fileName)
{
return ReadFromFile(fileName, DrivingCycleData.CycleType.EngineOnly);
}
public static DrivingCycleData ReadFromFileDistanceBased(string fileName)
{
return ReadFromFile(fileName, DrivingCycleData.CycleType.DistanceBased);
}
public static DrivingCycleData ReadFromFileTimeBased(string fileName)
{
return ReadFromFile(fileName, DrivingCycleData.CycleType.TimeBased);
}
public static DrivingCycleData ReadFromFile(string fileName, DrivingCycleData.CycleType type)
{
var retVal = DoReadCycleData(type, VectoCSVFile.Read(fileName));
retVal.Name = Path.GetFileNameWithoutExtension(fileName);
return retVal;
}
private static DrivingCycleData DoReadCycleData(DrivingCycleData.CycleType type, DataTable data)
{
var parser = CreateDataParser(type);
var entries = parser.Parse(data).ToList();
if (type == DrivingCycleData.CycleType.DistanceBased) {
entries = FilterDrivingCycleEntries(entries);
}
var cycle = new DrivingCycleData {
Entries = entries,
};
return cycle;
}
// ----
private static List<DrivingCycleData.DrivingCycleEntry> FilterDrivingCycleEntries(
List<DrivingCycleData.DrivingCycleEntry> entries)
{
var log = LogManager.GetLogger<DrivingCycleData>();
var filtered = new List<DrivingCycleData.DrivingCycleEntry>();
var current = entries.First();
current.Altitude = 0.SI<Meter>();
filtered.Add(current);
var distance = current.Distance;
var altitude = current.Altitude;
foreach (var entry in entries) {
entry.Altitude = altitude;
if (!CycleEntriesAreEqual(current, entry)) {
entry.Altitude = altitude;
filtered.Add(entry);
current = entry;
}
if (entry.StoppingTime.IsEqual(0) && !entry.VehicleTargetSpeed.IsEqual(0)) {
altitude += (entry.Distance - distance) * entry.RoadGradientPercent / 100.0;
}
distance = entry.Distance;
}
log.Info(string.Format("Data loaded. Number of Entries: {0}, filtered Entries: {1}", entries.Count, filtered.Count));
entries = filtered;
AdjustDistanceAfterStop(entries);
return entries;
}
private static void AdjustDistanceAfterStop(List<DrivingCycleData.DrivingCycleEntry> entries)
{
var currentIt = entries.GetEnumerator();
var nextIt = entries.GetEnumerator();
nextIt.MoveNext();
while (currentIt.MoveNext() && nextIt.MoveNext()) {
if (currentIt.Current != null && !currentIt.Current.StoppingTime.IsEqual(0)) {
if (nextIt.Current != null) {
nextIt.Current.Distance = currentIt.Current.Distance;
}
}
}
}
// -----
private static bool CycleEntriesAreEqual(DrivingCycleData.DrivingCycleEntry first,
DrivingCycleData.DrivingCycleEntry second)
{
if (first.Distance.IsEqual(second.Distance)) {
return true;
}
var retVal = first.VehicleTargetSpeed == second.VehicleTargetSpeed;
retVal = retVal &&
first.RoadGradient.IsEqual(second.RoadGradient, Constants.SimulationSettings.DrivingCycleRoadGradientTolerance);
retVal = retVal && first.StoppingTime.IsEqual(0) && second.StoppingTime.IsEqual(0);
retVal = retVal && first.AdditionalAuxPowerDemand == second.AdditionalAuxPowerDemand;
retVal = retVal && first.AuxiliarySupplyPower.Count == second.AuxiliarySupplyPower.Count;
foreach (var key in first.AuxiliarySupplyPower.Keys) {
if (!second.AuxiliarySupplyPower.ContainsKey(key)) {
return false;
}
retVal = retVal && first.AuxiliarySupplyPower[key] == second.AuxiliarySupplyPower[key];
}
return retVal;
}
private static IDataParser CreateDataParser(DrivingCycleData.CycleType type)
{
switch (type) {
case DrivingCycleData.CycleType.EngineOnly:
return new EngineOnlyDataParser();
case DrivingCycleData.CycleType.TimeBased:
return new TimeBasedDataParser();
case DrivingCycleData.CycleType.DistanceBased:
return new DistanceBasedDataParser();
default:
throw new ArgumentOutOfRangeException("type");
}
}
private static class Fields
{
/// <summary>
/// [m] Travelled distance used for distance-based cycles. If t is also defined this column will be ignored.
/// </summary>
public const string Distance = "s";
/// <summary>
/// [s] Used for time-based cycles. If neither this nor the distance s is defined the data will be interpreted as 1Hz.
/// </summary>
public const string Time = "t";
/// <summary>
/// [km/h] Required except for Engine Only Mode calculations.
/// </summary>
public const string VehicleSpeed = "v";
/// <summary>
/// [%] Optional.
/// </summary>
public const string RoadGradient = "grad";
/// <summary>
/// [s] Required for distance-based cycles. Not used in time based cycles. stop defines the time the vehicle spends in
/// stop phases.
/// </summary>
public const string StoppingTime = "stop";
/// <summary>
/// [kW] "Aux_xxx" Supply Power input for each auxiliary defined in the .vecto file , where xxx matches the ID of the
/// corresponding Auxiliary. ID's are not case sensitive and must not contain space or special characters.
/// </summary>
// todo: implement additional aux as dictionary!
public const string AuxiliarySupplyPower = "Aux_";
/// <summary>
/// [rpm] If n is defined VECTO uses that instead of the calculated engine speed value.
/// </summary>
public const string EngineSpeed = "n";
/// <summary>
/// [-] Gear input. Overwrites the gear shift model.
/// </summary>
public const string Gear = "gear";
/// <summary>
/// [kW] This power input will be directly added to the engine power in addition to possible other auxiliaries. Also
/// used in Engine Only Mode.
/// </summary>
public const string AdditionalAuxPowerDemand = "Padd";
/// <summary>
/// [km/h] Only required if Cross Wind Correction is set to Vair and Beta Input.
/// </summary>
public const string AirSpeedRelativeToVehicle = "vair_res";
/// <summary>
/// [°] Only required if Cross Wind Correction is set to Vair and Beta Input.
/// </summary>
public const string WindYawAngle = "vair_beta";
/// <summary>
/// [kW] Effective engine power at clutch. Only required in Engine Only Mode. Alternatively torque Me can be defined.
/// Use DRAG to define motoring operation.
/// </summary>
public const string EnginePower = "Pe";
/// <summary>
/// [Nm] Effective engine torque at clutch. Only required in Engine Only Mode. Alternatively power Pe can be defined.
/// Use DRAG to define motoring operation.
/// </summary>
public const string EngineTorque = "Me";
}
#region DataParser
private interface IDataParser
{
IEnumerable<DrivingCycleData.DrivingCycleEntry> Parse(DataTable table);
}
internal class DistanceBasedDataParser : IDataParser
{
public IEnumerable<DrivingCycleData.DrivingCycleEntry> Parse(DataTable table)
{
ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
return table.Rows.Cast<DataRow>().Select(row => new DrivingCycleData.DrivingCycleEntry {
Distance = row.ParseDouble(Fields.Distance).SI<Meter>(),
VehicleTargetSpeed =
row.ParseDouble(Fields.VehicleSpeed)
.SI()
.Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(),
RoadGradientPercent = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
RoadGradient =
VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0),
StoppingTime =
(row.ParseDouble(Fields.StoppingTime)).SI<Second>(),
AdditionalAuxPowerDemand =
row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
EngineSpeed =
row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.Cast<PerSecond>(),
Gear = row.ParseDoubleOrGetDefault(Fields.Gear),
AirSpeedRelativeToVehicle =
row.ParseDoubleOrGetDefault(Fields.AirSpeedRelativeToVehicle)
.SI()
.Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(),
WindYawAngle = row.ParseDoubleOrGetDefault(Fields.WindYawAngle),
AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
});
}
private static void ValidateHeader(string[] header)
{
var allowedCols = new[] {
Fields.Distance,
Fields.VehicleSpeed,
Fields.RoadGradient,
Fields.StoppingTime,
Fields.EngineSpeed,
Fields.Gear,
Fields.AdditionalAuxPowerDemand,
Fields.AirSpeedRelativeToVehicle,
Fields.WindYawAngle
};
foreach (
var col in
header.Where(
col => !(allowedCols.Contains(col) || col.StartsWith(Fields.AuxiliarySupplyPower)))
) {
throw new VectoException(string.Format("Column '{0}' is not allowed.", col));
}
if (!header.Contains(Fields.VehicleSpeed)) {
throw new VectoException(string.Format("Column '{0}' is missing.",
Fields.VehicleSpeed));
}
if (!header.Contains(Fields.Distance)) {
throw new VectoException(string.Format("Column '{0}' is missing.", Fields.Distance));
}
if (header.Contains(Fields.AirSpeedRelativeToVehicle) ^
header.Contains(Fields.WindYawAngle)) {
throw new VectoException(
string.Format("Both Columns '{0}' and '{1}' must be defined, or none of them.",
Fields.AirSpeedRelativeToVehicle, Fields.WindYawAngle));
}
}
}
private class TimeBasedDataParser : IDataParser
{
public IEnumerable<DrivingCycleData.DrivingCycleEntry> Parse(DataTable table)
{
ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
var entries = table.Rows.Cast<DataRow>().Select((row, index) => new DrivingCycleData.DrivingCycleEntry {
Time = row.ParseDoubleOrGetDefault(Fields.Time, index).SI<Second>(),
VehicleTargetSpeed =
row.ParseDouble(Fields.VehicleSpeed)
.SI()
.Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(),
RoadGradientPercent = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
RoadGradient =
VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0),
AdditionalAuxPowerDemand =
row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
Gear = row.ParseDoubleOrGetDefault(Fields.Gear),
EngineSpeed =
row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.Cast<PerSecond>(),
AirSpeedRelativeToVehicle =
row.ParseDoubleOrGetDefault(Fields.AirSpeedRelativeToVehicle)
.SI()
.Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(),
WindYawAngle = row.ParseDoubleOrGetDefault(Fields.WindYawAngle),
AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
}).ToArray();
return entries;
}
private static void ValidateHeader(string[] header)
{
var allowedCols = new[] {
Fields.Time,
Fields.VehicleSpeed,
Fields.RoadGradient,
Fields.EngineSpeed,
Fields.Gear,
Fields.AdditionalAuxPowerDemand,
Fields.AirSpeedRelativeToVehicle,
Fields.WindYawAngle
};
foreach (
var col in
header.Where(
col => !(allowedCols.Contains(col) || col.StartsWith(Fields.AuxiliarySupplyPower)))
) {
throw new VectoException(string.Format("Column '{0}' is not allowed.", col));
}
if (!header.Contains(Fields.VehicleSpeed)) {
throw new VectoException(string.Format("Column '{0}' is missing.",
Fields.VehicleSpeed));
}
if (header.Contains(Fields.AirSpeedRelativeToVehicle) ^
header.Contains(Fields.WindYawAngle)) {
throw new VectoException(
string.Format("Both Columns '{0}' and '{1}' must be defined, or none of them.",
Fields.AirSpeedRelativeToVehicle, Fields.WindYawAngle));
}
}
}
private class EngineOnlyDataParser : IDataParser
{
public IEnumerable<DrivingCycleData.DrivingCycleEntry> Parse(DataTable table)
{
ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
var absTime = 0.SI<Second>();
foreach (DataRow row in table.Rows) {
var entry = new DrivingCycleData.DrivingCycleEntry {
EngineSpeed =
row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.Cast<PerSecond>(),
AdditionalAuxPowerDemand =
row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
};
if (row.Table.Columns.Contains(Fields.EngineTorque)) {
if (row.Field<string>(Fields.EngineTorque).Equals("<DRAG>")) {
entry.Drag = true;
} else {
entry.EngineTorque =
row.ParseDouble(Fields.EngineTorque).SI<NewtonMeter>();
}
} else {
if (row.Field<string>(Fields.EnginePower).Equals("<DRAG>")) {
entry.Drag = true;
} else {
entry.EngineTorque =
Formulas.PowerToTorque(
row.ParseDouble(Fields.EnginePower)
.SI()
.Kilo.Watt.Cast<Watt>(),
entry.EngineSpeed);
}
}
entry.Time = absTime;
absTime += 1.SI<Second>();
yield return entry;
}
}
private static void ValidateHeader(string[] header)
{
var allowedCols = new[] {
Fields.EngineTorque,
Fields.EnginePower,
Fields.EngineSpeed,
Fields.AdditionalAuxPowerDemand
};
foreach (var col in header.Where(col => !allowedCols.Contains(col))) {
throw new VectoException(string.Format("Column '{0}' is not allowed.", col));
}
if (!header.Contains(Fields.EngineSpeed)) {
throw new VectoException(string.Format("Column '{0}' is missing.",
Fields.EngineSpeed));
}
if (!(header.Contains(Fields.EngineTorque) || header.Contains(Fields.EnginePower))) {
throw new VectoException(
string.Format("Columns missing: Either column '{0}' or column '{1}' must be defined.",
Fields.EngineTorque, Fields.EnginePower));
}
if (header.Contains(Fields.EngineTorque) && header.Contains(Fields.EnginePower)) {
LogManager.GetLogger<DrivingCycleData>()
.WarnFormat("Found column '{0}' and column '{1}': only column '{0}' will be used.",
Fields.EngineTorque, Fields.EnginePower);
}
}
}
#endregion
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.IO;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.FileIO.DeclarationFile;
using TUGraz.VectoCore.Models.Declaration;
using System.Collections.Generic;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.FileIO.Reader.Impl
{
......@@ -15,14 +7,15 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl
{
//protected string JobBasePath = "";
protected VectoJobFile Job;
protected VectoJobFile Job { get; set; }
protected VectoVehicleFile Vehicle;
protected VectoVehicleFile Vehicle { get; set; }
protected VectoGearboxFile Gearbox;
protected VectoGearboxFile Gearbox { get; set; }
protected VectoEngineFile Engine;
protected VectoEngineFile Engine { get; set; }
protected IList<VectoRunData.AuxData> Aux { get; set; }
public void SetJobFile(string filename)
{
......@@ -38,10 +31,14 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl
protected abstract void ProcessJob(VectoJobFile job);
// has to read the file string and create file-container
/// <summary>
/// has to read the file string and create file-container
/// </summary>
protected abstract void ReadJobFile(string file);
// has to read the file string and create file-container
/// <summary>
/// has to read the file string and create file-container
/// </summary>
protected abstract void ReadVehicle(string file);
protected abstract void ReadEngine(string file);
......
using System;
using System.Collections.Generic;
using System.Data;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
......@@ -10,8 +8,6 @@ using TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper;
using TUGraz.VectoCore.Models.Declaration;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.FileIO.Reader.Impl
......@@ -34,26 +30,23 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl
var tmpVehicle = dao.CreateVehicleData(Vehicle);
var segment = GetVehicleClassification(tmpVehicle.VehicleCategory, tmpVehicle.AxleConfiguration,
tmpVehicle.GrossVehicleMassRating, tmpVehicle.CurbWeight);
var driverdata = dao.CreateDriverData(Job);
driverdata.AccelerationCurve = AccelerationCurveData.ReadFromStream(segment.AccelerationFile);
foreach (var mission in segment.Missions) {
foreach (var loading in mission.Loadings) {
var engineData = dao.CreateEngineData(Engine);
var parser = new DrivingCycleData.DistanceBasedDataParser();
var data = VectoCSVFile.ReadStream(mission.CycleFile);
var cycleEntries = parser.Parse(data).ToList();
var simulationRunData = new VectoRunData() {
var simulationRunData = new VectoRunData {
VehicleData = dao.CreateVehicleData(Vehicle, mission, loading),
EngineData = engineData,
GearboxData = dao.CreateGearboxData(Gearbox, engineData),
// @@@ TODO: auxiliaries
// @@@ TODO: ...
Cycle = new DrivingCycleData() {
Name = "Dummy",
SavedInDeclarationMode = true,
Entries = cycleEntries
},
Aux = dao.CreateAuxiliaryData(Aux, mission.MissionType, segment.VehicleClass),
Cycle = DrivingCycleDataReader.ReadFromStream(mission.CycleFile, DrivingCycleData.CycleType.DistanceBased),
DriverData = driverdata,
IsEngineOnly = IsEngineOnly,
JobFileName = Job.JobFile,
JobFileName = Job.JobFile
};
simulationRunData.VehicleData.VehicleClass = segment.VehicleClass;
yield return simulationRunData;
}
}
......@@ -72,6 +65,8 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl
ReadEngine(Path.Combine(job.BasePath, job.Body.EngineFile));
ReadGearbox(Path.Combine(job.BasePath, job.Body.GearboxFile));
ReadAuxiliary(job.Body.Aux);
}
protected override void ReadJobFile(string file)
......@@ -91,7 +86,6 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl
}
}
protected override void ReadVehicle(string file)
{
var json = File.ReadAllText(file);
......@@ -115,12 +109,12 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl
CheckForDeclarationMode(fileInfo, "Engine");
switch (fileInfo.Version) {
case 2:
Engine = JsonConvert.DeserializeObject<EngineFileV2Declaration>(json);
case 3:
Engine = JsonConvert.DeserializeObject<EngineFileV3Declaration>(json);
Engine.BasePath = Path.GetDirectoryName(file);
break;
default:
throw new UnsupportedFileVersionException("Unsopported Version of engine-file. Got version " + fileInfo.Version);
throw new UnsupportedFileVersionException("Unsupported Version of engine-file. Got version " + fileInfo.Version);
}
}
......@@ -131,15 +125,33 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl
CheckForDeclarationMode(fileInfo, "Gearbox");
switch (fileInfo.Version) {
case 4:
Gearbox = JsonConvert.DeserializeObject<GearboxFileV4Declaration>(json);
case 5:
Gearbox = JsonConvert.DeserializeObject<GearboxFileV5Declaration>(json);
Gearbox.BasePath = Path.GetDirectoryName(file);
break;
default:
throw new UnsupportedFileVersionException("Unsopported Version of gearbox-file. Got version " + fileInfo.Version);
throw new UnsupportedFileVersionException("Unsupported Version of gearbox-file. Got version " + fileInfo.Version);
}
}
private void ReadAuxiliary(IEnumerable<VectoJobFileV2Declaration.DataBodyDecl.AuxDataDecl> auxiliaries)
{
var aux = DeclarationData.AuxiliaryIDs().Select(id => {
var a = auxiliaries.First(decl => decl.ID == id);
return new VectoRunData.AuxData {
ID = a.ID,
Type = AuxiliaryTypeHelper.Parse(a.Type),
Technology = a.Technology,
TechList = a.TechList.DefaultIfNull(Enumerable.Empty<string>()).ToArray(),
DemandType = AuxiliaryDemandType.Constant
};
});
// add a direct auxiliary
aux = aux.Concat(new VectoRunData.AuxData { ID = "", DemandType = AuxiliaryDemandType.Direct }.ToEnumerable());
Aux = aux.ToArray();
}
internal Segment GetVehicleClassification(VehicleCategory category, AxleConfiguration axles, Kilogram grossMassRating,
Kilogram curbWeight)
......
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