From 428d876cc56c4ffd962c4b4417d6e1211527ba31 Mon Sep 17 00:00:00 2001 From: Michael Krisper <michael.krisper@tugraz.at> Date: Mon, 24 Apr 2017 17:02:28 +0200 Subject: [PATCH] CrossWindCorrection: Added VehicleWeight in model and updated calculation --- VECTO/Input Files/Vehicle.vb | 28 +++---- .../CrossWindCorrectionCurveReader.cs | 52 +++++++------ .../DeclarationDataAdapter.cs | 57 ++++++++------ .../EngineeringDataAdapter.cs | 5 +- .../DeclarationModeVectoRunDataFactory.cs | 7 +- .../Models/Declaration/DeclarationDataTest.cs | 76 +++++++++++++------ .../Models/SimulationComponent/VehicleTest.cs | 27 +++---- 7 files changed, 152 insertions(+), 100 deletions(-) diff --git a/VECTO/Input Files/Vehicle.vb b/VECTO/Input Files/Vehicle.vb index 0c3cd37815..6385f90c40 100644 --- a/VECTO/Input Files/Vehicle.vb +++ b/VECTO/Input Files/Vehicle.vb @@ -26,7 +26,7 @@ Imports TUGraz.VectoCore.Utils <CustomValidation(GetType(Vehicle), "ValidateVehicle")> Public Class Vehicle - Implements IVehicleEngineeringInputData, IVehicleDeclarationInputData, IRetarderInputData, IPTOTransmissionInputData, + Implements IVehicleEngineeringInputData, IVehicleDeclarationInputData, IRetarderInputData, IPTOTransmissionInputData, IAngledriveInputData Private _filePath As String @@ -96,7 +96,7 @@ Public Class Vehicle Dim angledriveData As AngledriveData Dim modeService As VectoValidationModeServiceContainer = - TryCast(validationContext.GetService(GetType(VectoValidationModeServiceContainer)), + TryCast(validationContext.GetService(GetType(VectoValidationModeServiceContainer)), VectoValidationModeServiceContainer) Dim mode As ExecutionMode = If(modeService Is Nothing, ExecutionMode.Declaration, modeService.Mode) Dim emsCycle As Boolean = (modeService IsNot Nothing) AndAlso modeService.IsEMSCycle @@ -108,7 +108,7 @@ Public Class Vehicle Dim segment As Segment = DeclarationData.Segments.Lookup(vehicle.VehicleCategory, vehicle.AxleConfiguration, vehicle.GrossVehicleMassRating, vehicle.CurbWeightChassis) vehicleData = doa.CreateVehicleData(vehicle, segment.Missions.First(), - segment.Missions.First().Loadings.First().Value) + segment.Missions.First().Loadings.First().Value, segment.VehicleHeight) retarderData = doa.CreateRetarderData(vehicle) angledriveData = doa.CreateAngledriveData(vehicle, False) Else @@ -315,34 +315,34 @@ Public Class Vehicle Public ReadOnly Property CurbWeightChassis As Kilogram Implements IVehicleDeclarationInputData.CurbWeightChassis Get - Return Mass.SI(Of Kilogram)() + Return Mass.SI (Of Kilogram)() End Get End Property Public ReadOnly Property GrossVehicleMassRating As Kilogram _ Implements IVehicleDeclarationInputData.GrossVehicleMassRating Get - Return MassMax.SI().Ton.Cast(Of Kilogram)() + Return MassMax.SI().Ton.Cast (Of Kilogram)() End Get End Property Public ReadOnly Property AirDragArea As SquareMeter Implements IVehicleDeclarationInputData.AirDragArea Get - Return CdA0.SI(Of SquareMeter)() + Return CdA0.SI (Of SquareMeter)() End Get End Property Public ReadOnly Property IVehicleEngineeringInputData_Axles As IList(Of IAxleEngineeringInputData) _ Implements IVehicleEngineeringInputData.Axles Get - Return AxleWheels().Cast(Of IAxleEngineeringInputData)().ToList() + Return AxleWheels().Cast (Of IAxleEngineeringInputData)().ToList() End Get End Property Public ReadOnly Property IVehicleDeclarationInputData_Axles As IList(Of IAxleDeclarationInputData) _ Implements IVehicleDeclarationInputData.Axles Get - Return AxleWheels().Cast(Of IAxleDeclarationInputData)().ToList() + Return AxleWheels().Cast (Of IAxleDeclarationInputData)().ToList() End Get End Property @@ -350,18 +350,18 @@ Public Class Vehicle Return Axles.Select(Function(axle) New AxleInputData With { .SourceType = DataSourceType.JSONFile, .Source = FilePath, - .Inertia = axle.Inertia.SI(Of KilogramSquareMeter)(), + .Inertia = axle.Inertia.SI (Of KilogramSquareMeter)(), .Wheels = axle.Wheels, .AxleWeightShare = axle.Share, .TwinTyres = axle.TwinTire, .RollResistanceCoefficient = axle.RRC, - .TyreTestLoad = axle.FzISO.SI(Of Newton)() + .TyreTestLoad = axle.FzISO.SI (Of Newton)() }) End Function Public ReadOnly Property CurbWeightExtra As Kilogram Implements IVehicleEngineeringInputData.CurbWeightExtra Get - Return MassExtra.SI(Of Kilogram)() + Return MassExtra.SI (Of Kilogram)() End Get End Property @@ -382,14 +382,14 @@ Public Class Vehicle Public ReadOnly Property IVehicleEngineeringInputData_DynamicTyreRadius As Meter _ Implements IVehicleEngineeringInputData.DynamicTyreRadius Get - Return DynamicTyreRadius.SI().Milli.Meter.Cast(Of Meter)() + Return DynamicTyreRadius.SI().Milli.Meter.Cast (Of Meter)() End Get End Property Public ReadOnly Property IVehicleEngineeringInputData_Loading As Kilogram _ Implements IVehicleEngineeringInputData.Loading Get - Return Loading.SI(Of Kilogram)() + Return Loading.SI (Of Kilogram)() End Get End Property @@ -434,7 +434,7 @@ Public Class Vehicle Public ReadOnly Property Efficiency As Double Implements IAngledriveInputData.Efficiency Get - Return If(IsNumeric(AngledriveLossMapFile.OriginalPath), AngledriveLossMapFile.OriginalPath.ToDouble(), -1.0) + Return If(IsNumeric(AngledriveLossMapFile.OriginalPath), AngledriveLossMapFile.OriginalPath.ToDouble(), - 1.0) End Get End Property diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/CrossWindCorrectionCurveReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/CrossWindCorrectionCurveReader.cs index 4f7063c65a..0485ea6a87 100644 --- a/VectoCore/VectoCore/InputData/Reader/ComponentData/CrossWindCorrectionCurveReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/CrossWindCorrectionCurveReader.cs @@ -29,8 +29,11 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Data; +using System.Diagnostics; using System.IO; using System.Linq; using TUGraz.VectoCommon.Exceptions; @@ -40,7 +43,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.InputData.Reader.ComponentData { - public class CrossWindCorrectionCurveReader : LoggingObject + public static class CrossWindCorrectionCurveReader { public static List<CrossWindCorrectionEntry> GetNoCorrectionCurve(SquareMeter aerodynamicDragArea) { @@ -56,6 +59,8 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData }.ToList(); } + // TODO mk2017-04-24: remove this method? static code analysis says it is not used. + [Obsolete("Is this still used? Static Code Analysis says No.", true)] public static List<CrossWindCorrectionEntry> ReadSpeedDependentCorrectionFromFile(string fileName, SquareMeter aerodynamicDragArea) { @@ -87,11 +92,12 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData if (HeaderIsValid(betaTable.Columns)) { return ParseCdxABetaFromColumnNames(betaTable); } - Logger<CrossWindCorrectionCurveReader>().Warn("VAir/Beta Crosswind Correction header Line is not valid"); + LogManager.GetLogger(typeof(CrossWindCorrectionCurveReader).FullName) + .Warn("VAir/Beta Crosswind Correction header Line is not valid"); return ParseCdxABetaFromColumnIndices(betaTable); } - protected static List<CrossWindCorrectionEntry> ParseSpeedDependent(DataTable data, SquareMeter aerodynamicDragArea) + private static List<CrossWindCorrectionEntry> ParseSpeedDependent(DataTable data, SquareMeter aerodynamicDragArea) { if (data.Columns.Count != 2) { throw new VectoException("Crosswind correction file must consist of 2 columns."); @@ -103,15 +109,14 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData if (SpeedDependentHeaderIsValid(data.Columns)) { return ParseSpeedDependentFromColumnNames(data, aerodynamicDragArea); } - Logger<CrossWindCorrectionCurveReader>() - .Warn( + LogManager.GetLogger(typeof(CrossWindCorrectionCurveReader).FullName).Warn( "Crosswind correction file: Header line is not valid. Expected: '{0}, {1}', Got: '{2}'. Falling back to column index.", FieldsSpeedDependent.Velocity, FieldsSpeedDependent.Cd, string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Reverse())); return ParseSpeedDependentFromColumnIndizes(data, aerodynamicDragArea); } - protected static List<CrossWindCorrectionEntry> ParseSpeedDependentFromColumnIndizes(DataTable data, + private static List<CrossWindCorrectionEntry> ParseSpeedDependentFromColumnIndizes(DataTable data, SquareMeter aerodynamicDragArea) { return (from DataRow row in data.Rows @@ -121,7 +126,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData }).ToList(); } - protected static List<CrossWindCorrectionEntry> ParseSpeedDependentFromColumnNames(DataTable data, + private static List<CrossWindCorrectionEntry> ParseSpeedDependentFromColumnNames(DataTable data, SquareMeter aerodynamicDragArea) { return (from DataRow row in data.Rows @@ -140,20 +145,20 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData { return (from DataRow row in betaTable.Rows select - new AirDragBetaEntry() { - Beta = row.ParseDouble(0), - DeltaCdA = row.ParseDouble(1).SI<SquareMeter>() - }).ToList(); + new AirDragBetaEntry { + Beta = row.ParseDouble(0), + DeltaCdA = row.ParseDouble(1).SI<SquareMeter>() + }).ToList(); } private static List<AirDragBetaEntry> ParseCdxABetaFromColumnNames(DataTable betaTable) { return (from DataRow row in betaTable.Rows select - new AirDragBetaEntry() { - Beta = row.ParseDouble(FieldsCdxABeta.Beta), - DeltaCdA = row.ParseDouble(FieldsCdxABeta.DeltaCdxA).SI<SquareMeter>() - }).ToList(); + new AirDragBetaEntry { + Beta = row.ParseDouble(FieldsCdxABeta.Beta), + DeltaCdA = row.ParseDouble(FieldsCdxABeta.DeltaCdxA).SI<SquareMeter>() + }).ToList(); } private static bool HeaderIsValid(DataColumnCollection columns) @@ -161,25 +166,26 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData return columns.Contains(FieldsCdxABeta.Beta) && columns.Contains(FieldsCdxABeta.DeltaCdxA); } - public static class FieldsCdxABeta + private static class FieldsCdxABeta { public const string Beta = "beta"; - public const string DeltaCdxA = "delta CdA"; } - public class AirDragBetaEntry + private static class FieldsSpeedDependent { - public double Beta; - public SquareMeter DeltaCdA; + public const string Velocity = "v_veh"; + public const string Cd = "Cd"; } - public class FieldsSpeedDependent + [DebuggerDisplay("beta: {Beta}, deltaCdxA: {DeltaCdA}")] + public class AirDragBetaEntry { - public static readonly string Velocity = "v_veh"; - public static readonly string Cd = "Cd"; + public double Beta; + public SquareMeter DeltaCdA; } + [DebuggerDisplay("v: {Velocity}, CdxA: {EffectiveCrossSectionArea}")] public class CrossWindCorrectionEntry { public SquareMeter EffectiveCrossSectionArea; diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs index 705bd8b7de..068a58eadd 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs @@ -87,7 +87,8 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter return retVal; } - internal VehicleData CreateVehicleData(IVehicleDeclarationInputData data, Mission mission, Kilogram loading) + internal VehicleData CreateVehicleData(IVehicleDeclarationInputData data, Mission mission, Kilogram loading, + Meter vehicleHeight) { if (!data.SavedInDeclarationMode) { WarnDeclarationMode("VehicleData"); @@ -108,7 +109,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter retVal.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(aerodynamicDragArea, - GetDeclarationAirResistanceCurve(mission.CrossWindCorrectionParameters, aerodynamicDragArea), + GetDeclarationAirResistanceCurve(mission.CrossWindCorrectionParameters, aerodynamicDragArea, vehicleHeight), CrossWindCorrectionMode.DeclarationModeCorrection); var axles = data.Axles; if (axles.Count < mission.AxleWeightDistribution.Length) { @@ -302,7 +303,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter } public static List<CrossWindCorrectionCurveReader.CrossWindCorrectionEntry> GetDeclarationAirResistanceCurve( - string crosswindCorrectionParameters, SquareMeter aerodynamicDragAera) + string crosswindCorrectionParameters, SquareMeter aerodynamicDragAera, Meter vehicleHeight) { const int startSpeed = 60; const int maxSpeed = 130; @@ -311,7 +312,14 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter const int maxAlpha = 180; const int alphaStep = 10; + const int startHeightPercent = 5; + const int maxHeightPercent = 100; + const int heightPercentStep = 10; + const double heightShare = (double)heightPercentStep / maxHeightPercent; + var values = DeclarationData.AirDrag.Lookup(crosswindCorrectionParameters); + + // first entry (0m/s) will get CdxA of second entry. var points = new List<CrossWindCorrectionCurveReader.CrossWindCorrectionEntry> { new CrossWindCorrectionCurveReader.CrossWindCorrectionEntry { Velocity = 0.SI<MeterPerSecond>(), @@ -321,21 +329,31 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter for (var speed = startSpeed; speed <= maxSpeed; speed += speedStep) { var vVeh = speed.KMPHtoMeterPerSecond(); - var cdASum = 0.0.SI<SquareMeter>(); - - for (var alpha = 0; alpha <= maxAlpha; alpha += alphaStep) { - var vAirX = vVeh + Physics.BaseWindSpeed * Math.Cos(alpha.ToRadian()); - var vAirY = Physics.BaseWindSpeed * Math.Sin(alpha.ToRadian()); - var beta = Math.Atan(vAirY / vAirX).ToDegree(); - var deltaCdA = ComputeDeltaCd(beta, values); - var cdA = aerodynamicDragAera + deltaCdA; - - var degreeShare = (double)alphaStep / maxAlpha; - if (alpha == 0 || alpha == maxAlpha) { - degreeShare /= 2; - } - cdASum += degreeShare * cdA * ((vAirX * vAirX + vAirY * vAirY) / (vVeh * vVeh)).Cast<Scalar>(); + var cdASum = 0.SI<SquareMeter>(); + + for (var heightPercent = startHeightPercent; heightPercent < maxHeightPercent; heightPercent += heightPercentStep) { + var height = (heightPercent / 100.0) * vehicleHeight; + var vWind = Physics.BaseWindSpeed * Math.Pow(height / Physics.BaseWindHeight, Physics.HellmannExponent); + + for (var alpha = 0; alpha <= maxAlpha; alpha += alphaStep) { + var vAirX = vVeh + vWind * Math.Cos(alpha.ToRadian()); + var vAirY = vWind * Math.Sin(alpha.ToRadian()); + + var beta = Math.Atan(vAirY / vAirX).ToDegree(); + + // ΔCdxA = A1β + A2β² + A3β³ + var deltaCdA = values.A1 * beta + values.A2 * beta * beta + values.A3 * beta * beta * beta; + + // CdxA(β) = CdxA(0) + ΔCdxA(β) + var cdA = aerodynamicDragAera + deltaCdA; + + var share = (alpha == 0 || alpha == maxAlpha ? alphaStep / 2.0 : alphaStep) / maxAlpha; + + // v_air = sqrt(v_airX²+vAirY²) + // cdASum = CdxA(β) * v_air²/v_veh² + cdASum += heightShare * share * cdA * (vAirX * vAirX + vAirY * vAirY) / (vVeh * vVeh); + } } points.Add(new CrossWindCorrectionCurveReader.CrossWindCorrectionEntry { Velocity = vVeh, @@ -346,10 +364,5 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter points[0].EffectiveCrossSectionArea = points[1].EffectiveCrossSectionArea; return points; } - - protected static SquareMeter ComputeDeltaCd(double beta, AirDrag.Entry values) - { - return (values.A1 * beta + values.A2 * beta * beta + values.A3 * beta * beta * beta).SI<SquareMeter>(); - } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs index 466a9b0ba7..1ff270b97a 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs @@ -79,11 +79,14 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter CrossWindCorrectionCurveReader.ReadCdxABetaTable(data.CrosswindCorrectionMap)); break; case CrossWindCorrectionMode.DeclarationModeCorrection: + + var segment = DeclarationData.Segments.Lookup(data.VehicleCategory, data.AxleConfiguration, + retVal.GrossVehicleWeight, retVal.CurbWeight); retVal.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(data.AirDragArea, DeclarationDataAdapter.GetDeclarationAirResistanceCurve( GetAirdragParameterSet(retVal.VehicleCategory, data.AxleConfiguration, axles.Count), - data.AirDragArea), CrossWindCorrectionMode.DeclarationModeCorrection); + data.AirDragArea, segment.VehicleHeight), CrossWindCorrectionMode.DeclarationModeCorrection); break; default: throw new ArgumentOutOfRangeException("CrosswindCorrection", data.CrossWindCorrectionMode.ToString()); diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs index 5a97451882..d4c7ad4358 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs @@ -71,7 +71,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl driverdata.AccelerationCurve = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); var tempVehicle = dao.CreateVehicleData(InputDataProvider.VehicleInputData, segment.Missions.First(), - segment.Missions.First().Loadings.First().Value); + segment.Missions.First().Loadings.First().Value, segment.VehicleHeight); var engineData = dao.CreateEngineData(InputDataProvider.EngineInputData, InputDataProvider.GearboxInputData.Type); var axlegearData = dao.CreateAxleGearData(InputDataProvider.AxleGearInputData, false); var angledriveData = dao.CreateAngledriveData(InputDataProvider.AngledriveInputData, false); @@ -82,7 +82,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl if (Report != null) { var powertrainConfig = new VectoRunData() { VehicleData = dao.CreateVehicleData(InputDataProvider.VehicleInputData, segment.Missions.First(), - segment.Missions.First().Loadings.First().Value), + segment.Missions.First().Loadings.First().Value, segment.VehicleHeight), EngineData = engineData, GearboxData = gearboxData, AxleGearData = axlegearData, @@ -109,7 +109,8 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl foreach (var loading in mission.Loadings) { var simulationRunData = new VectoRunData { Loading = loading.Key, - VehicleData = dao.CreateVehicleData(InputDataProvider.VehicleInputData, mission, loading.Value), + VehicleData = dao.CreateVehicleData(InputDataProvider.VehicleInputData, mission, loading.Value, + segment.VehicleHeight), EngineData = engineData.Copy(), GearboxData = gearboxData, AxleGearData = axlegearData, diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs index 9c99116491..efe2def6c2 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs @@ -172,9 +172,9 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration public void AirDrag_WithStringKey(string key, double a1, double a2, double a3) { var value = DeclarationData.AirDrag.Lookup(key); - Assert.AreEqual(a1, value.A1); - Assert.AreEqual(a2, value.A2); - Assert.AreEqual(a3, value.A3); + AssertHelper.AreRelativeEqual(a1, value.A1); + AssertHelper.AreRelativeEqual(a2, value.A2); + AssertHelper.AreRelativeEqual(a3, value.A3); } [TestCase("RigidSolo", 0.013526, 0.017746, -0.000666), @@ -184,40 +184,68 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration public void AirDrag_WithVehicleCategory(string parameterSet, double a1, double a2, double a3) { var value = DeclarationData.AirDrag.Lookup(parameterSet); - Assert.AreEqual(a1, value.A1); - Assert.AreEqual(a2, value.A2); - Assert.AreEqual(a3, value.A3); + AssertHelper.AreRelativeEqual(a1, value.A1); + AssertHelper.AreRelativeEqual(a2, value.A2); + AssertHelper.AreRelativeEqual(a3, value.A3); } - [TestCase("TractorSemitrailer", 6.46, 0, 8.05913), - TestCase("TractorSemitrailer", 6.46, 60, 8.05913), - TestCase("TractorSemitrailer", 6.46, 75, 7.639436), - TestCase("TractorSemitrailer", 6.46, 100, 7.22305), - TestCase("TractorSemitrailer", 6.46, 52.1234, 8.059126), - TestCase("TractorSemitrailer", 6.46, 73.5432, 7.67487), - TestCase("TractorSemitrailer", 6.46, 92.8765, 7.317215), - TestCase("TractorSemitrailer", 6.46, 100.449, 7.217975), - TestCase("TractorSemitrailer", 6.46, 103, 7.18915), - TestCase("TractorSemitrailer", 6.46, 105, 7.166555), - TestCase("TractorSemitrailer", 6.46, 115, 7.071136), - TestCase("TractorSemitrailer", 6.46, 130, 6.961237),] - public void CrossWindCorrectionTest(string parameterSet, double crossSectionArea, double kmph, + [TestCase("TractorSemitrailer", 6.46, 0, 3.0, 8.05913), + TestCase("TractorSemitrailer", 6.46, 60, 3.0, 8.05913), + TestCase("TractorSemitrailer", 6.46, 75, 3.0, 7.639436), + TestCase("TractorSemitrailer", 6.46, 100, 3.0, 7.22305), + TestCase("TractorSemitrailer", 6.46, 52.1234, 3.0, 8.059126), + TestCase("TractorSemitrailer", 6.46, 73.5432, 3.0, 7.67487), + TestCase("TractorSemitrailer", 6.46, 92.8765, 3.0, 7.317215), + TestCase("TractorSemitrailer", 6.46, 100.449, 3.0, 7.217975), + TestCase("TractorSemitrailer", 6.46, 103, 3.0, 7.18915), + TestCase("TractorSemitrailer", 6.46, 105, 3.0, 7.166555), + TestCase("TractorSemitrailer", 6.46, 115, 3.0, 7.071136), + TestCase("TractorSemitrailer", 6.46, 130, 3.0, 6.961237),] + public void CrossWindCorrectionTest(string parameterSet, double crossSectionArea, double kmph, double height, double expected) { var crossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(crossSectionArea.SI<SquareMeter>(), - DeclarationDataAdapter.GetDeclarationAirResistanceCurve(parameterSet, crossSectionArea.SI<SquareMeter>()), + DeclarationDataAdapter.GetDeclarationAirResistanceCurve(parameterSet, crossSectionArea.SI<SquareMeter>(), + height.SI<Meter>()), CrossWindCorrectionMode.DeclarationModeCorrection); var tmp = crossWindCorrectionCurve.EffectiveAirDragArea(kmph.KMPHtoMeterPerSecond()); Assert.AreEqual(expected, tmp.Value(), Tolerance); } - [TestCase("TractorSemitrailer", 6.46, -0.1), - TestCase("TractorSemitrailer", 6.46, 130.1),] - public void CrossWindCorrectionExceptionTest(string parameterSet, double crossSectionArea, double kmph) + [TestCase("TractorSemitrailer", 5.8, 3)] + public void CrossWindGetDeclarationAirResistance(string parameterSet, double cdxa0, double height) + { + var curve = + DeclarationDataAdapter.GetDeclarationAirResistanceCurve(parameterSet, cdxa0.SI<SquareMeter>(), height.SI<Meter>()); + + AssertHelper.AreRelativeEqual(60.KMPHtoMeterPerSecond(), curve[1].Velocity); + AssertHelper.AreRelativeEqual(6.9458665452978.SI<SquareMeter>(), curve[1].EffectiveCrossSectionArea); + + AssertHelper.AreRelativeEqual(65.KMPHtoMeterPerSecond(), curve[2].Velocity); + AssertHelper.AreRelativeEqual(6.82099720057797.SI<SquareMeter>(), curve[2].EffectiveCrossSectionArea); + + AssertHelper.AreRelativeEqual(85.KMPHtoMeterPerSecond(), curve[6].Velocity); + AssertHelper.AreRelativeEqual(6.47838869554302.SI<SquareMeter>(), curve[6].EffectiveCrossSectionArea); + + AssertHelper.AreRelativeEqual(100.KMPHtoMeterPerSecond(), curve[9].Velocity); + AssertHelper.AreRelativeEqual(6.32370528142309.SI<SquareMeter>(), curve[9].EffectiveCrossSectionArea); + + AssertHelper.AreRelativeEqual(105.KMPHtoMeterPerSecond(), curve[10].Velocity); + AssertHelper.AreRelativeEqual(6.28404140744208.SI<SquareMeter>(), curve[10].EffectiveCrossSectionArea); + + Assert.Greater(20, curve.Count); + } + + [ + TestCase("TractorSemitrailer", 6.46, -0.1, 3.0), + TestCase("TractorSemitrailer", 6.46, 130.1, 3.0), + ] + public void CrossWindCorrectionExceptionTest(string parameterSet, double crossSectionArea, double kmph, double height) { var crossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(crossSectionArea.SI<SquareMeter>(), - DeclarationDataAdapter.GetDeclarationAirResistanceCurve(parameterSet, crossSectionArea.SI<SquareMeter>()), + DeclarationDataAdapter.GetDeclarationAirResistanceCurve(parameterSet, crossSectionArea.SI<SquareMeter>(), + height.SI<Meter>()), CrossWindCorrectionMode.DeclarationModeCorrection); AssertHelper.Exception<VectoException>(() => diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/VehicleTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/VehicleTest.cs index 79a121180b..a27ede17be 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/VehicleTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/VehicleTest.cs @@ -82,23 +82,24 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent Assert.AreEqual(16.954303841, mockPort.Velocity.Value(), 0.0001); } - [Test, - TestCase(0, 0, 0.5, 0), - TestCase(0, 1, 0.5, 0.59839), - TestCase(60, 0, 0.5, 1329.7558), - TestCase(60, 1, 0.5, 1365.386), - TestCase(60, 0.5, 0.5, 1347.457494), - TestCase(72, 0.5, 0.5, 1852.8837), - TestCase(72, 1, 3, 2093.7506)] - public void VehicleAirResistanceTest(double vehicleSpeed, double acceleration, double dt, double expected) + [ + TestCase(0, 0, 0.5, 3.0, 0), + TestCase(0, 1, 0.5, 3.0, 0.59839), + TestCase(60, 0, 0.5, 3.0, 1329.7558), + TestCase(60, 1, 0.5, 3.0, 1365.386), + TestCase(60, 0.5, 0.5, 3.0, 1347.457494), + TestCase(72, 0.5, 0.5, 3.0, 1852.8837), + TestCase(72, 1, 3, 3.0, 2093.7506) + ] + public void VehicleAirResistanceTest(double vehicleSpeed, double acceleration, double dt, double height, + double expected) { var container = new VehicleContainer(ExecutionMode.Declaration); var vehicleData = MockSimulationDataFactory.CreateVehicleDataFromFile(VehicleDataFileTruck); - //vehicleData.AerodynamicDragAera = 6.46.SI<SquareMeter>(); vehicleData.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(6.46.SI<SquareMeter>(), DeclarationDataAdapter.GetDeclarationAirResistanceCurve("TractorSemitrailer", - 6.46.SI<SquareMeter>()), CrossWindCorrectionMode.DeclarationModeCorrection); + 6.46.SI<SquareMeter>(), height.SI<Meter>()), CrossWindCorrectionMode.DeclarationModeCorrection); var vehicle = new Vehicle(container, vehicleData); var mockPort = new MockFvOutPort(); @@ -112,7 +113,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var avgForce = vehicle.AirDragResistance(vehicleSpeed.KMPHtoMeterPerSecond(), nextSpeed); Assert.AreEqual(expected, avgForce.Value(), Tolerance); } - + [Test] public void VehicleAirDragPowerLossDeclarationTest() { @@ -121,7 +122,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var vehicleData = MockSimulationDataFactory.CreateVehicleDataFromFile(VehicleDataFileTruck); vehicleData.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(6.2985.SI<SquareMeter>(), DeclarationDataAdapter.GetDeclarationAirResistanceCurve("TractorSemitrailer", - 6.2985.SI<SquareMeter>()), CrossWindCorrectionMode.DeclarationModeCorrection); + 6.2985.SI<SquareMeter>(), 3.SI<Meter>()), CrossWindCorrectionMode.DeclarationModeCorrection); var vehicle = new Vehicle(container, vehicleData); var driver = new MockDriver(container) { DriverBehavior = DrivingBehavior.Driving }; -- GitLab