diff --git a/VECTO/Input Files/cGBX.vb b/VECTO/Input Files/cGBX.vb index 89ee1ab780ac738e8fd1fd8bec0d482022771060..e3212d3854e57a73e7b2cf1600e57b0f93318356 100644 --- a/VECTO/Input Files/cGBX.vb +++ b/VECTO/Input Files/cGBX.vb @@ -391,12 +391,12 @@ Public Class cGBX Do While Not file.EndOfFile line = file.ReadLine TCnuMax = CSng(line(0)) - If CSng(line(0)) < 1 Then - TCnu.Add(TCnuMax) - TCmu.Add(CSng(line(1))) - TCtorque.Add(CSng(line(2))) - TCdim += 1 - End If + 'If CSng(line(0)) < 1 Then '@@@quam: read the complete file! + TCnu.Add(TCnuMax) + TCmu.Add(CSng(line(1))) + TCtorque.Add(CSng(line(2))) + TCdim += 1 + 'End If Loop Catch ex As Exception WorkerMsg(tMsgID.Err, "Error while reading Torque Converter file! (" & ex.Message & ")", MsgSrc) @@ -413,29 +413,31 @@ Public Class cGBX If TCnuMax > 1 Then TCnuMax = 1 - 'Add default values for nu>1 - If Not file.OpenRead(MyDeclPath & "DefaultTC.vtcc") Then - WorkerMsg(tMsgID.Err, "Default Torque Converter file not found!", MsgSrc) - Return False - End If + If False Then ' @@@quam: don'r read default tcc file + 'Add default values for nu>1 + If Not file.OpenRead(MyDeclPath & "DefaultTC.vtcc") Then + WorkerMsg(tMsgID.Err, "Default Torque Converter file not found!", MsgSrc) + Return False + End If - 'Skip Header - file.ReadLine() + 'Skip Header + file.ReadLine() - Try - Do While Not file.EndOfFile - line = file.ReadLine - TCnu.Add(CSng(line(0))) - TCmu.Add(CSng(line(1))) - TCtorque.Add(CSng(line(2))) - TCdim += 1 - Loop - Catch ex As Exception - WorkerMsg(tMsgID.Err, "Error while reading Default Torque Converter file! (" & ex.Message & ")", MsgSrc) - Return False - End Try + Try + Do While Not file.EndOfFile + line = file.ReadLine + TCnu.Add(CSng(line(0))) + TCmu.Add(CSng(line(1))) + TCtorque.Add(CSng(line(2))) + TCdim += 1 + Loop + Catch ex As Exception + WorkerMsg(tMsgID.Err, "Error while reading Default Torque Converter file! (" & ex.Message & ")", MsgSrc) + Return False + End Try - file.Close() + file.Close() + End If Return True End Function diff --git a/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs b/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs index 18411c284f903f28f2ec4a691ea4397ed7e2919a..ad9bdc4e2200f7fff038df103a014b5c8a1655af 100644 --- a/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs +++ b/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs @@ -83,7 +83,7 @@ namespace TUGraz.VectoCommon.InputData /// cf. VECTO Input Parameters.xlsx /// </summary> Kilogram CurbWeightChassis { get; } - + /// <summary> /// P041 Max. vehicle weight /// cf. VECTO Input Parameters.xlsx @@ -375,30 +375,18 @@ namespace TUGraz.VectoCommon.InputData public interface IAuxiliaryDeclarationInputData { - bool SavedInDeclarationMode { get; } - - /// <summary> - /// P006 Aux-ID - /// cf. VECTO Input Parameters.xlsx - /// </summary> - string ID { get; } - /// <summary> /// P005 Aux-Type /// cf. VECTO Input Parameters.xlsx /// </summary> - string Type { get; } + AuxiliaryType Type { get; } /// <summary> /// P118 Aux-Technology /// cf. VECTO Input Parameters.xlsx /// </summary> - string Technology { get; } - - /// <summary> - /// P143 Aux-Techlist - /// cf. VECTO Input Parameters.xlsx - /// </summary> - IList<string> TechList { get; } + IList<string> Technology { get; } } + + } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs b/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs index 38d30a59b8533fd2e06ed28b93a4265c00f2d93a..a254918c4bb40b75bfb7412c8bf5cd4cdf7bf54b 100644 --- a/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs +++ b/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs @@ -214,9 +214,9 @@ namespace TUGraz.VectoCommon.InputData KilogramSquareMeter Inertia { get; } } - public interface IAuxiliariesEngineeringInputData : IAuxiliariesDeclarationInputData + public interface IAuxiliariesEngineeringInputData { - new IList<IAuxiliaryEngineeringInputData> Auxiliaries { get; } + IList<IAuxiliaryEngineeringInputData> Auxiliaries { get; } // Advanced Auxiliaries AuxiliaryModel AuxiliaryAssembly { get; } @@ -312,8 +312,14 @@ namespace TUGraz.VectoCommon.InputData DataTable CoastingDecisionFactorVelocityDropLookup { get; } } - public interface IAuxiliaryEngineeringInputData : IAuxiliaryDeclarationInputData + public interface IAuxiliaryEngineeringInputData { + /// <summary> + /// P006 Aux-ID + /// cf. VECTO Input Parameters.xlsx + /// </summary> + string ID { get; } + /// <summary> /// either mapping or constant /// </summary> diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryType.cs b/VectoCommon/VectoCommon/Models/AuxiliaryType.cs similarity index 93% rename from VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryType.cs rename to VectoCommon/VectoCommon/Models/AuxiliaryType.cs index 301861343d903b516668c214105d43b9fb755a90..094eb9209e3af9cd05934238a18f165d263e57eb 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryType.cs +++ b/VectoCommon/VectoCommon/Models/AuxiliaryType.cs @@ -32,13 +32,13 @@ using System; using TUGraz.VectoCore.Configuration; -namespace TUGraz.VectoCore.Models.SimulationComponent.Data +namespace TUGraz.VectoCommon.Models { public enum AuxiliaryType { Fan, SteeringPump, - HeatingVentilationAirCondition, + HVAC, PneumaticSystem, ElectricSystem } @@ -53,7 +53,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data case Constants.Auxiliaries.Names.SteeringPump: return AuxiliaryType.SteeringPump; case Constants.Auxiliaries.Names.HeatingVentilationAirCondition: - return AuxiliaryType.HeatingVentilationAirCondition; + return AuxiliaryType.HVAC; case Constants.Auxiliaries.Names.ElectricSystem: return AuxiliaryType.ElectricSystem; case Constants.Auxiliaries.Names.PneumaticSystem: @@ -70,7 +70,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data return Constants.Auxiliaries.Names.Fan; case AuxiliaryType.SteeringPump: return Constants.Auxiliaries.Names.SteeringPump; - case AuxiliaryType.HeatingVentilationAirCondition: + case AuxiliaryType.HVAC: return Constants.Auxiliaries.Names.HeatingVentilationAirCondition; case AuxiliaryType.PneumaticSystem: return Constants.Auxiliaries.Names.PneumaticSystem; diff --git a/VectoCommon/VectoCommon/Utils/Validation.cs b/VectoCommon/VectoCommon/Utils/Validation.cs index e5c10dec5ac691420805f1e8eb3bb4071bc52281..489976cea781baec7061bd47728b799f4fa550eb 100644 --- a/VectoCommon/VectoCommon/Utils/Validation.cs +++ b/VectoCommon/VectoCommon/Utils/Validation.cs @@ -36,6 +36,7 @@ using System.ComponentModel.DataAnnotations; using System.IO; using System.Linq; using System.Reflection; +using TUGraz.VectoCommon.Models; namespace TUGraz.VectoCommon.Utils { @@ -49,12 +50,14 @@ namespace TUGraz.VectoCommon.Utils /// </summary> /// <typeparam name="T"></typeparam> /// <param name="entity">The entity.</param> + /// <param name="mode">validate the entity for the given execution mode</param> /// <returns>Null, if the validation was successfull. Otherwise a list of ValidationResults with the ErrorMessages.</returns> - public static IList<ValidationResult> Validate<T>(this T entity) + public static IList<ValidationResult> Validate<T>(this T entity, ExecutionMode mode) { var context = new ValidationContext(entity); + context.ServiceContainer.AddService(typeof(ExecutionMode), new ExecutionModeServiceContainer(mode)); var results = new List<ValidationResult>(); - Validator.TryValidateObject(entity, new ValidationContext(entity), results, true); + Validator.TryValidateObject(entity, context, results, true); const BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | @@ -128,6 +131,16 @@ namespace TUGraz.VectoCommon.Utils } } + public class ExecutionModeServiceContainer + { + public ExecutionModeServiceContainer(ExecutionMode mode) + { + Mode = mode; + } + + public ExecutionMode Mode { get; protected set; } + } + /// <summary> /// Determines that the attributed object should be validated recursively. /// </summary> @@ -147,11 +160,14 @@ namespace TUGraz.VectoCommon.Utils return ValidationResult.Success; } + var modeService = validationContext.GetService(typeof(ExecutionMode)) as ExecutionModeServiceContainer; + var mode = modeService != null ? modeService.Mode : ExecutionMode.Declaration; + var enumerable = value as IEnumerable; if (enumerable != null) { var i = 0; foreach (var element in enumerable) { - var results = element.Validate(); + var results = element.Validate(mode); if (results.Any()) { return new ValidationResult( string.Format("{1}[{0}] in {1} invalid: {2}", i, validationContext.DisplayName, @@ -160,7 +176,7 @@ namespace TUGraz.VectoCommon.Utils i++; } } else { - var results = value.Validate(); + var results = value.Validate(mode); if (!results.Any()) { return ValidationResult.Success; } diff --git a/VectoCommon/VectoCommon/VectoCommon.csproj b/VectoCommon/VectoCommon/VectoCommon.csproj index 0a9080e74cc13e3127d0b6da3f552eb0f6ca4533..1132531c6f72d50ca2acd874590b1387f462952e 100644 --- a/VectoCommon/VectoCommon/VectoCommon.csproj +++ b/VectoCommon/VectoCommon/VectoCommon.csproj @@ -44,6 +44,7 @@ <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> + <Compile Include="Models\AuxiliaryType.cs" /> <Compile Include="Exceptions\VectoExceptions.cs" /> <Compile Include="Exceptions\VectoSimulationException.cs" /> <Compile Include="InputData\DeclarationInputData.cs" /> diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs index f3e79e02a1a81b8b88af2ce30ff93908fd978367..c382a404ed04b50fedfee16a3f69f67dda2e70a4 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs @@ -107,7 +107,8 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON /// Fileformat: .vecto /// </summary> public class JSONInputDataV2 : JSONFile, IEngineeringInputDataProvider, IDeclarationInputDataProvider, - IEngineeringJobInputData, IDriverEngineeringInputData, IAuxiliariesEngineeringInputData + IEngineeringJobInputData, IDriverEngineeringInputData, IAuxiliariesEngineeringInputData, + IAuxiliariesDeclarationInputData { protected IGearboxEngineeringInputData Gearbox; protected IAxleGearInputData AxleGear; @@ -262,7 +263,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON IAuxiliariesDeclarationInputData IDeclarationInputDataProvider.AuxiliaryInputData() { - return AuxiliaryInputData(); + return this; } public virtual IRetarderInputData RetarderInputData @@ -450,7 +451,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON #endregion - public virtual IList<IAuxiliaryEngineeringInputData> Auxiliaries + IList<IAuxiliaryEngineeringInputData> IAuxiliariesEngineeringInputData.Auxiliaries { get { return AuxData().Cast<IAuxiliaryEngineeringInputData>().ToList(); } } @@ -466,12 +467,12 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON foreach (var aux in Body["Aux"] ?? Enumerable.Empty<JToken>()) { var auxData = new AuxiliaryDataInputData { ID = aux.GetEx<string>("ID"), - Type = aux.GetEx<string>("Type"), - Technology = aux.GetEx<string>("Technology"), + Type = AuxiliaryTypeHelper.Parse(aux.GetEx<string>("Type")), + Technology = new List<string>() { aux.GetEx<string>("Technology") }, }; - if (aux["TechList"] != null) { - auxData.TechList = aux["TechList"].Select(x => x.ToString()).ToList(); // .Select(x => x.ToString).ToArray(); - } + //if (aux["TechList"] != null) { + // auxData.TechList = aux["TechList"].Select(x => x.ToString()).ToList(); // .Select(x => x.ToString).ToArray(); + //} var auxFile = aux["Path"]; retVal.Add(auxData); diff --git a/VectoCore/VectoCore/InputData/Impl/InputData.cs b/VectoCore/VectoCore/InputData/Impl/InputData.cs index a142e60497c3d61b6f75f6634f05c67894237c12..7f065d5a4bf733e92482f20c99f9610d69ff1fdb 100644 --- a/VectoCore/VectoCore/InputData/Impl/InputData.cs +++ b/VectoCore/VectoCore/InputData/Impl/InputData.cs @@ -136,7 +136,7 @@ namespace TUGraz.VectoCore.InputData.Impl public KilogramSquareMeter Inertia { get; internal set; } } - public class AuxiliaryDataInputData : IAuxiliaryEngineeringInputData + public class AuxiliaryDataInputData : IAuxiliaryEngineeringInputData, IAuxiliaryDeclarationInputData { public AuxiliaryDataInputData() { @@ -146,15 +146,11 @@ namespace TUGraz.VectoCore.InputData.Impl public AuxiliaryDemandType AuxiliaryType { get; internal set; } - public bool SavedInDeclarationMode { get; internal set; } - public string ID { get; internal set; } - public string Type { get; internal set; } - - public string Technology { get; internal set; } + public AuxiliaryType Type { get; internal set; } - public IList<string> TechList { get; internal set; } + public IList<string> Technology { get; internal set; } public double TransmissionRatio { get; internal set; } diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/AuxiliaryDataReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/AuxiliaryDataReader.cs new file mode 100644 index 0000000000000000000000000000000000000000..83aef8d8b764730a22698e01a1d0a5c43d776b79 --- /dev/null +++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/AuxiliaryDataReader.cs @@ -0,0 +1,105 @@ +using System.Data; +using System.IO; +using System.Linq; +using System.Text; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.InputData.Reader.ComponentData +{ + public sealed class AuxiliaryDataReader + { + public static AuxiliaryData Create(IAuxiliaryEngineeringInputData data) + { + var map = ReadAuxMap(data.ID, data.DemandMap); + return new AuxiliaryData(data.TransmissionRatio, data.EfficiencyToEngine, data.EfficiencyToSupply, map); + } + + public static AuxiliaryData ReadFromFile(string fileName, string id) + { + try { + var stream = new StreamReader(fileName); + stream.ReadLine(); // skip header "Transmission ration to engine rpm [-]" + var transmissionRatio = stream.ReadLine().IndulgentParse(); + stream.ReadLine(); // skip header "Efficiency to engine [-]" + var efficiencyToEngine = stream.ReadLine().IndulgentParse(); + stream.ReadLine(); // skip header "Efficiency auxiliary to supply [-]" + var efficiencyToSupply = stream.ReadLine().IndulgentParse(); + + var m = new MemoryStream(Encoding.UTF8.GetBytes(stream.ReadToEnd())); + var table = VectoCSVFile.ReadStream(m); + var map = ReadAuxMap(id, table); + + return new AuxiliaryData(transmissionRatio, efficiencyToEngine, efficiencyToSupply, map); + ; + } catch (FileNotFoundException e) { + throw new VectoException("Auxiliary file not found: " + fileName, e); + } + } + + private static DelaunayMap ReadAuxMap(string id, DataTable table) + { + var map = new DelaunayMap(id); + if (HeaderIsValid(table.Columns)) { + FillFromColumnNames(table, map); + } else { + FillFromColumnIndizes(table, map); + } + + map.Triangulate(); + return map; + } + + + private static void FillFromColumnIndizes(DataTable table, DelaunayMap map) + { + var data = table.Rows.Cast<DataRow>().Select(row => new { + AuxiliarySpeed = row.ParseDouble(0).RPMtoRad(), + MechanicalPower = row.ParseDouble(1).SI().Kilo.Watt.Cast<Watt>(), + SupplyPower = row.ParseDouble(2).SI().Kilo.Watt.Cast<Watt>() + }); + foreach (var d in data) { + map.AddPoint(d.AuxiliarySpeed.Value(), d.SupplyPower.Value(), d.MechanicalPower.Value()); + } + } + + private static void FillFromColumnNames(DataTable table, DelaunayMap map) + { + var data = table.Rows.Cast<DataRow>().Select(row => new { + AuxiliarySpeed = DataTableExtensionMethods.ParseDouble(row, (string)Fields.AuxSpeed).RPMtoRad(), + MechanicalPower = DataTableExtensionMethods.ParseDouble(row, (string)Fields.MechPower).SI().Kilo.Watt.Cast<Watt>(), + SupplyPower = DataTableExtensionMethods.ParseDouble(row, (string)Fields.SupplyPower).SI().Kilo.Watt.Cast<Watt>() + }); + foreach (var d in data) { + map.AddPoint(d.AuxiliarySpeed.Value(), d.SupplyPower.Value(), d.MechanicalPower.Value()); + } + } + + private static bool HeaderIsValid(DataColumnCollection columns) + { + return columns.Contains(Fields.AuxSpeed) && columns.Contains(Fields.MechPower) && + columns.Contains(Fields.SupplyPower); + } + + public static class Fields + { + /// <summary> + /// [1/min] + /// </summary> + public const string AuxSpeed = "Auxiliary speed"; + + /// <summary> + /// [kW] + /// </summary> + public const string MechPower = "Mechanical power"; + + /// <summary> + /// [kW] + /// </summary> + public const string SupplyPower = "Supply power"; + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs index d8627ac1fd1fa880aff9000a27e51fdf2efec1af..5174534314af747bc016b9c84aa2565047440822 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs @@ -240,7 +240,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter } foreach (var auxType in EnumHelper.GetValues<AuxiliaryType>()) { - var auxData = auxInputData.Auxiliaries.FirstOrDefault(a => AuxiliaryTypeHelper.Parse(a.Type) == auxType); + var auxData = auxInputData.Auxiliaries.FirstOrDefault(a => a.Type == auxType); if (auxData == null) { throw new VectoException("Auxiliary {0} not found.", auxType); } @@ -250,14 +250,14 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter }; switch (auxType) { case AuxiliaryType.Fan: - aux.PowerDemand = DeclarationData.Fan.Lookup(mission, auxData.Technology); + aux.PowerDemand = DeclarationData.Fan.Lookup(mission, auxData.Technology.First()); aux.ID = Constants.Auxiliaries.IDs.Fan; break; case AuxiliaryType.SteeringPump: - aux.PowerDemand = DeclarationData.SteeringPump.Lookup(mission, hvdClass, new[] { auxData.Technology }); + aux.PowerDemand = DeclarationData.SteeringPump.Lookup(mission, hvdClass, auxData.Technology); aux.ID = Constants.Auxiliaries.IDs.SteeringPump; break; - case AuxiliaryType.HeatingVentilationAirCondition: + case AuxiliaryType.HVAC: aux.PowerDemand = DeclarationData.HeatingVentilationAirConditioning.Lookup(mission, hvdClass); aux.ID = Constants.Auxiliaries.IDs.HeatingVentilationAirCondition; break; @@ -266,10 +266,10 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter aux.ID = Constants.Auxiliaries.IDs.PneumaticSystem; break; case AuxiliaryType.ElectricSystem: - aux.PowerDemand = DeclarationData.ElectricSystem.Lookup(mission, - auxData.TechList.DefaultIfNull(Enumerable.Empty<string>()).ToArray()); + //aux.PowerDemand = DeclarationData.ElectricSystem.Lookup(mission, + // auxData.TechList.DefaultIfNull(Enumerable.Empty<string>()).ToArray()); aux.ID = Constants.Auxiliaries.IDs.ElectricSystem; - aux.TechList = auxData.TechList.DefaultIfNull(Enumerable.Empty<string>()).ToArray(); + //aux.TechList = auxData.TechList.DefaultIfNull(Enumerable.Empty<string>()).ToArray(); break; default: continue; diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs index 223e245d2b91ea465368c4fd18a7a3ef2ddfd67b..70c767dea099d713ffe49b6fc5c25face3a9d335 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs @@ -36,6 +36,7 @@ using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader.ComponentData; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; @@ -149,7 +150,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter } else { throw new InvalidFileFormatException("Gear {0} LossMap or Efficiency missing.", i + 1); } - + var fullLoadCurve = IntersectFullLoadCurves(engineData.FullLoadCurve, gear.MaxTorque); var shiftPolygon = gear.ShiftPolygon != null ? ShiftPolygonReader.Create(gear.ShiftPolygon) @@ -172,9 +173,6 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesEngineeringInputData auxInputData) { - if (auxInputData.SavedInDeclarationMode) { - WarnEngineeringMode("AuxData"); - } return auxInputData.Auxiliaries.Select(a => { switch (a.AuxiliaryType) { case AuxiliaryDemandType.Mapping: @@ -190,18 +188,16 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter private static VectoRunData.AuxData CreateMappingAuxiliary(IAuxiliaryEngineeringInputData a) { if (a.DemandMap == null) { - throw new VectoSimulationException("Demand Map for auxiliary {0} {1} required", a.ID, a.Technology); + throw new VectoSimulationException("Demand Map for auxiliary {0} required", a.ID); } if (a.DemandMap.Columns.Count != 3 || a.DemandMap.Rows.Count < 4) { throw new VectoSimulationException( - "Demand Map for auxiliary {0} {1} has to contain exactly 3 columns and at least 4 rows", a.ID, a.Technology); + "Demand Map for auxiliary {0} has to contain exactly 3 columns and at least 4 rows", a.ID); } return new VectoRunData.AuxData { ID = a.ID, - Technology = a.Technology, - TechList = a.TechList.DefaultIfNull(Enumerable.Empty<string>()).ToArray(), DemandType = AuxiliaryDemandType.Mapping, - Data = new AuxiliaryData(a, a.ID) //AuxiliaryData.Create(a.DemandMap) + Data = AuxiliaryDataReader.Create(a) }; } diff --git a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs index cfcd4fc25bb076ce6eed6f6d1c7a9b8c540a3c0f..b1a536787dc597d6a584ec6245c52c3db544eccf 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs @@ -29,6 +29,7 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using TUGraz.VectoCommon.Exceptions; @@ -102,7 +103,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data [Required] public AuxiliaryType Type; - public string Technology; + public IList<string> Technology; public string[] TechList; @@ -143,6 +144,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Data string.Format("Interpolation of Gear-{0}-LossMap failed with torque={1} and angularSpeed={2}", gear.Key, inTorque, angularVelocity.ConvertTo().Rounds.Per.Minute)); } + var velocity = angularVelocity / gear.Value.Ratio / axleGearData.AxleGear.Ratio * + runData.VehicleData.DynamicTyreRadius; if (axleGearData != null) { var axleAngularVelocity = angularVelocity / gear.Value.Ratio; @@ -151,8 +154,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Data } catch (VectoException) { return new ValidationResult( - string.Format("Interpolation of AxleGear-LossMap failed with torque={0} and angularSpeed={1}", axleTorque, - axleAngularVelocity.ConvertTo().Rounds.Per.Minute)); + string.Format( + "Interpolation of AxleGear-LossMap failed with torque={0} and angularSpeed={1} (gear={2}, velocity={3})", + axleTorque, axleAngularVelocity.ConvertTo().Rounds.Per.Minute, gear.Key, velocity)); } } } diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs index 9e59a781d64ab5784b4b86b61422a35d18e7ded2..96478896ffa410e3fb4e0f024593f8ac956591e1 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs @@ -151,7 +151,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl throw new ArgumentOutOfRangeException("CycleType unknown:" + data.Cycle.CycleType); } - var validationErrors = run.Validate(); + var validationErrors = run.Validate(_mode); if (validationErrors.Any()) { throw new VectoException("Validation of Run-Data Failed: " + "\n".Join(validationErrors.Select(r => r.ErrorMessage))); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryData.cs index fdf0714366099f365b954d0537ef8e8d1627522d..4056d61288a3efc3d51f731fef9a14ed6b943c26 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryData.cs @@ -40,6 +40,7 @@ using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader.ComponentData; using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Data @@ -61,109 +62,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public Watt GetPowerDemand(PerSecond nAuxiliary, Watt powerAuxOut) { var value = _map.Interpolate(nAuxiliary.Value(), powerAuxOut.Value()); - if (value.HasValue) + if (value.HasValue) { return value.Value.SI<Watt>(); + } throw new VectoException("AuxiliaryData: Interpolation failed. nAux: {0}, powerOut:{1}", nAuxiliary.AsRPM, powerAuxOut); } - public static AuxiliaryData ReadFromFile(string fileName, string id) - { - var auxData = new AuxiliaryData(id); - - try { - var stream = new StreamReader(fileName); - stream.ReadLine(); // skip header "Transmission ration to engine rpm [-]" - auxData.TransmissionRatio = stream.ReadLine().IndulgentParse(); - stream.ReadLine(); // skip header "Efficiency to engine [-]" - auxData.EfficiencyToEngine = stream.ReadLine().IndulgentParse(); - stream.ReadLine(); // skip header "Efficiency auxiliary to supply [-]" - auxData.EfficiencyToSupply = stream.ReadLine().IndulgentParse(); - - var m = new MemoryStream(Encoding.UTF8.GetBytes(stream.ReadToEnd())); - var table = VectoCSVFile.ReadStream(m); - - if (HeaderIsValid(table.Columns)) { - FillFromColumnNames(table, auxData._map); - } else { - FillFromColumnIndizes(table, auxData._map); - } - - auxData._map.Triangulate(); - - return auxData; - } catch (FileNotFoundException e) { - throw new VectoException("Auxiliary file not found: " + fileName, e); - } - } - - private static void FillFromColumnIndizes(DataTable table, DelaunayMap map) - { - var data = table.Rows.Cast<DataRow>().Select(row => new { - AuxiliarySpeed = row.ParseDouble(0).RPMtoRad(), - MechanicalPower = row.ParseDouble(1).SI().Kilo.Watt.Cast<Watt>(), - SupplyPower = row.ParseDouble(2).SI().Kilo.Watt.Cast<Watt>() - }); - foreach (var d in data) { - map.AddPoint(d.AuxiliarySpeed.Value(), d.SupplyPower.Value(), d.MechanicalPower.Value()); - } - } - - private static void FillFromColumnNames(DataTable table, DelaunayMap map) - { - var data = table.Rows.Cast<DataRow>().Select(row => new { - AuxiliarySpeed = row.ParseDouble(Fields.AuxSpeed).RPMtoRad(), - MechanicalPower = row.ParseDouble(Fields.MechPower).SI().Kilo.Watt.Cast<Watt>(), - SupplyPower = row.ParseDouble(Fields.SupplyPower).SI().Kilo.Watt.Cast<Watt>() - }); - foreach (var d in data) { - map.AddPoint(d.AuxiliarySpeed.Value(), d.SupplyPower.Value(), d.MechanicalPower.Value()); - } - } - - internal AuxiliaryData(string id) - { - _map = new DelaunayMap(id); - } - - internal AuxiliaryData(IAuxiliaryEngineeringInputData data, string id) - { - _map = new DelaunayMap("AuxiliaryData " + id); - TransmissionRatio = data.TransmissionRatio; - EfficiencyToEngine = data.EfficiencyToEngine; - EfficiencyToSupply = data.EfficiencyToSupply; - if (HeaderIsValid(data.DemandMap.Columns)) { - FillFromColumnNames(data.DemandMap, _map); - } else { - FillFromColumnIndizes(data.DemandMap, _map); - } - - _map.Triangulate(); - } - - private static bool HeaderIsValid(DataColumnCollection columns) - { - return columns.Contains(Fields.AuxSpeed) && columns.Contains(Fields.MechPower) && - columns.Contains(Fields.SupplyPower); - } - - private static class Fields + internal AuxiliaryData(double transmissionRatio, double efficiencyToEngine, double efficiencyToSupply, DelaunayMap map) { - /// <summary> - /// [1/min] - /// </summary> - public const string AuxSpeed = "Auxiliary speed"; - - /// <summary> - /// [kW] - /// </summary> - public const string MechPower = "Mechanical power"; - - /// <summary> - /// [kW] - /// </summary> - public const string SupplyPower = "Supply power"; + _map = map; + TransmissionRatio = transmissionRatio; + EfficiencyToEngine = efficiencyToEngine; + EfficiencyToSupply = efficiencyToSupply; } /// <summary> @@ -180,17 +92,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data var results = new List<ValidationResult>(); foreach (var entry in data._map.Points) { - context.DisplayName = Fields.AuxSpeed; + context.DisplayName = AuxiliaryDataReader.Fields.AuxSpeed; if (!Validator.TryValidateValue(entry.X, context, results, xValidationRules)) { return new ValidationResult(string.Concat(results)); } - context.DisplayName = Fields.SupplyPower; + context.DisplayName = AuxiliaryDataReader.Fields.SupplyPower; if (!Validator.TryValidateValue(entry.Y, context, results, yValidationRules)) { return new ValidationResult(string.Concat(results)); } - context.DisplayName = Fields.MechPower; + context.DisplayName = AuxiliaryDataReader.Fields.MechPower; if (!Validator.TryValidateValue(entry.Z, context, results, zValidationRules)) { return new ValidationResult(string.Concat(results)); } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs index bbc64f3d864745d28ce064917ec056179fc41745..2acbfd927794d80dc9eab4d117318941f1b08d6e 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs @@ -32,6 +32,7 @@ using System; using System.ComponentModel.DataAnnotations; using System.Data; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using TUGraz.VectoCommon.Exceptions; @@ -53,18 +54,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine /// <summary> /// Calculates the fuel consumption based on the given fuel map, the angularVelocity and the torque. /// </summary> - public KilogramPerSecond GetFuelConsumption(NewtonMeter torque, PerSecond angularVelocity, + public FuelConsumptionResult GetFuelConsumption(NewtonMeter torque, PerSecond angularVelocity, bool allowExtrapolation = false) { + var result = new FuelConsumptionResult(); // delaunay map needs is initialised with rpm, therefore the angularVelocity has to be converted. var value = _fuelMap.Interpolate(torque.Value(), angularVelocity.AsRPM); if (value.HasValue) { - return value.Value.SI().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>(); + result.Value = value.Value.SI().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>(); + return result; } if (allowExtrapolation) { - return + result.Value = _fuelMap.Extrapolate(torque.Value(), angularVelocity.AsRPM).SI().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>(); + result.Extrapolated = true; + return result; } throw new VectoException("FuelConsumptionMap: Interpolation failed. torque: {0}, n: {1}", torque.Value(), @@ -125,6 +130,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine #endregion } + [DebuggerDisplay("{Value} (extrapolated: {Extrapolated})")] + public class FuelConsumptionResult + { + public KilogramPerSecond Value; + public bool Extrapolated; + } + #region Equality members protected bool Equals(FuelConsumptionMap other) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs index 90441ee4d8a58c275af1f0385eb0f234051331ec..2640bba7283ed30a1adb68e42e732a619f38ea20 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs @@ -87,7 +87,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox /// <returns>Torque loss as seen on input side (towards the engine).</returns> public LossMapResult GetTorqueLoss(PerSecond outAngularVelocity, NewtonMeter outTorque) { - var result = new TransmissionLossMap.LossMapResult(); + var result = new LossMapResult(); var torqueLoss = _lossMap.Interpolate(outAngularVelocity.ConvertTo().Rounds.Per.Minute.Value() * _ratio, outTorque.Value() / _ratio); @@ -104,6 +104,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox return result; } + [DebuggerDisplay("{Value} (extrapolated: {Extrapolated})")] public class LossMapResult { public bool Extrapolated; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/SimulationComponentData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/SimulationComponentData.cs index a6dc7f1a4e287105d63931e51062914058991612..12f3ceaf702bd75c18e7693b14ab84d00c37e7a8 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/SimulationComponentData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/SimulationComponentData.cs @@ -29,8 +29,11 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System.ComponentModel.DataAnnotations; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Data { @@ -50,5 +53,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public string DigestValue { get; internal set; } public IntegrityStatus IntegrityStatus { get; internal set; } + + protected static ExecutionMode GetExecutionMode(ValidationContext context) + { + var modeService = context.GetService(typeof(ExecutionMode)) as ExecutionModeServiceContainer; + return modeService == null ? ExecutionMode.Declaration : modeService.Mode; + } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs index 335e24755da37245d8ff9edf69c0808843a17f75..9dec7cddfa6007f1fb89c02ef18bc0a902cb7b09 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs @@ -170,6 +170,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public static ValidationResult ValidateVehicleData(VehicleData vehicleData, ValidationContext validationContext) { + var mode = SimulationComponentData.GetExecutionMode(validationContext); + var weightShareSum = vehicleData.AxleData.Sum(axle => axle.AxleWeightShare); if (!weightShareSum.IsEqual(1.0, 1E-10)) { return new ValidationResult( @@ -180,13 +182,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data // total gvw is limited by max gvw (40t) var gvwTotal = VectoMath.Min(vehicleData.GrossVehicleWeight + vehicleData.TrailerGrossVehicleWeight, Constants.SimulationSettings.MaximumGrossVehicleWeight); + if (mode != ExecutionMode.Declaration) { + return ValidationResult.Success; + } if (vehicleData.TotalVehicleWeight() > gvwTotal) { return new ValidationResult( string.Format("Total Vehicle Weight is greater than GrossVehicleWeight! Weight: {0}, GVW: {1}", vehicleData.TotalVehicleWeight(), gvwTotal)); } - return ValidationResult.Success; } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs index 382fb9de85d8dde00b395dca2f0e5b6a47e14667..d2edb373da86ea2aa746a443c73ce742d589344c 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs @@ -89,11 +89,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl PreviousGear = Gearbox.Gear; } - public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) + public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) { if (DataBus.VehicleSpeed.IsEqual(0)) { for (var gear = (uint)Data.Gears.Count; gear > 1; gear--) { - var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio; + var inAngularSpeed = outAngularVelocity * Data.Gears[gear].Ratio; var ratedSpeed = Data.Gears[gear].FullLoadCurve != null ? Data.Gears[gear].FullLoadCurve.RatedSpeed @@ -102,7 +102,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl continue; } - var response = Gearbox.Initialize(gear, outTorque, outEngineSpeed); + var response = Gearbox.Initialize(gear, outTorque, outAngularVelocity); var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad; var reserve = 1 - response.EnginePowerRequest / fullLoadPower; @@ -117,9 +117,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return 1; } for (var gear = (uint)Data.Gears.Count; gear > 1; gear--) { - var response = Gearbox.Initialize(gear, outTorque, outEngineSpeed); + var response = Gearbox.Initialize(gear, outTorque, outAngularVelocity); - var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio; + var inAngularSpeed = outAngularVelocity * Data.Gears[gear].Ratio; var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad; var reserve = 1 - response.EnginePowerRequest / fullLoadPower; var inTorque = response.ClutchPowerRequest / inAngularSpeed; @@ -211,8 +211,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } // if a gear is skipped but acceleration is less than 0.1, try for next gear. if acceleration is still below 0.1 don't shift! if (nextGear > currentGear && - EstimateAccelerationForGear(currentGear + 1, outAngularVelocity).IsSmaller(Gearbox.ModelData.UpshiftMinAcceleration)) - { + EstimateAccelerationForGear(currentGear + 1, outAngularVelocity) + .IsSmaller(Gearbox.ModelData.UpshiftMinAcceleration)) { return currentGear; } nextGear = currentGear + 1; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs index c4aed9a98105c0b48518f2a7343005aa51cf94e5..7a83449f43ce8599eb55edf164ff4fb60f5c9264 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs @@ -275,7 +275,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public KilogramPerSecond GetFuelConsumption(NewtonMeter torque, PerSecond angularVelocity) { - return FcMap.GetFuelConsumption(torque, angularVelocity, AllowExtrapolation); + return FcMap.GetFuelConsumption(torque, angularVelocity, AllowExtrapolation).Value; } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 5cfd09c19c34a7a91fe21b230dc70d227e770c85..f058ce1e323d1c757cd178ddde816627e8b47cb5 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -344,8 +344,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl container[ModalResultField.Tq_full] = CurrentState.DynamicFullLoadTorque; container[ModalResultField.Tq_drag] = CurrentState.FullDragTorque; - var fc = ModelData.ConsumptionMap.GetFuelConsumption(CurrentState.EngineTorque, avgEngineSpeed); + var result = ModelData.ConsumptionMap.GetFuelConsumption(CurrentState.EngineTorque, avgEngineSpeed, + DataBus.ExecutionMode != ExecutionMode.Declaration); + if (DataBus.ExecutionMode != ExecutionMode.Declaration && result.Extrapolated) { + Log.Warn("FuelConsumptionMap was extrapolated: range for FC-Map is not sufficient: n: {0}, torque: {2}", + avgEngineSpeed.Value(), CurrentState.EngineTorque.Value()); + } + var fc = result.Value; //TODO mk-2015-11-11: calculate aux start stop correction var fcAux = fc; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index 2e2506572dcf708049c9e8328d4c308eba9404c8..86cab7ebb7ee32036489d58deab98691a8b866c2 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -480,7 +480,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } if (DataBus.VehicleStopped) { - Disengaged = false; + Disengaged = true; _engageTime = -double.MaxValue.SI<Second>(); } AdvanceState(); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs index 03002d7bfdd066d30ec935e6182a6c5406229fd0..9a1aad7709fd9fb81741e118d189397305ef74e4 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs @@ -62,7 +62,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public abstract bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularSpeed, uint gear, Second lastShiftTime); - public abstract uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed); + public abstract uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity); public Gearbox Gearbox { get; set; } diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index c05c592e2efa7ab8f8b02bcbd0b0534cda071b2f..92c6d951649a100953bc675be4235766873ac057 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -136,6 +136,7 @@ <Compile Include="InputData\Reader\ComponentData\TransmissionLossMapReader.cs" /> <Compile Include="InputData\Reader\ComponentData\RetarderLossMapReader.cs" /> <Compile Include="InputData\Reader\ComponentData\TorqueConverterDataReader.cs" /> + <Compile Include="InputData\Reader\ComponentData\AuxiliaryDataReader.cs" /> <Compile Include="Models\SimulationComponent\Data\Engine\FuelConsumptionMapReader.cs" /> <Compile Include="Models\SimulationComponent\Impl\TorqueConverter.cs" /> <Compile Include="Utils\ProviderExtensions.cs" /> @@ -197,7 +198,6 @@ <Compile Include="Models\Simulation\DataBus\IClutchInfo.cs" /> <Compile Include="Models\Simulation\DataBus\IDriverInfo.cs" /> <Compile Include="Models\Simulation\DataBus\IWheelsInfo.cs" /> - <Compile Include="Models\SimulationComponent\Data\AuxiliaryType.cs" /> <Compile Include="Models\SimulationComponent\Data\FullLoadCurve.cs" /> <Compile Include="Models\Simulation\DataBus\IMileageCounter.cs" /> <Compile Include="Utils\DebugData.cs" /> diff --git a/VectoCore/VectoCoreTest/FileIO/JsonTest.cs b/VectoCore/VectoCoreTest/FileIO/JsonTest.cs index 69f9c6ad9a986dd37c4c79d9775fef01d3c506b2..e086e41bc5ba9b4ad05ff19b7e7244c28a76aa79 100644 --- a/VectoCore/VectoCoreTest/FileIO/JsonTest.cs +++ b/VectoCore/VectoCoreTest/FileIO/JsonTest.cs @@ -95,9 +95,7 @@ namespace TUGraz.VectoCore.Tests.FileIO ((JObject)json["Body"]).Property("Cycles").Remove(); AssertHelper.Exception<InvalidFileFormatException>( - () => { - var tmp = new JSONInputDataV2(json, TestJobFile).Cycles; - }, "Key Cycles not found"); + () => { var tmp = new JSONInputDataV2(json, TestJobFile).Cycles; }, "Key Cycles not found"); } [TestMethod] @@ -107,7 +105,7 @@ namespace TUGraz.VectoCore.Tests.FileIO ((JObject)json["Body"]).Property("Aux").Remove(); // MK,2016-01-20: Changed for PWheel: aux entry may be missing, and that is ok. - var tmp = new JSONInputDataV2(json, TestJobFile).Auxiliaries; + var tmp = new JSONInputDataV2(json, TestJobFile).AuxiliaryInputData().Auxiliaries; Assert.IsTrue(tmp.Count == 0); } @@ -154,26 +152,24 @@ namespace TUGraz.VectoCore.Tests.FileIO ((JObject)json["Body"]).Property("OverSpeedEcoRoll").Remove(); AssertHelper.Exception<VectoException>( - () => { - var tmp = new JSONInputDataV2(json, TestJobFile).DriverInputData.OverSpeedEcoRoll; - }, + () => { var tmp = new JSONInputDataV2(json, TestJobFile).DriverInputData.OverSpeedEcoRoll; }, "Key OverSpeedEcoRoll not found"); } - [TestMethod] - public void TestReadingElectricTechlist() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - ((JArray)json["Body"]["Aux"][3]["TechList"]).Add("LED lights"); - - var job = new JSONInputDataV2(json, TestJobFile); - foreach (var aux in job.Auxiliaries) { - if (aux.ID == "ES") { - Assert.AreEqual(1, aux.TechList.Count); - Assert.AreEqual("LED lights", aux.TechList.First()); - } - } - } + //[TestMethod] + //public void TestReadingElectricTechlist() + //{ + // var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + // ((JArray)json["Body"]["Aux"][3]["TechList"]).Add("LED lights"); + + // var job = new JSONInputDataV2(json, TestJobFile); + // foreach (var aux in job.Auxiliaries) { + // if (aux.ID == "ES") { + // Assert.AreEqual(1, aux.TechList.Count); + // Assert.AreEqual("LED lights", aux.TechList.First()); + // } + // } + //} [TestMethod] public void JSON_Read_AngleGear() @@ -184,7 +180,7 @@ namespace TUGraz.VectoCore.Tests.FileIO Assert.AreEqual(AngularGearType.SeparateAngularGear, angleGear["Type"].Value<string>().ParseEnum<AngularGearType>()); Assert.AreEqual(3.5, angleGear["Ratio"].Value<double>()); - Assert.AreEqual("AngularGear.vtlm", angleGear["LossMap"].Value<string>()); + Assert.AreEqual("AngleGear.vtlm", angleGear["LossMap"].Value<string>()); } } diff --git a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs index 8e00b01a7f9b98b47ca3f428eb7d254819853932..be8e383a3074892fa92f77447ac1c69a880d0408 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs @@ -39,6 +39,7 @@ using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.InputData.FileIO.JSON; using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Impl; using TUGraz.VectoCore.OutputData; @@ -188,7 +189,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var aux = new EngineAuxiliary(container); - var auxData = AuxiliaryData.ReadFromFile(@"TestData\Components\24t_Coach_ALT.vaux", "ALT"); + var auxData = AuxiliaryDataReader.ReadFromFile(@"TestData\Components\24t_Coach_ALT.vaux", "ALT"); // ratio = 4.078 // efficiency_engine = 0.96 // efficiency_supply = 0.98 @@ -247,7 +248,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var aux = new EngineAuxiliary(container); - var auxData = AuxiliaryData.ReadFromFile(@"TestData\Components\24t_Coach_ALT.vaux", "ALT"); + var auxData = AuxiliaryDataReader.ReadFromFile(@"TestData\Components\24t_Coach_ALT.vaux", "ALT"); // ratio = 4.078 // efficiency_engine = 0.96 // efficiency_supply = 0.98 @@ -298,7 +299,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation [TestMethod] public void AuxFileMissing() { - AssertHelper.Exception<VectoException>(() => AuxiliaryData.ReadFromFile(@"NOT_EXISTING_AUX_FILE.vaux", "N.A."), + AssertHelper.Exception<VectoException>(() => AuxiliaryDataReader.ReadFromFile(@"NOT_EXISTING_AUX_FILE.vaux", "N.A."), "Auxiliary file not found: NOT_EXISTING_AUX_FILE.vaux"); } diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs index 15b8f7ebd8a2938abe7a57c06fc0feacc5fe1c39..8ac0b943496bf4e5dbf806807e9716855be2f56e 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs @@ -137,7 +137,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var vehicle = new VehicleContainer(ExecutionMode.Engineering); var axleGearData = MockSimulationDataFactory.CreateAxleGearDataFromFile(AxleGearValidRangeDataFile); var axleGear = new AxleGear(vehicle, axleGearData); - Assert.AreEqual(0, axleGear.Validate().Count); + Assert.AreEqual(0, axleGear.Validate(ExecutionMode.Declaration).Count); } [TestCase] @@ -146,7 +146,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var vehicle = new VehicleContainer(ExecutionMode.Engineering); var axleGearData = MockSimulationDataFactory.CreateAxleGearDataFromFile(AxleGearInvalidRangeDataFile); var axleGear = new AxleGear(vehicle, axleGearData); - var errors = axleGear.Validate(); + var errors = axleGear.Validate(ExecutionMode.Declaration); Assert.AreEqual(1, errors.Count); } diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/AuxiliaryTypeHelperTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/AuxiliaryTypeHelperTest.cs index 39c9c69acd400997ba48e11fd23481b4f5d2cfc0..868c10ab9c72ee76c6a5c0aa3cfd020c700fbcdd 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/AuxiliaryTypeHelperTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/AuxiliaryTypeHelperTest.cs @@ -31,9 +31,11 @@ using System; using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCommon.Models; using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData { @@ -46,7 +48,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData Assert.AreEqual(AuxiliaryType.Fan, AuxiliaryTypeHelper.Parse("Fan")); Assert.AreEqual(AuxiliaryType.SteeringPump, AuxiliaryTypeHelper.Parse("Steering pump")); Assert.AreEqual(AuxiliaryType.ElectricSystem, AuxiliaryTypeHelper.Parse("Electric System")); - Assert.AreEqual(AuxiliaryType.HeatingVentilationAirCondition, AuxiliaryTypeHelper.Parse("HVAC")); + Assert.AreEqual(AuxiliaryType.HVAC, AuxiliaryTypeHelper.Parse("HVAC")); Assert.AreEqual(AuxiliaryType.PneumaticSystem, AuxiliaryTypeHelper.Parse("Pneumatic System")); AssertHelper.Exception<ArgumentOutOfRangeException>(() => { AuxiliaryTypeHelper.Parse("Foo Bar Blupp"); }); } @@ -57,7 +59,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData Assert.AreEqual(Constants.Auxiliaries.Names.Fan, AuxiliaryTypeHelper.ToString(AuxiliaryType.Fan)); Assert.AreEqual(Constants.Auxiliaries.Names.SteeringPump, AuxiliaryTypeHelper.ToString(AuxiliaryType.SteeringPump)); Assert.AreEqual(Constants.Auxiliaries.Names.HeatingVentilationAirCondition, - AuxiliaryTypeHelper.ToString(AuxiliaryType.HeatingVentilationAirCondition)); + AuxiliaryTypeHelper.ToString(AuxiliaryType.HVAC)); Assert.AreEqual(Constants.Auxiliaries.Names.PneumaticSystem, AuxiliaryTypeHelper.ToString(AuxiliaryType.PneumaticSystem)); Assert.AreEqual(Constants.Auxiliaries.Names.ElectricSystem, diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs index 517e1508d52182d4d5219d20b8f2ceef89f43b1d..fc7427d407122e083bdffc46b40528ea31905514 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs @@ -66,7 +66,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData var entry = lines[i].Split(',').Select(x => double.Parse(x, CultureInfo.InvariantCulture)).ToArray(); Assert.AreEqual(entry[2].SI().Gramm.Per.Hour.ConvertTo().Kilo.Gramm.Per.Second.Value(), - map.GetFuelConsumption(entry[1].SI<NewtonMeter>(), entry[0].RPMtoRad(), true).Value(), Tolerance); + map.GetFuelConsumption(entry[1].SI<NewtonMeter>(), entry[0].RPMtoRad(), true).Value.Value(), Tolerance); } } } diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs index 25debf9c593b270c31b1d7f8d649b6fdc4c4b910..4e29db8b1aa55f486f2719e381351babad461b6c 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs @@ -1,9 +1,6 @@ -using System; -using System.Diagnostics; -using NUnit.Framework; +using NUnit.Framework; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; using TUGraz.VectoCore.Tests.Utils; namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs index 889858f55be88fc31707af43acc892565f5c4895..dfa575304fc3de210ef6f9e3409274d7a05dfe69 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs @@ -29,6 +29,7 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Data; using System.Diagnostics.CodeAnalysis; @@ -38,6 +39,7 @@ using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.InputData.Reader; using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; +using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.Models.SimulationComponent.Data; @@ -53,7 +55,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData [TestClass] [SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "UnusedMember.Local")] - public class CombustionEngineDataValidationTestClass + public class ValidationTestClass { /// <summary> /// VECTO-107 Check valid range of input parameters @@ -90,7 +92,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData }; data.FullLoadCurve.EngineData = data; - var results = data.Validate(); + var results = data.Validate(ExecutionMode.Declaration); Assert.IsFalse(results.Any(), "Validation Failed: " + "; ".Join(results.Select(r => r.ErrorMessage))); Assert.IsTrue(data.IsValid()); } @@ -125,7 +127,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData var engineData = dao.CreateEngineData(data); - var results = engineData.Validate(); + var results = engineData.Validate(ExecutionMode.Declaration); Assert.IsFalse(results.Any(), "Validation failed: " + "; ".Join(results.Select(r => r.ErrorMessage))); Assert.IsTrue(engineData.IsValid()); } @@ -163,11 +165,119 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData var engineData = dao.CreateEngineData(data); - var results = engineData.Validate(); + var results = engineData.Validate(ExecutionMode.Declaration); Assert.IsFalse(results.Any(), "Validation failed: " + "; ".Join(results.Select(r => r.ErrorMessage))); Assert.IsTrue(engineData.IsValid()); } + [TestMethod] + public void ValidationModeVehicleDataTest() + { + var vehicleData = new VehicleData() { + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + Creator = "Mr. Test", + CrossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection, + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(CrossWindCorrectionCurveReader.GetNoCorrectionCurve(5.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection), + CurbWeight = 7500.SI<Kilogram>(), + DynamicTyreRadius = 0.5.SI<Meter>(), + //CurbWeigthExtra = 0.SI<Kilogram>(), + Loading = 12000.SI<Kilogram>(), + GrossVehicleWeight = 16000.SI<Kilogram>() + }; + vehicleData.AxleData = new List<Axle>() { + new Axle() { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.4, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + new Axle() { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.6, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + }; + var result = vehicleData.Validate(ExecutionMode.Engineering); + Assert.IsTrue(!result.Any()); + + result = vehicleData.Validate(ExecutionMode.Declaration); + Assert.IsTrue(result.Any(), "validation should have failed, but succeeded"); + } + + /// <summary> + /// VECTO-107 Check valid range of input parameters + /// </summary> + [TestMethod] + public void ValidationModeVectoRunDataTest() + { + var container = new VehicleContainer(ExecutionMode.Engineering); + var data = new DistanceRun(container); + var engineData = new CombustionEngineData { + FullLoadCurve = EngineFullLoadCurve.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld"), + IdleSpeed = 560.RPMtoRad() + }; + + var gearboxData = new GearboxData(); + gearboxData.Gears[1] = new GearData { + LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\Direct Gear.vtlm", 1, "1"), + Ratio = 1 + }; + + var axleGearData = new AxleGearData { + AxleGear = new GearData { + Ratio = 1, + LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\limited.vtlm", 1, "1"), + } + }; + var vehicleData = new VehicleData() { + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + Creator = "Mr. Test", + CrossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection, + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(CrossWindCorrectionCurveReader.GetNoCorrectionCurve(5.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection), + CurbWeight = 7500.SI<Kilogram>(), + DynamicTyreRadius = 0.5.SI<Meter>(), + //CurbWeigthExtra = 0.SI<Kilogram>(), + Loading = 12000.SI<Kilogram>(), + GrossVehicleWeight = 16000.SI<Kilogram>() + }; + vehicleData.AxleData = new List<Axle>() { + new Axle() { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.4, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + new Axle() { + AxleType = AxleType.VehicleNonDriven, + AxleWeightShare = 0.6, + Inertia = 0.5.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.00555, + TyreTestLoad = 33000.SI<Newton>() + }, + }; + + container.RunData = new VectoRunData { + VehicleData = vehicleData, + GearboxData = gearboxData, + EngineData = engineData, + AxleGearData = axleGearData + }; + + var results = data.Validate(ExecutionMode.Declaration); + Assert.IsTrue(results.Any(), "Validation should have failed, but succeded."); + + results = vehicleData.Validate(ExecutionMode.Engineering); + Assert.IsTrue(!results.Any()); + } + /// <summary> /// VECTO-107 Check valid range of input parameters /// </summary> @@ -200,7 +310,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData AxleGearData = axleGearData }; - var results = data.Validate(); + var results = data.Validate(ExecutionMode.Declaration); Assert.IsTrue(results.Any(), "Validation should have failed, but succeded."); } @@ -210,7 +320,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData [TestMethod] public void Validation_Test() { - var results = new DataObject().Validate(); + var results = new DataObject().Validate(ExecutionMode.Declaration); // every field and property should be tested except private parent fields and properties and // (4*4+1) * 2 = 17*2= 34 - 4 private parent fields (+2 public field and property which are tested twice) = 32 @@ -237,7 +347,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData VectoCSVFile.ReadStream( InputDataHelper.InputDataAsStream("engine torque,downshift rpm [rpm],upshift rpm [rpm] ", vgbs))); - var results = shiftPolygon.Validate(); + var results = shiftPolygon.Validate(ExecutionMode.Declaration); Assert.IsFalse(results.Any()); shiftPolygon = @@ -245,7 +355,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData VectoCSVFile.ReadStream( InputDataHelper.InputDataAsStream("engine torque,upshift rpm [rpm], downshift rpm [rpm] ", vgbs))); - results = shiftPolygon.Validate(); + results = shiftPolygon.Validate(ExecutionMode.Declaration); Assert.IsTrue(results.Any()); } diff --git a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs index 0ff2688b69daab7cc9f30c5be5b0ae4ef523a841..8ed963b32f544500e3e45bda69cfe8420f029d9e 100644 --- a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs +++ b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs @@ -86,7 +86,7 @@ namespace TUGraz.VectoCore.Tests.Reports // check fuel consumption interpolation var fuelConsumption = (SI)row[(int)ModalResultField.FCMap]; Assert.AreEqual(fuelConsumption.Value(), - engineData.ConsumptionMap.GetFuelConsumption(tqEngFcmap, nEngFcMap).Value(), 1E-3, "time: {0} distance: {1}", + engineData.ConsumptionMap.GetFuelConsumption(tqEngFcmap, nEngFcMap).Value.Value(), 1E-3, "time: {0} distance: {1}", time, distance); // check P_eng_FCmap = T_eng_fcmap * n_eng