diff --git a/VectoCommon/VectoCommon/Utils/DoubleExtensionMethods.cs b/VectoCommon/VectoCommon/Utils/DoubleExtensionMethods.cs index 1c8c8d126998c645b3eb7faffec7640b290050a7..0dc5c5fdda2e8bffc8106ff3bd1b1912705eb99c 100644 --- a/VectoCommon/VectoCommon/Utils/DoubleExtensionMethods.cs +++ b/VectoCommon/VectoCommon/Utils/DoubleExtensionMethods.cs @@ -29,278 +29,279 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Runtime.CompilerServices; - -namespace TUGraz.VectoCommon.Utils -{ - /// <summary> - /// Extension methods for double. - /// </summary> - public static class DoubleExtensionMethods - { - /// <summary> - /// The tolerance. - /// </summary> - public const double Tolerance = 1e-6; - - /// <summary> - /// The tolerancefactor for relative comparisons. - /// </summary> - public const double ToleranceFactor = 1e-6; - - /// <summary> - /// Determines whether the specified other is equal within tolerance. - /// </summary> - /// <param name="self">The self.</param> - /// <param name="other">The other.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsEqual(this double self, double other, double tolerance = Tolerance) - { - return Math.Abs(self - other) < tolerance; - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsRelativeEqual(this SI expected, SI actual, double toleranceFactor = ToleranceFactor) - { - return IsRelativeEqual(expected.Value(), actual.Value(), toleranceFactor: toleranceFactor); - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsRelativeEqual(this double expected, double actual, - double toleranceFactor = DoubleExtensionMethods.ToleranceFactor) - { - if (double.IsNaN(expected)) { - return double.IsNaN(actual); - } - - var ratio = expected.IsEqual(0, toleranceFactor) ? Math.Abs(actual) : Math.Abs(actual / expected - 1); - return ratio < toleranceFactor; - } - - /// <summary> - /// Determines whether the specified other is smaller within tolerance. - /// </summary> - /// <param name="self">The self.</param> - /// <param name="other">The other.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsSmaller(this double self, double other, double tolerance = Tolerance) - { - return self < other - tolerance; - } - - /// <summary> - /// Determines whether the specified other is smaller or equal within tolerance. - /// </summary> - /// <param name="self">The self.</param> - /// <param name="other">The other.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsSmallerOrEqual(this double self, double other, double tolerance = Tolerance) - { - return self <= other + tolerance; - } - - /// <summary> - /// Determines whether the specified other is greater within tolerance. - /// </summary> - /// <param name="self">The self.</param> - /// <param name="other">The other.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsGreater(this double self, double other, double tolerance = Tolerance) - { - return self > other + tolerance; - } - - /// <summary> - /// Determines whether the specified other is greater or equal within tolerance. - /// </summary> - /// <param name="self">The self.</param> - /// <param name="other">The other.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsGreaterOrEqual(this double self, double other, double tolerance = Tolerance) - { - return self >= other - tolerance; - } - - /// <summary> - /// Determines whether the specified tolerance is positive within tolerance. - /// </summary> - /// <param name="self">The self.</param> - /// <param name="tolerance">The tolerance.</param> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsPositive(this double self, double tolerance = Tolerance) - { - return self >= -tolerance; - } - - /// <summary> - /// Checks if a value is between min and max (min <= value <= max) - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsBetween(this double self, double min, double max) - { - return min <= self && self <= max; - } - - /// <summary> - /// Checks if a value is between min and max (min <= value <= max) - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsBetween(this double self, SI min, SI max) - { - return min <= self && self <= max; - } - - /// <summary> - /// Converts the double-value from RPM (rounds per minute) to the SI Unit PerSecond. - /// </summary> - /// <param name="self"></param> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PerSecond RPMtoRad(this double self) - { - return SI<PerSecond>(self * 2 * Math.PI / 60.0); - } - - /// <summary> - /// Converts the double-value from RPM (rounds per minute) to the SI Unit PerSecond. - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PerSecond RPMtoRad(this float self) - { - return SI<PerSecond>(self * 2 * Math.PI / 60.0); - } - - /// <summary> - /// Converts the value from rounds per minute to the SI Unit PerSecond - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PerSecond RPMtoRad(this int self) - { - return SI<PerSecond>(self * 2.0 * Math.PI / 60.0); - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static MeterPerSecond KMPHtoMeterPerSecond(this double self) - { - return SI<MeterPerSecond>(self / 3.6); - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static MeterPerSecond KMPHtoMeterPerSecond(this int self) - { - return SI<MeterPerSecond>(self / 3.6); - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double ToDegree(this double self) - { - return self * 180.0 / Math.PI; - } - - /// <summary> - /// Creates an SI object for the number (unit-less: [-]). - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SI SI(this double value) - { - return new SI(value); - } - - /// <summary> - /// Creates an templated SI object for the number. - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T SI<T>(this double value) where T : SIBase<T> - { - return SIBase<T>.Create(value); - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IEnumerable<T> SI<T>(this IEnumerable<double> self) where T : SIBase<T> - { - return self.Select(x => x.SI<T>()); - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToGUIFormat(this double self) - { - return self.ToString(CultureInfo.InvariantCulture); - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToXMLFormat(this double self, uint? decimals = null) - { - decimals = decimals ?? 2; - return self.ToString("F" + decimals.Value); - } - - //[DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToMinSignificantDigits(this double self, uint? significant = null, uint? decimals = null) - { - significant = significant ?? 3; - decimals = decimals ?? 1; - var scale = Math.Ceiling(Math.Log10(Math.Abs(self))); - - if (double.IsInfinity(scale) || double.IsNaN(scale)) - return self.ToString("F" + decimals.Value); - - return self.ToString("F" + Math.Max(significant.Value - scale, decimals.Value)); - } - } - - public static class FloatExtensionMethods - { - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T SI<T>(this float value) where T : SIBase<T> - { - return SIBase<T>.Create(value); - } - } - - public static class IntegerExtensionMethods - { - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ToGUIFormat(this int self) - { - return self.ToString(); - } - } +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Runtime.CompilerServices; + +namespace TUGraz.VectoCommon.Utils +{ + /// <summary> + /// Extension methods for double. + /// </summary> + public static class DoubleExtensionMethods + { + /// <summary> + /// The tolerance. + /// </summary> + public const double Tolerance = 1e-6; + + /// <summary> + /// The tolerancefactor for relative comparisons. + /// </summary> + public const double ToleranceFactor = 1e-6; + + /// <summary> + /// Determines whether the specified other is equal within tolerance. + /// </summary> + /// <param name="self">The self.</param> + /// <param name="other">The other.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsEqual(this double self, double other, double tolerance = Tolerance) + { + return Math.Abs(self - other) < tolerance; + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsRelativeEqual(this SI expected, SI actual, double toleranceFactor = ToleranceFactor) + { + return IsRelativeEqual(expected.Value(), actual.Value(), toleranceFactor: toleranceFactor); + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsRelativeEqual(this double expected, double actual, + double toleranceFactor = DoubleExtensionMethods.ToleranceFactor) + { + if (double.IsNaN(expected)) { + return double.IsNaN(actual); + } + + var ratio = expected.IsEqual(0, toleranceFactor) ? Math.Abs(actual) : Math.Abs(actual / expected - 1); + return ratio < toleranceFactor; + } + + /// <summary> + /// Determines whether the specified other is smaller within tolerance. + /// </summary> + /// <param name="self">The self.</param> + /// <param name="other">The other.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsSmaller(this double self, double other, double tolerance = Tolerance) + { + return self < other - tolerance; + } + + /// <summary> + /// Determines whether the specified other is smaller or equal within tolerance. + /// </summary> + /// <param name="self">The self.</param> + /// <param name="other">The other.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsSmallerOrEqual(this double self, double other, double tolerance = Tolerance) + { + return self <= other + tolerance; + } + + /// <summary> + /// Determines whether the specified other is greater within tolerance. + /// </summary> + /// <param name="self">The self.</param> + /// <param name="other">The other.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsGreater(this double self, double other, double tolerance = Tolerance) + { + return self > other + tolerance; + } + + /// <summary> + /// Determines whether the specified other is greater or equal within tolerance. + /// </summary> + /// <param name="self">The self.</param> + /// <param name="other">The other.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsGreaterOrEqual(this double self, double other, double tolerance = Tolerance) + { + return self >= other - tolerance; + } + + /// <summary> + /// Determines whether the specified tolerance is positive within tolerance. + /// </summary> + /// <param name="self">The self.</param> + /// <param name="tolerance">The tolerance.</param> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsPositive(this double self, double tolerance = Tolerance) + { + return self >= -tolerance; + } + + /// <summary> + /// Checks if a value is between min and max (min <= value <= max) + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsBetween(this double self, double min, double max) + { + return min <= self && self <= max; + } + + /// <summary> + /// Checks if a value is between min and max (min <= value <= max) + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsBetween(this double self, SI min, SI max) + { + return min <= self && self <= max; + } + + /// <summary> + /// Converts the double-value from RPM (rounds per minute) to the SI Unit PerSecond. + /// </summary> + /// <param name="self"></param> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static PerSecond RPMtoRad(this double self) + { + return SI<PerSecond>(self * 2 * Math.PI / 60.0); + } + + /// <summary> + /// Converts the double-value from RPM (rounds per minute) to the SI Unit PerSecond. + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static PerSecond RPMtoRad(this float self) + { + return SI<PerSecond>(self * 2 * Math.PI / 60.0); + } + + /// <summary> + /// Converts the value from rounds per minute to the SI Unit PerSecond + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static PerSecond RPMtoRad(this int self) + { + return SI<PerSecond>(self * 2.0 * Math.PI / 60.0); + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static MeterPerSecond KMPHtoMeterPerSecond(this double self) + { + return SI<MeterPerSecond>(self / 3.6); + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static MeterPerSecond KMPHtoMeterPerSecond(this int self) + { + return SI<MeterPerSecond>(self / 3.6); + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double ToDegree(this double self) + { + return self * 180.0 / Math.PI; + } + + /// <summary> + /// Creates an SI object for the number (unit-less: [-]). + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SI SI(this double value) + { + return new SI(value); + } + + /// <summary> + /// Creates an templated SI object for the number. + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T SI<T>(this double value) where T : SIBase<T> + { + return SIBase<T>.Create(value); + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IEnumerable<T> SI<T>(this IEnumerable<double> self) where T : SIBase<T> + { + return self.Select(x => x.SI<T>()); + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string ToGUIFormat(this double self) + { + return self.ToString(CultureInfo.InvariantCulture); + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string ToXMLFormat(this double self, uint? decimals = null) + { + decimals = decimals ?? 2; + return self.ToString("F" + decimals.Value, CultureInfo.InvariantCulture); + } + + //[DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string ToMinSignificantDigits(this double self, uint? significant = null, uint? decimals = null) + { + significant = significant ?? 3; + decimals = decimals ?? 1; + var scale = Math.Ceiling(Math.Log10(Math.Abs(self))); + + if (double.IsInfinity(scale) || double.IsNaN(scale)) { + return self.ToString("F" + decimals.Value, CultureInfo.InvariantCulture); + } + + return self.ToString("F" + Math.Max(significant.Value - scale, decimals.Value), CultureInfo.InvariantCulture); + } + } + + public static class FloatExtensionMethods + { + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T SI<T>(this float value) where T : SIBase<T> + { + return SIBase<T>.Create(value); + } + } + + public static class IntegerExtensionMethods + { + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string ToGUIFormat(this int self) + { + return self.ToString(); + } + } } \ 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 8ce7e9175f58652ba8e8788ddb441a43bee6e7b9..734c8d536580577601269111a7dc63d01d21e810 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs @@ -62,7 +62,6 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter retVal.DynamicTyreRadius = data.DynamicTyreRadius; var axles = data.Axles; - retVal.AxleData = axles.Select(axle => new Axle { WheelsDimension = axle.Wheels, Inertia = axle.Inertia, @@ -82,8 +81,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter switch (airdragData.CrossWindCorrectionMode) { case CrossWindCorrectionMode.NoCorrection: - retVal.CrossWindCorrectionCurve = - new CrosswindCorrectionCdxALookup(airdragData.AirDragArea, + retVal.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(airdragData.AirDragArea, CrossWindCorrectionCurveReader.GetNoCorrectionCurve(airdragData.AirDragArea), CrossWindCorrectionMode.NoCorrection); break; @@ -97,13 +95,14 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter CrossWindCorrectionCurveReader.ReadCdxABetaTable(airdragData.CrosswindCorrectionMap)); break; case CrossWindCorrectionMode.DeclarationModeCorrection: + var airDragArea = airdragData.AirDragArea ?? + DeclarationData.Segments.LookupCdA(data.VehicleCategory, data.AxleConfiguration, data.GrossVehicleMassRating); var height = DeclarationData.Segments.LookupHeight(data.VehicleCategory, data.AxleConfiguration, data.GrossVehicleMassRating); - retVal.CrossWindCorrectionCurve = - new CrosswindCorrectionCdxALookup(airdragData.AirDragArea, + retVal.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(airDragArea, DeclarationDataAdapter.GetDeclarationAirResistanceCurve( - GetAirdragParameterSet(data.VehicleCategory, data.AxleConfiguration, data.Axles.Count), - airdragData.AirDragArea, height), CrossWindCorrectionMode.DeclarationModeCorrection); + GetAirdragParameterSet(data.VehicleCategory, data.AxleConfiguration, data.Axles.Count), airDragArea, height), + CrossWindCorrectionMode.DeclarationModeCorrection); break; default: throw new ArgumentOutOfRangeException("CrosswindCorrection", airdragData.CrossWindCorrectionMode.ToString()); @@ -231,7 +230,6 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter gearbox.TorqueConverter.CLUpshiftMinAcceleration, gearbox.TorqueConverter.CCUpshiftMinAcceleration); } - return retVal; } @@ -249,7 +247,6 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter retVal.UpshiftMinAcceleration = gearbox.UpshiftMinAcceleration; } - public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesEngineeringInputData auxInputData) { var auxList = new List<VectoRunData.AuxData>(auxInputData.Auxiliaries.Count + 1) { diff --git a/VectoCore/VectoCore/Models/Declaration/Segments.cs b/VectoCore/VectoCore/Models/Declaration/Segments.cs index 73227147dccd376e8732826952b61774dfac6bf4..1d6997e14eb7ddfd5db7cb1ef874ac3d7c56497a 100644 --- a/VectoCore/VectoCore/Models/Declaration/Segments.cs +++ b/VectoCore/VectoCore/Models/Declaration/Segments.cs @@ -155,6 +155,16 @@ namespace TUGraz.VectoCore.Models.Declaration return vehicleHeight; } + /// <summary> + /// Looks up the default CdxA value for the cross wind correction. + /// </summary> + public SquareMeter LookupCdA(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, + Kilogram grossVehicleMassRating) + { + var row = GetSegmentDataRow(vehicleCategory, axleConfiguration, grossVehicleMassRating, true); + return row.SI<SquareMeter>("cdxa_default"); + } + private static Mission[] CreateMissions(ref Kilogram grossVehicleWeight, Kilogram curbWeight, DataRow row) { var missionTypes = Enum.GetValues(typeof(MissionType)).Cast<MissionType>(); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs index 95244bc8ab9e073843affa71a204f57cb5a67154..49bcd6c601efeb2f4f8142e03cfe32712afa8bee 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs @@ -42,6 +42,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Data { + [CustomValidation(typeof(AirdragData), "ValidateAirDragData")] public class AirdragData : SimulationComponentData { public CrossWindCorrectionMode CrossWindCorrectionMode { get; set; } @@ -50,6 +51,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public ICrossWindCorrection CrossWindCorrectionCurve { get; internal set; } public SquareMeter DeclaredAirdragArea { get; internal set; } + + // ReSharper disable once UnusedMember.Global -- used via Validation + public static ValidationResult ValidateAirDragData(AirdragData airDragData, ValidationContext validationContext) + { + if (airDragData.CrossWindCorrectionMode != CrossWindCorrectionMode.DeclarationModeCorrection && + airDragData.CrossWindCorrectionCurve.AirDragArea == null) + return new ValidationResult( + "AirDrag Area (CdxA) must not be empty when the cross wind correction mode is not \"Speed dependent (Declaration Mode)\""); + + return ValidationResult.Success; + } } /// <summary> @@ -178,7 +190,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data get { return (CurbWeight ?? 0.SI<Kilogram>()) + (BodyAndTrailerWeight ?? 0.SI<Kilogram>()); } } - protected void ComputeRollResistanceAndReducedMassWheels() { if (TotalVehicleWeight == 0.SI<Kilogram>()) { @@ -217,7 +228,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data WheelsInertia = wheelsInertia; } - // ReSharper disable once UnusedMember.Global -- used via Validation public static ValidationResult ValidateVehicleData(VehicleData vehicleData, ValidationContext validationContext) { @@ -240,7 +250,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data } } - if (vehicleData.TotalRollResistanceCoefficient <= 0) { return new ValidationResult(string.Format("Total rolling resistance must be greater than 0! {0}", @@ -275,7 +284,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data return new ValidationResult("Exactly one axle has to be defined as driven!"); } - return ValidationResult.Success; } } diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationWriter.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationWriter.cs index 87fb34848e02e6e620f8fc6ae3f8f5afe2c7bb26..709c66864d9be213919b137e9d8b77cac657237a 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationWriter.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationWriter.cs @@ -29,389 +29,390 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml; -using System.Xml.Linq; -using TUGraz.IVT.VectoXML; -using TUGraz.IVT.VectoXML.Writer; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Resources; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.InputData.Reader.ComponentData; - -namespace TUGraz.VectoCore.OutputData.XML -{ - public class XMLDeclarationWriter : AbstractXMLWriter - { - private XNamespace componentNamespace; - //private readonly XNamespace _vectoNs = @"../../../API/VectoInput.xsd"; - - - public XMLDeclarationWriter(string vendor) : base(null, vendor) - { - tns = "urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v1.0"; - rootNamespace = "urn:tugraz:ivt:VectoAPI:DeclarationInput:v1.0"; - componentNamespace = "urn:tugraz:ivt:VectoAPI:DeclarationComponent:v1.0"; - } - - public XDocument GenerateVectoJob(IDeclarationInputDataProvider data) - { - var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); - - //<tns:VectoInputDeclaration - // xmlns="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v0.6" - // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="0.6" - // xmlns:tns="urn:tugraz:ivt:VectoAPI:DeclarationInput:v0.6" - // xsi:schemaLocation="urn:tugraz:ivt:VectoAPI:DeclarationInput:v0.6 http://markus.quaritsch.at/VECTO/VectoInput.xsd"> - var job = new XDocument(); - job.Add(new XElement(rootNamespace + XMLNames.VectoInputDeclaration, - new XAttribute("schemaVersion", SchemaVersion), - new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), - new XAttribute("xmlns", tns), - new XAttribute(XNamespace.Xmlns + "tns", rootNamespace), - new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoInput.xsd", rootNamespace, SchemaLocationBaseUrl)), - CreateDeclarationJob(data)) - ); - return job; - } - - public XDocument GenerateVectoComponent(IGearboxDeclarationInputData data, - ITorqueConverterDeclarationInputData torqueConverter) - { - return GenerateComponentDocument(CreateGearbox(data, torqueConverter, componentNamespace)); - } - - public XDocument GenerateVectoComponent(IAxleGearInputData data) - { - return GenerateComponentDocument(CreateAxlegear(data, componentNamespace)); - } - - protected XDocument GenerateComponentDocument(XElement content) - { - var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); - var component = new XDocument(); - component.Add(new XElement(componentNamespace + XMLNames.VectoInputDeclaration, - new XAttribute("schemaVersion", SchemaVersion), - new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), - new XAttribute("xmlns", tns), - new XAttribute(XNamespace.Xmlns + "tns", componentNamespace), - new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoComponent.xsd", componentNamespace, SchemaLocationBaseUrl)), - content) - ); - return component; - } - - protected XElement[] CreateDeclarationJob(IDeclarationInputDataProvider data) - { - return new[] { - CreateVehicle(data) - }; - } - - protected XElement CreateVehicle(IDeclarationInputDataProvider data) - { - var retarder = data.RetarderInputData; - var gearbox = data.GearboxInputData; - var vehicle = data.VehicleInputData; - var angledrive = data.AngledriveInputData; - - return new XElement(tns + XMLNames.Component_Vehicle, - new XAttribute(XMLNames.Component_ID_Attr, "VEH-" + vehicle.Model), - GetDefaultComponentElements(vehicle.CertificationNumber, vehicle.Model, "N.A."), - new XElement(tns + XMLNames.Vehicle_LegislativeClass, "N3"), - new XElement(tns + XMLNames.Vehicle_VehicleCategory, vehicle.VehicleCategory.ToXMLFormat()), - new XElement(tns + XMLNames.Vehicle_AxleConfiguration, vehicle.AxleConfiguration.GetName()), - new XElement(tns + XMLNames.Vehicle_CurbMassChassis, vehicle.CurbMassChassis.ToXMLFormat(0)), - new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, vehicle.GrossVehicleMassRating.ToXMLFormat(0)), - new XElement(tns + XMLNames.Vehicle_IdlingSpeed, vehicle.EngineIdleSpeed.AsRPM.ToXMLFormat(0)), - new XElement(tns + XMLNames.Vehicle_RetarderType, retarder.Type.ToXMLFormat()), - retarder.Type.IsDedicatedComponent() - ? new XElement(tns + XMLNames.Vehicle_RetarderRatio, retarder.Ratio.ToXMLFormat(3)) - : null, - new XElement(tns + XMLNames.Vehicle_AngledriveType, angledrive.Type.ToXMLFormat()), - new XElement(tns + XMLNames.Vehicle_PTO, - new XElement(tns + XMLNames.Vehicle_PTO_ShaftsGearWheels, "none"), - new XElement(tns + XMLNames.Vehicle_PTO_OtherElements, "none")), - CreateTorqueLimits(vehicle), - new XElement(tns + XMLNames.Vehicle_Components, - CreateEngine(data.EngineInputData), - CreateGearbox(gearbox, gearbox.Type.AutomaticTransmission() ? data.TorqueConverterInputData : null), - angledrive.Type == AngledriveType.SeparateAngledrive ? CreateAngleDrive(angledrive) : null, - retarder.Type.IsDedicatedComponent() ? CreateRetarder(retarder) : null, - CreateAxlegear(data.AxleGearInputData), - CreateAxleWheels(data.VehicleInputData), - CreateAuxiliaries(data.AuxiliaryInputData()), - CreateAirdrag(data.AirdragInputData) - ) - ); - } - - - protected XElement CreateEngine(IEngineDeclarationInputData data, XNamespace ns = null) - { - var id = string.Format("ENG-{0}", data.Model.RemoveWhitespace()); - var fld = FullLoadCurveReader.Create(data.FullLoadCurve, true); - return new XElement((ns ?? tns) + XMLNames.Component_Engine, - //new XAttribute(XMLNames.Component_CertificationNumber_Attr, string.Format("ENG-{0}", data.Model)), - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, id), - GetDefaultComponentElements(string.Format("ENG-{0}", data.Model), data.Model), - new XElement(tns + XMLNames.Engine_Displacement, (data.Displacement.Value() * 1000 * 1000).ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_IdlingSpeed, data.IdleSpeed.AsRPM.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_RatedSpeed, fld.RatedSpeed.AsRPM.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_RatedPower, fld.FullLoadStationaryPower(fld.RatedSpeed).ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_MaxTorque, fld.MaxTorque.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_WHTCUrban, data.WHTCUrban.ToXMLFormat(4)), - new XElement(tns + XMLNames.Engine_WHTCRural, data.WHTCRural.ToXMLFormat(4)), - new XElement(tns + XMLNames.Engine_WHTCMotorway, data.WHTCMotorway.ToXMLFormat(4)), - new XElement(tns + XMLNames.Engine_ColdHotBalancingFactor, data.ColdHotBalancingFactor.ToXMLFormat(4)), - new XElement(tns + XMLNames.Engine_CorrectionFactor_RegPer, "1.0000"), - new XElement(tns + XMLNames.Engine_CorrecionFactor_NCV, "1.0000"), - new XElement(tns + XMLNames.Engine_FuelType, "Diesel CI"), - new XElement(tns + XMLNames.Engine_FuelConsumptionMap, - EmbedDataTable(data.FuelConsumptionMap, AttributeMappings.FuelConsumptionMapMapping)), - new XElement(tns + XMLNames.Engine_FullLoadAndDragCurve, - EmbedDataTable(data.FullLoadCurve, AttributeMappings.EngineFullLoadCurveMapping) - ) - ), - AddSignatureDummy(id) - ); - } - - - protected XElement CreateGearbox(IGearboxDeclarationInputData gbxData, - ITorqueConverterDeclarationInputData torqueConverter, XNamespace ns = null) - { - var gears = new XElement(tns + XMLNames.Gearbox_Gears); - var i = 1; - foreach (var gearData in gbxData.Gears) { - var gear = new XElement(tns + XMLNames.Gearbox_Gears_Gear, - new XAttribute(XMLNames.Gearbox_Gear_GearNumber_Attr, i++), - new XElement(tns + XMLNames.Gearbox_Gear_Ratio, gearData.Ratio.ToXMLFormat(3)), - gearData.MaxTorque != null - ? new XElement(tns + XMLNames.Gearbox_Gears_MaxTorque, gearData.MaxTorque.Value().ToXMLFormat(0)) - : null, - gearData.MaxInputSpeed != null - ? new XElement(tns + XMLNames.Gearbox_Gear_MaxSpeed, gearData.MaxInputSpeed.AsRPM.ToXMLFormat(0)) - : null, - new XElement(tns + XMLNames.Gearbox_Gear_TorqueLossMap, - EmbedDataTable(gearData.LossMap, AttributeMappings.TransmissionLossmapMapping)) - ); - gears.Add(gear); - } - var id = string.Format("GBX-{0}", gbxData.Model.RemoveWhitespace()); - return new XElement((ns ?? tns) + XMLNames.Component_Gearbox, - //new XAttribute(XMLNames.Component_CertificationNumber_Attr, string.Format("GBX-{0}", gbxData.Model)), - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, id), - GetDefaultComponentElements(string.Format("GBX-{0}", gbxData.Model), gbxData.Model), - new XElement(tns + XMLNames.Gearbox_TransmissionType, gbxData.Type.ToXMLFormat()), - new XElement(tns + XMLNames.Component_Gearbox_CertificationMethod, "Standard values"), - gears - ), - AddSignatureDummy(id), - gbxData.Type.AutomaticTransmission() ? CreateTorqueConverter(torqueConverter) : null - ); - } - - - private XElement CreateTorqueConverter(ITorqueConverterDeclarationInputData data) - { - if (data == null) { - throw new Exception("Torque Converter is required!"); - } - var id = string.Format("TC-{0}", data.Model.RemoveWhitespace()); - return new XElement(tns + XMLNames.Component_TorqueConverter, - //new XAttribute(XMLNames.Component_CertificationNumber_Attr, id), - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, id), - GetDefaultComponentElements(data.CertificationNumber, data.Model), - new XElement(tns + XMLNames.Component_CertificationMethod, "Standard values"), - new XElement(tns + XMLNames.TorqueConverter_Characteristics, - EmbedDataTable(data.TCData, AttributeMappings.TorqueConverterDataMapping, - precision: new Dictionary<string, uint>() { - { TorqueConverterDataReader.Fields.SpeedRatio, 4 } - }) - ) - ), - AddSignatureDummy(id)); - } - - private XElement CreateAngleDrive(IAngledriveInputData data, XNamespace ns = null) - { - var id = string.Format("ANGL-{0}", data.Model.RemoveWhitespace()); - return new XElement((ns ??tns) + XMLNames.Component_Angledrive, - //new XAttribute(XMLNames.Component_CertificationNumber_Attr, "ANGL-" + data.Model), - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, id), - GetDefaultComponentElements(data.CertificationNumber, data.Model), - new XElement(tns + XMLNames.AngleDrive_Ratio, data.Ratio.ToXMLFormat(3)), - new XElement(tns + XMLNames.Component_CertificationMethod, "Standard values"), - new XElement(tns + XMLNames.AngleDrive_TorqueLossMap, - EmbedDataTable(data.LossMap, AttributeMappings.TransmissionLossmapMapping))), - AddSignatureDummy(id)); - } - - public XElement CreateRetarder(IRetarderInputData data, XNamespace ns = null) - { - var id = string.Format("RET-{0}", data.Model.RemoveWhitespace()); - return new XElement((ns ?? tns) + XMLNames.Component_Retarder, - //new XAttribute(XMLNames.Component_CertificationNumber_Attr, "RET-none"), - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, id), - GetDefaultComponentElements(data.CertificationNumber, data.Model), - new XElement(tns + XMLNames.Component_CertificationMethod, "Standard values"), - new XElement(tns + XMLNames.Retarder_RetarderLossMap, - EmbedDataTable(data.LossMap, AttributeMappings.RetarderLossmapMapping) - ) - ), - AddSignatureDummy(id) - ); - } - - public XElement CreateAxlegear(IAxleGearInputData data, XNamespace ns = null) - { - var typeId = string.Format("AXLGEAR-{0:0.000}", data.Ratio); - return new XElement((ns ?? tns) + XMLNames.Component_Axlegear, - //new XAttribute(XMLNames.Component_CertificationNumber_Attr, string.Format("AXL-{0}", data.Model)), - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, typeId), - GetDefaultComponentElements(typeId, "N.A."), - new XElement(tns + "LineType", "Single portal axle"), - new XElement(tns + XMLNames.Axlegear_Ratio, data.Ratio.ToXMLFormat(3)), - new XElement(tns + XMLNames.Component_CertificationMethod, "Standard values"), - new XElement(tns + XMLNames.Axlegear_TorqueLossMap, - EmbedDataTable(data.LossMap, AttributeMappings.TransmissionLossmapMapping))), - AddSignatureDummy(typeId) - ); - } - - public XElement CreateAxleWheels(IVehicleDeclarationInputData data, XNamespace ns = null) - { - var axleData = data.Axles; - var numAxles = axleData.Count; - var axles = new List<XElement>(numAxles); - for (var i = 0; i < numAxles; i++) { - var axle = axleData[i]; - axles.Add(new XElement(tns + XMLNames.AxleWheels_Axles_Axle, - new XAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, i + 1), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_AxleType_Attr, - i == 1 ? AxleType.VehicleDriven.ToString() : AxleType.VehicleNonDriven.ToString()), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_TwinTyres_Attr, axle.TwinTyres), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Steered, i == 0), - CreateTyre(axle) - )); - } - - return new XElement((ns ??tns) + XMLNames.Component_AxleWheels, - new XElement(tns + XMLNames.ComponentDataWrapper, - //new XAttribute(XMLNames.Component_ID_Attr, - // string.Format("AXLWHL-{0}", data.AxleConfiguration.GetName())), - new XElement(tns + XMLNames.AxleWheels_Axles, axles)) - ); - } - - private XElement CreateTyre(IAxleDeclarationInputData axle) - { - var id = string.Format("TYRE-{0}", axle.Wheels).RemoveWhitespace().Replace("/", "_"); - return new XElement(tns + "Tyre", - //new XAttribute(XMLNames.Component_CertificationNumber_Attr, id), - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, id), - GetDefaultComponentElements(string.Format("TYRE-{0}", axle.Wheels), axle.Wheels), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Dimension, axle.Wheels), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_RRCDeclared, axle.RollResistanceCoefficient.ToXMLFormat(4)), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_FzISO, axle.TyreTestLoad.Value().ToXMLFormat(0)) - ), - AddSignatureDummy(id)); - } - - public XElement CreateAuxiliaries(IAuxiliariesDeclarationInputData data) - { - var auxList = new Dictionary<AuxiliaryType, XElement>(); - foreach (var auxData in data.Auxiliaries) { - var entry = new XElement(tns + AuxTypeToXML(auxData.Type), - auxData.Technology.Select(x => new XElement(tns + XMLNames.Auxiliaries_Auxiliary_Technology, x)).ToArray<object>()); - auxList[auxData.Type] = entry; - } - var aux = new XElement(tns + XMLNames.ComponentDataWrapper); - foreach ( - var key in - new[] { - AuxiliaryType.Fan, AuxiliaryType.SteeringPump, AuxiliaryType.ElectricSystem, AuxiliaryType.PneumaticSystem, - AuxiliaryType.HVAC - }) { - aux.Add(auxList[key]); - } - return new XElement(tns + XMLNames.Component_Auxiliaries, aux); - } - - private XElement CreateAirdrag(IAirdragDeclarationInputData data, XNamespace ns = null) - { - var id = string.Format("Airdrag-{0}", data.Model); - return new XElement((ns ?? tns) + XMLNames.Component_AirDrag, - //new XAttribute(XMLNames.Component_CertificationNumber_Attr, string.Format("AD-{0}", data.Model)), - new XElement(tns + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, id), - GetDefaultComponentElements(data.Model, "N.A."), - new XElement(tns + "CdxA_0", data.AirDragArea.Value().ToXMLFormat(2)), // TODO - new XElement(tns + "TransferredCdxA", data.AirDragArea.Value().ToXMLFormat(2)), // TODO - new XElement(tns + XMLNames.AirDrag_DeclaredCdxA, data.AirDragArea.Value().ToXMLFormat(2))), - AddSignatureDummy(id) - ); - } - - private string AuxTypeToXML(AuxiliaryType type) - { - return type.ToString(); - } - - - private XElement AddSignatureDummy(string id) - { - return new XElement(tns + XMLNames.DI_Signature, - new XElement(di + XMLNames.DI_Signature_Reference, - new XAttribute(XMLNames.DI_Signature_Reference_URI_Attr, "#" + id), - new XElement(di + XMLNames.DI_Signature_Reference_Transforms, - new XElement(di + XMLNames.DI_Signature_Reference_Transforms_Transform, - new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, - "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments")), - new XElement(di + XMLNames.DI_Signature_Reference_Transforms_Transform, - new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, "urn:vecto:xml:2017:canonicalization")) - ), - new XElement(di + XMLNames.DI_Signature_Reference_DigestMethod, - new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, "http://www.w3.org/2001/04/xmlenc#sha256")), - new XElement(di + XMLNames.DI_Signature_Reference_DigestValue, "") - ) - ); - } - - protected XElement[] GetDefaultComponentElements(string componentId, string makeAndModel) - { - return new[] { - new XElement(tns + XMLNames.Component_Manufacturer, Vendor), - new XElement(tns + XMLNames.Component_Model, makeAndModel), - new XElement(tns + XMLNames.Component_CertificationNumber, componentId), - new XElement(tns + XMLNames.Component_Date, XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)), - new XElement(tns + XMLNames.Component_AppVersion, "VectoCore"), - }; - } - - protected XElement[] GetDefaultComponentElements(string vin, string makeAndModel, string address) - { - return new[] { - new XElement(tns + XMLNames.Component_Manufacturer, Vendor), - new XElement(tns + XMLNames.Component_ManufacturerAddress, address), - new XElement(tns + XMLNames.Component_Model, makeAndModel), - new XElement(tns + XMLNames.Vehicle_VIN, vin), - new XElement(tns + XMLNames.Component_Date, XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)), - }; - } - } +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Xml; +using System.Xml.Linq; +using TUGraz.IVT.VectoXML; +using TUGraz.IVT.VectoXML.Writer; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; + +namespace TUGraz.VectoCore.OutputData.XML +{ + public class XMLDeclarationWriter : AbstractXMLWriter + { + private XNamespace componentNamespace; + //private readonly XNamespace _vectoNs = @"../../../API/VectoInput.xsd"; + + + public XMLDeclarationWriter(string vendor) : base(null, vendor) + { + tns = "urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v1.0"; + rootNamespace = "urn:tugraz:ivt:VectoAPI:DeclarationInput:v1.0"; + componentNamespace = "urn:tugraz:ivt:VectoAPI:DeclarationComponent:v1.0"; + } + + public XDocument GenerateVectoJob(IDeclarationInputDataProvider data) + { + var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); + + //<tns:VectoInputDeclaration + // xmlns="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v0.6" + // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="0.6" + // xmlns:tns="urn:tugraz:ivt:VectoAPI:DeclarationInput:v0.6" + // xsi:schemaLocation="urn:tugraz:ivt:VectoAPI:DeclarationInput:v0.6 http://markus.quaritsch.at/VECTO/VectoInput.xsd"> + var job = new XDocument(); + job.Add(new XElement(rootNamespace + XMLNames.VectoInputDeclaration, + new XAttribute("schemaVersion", SchemaVersion), + new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), + new XAttribute("xmlns", tns), + new XAttribute(XNamespace.Xmlns + "tns", rootNamespace), + new XAttribute(xsi + "schemaLocation", + string.Format("{0} {1}VectoInput.xsd", rootNamespace, SchemaLocationBaseUrl)), + CreateDeclarationJob(data)) + ); + return job; + } + + public XDocument GenerateVectoComponent(IGearboxDeclarationInputData data, + ITorqueConverterDeclarationInputData torqueConverter) + { + return GenerateComponentDocument(CreateGearbox(data, torqueConverter, componentNamespace)); + } + + public XDocument GenerateVectoComponent(IAxleGearInputData data) + { + return GenerateComponentDocument(CreateAxlegear(data, componentNamespace)); + } + + protected XDocument GenerateComponentDocument(XElement content) + { + var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); + var component = new XDocument(); + component.Add(new XElement(componentNamespace + XMLNames.VectoInputDeclaration, + new XAttribute("schemaVersion", SchemaVersion), + new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), + new XAttribute("xmlns", tns), + new XAttribute(XNamespace.Xmlns + "tns", componentNamespace), + new XAttribute(xsi + "schemaLocation", + string.Format("{0} {1}VectoComponent.xsd", componentNamespace, SchemaLocationBaseUrl)), + content) + ); + return component; + } + + protected XElement[] CreateDeclarationJob(IDeclarationInputDataProvider data) + { + return new[] { + CreateVehicle(data) + }; + } + + protected XElement CreateVehicle(IDeclarationInputDataProvider data) + { + var retarder = data.RetarderInputData; + var gearbox = data.GearboxInputData; + var vehicle = data.VehicleInputData; + var angledrive = data.AngledriveInputData; + + return new XElement(tns + XMLNames.Component_Vehicle, + new XAttribute(XMLNames.Component_ID_Attr, "VEH-" + vehicle.Model), + GetDefaultComponentElements(vehicle.CertificationNumber, vehicle.Model, "N.A."), + new XElement(tns + XMLNames.Vehicle_LegislativeClass, "N3"), + new XElement(tns + XMLNames.Vehicle_VehicleCategory, vehicle.VehicleCategory.ToXMLFormat()), + new XElement(tns + XMLNames.Vehicle_AxleConfiguration, vehicle.AxleConfiguration.GetName()), + new XElement(tns + XMLNames.Vehicle_CurbMassChassis, vehicle.CurbMassChassis.ToXMLFormat(0)), + new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, vehicle.GrossVehicleMassRating.ToXMLFormat(0)), + new XElement(tns + XMLNames.Vehicle_IdlingSpeed, vehicle.EngineIdleSpeed.AsRPM.ToXMLFormat(0)), + new XElement(tns + XMLNames.Vehicle_RetarderType, retarder.Type.ToXMLFormat()), + retarder.Type.IsDedicatedComponent() + ? new XElement(tns + XMLNames.Vehicle_RetarderRatio, retarder.Ratio.ToXMLFormat(3)) + : null, + new XElement(tns + XMLNames.Vehicle_AngledriveType, angledrive.Type.ToXMLFormat()), + new XElement(tns + XMLNames.Vehicle_PTO, + new XElement(tns + XMLNames.Vehicle_PTO_ShaftsGearWheels, "none"), + new XElement(tns + XMLNames.Vehicle_PTO_OtherElements, "none")), + CreateTorqueLimits(vehicle), + new XElement(tns + XMLNames.Vehicle_Components, + CreateEngine(data.EngineInputData), + CreateGearbox(gearbox, gearbox.Type.AutomaticTransmission() ? data.TorqueConverterInputData : null), + angledrive.Type == AngledriveType.SeparateAngledrive ? CreateAngleDrive(angledrive) : null, + retarder.Type.IsDedicatedComponent() ? CreateRetarder(retarder) : null, + CreateAxlegear(data.AxleGearInputData), + CreateAxleWheels(data.VehicleInputData), + CreateAuxiliaries(data.AuxiliaryInputData()), + CreateAirdrag(data.AirdragInputData) + ) + ); + } + + + protected XElement CreateEngine(IEngineDeclarationInputData data, XNamespace ns = null) + { + var id = string.Format("ENG-{0}", data.Model.RemoveWhitespace()); + var fld = FullLoadCurveReader.Create(data.FullLoadCurve, true); + return new XElement((ns ?? tns) + XMLNames.Component_Engine, + //new XAttribute(XMLNames.Component_CertificationNumber_Attr, string.Format("ENG-{0}", data.Model)), + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, id), + GetDefaultComponentElements(string.Format("ENG-{0}", data.Model), data.Model), + new XElement(tns + XMLNames.Engine_Displacement, (data.Displacement.Value() * 1000 * 1000).ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_IdlingSpeed, data.IdleSpeed.AsRPM.ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_RatedSpeed, fld.RatedSpeed.AsRPM.ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_RatedPower, fld.FullLoadStationaryPower(fld.RatedSpeed).ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_MaxTorque, fld.MaxTorque.ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_WHTCUrban, data.WHTCUrban.ToXMLFormat(4)), + new XElement(tns + XMLNames.Engine_WHTCRural, data.WHTCRural.ToXMLFormat(4)), + new XElement(tns + XMLNames.Engine_WHTCMotorway, data.WHTCMotorway.ToXMLFormat(4)), + new XElement(tns + XMLNames.Engine_ColdHotBalancingFactor, data.ColdHotBalancingFactor.ToXMLFormat(4)), + new XElement(tns + XMLNames.Engine_CorrectionFactor_RegPer, "1.0000"), + new XElement(tns + XMLNames.Engine_CorrecionFactor_NCV, "1.0000"), + new XElement(tns + XMLNames.Engine_FuelType, "Diesel CI"), + new XElement(tns + XMLNames.Engine_FuelConsumptionMap, + EmbedDataTable(data.FuelConsumptionMap, AttributeMappings.FuelConsumptionMapMapping)), + new XElement(tns + XMLNames.Engine_FullLoadAndDragCurve, + EmbedDataTable(data.FullLoadCurve, AttributeMappings.EngineFullLoadCurveMapping) + ) + ), + AddSignatureDummy(id) + ); + } + + + protected XElement CreateGearbox(IGearboxDeclarationInputData gbxData, + ITorqueConverterDeclarationInputData torqueConverter, XNamespace ns = null) + { + var gears = new XElement(tns + XMLNames.Gearbox_Gears); + var i = 1; + foreach (var gearData in gbxData.Gears) { + var gear = new XElement(tns + XMLNames.Gearbox_Gears_Gear, + new XAttribute(XMLNames.Gearbox_Gear_GearNumber_Attr, i++), + new XElement(tns + XMLNames.Gearbox_Gear_Ratio, gearData.Ratio.ToXMLFormat(3)), + gearData.MaxTorque != null + ? new XElement(tns + XMLNames.Gearbox_Gears_MaxTorque, gearData.MaxTorque.Value().ToXMLFormat(0)) + : null, + gearData.MaxInputSpeed != null + ? new XElement(tns + XMLNames.Gearbox_Gear_MaxSpeed, gearData.MaxInputSpeed.AsRPM.ToXMLFormat(0)) + : null, + new XElement(tns + XMLNames.Gearbox_Gear_TorqueLossMap, + EmbedDataTable(gearData.LossMap, AttributeMappings.TransmissionLossmapMapping)) + ); + gears.Add(gear); + } + var id = string.Format("GBX-{0}", gbxData.Model.RemoveWhitespace()); + return new XElement((ns ?? tns) + XMLNames.Component_Gearbox, + //new XAttribute(XMLNames.Component_CertificationNumber_Attr, string.Format("GBX-{0}", gbxData.Model)), + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, id), + GetDefaultComponentElements(string.Format("GBX-{0}", gbxData.Model), gbxData.Model), + new XElement(tns + XMLNames.Gearbox_TransmissionType, gbxData.Type.ToXMLFormat()), + new XElement(tns + XMLNames.Component_Gearbox_CertificationMethod, "Standard values"), + gears + ), + AddSignatureDummy(id), + gbxData.Type.AutomaticTransmission() ? CreateTorqueConverter(torqueConverter) : null + ); + } + + + private XElement CreateTorqueConverter(ITorqueConverterDeclarationInputData data) + { + if (data == null) { + throw new Exception("Torque Converter is required!"); + } + var id = string.Format("TC-{0}", data.Model.RemoveWhitespace()); + return new XElement(tns + XMLNames.Component_TorqueConverter, + //new XAttribute(XMLNames.Component_CertificationNumber_Attr, id), + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, id), + GetDefaultComponentElements(data.CertificationNumber, data.Model), + new XElement(tns + XMLNames.Component_CertificationMethod, "Standard values"), + new XElement(tns + XMLNames.TorqueConverter_Characteristics, + EmbedDataTable(data.TCData, AttributeMappings.TorqueConverterDataMapping, + precision: new Dictionary<string, uint>() { + { TorqueConverterDataReader.Fields.SpeedRatio, 4 } + }) + ) + ), + AddSignatureDummy(id)); + } + + private XElement CreateAngleDrive(IAngledriveInputData data, XNamespace ns = null) + { + var id = string.Format("ANGL-{0}", data.Model.RemoveWhitespace()); + return new XElement((ns ?? tns) + XMLNames.Component_Angledrive, + //new XAttribute(XMLNames.Component_CertificationNumber_Attr, "ANGL-" + data.Model), + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, id), + GetDefaultComponentElements(data.CertificationNumber, data.Model), + new XElement(tns + XMLNames.AngleDrive_Ratio, data.Ratio.ToXMLFormat(3)), + new XElement(tns + XMLNames.Component_CertificationMethod, "Standard values"), + new XElement(tns + XMLNames.AngleDrive_TorqueLossMap, + EmbedDataTable(data.LossMap, AttributeMappings.TransmissionLossmapMapping))), + AddSignatureDummy(id)); + } + + public XElement CreateRetarder(IRetarderInputData data, XNamespace ns = null) + { + var id = string.Format("RET-{0}", data.Model.RemoveWhitespace()); + return new XElement((ns ?? tns) + XMLNames.Component_Retarder, + //new XAttribute(XMLNames.Component_CertificationNumber_Attr, "RET-none"), + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, id), + GetDefaultComponentElements(data.CertificationNumber, data.Model), + new XElement(tns + XMLNames.Component_CertificationMethod, "Standard values"), + new XElement(tns + XMLNames.Retarder_RetarderLossMap, + EmbedDataTable(data.LossMap, AttributeMappings.RetarderLossmapMapping) + ) + ), + AddSignatureDummy(id) + ); + } + + public XElement CreateAxlegear(IAxleGearInputData data, XNamespace ns = null) + { + var typeId = string.Format("AXLGEAR-{0}", data.Ratio.ToString("F3", CultureInfo.InvariantCulture)); + return new XElement((ns ?? tns) + XMLNames.Component_Axlegear, + //new XAttribute(XMLNames.Component_CertificationNumber_Attr, string.Format("AXL-{0}", data.Model)), + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, typeId), + GetDefaultComponentElements(typeId, "N.A."), + new XElement(tns + "LineType", "Single portal axle"), + new XElement(tns + XMLNames.Axlegear_Ratio, data.Ratio.ToXMLFormat(3)), + new XElement(tns + XMLNames.Component_CertificationMethod, "Standard values"), + new XElement(tns + XMLNames.Axlegear_TorqueLossMap, + EmbedDataTable(data.LossMap, AttributeMappings.TransmissionLossmapMapping))), + AddSignatureDummy(typeId) + ); + } + + public XElement CreateAxleWheels(IVehicleDeclarationInputData data, XNamespace ns = null) + { + var axleData = data.Axles; + var numAxles = axleData.Count; + var axles = new List<XElement>(numAxles); + for (var i = 0; i < numAxles; i++) { + var axle = axleData[i]; + axles.Add(new XElement(tns + XMLNames.AxleWheels_Axles_Axle, + new XAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, i + 1), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_AxleType_Attr, + i == 1 ? AxleType.VehicleDriven.ToString() : AxleType.VehicleNonDriven.ToString()), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_TwinTyres_Attr, axle.TwinTyres), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Steered, i == 0), + CreateTyre(axle) + )); + } + + return new XElement((ns ?? tns) + XMLNames.Component_AxleWheels, + new XElement(tns + XMLNames.ComponentDataWrapper, + //new XAttribute(XMLNames.Component_ID_Attr, + // string.Format("AXLWHL-{0}", data.AxleConfiguration.GetName())), + new XElement(tns + XMLNames.AxleWheels_Axles, axles)) + ); + } + + private XElement CreateTyre(IAxleDeclarationInputData axle) + { + var id = string.Format("TYRE-{0}", axle.Wheels).RemoveWhitespace().Replace("/", "_"); + return new XElement(tns + "Tyre", + //new XAttribute(XMLNames.Component_CertificationNumber_Attr, id), + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, id), + GetDefaultComponentElements(string.Format("TYRE-{0}", axle.Wheels), axle.Wheels), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_Dimension, axle.Wheels), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_RRCDeclared, axle.RollResistanceCoefficient.ToXMLFormat(4)), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_FzISO, axle.TyreTestLoad.Value().ToXMLFormat(0)) + ), + AddSignatureDummy(id)); + } + + public XElement CreateAuxiliaries(IAuxiliariesDeclarationInputData data) + { + var auxList = new Dictionary<AuxiliaryType, XElement>(); + foreach (var auxData in data.Auxiliaries) { + var entry = new XElement(tns + AuxTypeToXML(auxData.Type), + auxData.Technology.Select(x => new XElement(tns + XMLNames.Auxiliaries_Auxiliary_Technology, x)).ToArray<object>()); + auxList[auxData.Type] = entry; + } + var aux = new XElement(tns + XMLNames.ComponentDataWrapper); + foreach ( + var key in + new[] { + AuxiliaryType.Fan, AuxiliaryType.SteeringPump, AuxiliaryType.ElectricSystem, AuxiliaryType.PneumaticSystem, + AuxiliaryType.HVAC + }) { + aux.Add(auxList[key]); + } + return new XElement(tns + XMLNames.Component_Auxiliaries, aux); + } + + private XElement CreateAirdrag(IAirdragDeclarationInputData data, XNamespace ns = null) + { + var id = string.Format("Airdrag-{0}", data.Model); + return new XElement((ns ?? tns) + XMLNames.Component_AirDrag, + //new XAttribute(XMLNames.Component_CertificationNumber_Attr, string.Format("AD-{0}", data.Model)), + new XElement(tns + XMLNames.ComponentDataWrapper, + new XAttribute(XMLNames.Component_ID_Attr, id), + GetDefaultComponentElements(data.Model, "N.A."), + new XElement(tns + "CdxA_0", data.AirDragArea.Value().ToXMLFormat(2)), // TODO + new XElement(tns + "TransferredCdxA", data.AirDragArea.Value().ToXMLFormat(2)), // TODO + new XElement(tns + XMLNames.AirDrag_DeclaredCdxA, data.AirDragArea.Value().ToXMLFormat(2))), + AddSignatureDummy(id) + ); + } + + private string AuxTypeToXML(AuxiliaryType type) + { + return type.ToString(); + } + + + private XElement AddSignatureDummy(string id) + { + return new XElement(tns + XMLNames.DI_Signature, + new XElement(di + XMLNames.DI_Signature_Reference, + new XAttribute(XMLNames.DI_Signature_Reference_URI_Attr, "#" + id), + new XElement(di + XMLNames.DI_Signature_Reference_Transforms, + new XElement(di + XMLNames.DI_Signature_Reference_Transforms_Transform, + new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, + "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments")), + new XElement(di + XMLNames.DI_Signature_Reference_Transforms_Transform, + new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, "urn:vecto:xml:2017:canonicalization")) + ), + new XElement(di + XMLNames.DI_Signature_Reference_DigestMethod, + new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, "http://www.w3.org/2001/04/xmlenc#sha256")), + new XElement(di + XMLNames.DI_Signature_Reference_DigestValue, "") + ) + ); + } + + protected XElement[] GetDefaultComponentElements(string componentId, string makeAndModel) + { + return new[] { + new XElement(tns + XMLNames.Component_Manufacturer, Vendor), + new XElement(tns + XMLNames.Component_Model, makeAndModel), + new XElement(tns + XMLNames.Component_CertificationNumber, componentId), + new XElement(tns + XMLNames.Component_Date, XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)), + new XElement(tns + XMLNames.Component_AppVersion, "VectoCore"), + }; + } + + protected XElement[] GetDefaultComponentElements(string vin, string makeAndModel, string address) + { + return new[] { + new XElement(tns + XMLNames.Component_Manufacturer, Vendor), + new XElement(tns + XMLNames.Component_ManufacturerAddress, address), + new XElement(tns + XMLNames.Component_Model, makeAndModel), + new XElement(tns + XMLNames.Vehicle_VIN, vin), + new XElement(tns + XMLNames.Component_Date, XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)), + }; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs index 8647201ea834cd3b2053723081bbfbaa3df38f7c..ffb5f6d5dfca18bda17ec7e5907414defe6cc607 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs @@ -29,1573 +29,1604 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using NUnit.Framework; -using System; -using System.IO; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.FileIO.JSON; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; -using TUGraz.VectoCore.InputData.Reader.Impl; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Tests.Utils; - -namespace TUGraz.VectoCore.Tests.Models.Declaration -{ - [TestFixture] - public class DeclarationDataTest - { - private const double Tolerance = 0.0001; - - private readonly MissionType[] _missions = { - MissionType.LongHaul, - MissionType.RegionalDelivery, - MissionType.UrbanDelivery, - MissionType.MunicipalUtility, - MissionType.Construction, - }; - - [TestCase("285/60 R22.5", 10.6, 0.914, 3.03, 0.440766), - TestCase("285/70 R19.5", 7.9, 0.895, 3.05, 0.434453), - TestCase("395/85 R20", 27.9, 1.18, 3.05, 0.572798)] - public void WheelDataTest(string wheels, double inertia, double wheelsDiameter, double circumferenceFactor, - double expectedDynamicRadius) - { - var tmp = DeclarationData.Wheels.Lookup(wheels); - - AssertHelper.AreRelativeEqual(inertia, tmp.Inertia); - AssertHelper.AreRelativeEqual(wheelsDiameter, tmp.WheelsDiameter); - AssertHelper.AreRelativeEqual(circumferenceFactor, tmp.CircumferenceFactor); - Assert.AreEqual(expectedDynamicRadius, tmp.DynamicTyreRadius.Value(), 1e-6); - } - - [ - // fixed points - TestCase(400, 0), - TestCase(800, 0.47), - TestCase(1000, 0.58), - TestCase(1200, 0.53), - TestCase(1400, 0.46), - TestCase(1500, 0.43), - TestCase(1750, 0.22), - TestCase(1800, 0.2), - TestCase(2000, 0.11), - TestCase(2500, 0.11), - // interpolate - TestCase(600, 0.235), - TestCase(900, 0.525), - TestCase(1100, 0.555), - TestCase(1300, 0.495), - TestCase(1450, 0.445), - TestCase(1625, 0.325), - TestCase(1775, 0.21), - TestCase(1900, 0.155), - TestCase(2250, 0.11), - ] - public void PT1Test(double rpm, double expectedPt1) - { - var pt1 = DeclarationData.PT1.Lookup(rpm.RPMtoRad()); - Assert.AreEqual(expectedPt1, pt1.Value.Value(), Tolerance); - Assert.IsFalse(pt1.Extrapolated); - } - - [TestCase(200), - TestCase(0), - TestCase(3000),] - public void PT1ExceptionsTest(double rpm) - { - // EXTRAPOLATE - var tmp = DeclarationData.PT1.Lookup(rpm.RPMtoRad()); - Assert.IsTrue(tmp.Extrapolated); - } - - [TestCase] - public void WHTCTest() - { - var whtc = DeclarationData.WHTCCorrection; - - var factors = new { - urban = new[] { 0.11, 0.17, 0.69, 0.98, 0.62, 1.0, 1.0, 1.0, 0.45, 0.0 }, - rural = new[] { 0.0, 0.3, 0.27, 0.0, 0.32, 0.0, 0.0, 0.0, 0.36, 0.22 }, - motorway = new[] { 0.89, 0.53, 0.04, 0.02, 0.06, 0.0, 0.0, 0.0, 0.19, 0.78 } - }; - - var r = new Random(); - for (var i = 0; i < _missions.Length; i++) { - var urban = r.NextDouble() * 2; - var rural = r.NextDouble() * 2; - var motorway = r.NextDouble() * 2; - var whtcValue = whtc.Lookup(_missions[i], rural: rural, urban: urban, motorway: motorway); - Assert.AreEqual(urban * factors.urban[i] + rural * factors.rural[i] + motorway * factors.motorway[i], - whtcValue); - } - } - - [TestCase] - public void WHTCLookupTestLongHaul() - { - var expected = 1.015501; - - var rural = 1.0265; - var urban = 1.0948; - var motorway = 1.0057; - - var lookup = DeclarationData.WHTCCorrection.Lookup(MissionType.LongHaul, rural: rural, urban: urban, - motorway: motorway); - Assert.AreEqual(expected, lookup, 1e-8); - } - - [TestCase] - public void WHTCLookupTestRegionalDelivery() - { - var expected = 1.02708700; - - var rural = 1.0265; - var urban = 1.0948; - var motorway = 1.0057; - - var lookup = DeclarationData.WHTCCorrection.Lookup(MissionType.RegionalDelivery, rural: rural, urban: urban, - motorway: motorway); - Assert.AreEqual(expected, lookup, 1e-8); - } - - [TestCase("RigidSolo", 0.013526, 0.017746, -0.000666), - TestCase("RigidTrailer", 0.017125, 0.072275, -0.004148), - TestCase("TractorSemitrailer", 0.030042, 0.040817, -0.00213), - TestCase("CoachBus", -0.000794, 0.02109, -0.00109)] - public void AirDrag_WithStringKey(string key, double a1, double a2, double a3) - { - var value = DeclarationData.AirDrag.Lookup(key); - AssertHelper.AreRelativeEqual(a1, value.A1); - AssertHelper.AreRelativeEqual(a2, value.A2); - AssertHelper.AreRelativeEqual(a3, value.A3); - } - - [TestCase("RigidSolo", 0.013526, 0.017746, -0.000666), - TestCase("TractorSemitrailer", 0.030042, 0.040817, -0.00213), - TestCase("RigidTrailer", 0.017125, 0.072275, -0.004148), - TestCase("CoachBus", -0.000794, 0.02109, -0.00109)] - public void AirDrag_WithVehicleCategory(string parameterSet, double a1, double a2, double a3) - { - var value = DeclarationData.AirDrag.Lookup(parameterSet); - AssertHelper.AreRelativeEqual(a1, value.A1); - AssertHelper.AreRelativeEqual(a2, value.A2); - AssertHelper.AreRelativeEqual(a3, value.A3); - } - - [TestCase("TractorSemitrailer", 6.46, 0, 4.0, 7.71712257), - TestCase("TractorSemitrailer", 6.46, 60, 4.0, 7.71712257), - TestCase("TractorSemitrailer", 6.46, 75, 3.75, 7.35129203), - TestCase("TractorSemitrailer", 6.46, 100, 4.0, 7.03986404), - TestCase("TractorSemitrailer", 6.46, 62.1234, 4.0, 7.65751048), - TestCase("TractorSemitrailer", 6.46, 73.5432, 3.75, 7.37814098), - TestCase("TractorSemitrailer", 6.46, 92.8765, 4.0, 7.11234364), - TestCase("TractorSemitrailer", 6.46, 100.449, 4.0, 7.03571556), - TestCase("TractorSemitrailer", 6.46, 103, 3.6, 6.99454230), - TestCase("TractorSemitrailer", 6.46, 105, 3.9, 6.99177143), - TestCase("TractorSemitrailer", 6.46, 115, 4.0, 6.92267778), - TestCase("TractorSemitrailer", 6.46, 130, 4.0, 6.83867361),] - 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>(), - height.SI<Meter>()), - CrossWindCorrectionMode.DeclarationModeCorrection); - - var tmp = crossWindCorrectionCurve.EffectiveAirDragArea(kmph.KMPHtoMeterPerSecond()); - AssertHelper.AreRelativeEqual(expected, tmp.Value(), toleranceFactor: 1e-3); - } - - [TestCase("TractorSemitrailer", 5.8, 4.0)] - 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(7.0418009.SI<SquareMeter>(), curve[1].EffectiveCrossSectionArea); - - AssertHelper.AreRelativeEqual(65.KMPHtoMeterPerSecond(), curve[2].Velocity); - AssertHelper.AreRelativeEqual(6.90971991.SI<SquareMeter>(), curve[2].EffectiveCrossSectionArea); - - AssertHelper.AreRelativeEqual(85.KMPHtoMeterPerSecond(), curve[6].Velocity); - AssertHelper.AreRelativeEqual(6.54224222.SI<SquareMeter>(), curve[6].EffectiveCrossSectionArea); - - AssertHelper.AreRelativeEqual(100.KMPHtoMeterPerSecond(), curve[9].Velocity); - AssertHelper.AreRelativeEqual(6.37434824.SI<SquareMeter>(), curve[9].EffectiveCrossSectionArea); - - AssertHelper.AreRelativeEqual(105.KMPHtoMeterPerSecond(), curve[10].Velocity); - AssertHelper.AreRelativeEqual(6.33112792.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>(), - height.SI<Meter>()), - CrossWindCorrectionMode.DeclarationModeCorrection); - - AssertHelper.Exception<VectoException>(() => - crossWindCorrectionCurve.EffectiveAirDragArea(kmph.KMPHtoMeterPerSecond())); - } - - [TestCase(MissionType.LongHaul, "Standard technology", 1200, 0.7), - TestCase(MissionType.RegionalDelivery, "Standard technology", 1000, 0.7), - TestCase(MissionType.UrbanDelivery, "Standard technology", 1000, 0.7), - TestCase(MissionType.MunicipalUtility, "Standard technology", 1000, 0.7), - TestCase(MissionType.Construction, "Standard technology", 1000, 0.7), - TestCase(MissionType.LongHaul, "Standard technology - LED headlights, all", 1150, 0.7), - TestCase(MissionType.RegionalDelivery, "Standard technology - LED headlights, all", 950, 0.7), - TestCase(MissionType.UrbanDelivery, "Standard technology - LED headlights, all", 950, 0.7), - TestCase(MissionType.MunicipalUtility, "Standard technology - LED headlights, all", 950, 0.7), - TestCase(MissionType.Construction, "Standard technology - LED headlights, all", 950, 0.7),] - public void AuxElectricSystemTest(MissionType mission, string technology, double value, double efficiency) - { - AssertHelper.AreRelativeEqual(value / efficiency, DeclarationData.ElectricSystem.Lookup(mission, technology)); - } - - [TestCase(MissionType.Interurban, "Standard technology"), - TestCase(MissionType.LongHaul, "Standard technology - Flux-Compensator")] - public void AuxElectricSystem_NotExistingError(MissionType mission, string technology) - { - AssertHelper.Exception<VectoException>(() => { DeclarationData.ElectricSystem.Lookup(mission, technology); }); - } - - [TestCase("only the drive shaft of the PTO - shift claw, synchronizer, sliding gearwheel", 50), - TestCase("only the drive shaft of the PTO - multi-disc clutch", 1000), - TestCase("only the drive shaft of the PTO - multi-disc clutch, oil pump", 2000), - TestCase("drive shaft and/or up to 2 gear wheels - shift claw, synchronizer, sliding gearwheel", 300), - TestCase("drive shaft and/or up to 2 gear wheels - multi-disc clutch", 1500), - TestCase("drive shaft and/or up to 2 gear wheels - multi-disc clutch, oil pump", 3000), - TestCase("drive shaft and/or more than 2 gear wheels - shift claw, synchronizer, sliding gearwheel", 600), - TestCase("drive shaft and/or more than 2 gear wheels - multi-disc clutch", 2000), - TestCase("drive shaft and/or more than 2 gear wheels - multi-disc clutch, oil pump", 4000), - TestCase("only one engaged gearwheel above oil level", 0)] - public void AuxPTOTransmissionTest(string technology, double value) - { - AssertHelper.AreRelativeEqual(value, DeclarationData.PTOTransmission.Lookup(technology)); - } - - [TestCase("Superfluid")] - public void AuxPTOTransmission_NotExistingError(string technology) - { - AssertHelper.Exception<VectoException>(() => { DeclarationData.PTOTransmission.Lookup(technology); }); - } - - [TestCase("", new[] { 618, 671, 516, 566, 1037 }), - TestCase("Crankshaft mounted - Electronically controlled visco clutch", new[] { 618, 671, 516, 566, 1037 }), - TestCase("Crankshaft mounted - Bimetallic controlled visco clutch", new[] { 818, 871, 676, 766, 1277 }), - TestCase("Crankshaft mounted - Discrete step clutch", new[] { 668, 721, 616, 616, 1157 }), - TestCase("Crankshaft mounted - On/off clutch", new[] { 718, 771, 666, 666, 1237 }), - TestCase("Belt driven or driven via transm. - Electronically controlled visco clutch", - new[] { 989, 1044, 833, 933, 1478 }), - TestCase("Belt driven or driven via transm. - Bimetallic controlled visco clutch", - new[] { 1189, 1244, 993, 1133, 1718 }), - TestCase("Belt driven or driven via transm. - Discrete step clutch", new[] { 1039, 1094, 983, 983, 1598 }), - TestCase("Belt driven or driven via transm. - On/off clutch", new[] { 1089, 1144, 1033, 1033, 1678 }), - TestCase("Hydraulic driven - Variable displacement pump", new[] { 938, 1155, 832, 917, 1872 }), - TestCase("Hydraulic driven - Constant displacement pump", new[] { 1200, 1400, 1000, 1100, 2300 }), - TestCase("Hydraulic driven - Electronically controlled", new[] { 700, 800, 600, 600, 1400 }),] - public void AuxFanTechTest(string technology, int[] expected) - { - for (var i = 0; i < _missions.Length; i++) { - var value = DeclarationData.Fan.Lookup(_missions[i], technology); - Assert.AreEqual(expected[i], value.Value(), Tolerance); - } - } - - [TestCase("Superfluid Hydraulic", MissionType.LongHaul, TestName = "AuxFanTechError( wrong tech )"), - TestCase("Hydraulic driven - Electronically controlled", MissionType.Coach, - TestName = "AuxFanTechError( wrong mission )") - ] - public void AuxFanTechError(string technology, MissionType missionType) - { - AssertHelper.Exception<VectoException>(() => DeclarationData.Fan.Lookup(missionType, technology)); - } - - [TestCase(VehicleClass.Class1, new[] { 0, 150, 150, 0, 0 }), - TestCase(VehicleClass.Class2, new[] { 200, 200, 150, 0, 0 }), - TestCase(VehicleClass.Class3, new[] { 0, 200, 150, 0, 0 }), - TestCase(VehicleClass.Class4, new[] { 350, 200, 0, 300, 0 }), - TestCase(VehicleClass.Class5, new[] { 350, 200, 0, 0, 0 }), - TestCase(VehicleClass.Class9, new[] { 350, 200, 0, 300, 0 }), - TestCase(VehicleClass.Class10, new[] { 350, 200, 0, 0, 0 }), - TestCase(VehicleClass.Class11, new[] { 350, 200, 0, 300, 200 }), - TestCase(VehicleClass.Class12, new[] { 350, 200, 0, 0, 200 }), - TestCase(VehicleClass.Class16, new[] { 0, 0, 0, 0, 200 })] - public void AuxHeatingVentilationAirConditionTest_Default(VehicleClass vehicleClass, int[] expected) - { - for (var i = 0; i < expected.Length; i++) { - if (expected[i] > 0) { - AssertHelper.AreRelativeEqual(expected[i], - DeclarationData.HeatingVentilationAirConditioning.Lookup(_missions[i], "Default", vehicleClass)); - } else { - var i1 = i; - AssertHelper.Exception<VectoException>( - () => DeclarationData.HeatingVentilationAirConditioning.Lookup(_missions[i1], "Default", vehicleClass)); - } - } - } - - [TestCase(VehicleClass.Class1, new[] { 0, 0, 0, 0, 0 }), - TestCase(VehicleClass.Class2, new[] { 0, 0, 0, 0, 0 }), - TestCase(VehicleClass.Class3, new[] { 0, 0, 0, 0, 0 }), - TestCase(VehicleClass.Class4, new[] { 0, 0, 0, 0, 0 }), - TestCase(VehicleClass.Class5, new[] { 0, 0, 0, 0, 0 }), - TestCase(VehicleClass.Class9, new[] { 0, 0, 0, 0, 0 }), - TestCase(VehicleClass.Class10, new[] { 0, 0, 0, 0, 0 }), - TestCase(VehicleClass.Class11, new[] { 0, 0, 0, 0, 0 }), - TestCase(VehicleClass.Class12, new[] { 0, 0, 0, 0, 0 }), - TestCase(VehicleClass.Class16, new[] { 0, 0, 0, 0, 0 })] - public void AuxHeatingVentilationAirConditionTest_None(VehicleClass vehicleClass, int[] expected) - { - for (var i = 0; i < expected.Length; i++) { - AssertHelper.AreRelativeEqual(expected[i], - DeclarationData.HeatingVentilationAirConditioning.Lookup(_missions[i], "None", vehicleClass)); - } - } - - [TestCase()] - public void AuxHetingVentilationAirConditionTechnologyTest() - { - var tech = DeclarationData.HeatingVentilationAirConditioning.GetTechnologies(); - Assert.AreEqual(2, tech.Length); - Assert.IsTrue(tech.Contains("Default")); - Assert.IsTrue(tech.Contains("None")); - } - - [Test, - TestCase("Small", new[] { 1400, 1300, 1200, 1200, 1300 }), - TestCase("Small + ESS", new[] { 900, 800, 800, 800, 800 }), - TestCase("Small + visco clutch", new[] { 800, 700, 700, 700, 700 }), - TestCase("Small + mech. clutch", new[] { 600, 600, 650, 650, 600 }), - TestCase("Small + ESS + AMS", new[] { 500, 400, 500, 500, 400 }), - TestCase("Small + visco clutch + AMS", new[] { 400, 300, 400, 400, 300 }), - TestCase("Small + mech. clutch + AMS", new[] { 200, 200, 350, 350, 200 }), - TestCase("Medium Supply 1-stage", new[] { 1600, 1400, 1350, 1350, 1500 }), - TestCase("Medium Supply 1-stage + ESS", new[] { 1000, 900, 900, 900, 900 }), - TestCase("Medium Supply 1-stage + visco clutch", new[] { 850, 800, 800, 800, 750 }), - TestCase("Medium Supply 1-stage + mech. clutch", new[] { 600, 550, 550, 550, 600 }), - TestCase("Medium Supply 1-stage + ESS + AMS", new[] { 600, 700, 700, 700, 500 }), - TestCase("Medium Supply 1-stage + visco clutch + AMS", new[] { 450, 600, 600, 600, 350 }), - TestCase("Medium Supply 1-stage + mech. clutch + AMS", new[] { 200, 350, 350, 350, 200 }), - TestCase("Medium Supply 2-stage", new[] { 2100, 1750, 1700, 1700, 2100 }), - TestCase("Medium Supply 2-stage + ESS", new[] { 1100, 1050, 1000, 1000, 1000 }), - TestCase("Medium Supply 2-stage + visco clutch", new[] { 1000, 850, 800, 800, 900 }), - TestCase("Medium Supply 2-stage + mech. clutch", new[] { 700, 650, 600, 600, 800 }), - TestCase("Medium Supply 2-stage + ESS + AMS", new[] { 700, 850, 800, 800, 500 }), - TestCase("Medium Supply 2-stage + visco clutch + AMS", new[] { 600, 650, 600, 600, 400 }), - TestCase("Medium Supply 2-stage + mech. clutch + AMS", new[] { 300, 450, 400, 400, 300 }), - TestCase("Large Supply", new[] { 4300, 3600, 3500, 3500, 4100 }), - TestCase("Large Supply + ESS", new[] { 1600, 1300, 1200, 1200, 1500 }), - TestCase("Large Supply + visco clutch", new[] { 1300, 1100, 1000, 1000, 1200 }), - TestCase("Large Supply + mech. clutch", new[] { 800, 800, 700, 700, 900 }), - TestCase("Large Supply + ESS + AMS", new[] { 1100, 1000, 1000, 1000, 1000 }), - TestCase("Large Supply + visco clutch + AMS", new[] { 800, 800, 800, 800, 700 }), - TestCase("Large Supply + mech. clutch + AMS", new[] { 300, 500, 500, 500, 400 }), - TestCase("Vacuum pump", new[] { 190, 160, 130, 130, 130 }), - ] - public void AuxPneumaticSystemTest(string technology, int[] expected) - { - for (var i = 0; i < _missions.Length; i++) { - var value = DeclarationData.PneumaticSystem.Lookup(_missions[i], technology); - AssertHelper.AreRelativeEqual(expected[i], value); - } - } - - [ - TestCase(MissionType.LongHaul, VehicleClass.Class2, 370, "Fixed displacement", null, null, null), - TestCase(MissionType.LongHaul, VehicleClass.Class4, 610, "Fixed displacement", null, null, null), - TestCase(MissionType.LongHaul, VehicleClass.Class5, 720, "Fixed displacement", null, null, null), - TestCase(MissionType.LongHaul, VehicleClass.Class9, 720, "Fixed displacement", null, null, null), - TestCase(MissionType.LongHaul, VehicleClass.Class10, 570, "Fixed displacement", null, null, null), - TestCase(MissionType.LongHaul, VehicleClass.Class11, 720, "Fixed displacement", null, null, null), - TestCase(MissionType.LongHaul, VehicleClass.Class12, 570, "Fixed displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class1, 280, "Fixed displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 340, "Fixed displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class3, 370, "Fixed displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class4, 570, "Fixed displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class5, 670, "Fixed displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class9, 590, "Fixed displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class10, 570, "Fixed displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class11, 590, "Fixed displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class12, 570, "Fixed displacement", null, null, null), - TestCase(MissionType.UrbanDelivery, VehicleClass.Class1, 270, "Fixed displacement", null, null, null), - TestCase(MissionType.UrbanDelivery, VehicleClass.Class2, 310, "Fixed displacement", null, null, null), - TestCase(MissionType.UrbanDelivery, VehicleClass.Class3, 350, "Fixed displacement", null, null, null), - TestCase(MissionType.UrbanDelivery, VehicleClass.Class5, 620, "Fixed displacement", null, null, null), - TestCase(MissionType.MunicipalUtility, VehicleClass.Class4, 510, "Fixed displacement", null, null, null), - TestCase(MissionType.MunicipalUtility, VehicleClass.Class9, 510, "Fixed displacement", null, null, null), - TestCase(MissionType.MunicipalUtility, VehicleClass.Class11, 510, "Fixed displacement", null, null, null), - TestCase(MissionType.Construction, VehicleClass.Class11, 770, "Fixed displacement", null, null, null), - TestCase(MissionType.Construction, VehicleClass.Class12, 770, "Fixed displacement", null, null, null), - TestCase(MissionType.Construction, VehicleClass.Class16, 770, "Fixed displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 325.5, "Fixed displacement with elec. control", null, - null, - null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 289, "Dual displacement", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 255, "Variable displacement mech. controlled", null, - null, - null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 204, "Variable displacement elec. controlled", null, - null, - null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 92.8571, "Electric", null, null, null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 665, "Fixed displacement", "Fixed displacement", null, - null), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 1295, "Fixed displacement", "Fixed displacement", - "Fixed displacement", "Fixed displacement"), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 1021.5, "Dual displacement", - "Variable displacement mech. controlled", "Fixed displacement with elec. control", - "Variable displacement elec. controlled"), - ] - public void Aux_SteeringPumpLookupValues(MissionType mission, VehicleClass hdvClass, double expected, string axle1, - string axle2, string axle3, string axle4) - { - // mk remark: made the test call with 4 axle params, so that the test name is clear in the test explorer. - AssertHelper.AreRelativeEqual(expected, - DeclarationData.SteeringPump.Lookup(mission, hdvClass, - new[] { axle1, axle2, axle3, axle4 }.TakeWhile(a => a != null).ToArray())); - } - - [TestCase(MissionType.LongHaul, VehicleClass.Class1, "Dual displacement", - TestName = "Aux_SteeringPumpLookupFail( No Value )"), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, "Super displacement", - TestName = "Aux_SteeringPumpLookupFail( Wrong Tech )"), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, "Dual displacement", "Dual displacement", - "Dual displacement", "Dual displacement", "Dual displacement", TestName = "Aux_SteeringPumpLookupFail( >4 Techs )"), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, TestName = "Aux_SteeringPumpLookupFail( Null Techs )"), - TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, new string[0], - TestName = "Aux_SteeringPumpLookupFail( 0 Techs )"), - ] - public void Aux_SteeringPumpLookupFail(MissionType mission, VehicleClass hdvClass, params string[] tech) - { - AssertHelper.Exception<VectoException>(() => DeclarationData.SteeringPump.Lookup(mission, hdvClass, tech)); - } - - [ - TestCase(0), - TestCase(1000), - TestCase(3500), - TestCase(7499) - ] - public void SegmentWeightOutOfRange4X2(double weight) - { - AssertHelper.Exception<VectoException>(() => - DeclarationData.Segments.Lookup( - VehicleCategory.RigidTruck, - AxleConfiguration.AxleConfig_4x2, - weight.SI<Kilogram>(), - 0.SI<Kilogram>()), - "Gross vehicle mass must be greater than 7.5 tons"); - } - - [ - TestCase(0), - TestCase(1000), - TestCase(3500), - TestCase(7499) - ] - public void SegmentWeightOutOfRange4X4(double weight) - { - AssertHelper.Exception<VectoException>(() => - DeclarationData.Segments.Lookup( - VehicleCategory.RigidTruck, - AxleConfiguration.AxleConfig_4x4, - weight.SI<Kilogram>(), - 0.SI<Kilogram>()), - "Gross vehicle mass must be greater than 7.5 tons"); - } - - [Test, - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 7500, 0, VehicleClass.Class1), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 7500, 0, VehicleClass.Class1), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 10001, 0, VehicleClass.Class2), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 10001, 0, VehicleClass.Class2), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12001, 0, VehicleClass.Class3), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 12001, 0, VehicleClass.Class3), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16001, 0, VehicleClass.Class4), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 99000, 0, VehicleClass.Class4), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16001, 0, VehicleClass.Class5), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 99000, 0, VehicleClass.Class5), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 7500, 0, VehicleClass.Class9), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 16000, 0, VehicleClass.Class9), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class9), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 99000, 0, VehicleClass.Class9), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 7500, 0, VehicleClass.Class10), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 16000, 0, VehicleClass.Class10), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class10), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 99000, 0, VehicleClass.Class10), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 7500, 0, VehicleClass.Class11), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 40000, 0, VehicleClass.Class11), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 7500, 0, VehicleClass.Class12), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 99000, 0, VehicleClass.Class12), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 7500, 0, VehicleClass.Class16), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 99000, 0, VehicleClass.Class16) - ] - public void SegmentLookupTest(VehicleCategory category, AxleConfiguration axleConfiguration, double grossWeight, - double curbWeight, VehicleClass expectedClass) - { - var segment = DeclarationData.Segments.Lookup(category, axleConfiguration, grossWeight.SI<Kilogram>(), - curbWeight.SI<Kilogram>()); - Assert.AreEqual(expectedClass, segment.VehicleClass); - } - - [TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 7500, 0, VehicleClass.Class1, 85), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 10001, 0, VehicleClass.Class2, 85), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12001, 0, VehicleClass.Class3, 85), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16001, 0, VehicleClass.Class4, 85), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16001, 0, VehicleClass.Class5, 85), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 7500, 0, VehicleClass.Class9, 85), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 7500, 0, VehicleClass.Class10, 85), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 7500, 0, VehicleClass.Class11, 85), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 7500, 0, VehicleClass.Class12, 85), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 7500, 0, VehicleClass.Class16, 85), - ] - public void SegmentDesignSpeedTest(VehicleCategory category, AxleConfiguration axleConfiguration, double grossWeight, - double curbWeight, VehicleClass expectedClass, double speed) - { - var segment = DeclarationData.Segments.Lookup(category, axleConfiguration, grossWeight.SI<Kilogram>(), - curbWeight.SI<Kilogram>()); - - Assert.AreEqual(speed.KMPHtoMeterPerSecond(), segment.DesignSpeed); - } - - [Test, - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1, 1600, null, - TestName = "SegmentLookupBodyWeight Class1 Rigid"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1, 1600, null, - TestName = "SegmentLookupBodyWeight Class1 Tractor"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, 1900, 3400, - TestName = "SegmentLookupBodyWeight Class2 Rigid"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, 1900, 3400, - TestName = "SegmentLookupBodyWeight Class2 Tractor"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, 2000, null, - TestName = "SegmentLookupBodyWeight Class3 Rigid"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, 2000, null, - TestName = "SegmentLookupBodyWeight Class3 Tractor"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class4, 2100, 5400, - TestName = "SegmentLookupBodyWeight Class4"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class5, null, 7500, - TestName = "SegmentLookupBodyWeight Class5"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class9, 2200, 5400, - TestName = "SegmentLookupBodyWeight Class9"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class10, null, 7500, - TestName = "SegmentLookupBodyWeight Class10"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 12000, 0, VehicleClass.Class11, 2200, 5400, - TestName = "SegmentLookupBodyWeight Class11"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 12000, 0, VehicleClass.Class12, null, 7500, - TestName = "SegmentLookupBodyWeight Class12"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 12000, 0, VehicleClass.Class16, null, null, - TestName = "SegmentLookupBodyWeight Class16")] - public void SegmentLookupBodyTest(VehicleCategory category, AxleConfiguration axleConfiguration, double grossWeight, - double curbWeight, VehicleClass expectedClass, int? expectedBodyWeight, int? expectedTrailerWeight) - { - var segment = DeclarationData.Segments.Lookup(category, axleConfiguration, grossWeight.SI<Kilogram>(), - curbWeight.SI<Kilogram>()); - Assert.AreEqual(expectedClass, segment.VehicleClass); - - if (expectedBodyWeight.HasValue) { - Assert.AreEqual(expectedBodyWeight, segment.Missions[0].BodyCurbWeight.Value()); - } - if (expectedTrailerWeight.HasValue) { - var trailerMission = segment.Missions.Where(m => m.Trailer.Count > 0).ToList(); - if (trailerMission.Count > 0) { - Assert.AreEqual(expectedTrailerWeight, trailerMission.First().Trailer.First().TrailerCurbWeight.Value()); - } - } - } - - [Test, - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1, 3.6, - TestName = "SegmentLookupHeight Class1 Rigid"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1, 3.6, - TestName = "SegmentLookupHeight Class1 Tractor"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, 3.75, - TestName = "SegmentLookupHeight Class2 Rigid"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, 3.75, - TestName = "SegmentLookupHeight Class2 Tractor"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, 3.9, - TestName = "SegmentLookupHeight Class3 Rigid"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, 3.9, - TestName = "SegmentLookupHeight Class3 Tractor"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class4, 4.0, - TestName = "SegmentLookupHeight Class4"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class5, 4.0, - TestName = "SegmentLookupHeight Class5"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 10000, 0, VehicleClass.Class9, 3.6, - TestName = "SegmentLookupHeight Class9 - 1"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 12000, 0, VehicleClass.Class9, 3.75, - TestName = "SegmentLookupHeight Class9 - 2"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 16000, 0, VehicleClass.Class9, 3.9, - TestName = "SegmentLookupHeight Class9 - 3"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 18000, 0, VehicleClass.Class9, 4.0, - TestName = "SegmentLookupHeight Class9 - 4"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class9, 4.0, - TestName = "SegmentLookupHeight Class9 - other"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class10, 4.0, - TestName = "SegmentLookupHeight Class10"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 12000, 0, VehicleClass.Class11, 4.0, - TestName = "SegmentLookupHeight Class11"), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 12000, 0, VehicleClass.Class12, 4.0, - TestName = "SegmentLookupHeight Class12"), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 12000, 0, VehicleClass.Class16, 3.6, - TestName = "SegmentLookupHeight Class16")] - public void SegmentLookupHeightTest(VehicleCategory category, AxleConfiguration axleConfiguration, double grossWeight, - double curbWeight, VehicleClass expectedClass, double expectedHeight) - { - var segment = DeclarationData.Segments.Lookup(category, axleConfiguration, grossWeight.SI<Kilogram>(), - curbWeight.SI<Kilogram>()); - Assert.AreEqual(expectedClass, segment.VehicleClass); - AssertHelper.AreRelativeEqual(expectedHeight, segment.VehicleHeight); - } - - [Test, - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 7500, 0, VehicleClass.Class1, - new[] { 36.5, 36.5 }), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 7500, 0, VehicleClass.Class1, - new[] { 36.5, 36.5 }), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, - new[] { 85.0, 45.2, 45.2 }), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, - new[] { 85.0, 45.2, 45.2 }), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, - new[] { 47.7, 47.7 }), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, - new[] { 47.7, 47.7 }), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class4, - new[] { 98.9, 49.4, 49.4 }), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class5, - new[] { 91.0, 140.5, 91.0, 140.5 }), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 16000, 0, VehicleClass.Class9, - new[] { 101.4, 142.9, 51.9, 142.9, 51.9 }), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 16000, 0, VehicleClass.Class10, - new[] { 91.0, 140.5, 91.0, 140.5 }), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 40000, 0, VehicleClass.Class11, - new[] { 101.4, 142.9, 51.9, 142.9, 51.9, 51.9 }), - TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 99000, 0, VehicleClass.Class12, - new[] { 91.0, 140.5, 91.0, 140.5, 91.0 }), - TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 99000, 0, VehicleClass.Class16, - new[] { 0.0 }) - ] - public void SegmentLookupCargoVolumeTest(VehicleCategory category, AxleConfiguration axleConfiguration, - double grossWeight, - double curbWeight, VehicleClass expectedClass, double[] expectedCargoVolume) - { - var segment = DeclarationData.Segments.Lookup(category, axleConfiguration, grossWeight.SI<Kilogram>(), - curbWeight.SI<Kilogram>()); - Assert.AreEqual(expectedClass, segment.VehicleClass); - Assert.AreEqual(expectedCargoVolume.Length, segment.Missions.Length); - for (var i = 0; i < expectedCargoVolume.Length; i++) { - Assert.AreEqual(expectedCargoVolume[i], segment.Missions[i].TotalCargoVolume.Value()); - } - } - - /// <summary> - /// trailer in longhaul, always pc formula - /// </summary> - [TestCase] - public void Segment2Test() - { - var vehicleData = new { - VehicleCategory = VehicleCategory.RigidTruck, - AxleConfiguration = AxleConfiguration.AxleConfig_4x2, - GrossVehicleMassRating = 11900.SI<Kilogram>(), - CurbWeight = 5850.SI<Kilogram>() - }; - - var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, - vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); - - Assert.AreEqual(VehicleClass.Class2, segment.VehicleClass); - - var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); - TestAcceleration(data); - - Assert.AreEqual(3, segment.Missions.Length); - - AssertMission(segment.Missions[0], - vehicleData: vehicleData, - missionType: MissionType.LongHaul, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.225, 0.325 }, - trailerAxleWeightDistribution: new[] { 0.45 }, - trailerAxleCount: new[] { 2 }, - bodyCurbWeight: 1900, - trailerCurbWeight: new[] { 3400.0 }, - trailerType: new[] { TrailerType.T1 }, - lowLoad: 1306.8235, - refLoad: 9813.2353, - trailerGrossVehicleWeight: new[] { 10500.0 }, - deltaCdA: 1.3, - maxLoad: 11250); - - AssertMission(segment.Missions[1], - vehicleData: vehicleData, - missionType: MissionType.RegionalDelivery, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.45, 0.55 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 1900, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 596.8235, - refLoad: 2984.1176, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 4150); - - AssertMission(segment.Missions[2], - vehicleData: vehicleData, - missionType: MissionType.UrbanDelivery, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.45, 0.55 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 1900, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 596.8235, - refLoad: 2984.1176, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 4150); - } - - /// <summary> - /// normal pc formula, no trailer - /// </summary> - [TestCase] - public void Segment3Test() - { - var vehicleData = new { - VehicleCategory = VehicleCategory.RigidTruck, - AxleConfiguration = AxleConfiguration.AxleConfig_4x2, - GrossVehicleMassRating = 14000.SI<Kilogram>(), - CurbWeight = 5850.SI<Kilogram>() - }; - - var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, - vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); - - Assert.AreEqual(VehicleClass.Class3, segment.VehicleClass); - - Assert.AreEqual(2, segment.Missions.Length); - - AssertMission(segment.Missions[0], - vehicleData: vehicleData, - missionType: MissionType.RegionalDelivery, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.4, 0.6 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 2000, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 762.3529, - refLoad: 3811.7647, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 6150); - - AssertMission(segment.Missions[1], - vehicleData: vehicleData, - missionType: MissionType.UrbanDelivery, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.4, 0.6 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 2000, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 762.3529, - refLoad: 3811.7647, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 6150); - } - - /// <summary> - /// fixed reference weight, trailer only in longhaul - /// </summary> - [TestCase] - public void Segment4Test() - { - var vehicleData = new { - VehicleCategory = VehicleCategory.RigidTruck, - AxleConfiguration = AxleConfiguration.AxleConfig_4x2, - GrossVehicleMassRating = 18000.SI<Kilogram>(), - CurbWeight = 7500.SI<Kilogram>() - }; - - var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, - vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); - - Assert.AreEqual(VehicleClass.Class4, segment.VehicleClass); - - var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); - TestAcceleration(data); - - Assert.AreEqual(3, segment.Missions.Length); - - AssertMission(segment.Missions[0], - vehicleData: vehicleData, - missionType: MissionType.LongHaul, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.2, 0.3 }, - trailerAxleWeightDistribution: new[] { 0.5 }, - trailerAxleCount: new[] { 2 }, - bodyCurbWeight: 2100, - trailerCurbWeight: new[] { 5400.0 }, - trailerType: new[] { TrailerType.T2 }, - lowLoad: 1900, - refLoad: 14000, - trailerGrossVehicleWeight: new[] { 18000.0 }, - deltaCdA: 1.5, - maxLoad: 21000); - - AssertMission(segment.Missions[1], - vehicleData: vehicleData, - missionType: MissionType.RegionalDelivery, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.45, 0.55 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 2100, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 900, - refLoad: 4400, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 8400); - - AssertMission(segment.Missions[2], - vehicleData: vehicleData, - missionType: MissionType.MunicipalUtility, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.45, 0.55 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 2100, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 600, - refLoad: 3000, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 8400); - } - - /// <summary> - /// Segment 5: fixed reference weight, trailer always used - /// </summary> - [TestCase] - public void Segment5Test() - { - var vehicleData = new { - VehicleCategory = VehicleCategory.Tractor, - AxleConfiguration = AxleConfiguration.AxleConfig_4x2, - GrossVehicleMassRating = 18000.SI<Kilogram>(), - CurbWeight = 7500.SI<Kilogram>() - }; - - var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, - vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); - - Assert.AreEqual(VehicleClass.Class5, segment.VehicleClass); - - var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); - TestAcceleration(data); - - Assert.AreEqual(4, segment.Missions.Length); - - AssertMission(segment.Missions[0], - vehicleData: vehicleData, - missionType: MissionType.LongHaul, - cosswindCorrection: "TractorSemitrailer", - axleWeightDistribution: new[] { 0.2, 0.25 }, - trailerAxleWeightDistribution: new[] { 0.55 }, - trailerAxleCount: new[] { 3 }, bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0 }, - trailerType: new[] { TrailerType.ST1 }, - lowLoad: 2600, - refLoad: 19300, - trailerGrossVehicleWeight: new[] { 24000.0 }, - deltaCdA: 0, - maxLoad: 25000); - - AssertMission(segment.Missions[1], - vehicleData: vehicleData, - missionType: MissionType.LongHaulEMS, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.15, 0.2 }, - trailerAxleWeightDistribution: new[] { 0.40, 0.25 }, - trailerAxleCount: new[] { 3, 2 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0, 5400 }, - trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, - lowLoad: 3500, - refLoad: 26500, - trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, - deltaCdA: 1.5, - maxLoad: 39600, - ems: true); - - AssertMission(segment.Missions[2], - vehicleData: vehicleData, - missionType: MissionType.RegionalDelivery, - cosswindCorrection: "TractorSemitrailer", - axleWeightDistribution: new[] { 0.25, 0.25 }, - trailerAxleWeightDistribution: new[] { 0.5 }, - trailerAxleCount: new[] { 3 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0 }, - trailerType: new[] { TrailerType.ST1 }, - lowLoad: 2600, - refLoad: 12900, - trailerGrossVehicleWeight: new[] { 24000.0 }, - deltaCdA: 0, maxLoad: 25000); - - AssertMission(segment.Missions[3], - vehicleData: vehicleData, - missionType: MissionType.RegionalDeliveryEMS, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.175, 0.25 }, - trailerAxleWeightDistribution: new[] { 0.35, 0.225 }, - trailerAxleCount: new[] { 3, 2 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0, 5400 }, - trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, - lowLoad: 3500, - refLoad: 17500, - trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, - deltaCdA: 1.5, - maxLoad: 39600, - ems: true); - } - - /// <summary> - /// Segment 9: fixed reference weight, trailer always used - /// </summary> - [TestCase] - public void Segment9Test() - { - var vehicleData = new { - VehicleCategory = VehicleCategory.RigidTruck, - AxleConfiguration = AxleConfiguration.AxleConfig_6x2, - GrossVehicleMassRating = 24000.SI<Kilogram>(), - CurbWeight = 7500.SI<Kilogram>() - }; - - var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, - vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); - - Assert.AreEqual(VehicleClass.Class9, segment.VehicleClass); - - var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); - TestAcceleration(data); - - Assert.AreEqual(5, segment.Missions.Length); - - AssertMission(segment.Missions[0], - vehicleData: vehicleData, - missionType: MissionType.LongHaul, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.2, 0.3, 0.15 }, - trailerAxleWeightDistribution: new[] { 0.35 }, - trailerAxleCount: new[] { 2 }, - bodyCurbWeight: 2200, - trailerCurbWeight: new[] { 5400.0 }, - trailerType: new[] { TrailerType.T2 }, - lowLoad: 2600, - refLoad: 19300, - trailerGrossVehicleWeight: new[] { 18000.0 }, - deltaCdA: 1.5, - maxLoad: 24900); - - AssertMission(segment.Missions[1], - vehicleData: vehicleData, - missionType: MissionType.LongHaulEMS, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.15, 0.2, 0.1 }, - trailerAxleWeightDistribution: new[] { 0.225, 0.325 }, - trailerAxleCount: new[] { 2, 3 }, - bodyCurbWeight: 2200, - trailerCurbWeight: new[] { 2500, 7500.0 }, - trailerType: new[] { TrailerType.Dolly, TrailerType.ST1 }, - lowLoad: 3500, - refLoad: 26500, - trailerGrossVehicleWeight: new[] { 12000.0, 24000 }, - deltaCdA: 2.1, - maxLoad: 40300, - ems: true); - - AssertMission(segment.Missions[2], - vehicleData: vehicleData, - missionType: MissionType.RegionalDelivery, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.35, 0.4, 0.25 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 2200, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 1400, - refLoad: 7100, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 14300); - - AssertMission(segment.Missions[3], - vehicleData: vehicleData, - missionType: MissionType.RegionalDeliveryEMS, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.175, 0.2, 0.1 }, - trailerAxleWeightDistribution: new[] { 0.225, 0.3 }, - trailerAxleCount: new[] { 2, 3 }, - bodyCurbWeight: 2200, - trailerCurbWeight: new[] { 2500, 7500.0 }, - trailerType: new[] { TrailerType.Dolly, TrailerType.ST1 }, - lowLoad: 3500, - refLoad: 17500, - trailerGrossVehicleWeight: new[] { 12000.0, 24000 }, - deltaCdA: 2.1, - maxLoad: 40300, - ems: true); - - AssertMission(segment.Missions[4], - vehicleData: vehicleData, - missionType: MissionType.MunicipalUtility, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.35, 0.4, 0.25 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 2200, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 1200, - refLoad: 6000, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 14300); - } - - /// <summary> - /// Segment 10: fixed reference weight, trailer always used - /// </summary> - [TestCase] - public void Segment10Test() - { - var vehicleData = new { - VehicleCategory = VehicleCategory.Tractor, - AxleConfiguration = AxleConfiguration.AxleConfig_6x2, - GrossVehicleMassRating = 24000.SI<Kilogram>(), - CurbWeight = 7500.SI<Kilogram>() - }; - - var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, - vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); - - Assert.AreEqual(VehicleClass.Class10, segment.VehicleClass); - - var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); - TestAcceleration(data); - - Assert.AreEqual(4, segment.Missions.Length); - - AssertMission(segment.Missions[0], - vehicleData: vehicleData, - missionType: MissionType.LongHaul, - cosswindCorrection: "TractorSemitrailer", - axleWeightDistribution: new[] { 0.15, 0.1, 0.2 }, - trailerAxleWeightDistribution: new[] { 0.55 }, - trailerAxleCount: new[] { 3 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0 }, - trailerType: new[] { TrailerType.ST1 }, - lowLoad: 2600, - refLoad: 19300, - trailerGrossVehicleWeight: new[] { 24000.0 }, - deltaCdA: 0, - maxLoad: 25000); - - AssertMission(segment.Missions[1], - vehicleData: vehicleData, - missionType: MissionType.LongHaulEMS, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.125, 0.15, 0.1 }, - trailerAxleWeightDistribution: new[] { 0.375, 0.25 }, - trailerAxleCount: new[] { 3, 2 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0, 5400 }, - trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, - lowLoad: 3500, - refLoad: 26500, - trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, - deltaCdA: 1.5, - maxLoad: 39600, - ems: true); - - AssertMission(segment.Missions[2], - vehicleData: vehicleData, - missionType: MissionType.RegionalDelivery, - cosswindCorrection: "TractorSemitrailer", - axleWeightDistribution: new[] { 0.2, 0.1, 0.2 }, - trailerAxleWeightDistribution: new[] { 0.5 }, - trailerAxleCount: new[] { 3 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0 }, - trailerType: new[] { TrailerType.ST1 }, - lowLoad: 2600, - refLoad: 12900, - trailerGrossVehicleWeight: new[] { 24000.0 }, - deltaCdA: 0, - maxLoad: 25000); - - AssertMission(segment.Missions[3], - vehicleData: vehicleData, - missionType: MissionType.RegionalDeliveryEMS, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.15, 0.15, 0.1 }, - trailerAxleWeightDistribution: new[] { 0.35, 0.25 }, - trailerAxleCount: new[] { 3, 2 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0, 5400 }, - trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, - lowLoad: 3500, - refLoad: 17500, - trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, - deltaCdA: 1.5, - maxLoad: 39600, - ems: true); - } - - /// <summary> - /// Segment 11: fixed reference weight, trailer always used - /// </summary> - [TestCase] - public void Segment11Test() - { - var vehicleData = new { - VehicleCategory = VehicleCategory.RigidTruck, - AxleConfiguration = AxleConfiguration.AxleConfig_6x4, - GrossVehicleMassRating = 24000.SI<Kilogram>(), - CurbWeight = 7500.SI<Kilogram>() - }; - - var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, - vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); - - Assert.AreEqual(VehicleClass.Class11, segment.VehicleClass); - - var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); - TestAcceleration(data); - - Assert.AreEqual(6, segment.Missions.Length); - - AssertMission(segment.Missions[0], - vehicleData: vehicleData, - missionType: MissionType.LongHaul, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.2, 0.225, 0.225 }, - trailerAxleWeightDistribution: new[] { 0.35 }, - trailerAxleCount: new[] { 2 }, - bodyCurbWeight: 2200, - trailerCurbWeight: new[] { 5400.0 }, - trailerType: new[] { TrailerType.T2 }, - lowLoad: 2600, - refLoad: 19300, - trailerGrossVehicleWeight: new[] { 18000.0 }, - deltaCdA: 1.5, - maxLoad: 24900); - - AssertMission(segment.Missions[1], - vehicleData: vehicleData, - missionType: MissionType.LongHaulEMS, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.15, 0.2, 0.1 }, - trailerAxleWeightDistribution: new[] { 0.225, 0.325 }, - trailerAxleCount: new[] { 2, 3 }, - bodyCurbWeight: 2200, - trailerCurbWeight: new[] { 2500, 7500.0 }, - trailerType: new[] { TrailerType.Dolly, TrailerType.ST1 }, - lowLoad: 3500, - refLoad: 26500, - trailerGrossVehicleWeight: new[] { 12000.0, 24000 }, - deltaCdA: 2.1, - maxLoad: 40300, - ems: true); - - AssertMission(segment.Missions[2], - vehicleData: vehicleData, - missionType: MissionType.RegionalDelivery, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.35, 0.35, 0.3 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, bodyCurbWeight: 2200, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 1400, - refLoad: 7100, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 14300); - - AssertMission(segment.Missions[3], - vehicleData: vehicleData, - missionType: MissionType.RegionalDeliveryEMS, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.175, 0.2, 0.1 }, - trailerAxleWeightDistribution: new[] { 0.225, 0.3 }, - trailerAxleCount: new[] { 2, 3 }, - bodyCurbWeight: 2200, - trailerCurbWeight: new[] { 2500, 7500.0 }, - trailerType: new[] { TrailerType.Dolly, TrailerType.ST1 }, - lowLoad: 3500, - refLoad: 17500, - trailerGrossVehicleWeight: new[] { 12000.0, 24000 }, - deltaCdA: 2.1, - maxLoad: 40300, - ems: true); - - AssertMission(segment.Missions[4], - vehicleData: vehicleData, - missionType: MissionType.MunicipalUtility, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.35, 0.35, 0.3 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 2200, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 1200, - refLoad: 6000, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 14300); - - AssertMission(segment.Missions[5], - vehicleData: vehicleData, - missionType: MissionType.Construction, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.35, 0.35, 0.3 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 2200, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 1400, - refLoad: 7100, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 14300); - } - - /// <summary> - /// Segment 10: fixed reference weight, trailer always used - /// </summary> - [TestCase] - public void Segment12Test() - { - var vehicleData = new { - VehicleCategory = VehicleCategory.Tractor, - AxleConfiguration = AxleConfiguration.AxleConfig_6x4, - GrossVehicleMassRating = 24000.SI<Kilogram>(), - CurbWeight = 7500.SI<Kilogram>() - }; - - var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, - vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); - - Assert.AreEqual(VehicleClass.Class12, segment.VehicleClass); - - var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); - TestAcceleration(data); - - Assert.AreEqual(5, segment.Missions.Length); - - AssertMission(segment.Missions[0], - vehicleData: vehicleData, - missionType: MissionType.LongHaul, - cosswindCorrection: "TractorSemitrailer", - axleWeightDistribution: new[] { 0.15, 0.15, 0.15 }, - trailerAxleWeightDistribution: new[] { 0.55 }, - trailerAxleCount: new[] { 3 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0 }, - trailerType: new[] { TrailerType.ST1 }, - lowLoad: 2600, - refLoad: 19300, - trailerGrossVehicleWeight: new[] { 24000.0 }, - deltaCdA: 0, - maxLoad: 25000); - - AssertMission(segment.Missions[1], - vehicleData: vehicleData, - missionType: MissionType.LongHaulEMS, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.125, 0.15, 0.1 }, - trailerAxleWeightDistribution: new[] { 0.375, 0.25 }, - trailerAxleCount: new[] { 3, 2 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0, 5400 }, - trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, - lowLoad: 3500, - refLoad: 26500, - trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, - deltaCdA: 1.5, - maxLoad: 39600, - ems: true); - - AssertMission(segment.Missions[2], - vehicleData: vehicleData, - missionType: MissionType.RegionalDelivery, - cosswindCorrection: "TractorSemitrailer", - axleWeightDistribution: new[] { 0.2, 0.15, 0.15 }, - trailerAxleWeightDistribution: new[] { 0.5 }, - trailerAxleCount: new[] { 3 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0 }, - trailerType: new[] { TrailerType.ST1 }, - lowLoad: 2600, - refLoad: 12900, - trailerGrossVehicleWeight: new[] { 24000.0 }, - deltaCdA: 0, - maxLoad: 25000); - - AssertMission(segment.Missions[3], - vehicleData: vehicleData, - missionType: MissionType.RegionalDeliveryEMS, - cosswindCorrection: "RigidTrailer", - axleWeightDistribution: new[] { 0.15, 0.15, 0.1 }, - trailerAxleWeightDistribution: new[] { 0.35, 0.25 }, - trailerAxleCount: new[] { 3, 2 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0, 5400 }, - trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, - lowLoad: 3500, - refLoad: 17500, - trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, - deltaCdA: 1.5, - maxLoad: 39600, - ems: true); - - AssertMission(segment.Missions[4], - vehicleData: vehicleData, - missionType: MissionType.Construction, - cosswindCorrection: "TractorSemitrailer", - axleWeightDistribution: new[] { 0.2, 0.15, 0.15 }, - trailerAxleWeightDistribution: new[] { 0.5 }, - trailerAxleCount: new[] { 3 }, - bodyCurbWeight: 0, - trailerCurbWeight: new[] { 7500.0 }, - trailerType: new[] { TrailerType.ST1 }, - lowLoad: 2600, - refLoad: 12900, - trailerGrossVehicleWeight: new[] { 24000.0 }, - deltaCdA: 0, - maxLoad: 25000, - ems: false); - } - - /// <summary> - /// Segment 9: fixed reference weight, trailer always used - /// </summary> - [TestCase] - public void Segment16Test() - { - var vehicleData = new { - VehicleCategory = VehicleCategory.RigidTruck, - AxleConfiguration = AxleConfiguration.AxleConfig_8x4, - GrossVehicleMassRating = 36000.SI<Kilogram>(), - CurbWeight = 7500.SI<Kilogram>() - }; - - var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, - vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); - - Assert.AreEqual(VehicleClass.Class16, segment.VehicleClass); - - var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); - TestAcceleration(data); - - Assert.AreEqual(1, segment.Missions.Length); - - AssertMission(segment.Missions[0], - vehicleData: vehicleData, - missionType: MissionType.Construction, - cosswindCorrection: "RigidSolo", - axleWeightDistribution: new[] { 0.25, 0.25, 0.25, 0.25 }, - trailerAxleWeightDistribution: new double[] { }, - trailerAxleCount: new int[] { }, - bodyCurbWeight: 0, - trailerCurbWeight: new double[] { }, - trailerType: new TrailerType[] { }, - lowLoad: 2600, - refLoad: 12900, - trailerGrossVehicleWeight: new double[] { }, - deltaCdA: 0, - maxLoad: 28500); - } - - public static void AssertMission(Mission m, dynamic vehicleData, MissionType missionType, string cosswindCorrection, - double[] axleWeightDistribution, double[] trailerAxleWeightDistribution, int[] trailerAxleCount, - double bodyCurbWeight, double[] trailerCurbWeight, TrailerType[] trailerType, double lowLoad, double refLoad, - double maxLoad, double[] trailerGrossVehicleWeight, double deltaCdA, bool ems = false) - { - Assert.AreEqual(missionType, m.MissionType); - Assert.AreEqual(cosswindCorrection, m.CrossWindCorrectionParameters); - CollectionAssert.AreEqual(axleWeightDistribution, m.AxleWeightDistribution, - "Axle distribution not equal.\nexpected: {0}\nactual: {1}", string.Join(",", axleWeightDistribution), - string.Join(",", m.AxleWeightDistribution)); - CollectionAssert.AreEqual(trailerAxleWeightDistribution, m.Trailer.Select(t => t.TrailerAxleWeightShare), - "Trailer axle distribution not equal.\nexpected: {0}\nactual: {1}", string.Join(",", trailerAxleWeightDistribution), - string.Join(",", m.Trailer.Select(t => t.TrailerAxleWeightShare))); - Assert.AreEqual(bodyCurbWeight.SI<Kilogram>(), m.BodyCurbWeight); - CollectionAssert.AreEqual(trailerCurbWeight, m.Trailer.Select(t => t.TrailerCurbWeight.Value())); - CollectionAssert.AreEqual(trailerType, m.Trailer.Select(t => t.TrailerType)); - CollectionAssert.AreEqual(trailerAxleCount, m.Trailer.Select(t => t.TrailerWheels.Count)); - Assert.IsNotNull(m.CycleFile); - Assert.IsTrue(!string.IsNullOrEmpty(new StreamReader(m.CycleFile).ReadLine())); - Assert.AreEqual(0.SI<Kilogram>(), m.MinLoad); - AssertHelper.AreRelativeEqual(lowLoad, m.LowLoad); - AssertHelper.AreRelativeEqual(refLoad, m.RefLoad); - Assert.AreEqual(maxLoad.SI<Kilogram>(), m.MaxLoad); - CollectionAssert.AreEqual(trailerGrossVehicleWeight, m.Trailer.Select(t => t.TrailerGrossVehicleWeight.Value())); - Assert.AreEqual( - VectoMath.Min( - vehicleData.GrossVehicleMassRating + - m.Trailer.Sum(t => t.TrailerGrossVehicleWeight).DefaultIfNull(0), - ems ? 60000.SI<Kilogram>() : 40000.SI<Kilogram>()) - - m.BodyCurbWeight - m.Trailer.Sum(t => t.TrailerCurbWeight).DefaultIfNull(0) - - vehicleData.CurbWeight, - m.MaxLoad); - Assert.AreEqual(deltaCdA.SI<SquareMeter>(), - m.Trailer.Sum(t => t.DeltaCdA).DefaultIfNull(0)); - } - - private static void EqualAcceleration(AccelerationCurveData data, double velocity, double acceleration, - double deceleration) - { - var entry = data.Lookup(velocity.KMPHtoMeterPerSecond()); - Assert.AreEqual(entry.Acceleration.Value(), acceleration, Tolerance); - Assert.AreEqual(entry.Deceleration.Value(), deceleration, Tolerance); - } - - private static void TestAcceleration(AccelerationCurveData data) - { - // FIXED POINTS - EqualAcceleration(data, 0, 1, -1); - EqualAcceleration(data, 25, 1, -1); - EqualAcceleration(data, 50, 0.642857143, -1); - EqualAcceleration(data, 60, 0.5, -0.5); - EqualAcceleration(data, 120, 0.5, -0.5); - - // INTERPOLATED POINTS - EqualAcceleration(data, 20, 1, -1); - EqualAcceleration(data, 40, 0.785714286, -1); - EqualAcceleration(data, 55, 0.571428572, -0.75); - EqualAcceleration(data, 80, 0.5, -0.5); - EqualAcceleration(data, 100, 0.5, -0.5); - - // EXTRAPOLATE - EqualAcceleration(data, -20, 1, -1); - EqualAcceleration(data, 140, 0.5, -0.5); - } - - [TestCase] - public void Declaration_WheelsForT1_Class2() - { - var dataProvider = - JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\12t Delivery Truck.vecto") as IDeclarationInputDataProvider; - var dataReader = new DeclarationModeVectoRunDataFactory(dataProvider, null); - - var runs = dataReader.NextRun().ToList(); - Assert.AreEqual(6, runs.Count); - var withT1 = new[] { 6.0, 6.0, 4.5, 4.5 }; - - CollectionAssert.AreEqual(withT1, runs[0].VehicleData.AxleData.Select(a => a.Inertia.Value())); - CollectionAssert.AreEqual(withT1, runs[1].VehicleData.AxleData.Select(a => a.Inertia.Value())); - - var bodyOnly = new[] { 6.0, 6.0 }; - - CollectionAssert.AreEqual(bodyOnly, runs[2].VehicleData.AxleData.Select(a => a.Inertia.Value())); - CollectionAssert.AreEqual(bodyOnly, runs[3].VehicleData.AxleData.Select(a => a.Inertia.Value())); - - CollectionAssert.AreEqual(bodyOnly, runs[4].VehicleData.AxleData.Select(a => a.Inertia.Value())); - CollectionAssert.AreEqual(bodyOnly, runs[5].VehicleData.AxleData.Select(a => a.Inertia.Value())); - } - - [TestCase] - public void Declaration_WheelsForT2_Class4() - { - var dataProvider = - JSONInputDataFactory.ReadJsonJob( - @"TestData\Jobs\Class4_40t_Long_Haul_Truck.vecto") as IDeclarationInputDataProvider; - var dataReader = new DeclarationModeVectoRunDataFactory(dataProvider, null); - - var runs = dataReader.NextRun().ToList(); - Assert.AreEqual(6, runs.Count); - var withT1 = new[] { 14.9, 14.9, 19.2, 19.2 }; - CollectionAssert.AreEqual(withT1, runs[0].VehicleData.AxleData.Select(a => a.Inertia.Value())); - CollectionAssert.AreEqual(withT1, runs[1].VehicleData.AxleData.Select(a => a.Inertia.Value())); - - var bodyOnly = new[] { 14.9, 14.9 }; - CollectionAssert.AreEqual(bodyOnly, runs[2].VehicleData.AxleData.Select(a => a.Inertia.Value())); - CollectionAssert.AreEqual(bodyOnly, runs[3].VehicleData.AxleData.Select(a => a.Inertia.Value())); - - CollectionAssert.AreEqual(bodyOnly, runs[4].VehicleData.AxleData.Select(a => a.Inertia.Value())); - CollectionAssert.AreEqual(bodyOnly, runs[5].VehicleData.AxleData.Select(a => a.Inertia.Value())); - } - - [TestCase] - public void Declaration_WheelsForDefault_Class5() - { - var dataProvider = - JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\40t_Long_Haul_Truck.vecto") as IDeclarationInputDataProvider; - var dataReader = new DeclarationModeVectoRunDataFactory(dataProvider, null); - - var runs = dataReader.NextRun().ToList(); - - Assert.AreEqual(VehicleClass.Class5, runs[0].VehicleData.VehicleClass); - Assert.AreEqual(8, runs.Count); - - //var bodyOnly = new[] { 14.9, 14.9 }; - var withST1 = new[] { 14.9, 14.9, 19.2, 19.2, 19.2 }; - var withST1andT2 = new[] { 14.9, 14.9, 19.2, 19.2, 19.2, 19.2, 19.2 }; - - CollectionAssert.AreEqual(withST1, runs[0].VehicleData.AxleData.Select(a => a.Inertia.Value())); - CollectionAssert.AreEqual(withST1, runs[1].VehicleData.AxleData.Select(a => a.Inertia.Value())); - - CollectionAssert.AreEqual(withST1andT2, runs[2].VehicleData.AxleData.Select(a => a.Inertia.Value())); - CollectionAssert.AreEqual(withST1andT2, runs[3].VehicleData.AxleData.Select(a => a.Inertia.Value())); - - CollectionAssert.AreEqual(withST1, runs[4].VehicleData.AxleData.Select(a => a.Inertia.Value())); - CollectionAssert.AreEqual(withST1, runs[5].VehicleData.AxleData.Select(a => a.Inertia.Value())); - - CollectionAssert.AreEqual(withST1andT2, runs[6].VehicleData.AxleData.Select(a => a.Inertia.Value())); - CollectionAssert.AreEqual(withST1andT2, runs[7].VehicleData.AxleData.Select(a => a.Inertia.Value())); - } - } +using NUnit.Framework; +using System; +using System.IO; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; +using TUGraz.VectoCore.InputData.Reader.Impl; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Tests.Utils; + +namespace TUGraz.VectoCore.Tests.Models.Declaration +{ + [TestFixture] + public class DeclarationDataTest + { + private const double Tolerance = 0.0001; + + private readonly MissionType[] _missions = { + MissionType.LongHaul, + MissionType.RegionalDelivery, + MissionType.UrbanDelivery, + MissionType.MunicipalUtility, + MissionType.Construction, + }; + + [TestCase("285/60 R22.5", 10.6, 0.914, 3.03, 0.440766), + TestCase("285/70 R19.5", 7.9, 0.895, 3.05, 0.434453), + TestCase("395/85 R20", 27.9, 1.18, 3.05, 0.572798)] + public void WheelDataTest(string wheels, double inertia, double wheelsDiameter, double circumferenceFactor, + double expectedDynamicRadius) + { + var tmp = DeclarationData.Wheels.Lookup(wheels); + + AssertHelper.AreRelativeEqual(inertia, tmp.Inertia); + AssertHelper.AreRelativeEqual(wheelsDiameter, tmp.WheelsDiameter); + AssertHelper.AreRelativeEqual(circumferenceFactor, tmp.CircumferenceFactor); + Assert.AreEqual(expectedDynamicRadius, tmp.DynamicTyreRadius.Value(), 1e-6); + } + + [ + // fixed points + TestCase(400, 0), + TestCase(800, 0.47), + TestCase(1000, 0.58), + TestCase(1200, 0.53), + TestCase(1400, 0.46), + TestCase(1500, 0.43), + TestCase(1750, 0.22), + TestCase(1800, 0.2), + TestCase(2000, 0.11), + TestCase(2500, 0.11), + // interpolate + TestCase(600, 0.235), + TestCase(900, 0.525), + TestCase(1100, 0.555), + TestCase(1300, 0.495), + TestCase(1450, 0.445), + TestCase(1625, 0.325), + TestCase(1775, 0.21), + TestCase(1900, 0.155), + TestCase(2250, 0.11), + ] + public void PT1Test(double rpm, double expectedPt1) + { + var pt1 = DeclarationData.PT1.Lookup(rpm.RPMtoRad()); + Assert.AreEqual(expectedPt1, pt1.Value.Value(), Tolerance); + Assert.IsFalse(pt1.Extrapolated); + } + + [TestCase(200), + TestCase(0), + TestCase(3000),] + public void PT1ExceptionsTest(double rpm) + { + // EXTRAPOLATE + var tmp = DeclarationData.PT1.Lookup(rpm.RPMtoRad()); + Assert.IsTrue(tmp.Extrapolated); + } + + [TestCase] + public void WHTCTest() + { + var whtc = DeclarationData.WHTCCorrection; + + var factors = new { + urban = new[] { 0.11, 0.17, 0.69, 0.98, 0.62, 1.0, 1.0, 1.0, 0.45, 0.0 }, + rural = new[] { 0.0, 0.3, 0.27, 0.0, 0.32, 0.0, 0.0, 0.0, 0.36, 0.22 }, + motorway = new[] { 0.89, 0.53, 0.04, 0.02, 0.06, 0.0, 0.0, 0.0, 0.19, 0.78 } + }; + + var r = new Random(); + for (var i = 0; i < _missions.Length; i++) { + var urban = r.NextDouble() * 2; + var rural = r.NextDouble() * 2; + var motorway = r.NextDouble() * 2; + var whtcValue = whtc.Lookup(_missions[i], rural: rural, urban: urban, motorway: motorway); + Assert.AreEqual(urban * factors.urban[i] + rural * factors.rural[i] + motorway * factors.motorway[i], + whtcValue); + } + } + + [TestCase] + public void WHTCLookupTestLongHaul() + { + var expected = 1.015501; + + var rural = 1.0265; + var urban = 1.0948; + var motorway = 1.0057; + + var lookup = DeclarationData.WHTCCorrection.Lookup(MissionType.LongHaul, rural: rural, urban: urban, + motorway: motorway); + Assert.AreEqual(expected, lookup, 1e-8); + } + + [TestCase] + public void WHTCLookupTestRegionalDelivery() + { + var expected = 1.02708700; + + var rural = 1.0265; + var urban = 1.0948; + var motorway = 1.0057; + + var lookup = DeclarationData.WHTCCorrection.Lookup(MissionType.RegionalDelivery, rural: rural, urban: urban, + motorway: motorway); + Assert.AreEqual(expected, lookup, 1e-8); + } + + [TestCase("RigidSolo", 0.013526, 0.017746, -0.000666), + TestCase("RigidTrailer", 0.017125, 0.072275, -0.004148), + TestCase("TractorSemitrailer", 0.030042, 0.040817, -0.00213), + TestCase("CoachBus", -0.000794, 0.02109, -0.00109)] + public void AirDrag_WithStringKey(string key, double a1, double a2, double a3) + { + var value = DeclarationData.AirDrag.Lookup(key); + AssertHelper.AreRelativeEqual(a1, value.A1); + AssertHelper.AreRelativeEqual(a2, value.A2); + AssertHelper.AreRelativeEqual(a3, value.A3); + } + + [TestCase("RigidSolo", 0.013526, 0.017746, -0.000666), + TestCase("TractorSemitrailer", 0.030042, 0.040817, -0.00213), + TestCase("RigidTrailer", 0.017125, 0.072275, -0.004148), + TestCase("CoachBus", -0.000794, 0.02109, -0.00109)] + public void AirDrag_WithVehicleCategory(string parameterSet, double a1, double a2, double a3) + { + var value = DeclarationData.AirDrag.Lookup(parameterSet); + AssertHelper.AreRelativeEqual(a1, value.A1); + AssertHelper.AreRelativeEqual(a2, value.A2); + AssertHelper.AreRelativeEqual(a3, value.A3); + } + + [TestCase("TractorSemitrailer", 6.46, 0, 4.0, 7.71712257), + TestCase("TractorSemitrailer", 6.46, 60, 4.0, 7.71712257), + TestCase("TractorSemitrailer", 6.46, 75, 3.75, 7.35129203), + TestCase("TractorSemitrailer", 6.46, 100, 4.0, 7.03986404), + TestCase("TractorSemitrailer", 6.46, 62.1234, 4.0, 7.65751048), + TestCase("TractorSemitrailer", 6.46, 73.5432, 3.75, 7.37814098), + TestCase("TractorSemitrailer", 6.46, 92.8765, 4.0, 7.11234364), + TestCase("TractorSemitrailer", 6.46, 100.449, 4.0, 7.03571556), + TestCase("TractorSemitrailer", 6.46, 103, 3.6, 6.99454230), + TestCase("TractorSemitrailer", 6.46, 105, 3.9, 6.99177143), + TestCase("TractorSemitrailer", 6.46, 115, 4.0, 6.92267778), + TestCase("TractorSemitrailer", 6.46, 130, 4.0, 6.83867361),] + 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>(), + height.SI<Meter>()), + CrossWindCorrectionMode.DeclarationModeCorrection); + + var tmp = crossWindCorrectionCurve.EffectiveAirDragArea(kmph.KMPHtoMeterPerSecond()); + AssertHelper.AreRelativeEqual(expected, tmp.Value(), toleranceFactor: 1e-3); + } + + [TestCase("TractorSemitrailer", 5.8, 4.0)] + 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(7.0418009.SI<SquareMeter>(), curve[1].EffectiveCrossSectionArea); + + AssertHelper.AreRelativeEqual(65.KMPHtoMeterPerSecond(), curve[2].Velocity); + AssertHelper.AreRelativeEqual(6.90971991.SI<SquareMeter>(), curve[2].EffectiveCrossSectionArea); + + AssertHelper.AreRelativeEqual(85.KMPHtoMeterPerSecond(), curve[6].Velocity); + AssertHelper.AreRelativeEqual(6.54224222.SI<SquareMeter>(), curve[6].EffectiveCrossSectionArea); + + AssertHelper.AreRelativeEqual(100.KMPHtoMeterPerSecond(), curve[9].Velocity); + AssertHelper.AreRelativeEqual(6.37434824.SI<SquareMeter>(), curve[9].EffectiveCrossSectionArea); + + AssertHelper.AreRelativeEqual(105.KMPHtoMeterPerSecond(), curve[10].Velocity); + AssertHelper.AreRelativeEqual(6.33112792.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>(), + height.SI<Meter>()), + CrossWindCorrectionMode.DeclarationModeCorrection); + + AssertHelper.Exception<VectoException>(() => + crossWindCorrectionCurve.EffectiveAirDragArea(kmph.KMPHtoMeterPerSecond())); + } + + [TestCase] + public void CrossWindAreaCdxANotSet_DeclarationMode() + { + var airDrag = new AirdragData() { + CrossWindCorrectionMode = CrossWindCorrectionMode.DeclarationModeCorrection, + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(null, null, CrossWindCorrectionMode.DeclarationModeCorrection) + }; + + Assert.IsTrue(airDrag.IsValid(), + "In Speed Dependent (Declaration Mode) Crosswind Correction the CdxA Value can be empty."); + } + + [TestCase] + public void CrossWindAreaCdxANotSet_Other() + { + foreach (var correctionMode in EnumHelper.GetValues<CrossWindCorrectionMode>()) { + if (correctionMode == CrossWindCorrectionMode.DeclarationModeCorrection) + continue; + + var airDrag = new AirdragData { + CrossWindCorrectionMode = correctionMode, + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(null, null, correctionMode) + }; + + Assert.IsFalse(airDrag.IsValid(), + "Only in Speed Dependent (Declaration Mode) Crosswind Correction the CdxA Value can be empty."); + } + } + + [TestCase(MissionType.LongHaul, "Standard technology", 1200, 0.7), + TestCase(MissionType.RegionalDelivery, "Standard technology", 1000, 0.7), + TestCase(MissionType.UrbanDelivery, "Standard technology", 1000, 0.7), + TestCase(MissionType.MunicipalUtility, "Standard technology", 1000, 0.7), + TestCase(MissionType.Construction, "Standard technology", 1000, 0.7), + TestCase(MissionType.LongHaul, "Standard technology - LED headlights, all", 1150, 0.7), + TestCase(MissionType.RegionalDelivery, "Standard technology - LED headlights, all", 950, 0.7), + TestCase(MissionType.UrbanDelivery, "Standard technology - LED headlights, all", 950, 0.7), + TestCase(MissionType.MunicipalUtility, "Standard technology - LED headlights, all", 950, 0.7), + TestCase(MissionType.Construction, "Standard technology - LED headlights, all", 950, 0.7),] + public void AuxElectricSystemTest(MissionType mission, string technology, double value, double efficiency) + { + AssertHelper.AreRelativeEqual(value / efficiency, DeclarationData.ElectricSystem.Lookup(mission, technology)); + } + + [TestCase(MissionType.Interurban, "Standard technology"), + TestCase(MissionType.LongHaul, "Standard technology - Flux-Compensator")] + public void AuxElectricSystem_NotExistingError(MissionType mission, string technology) + { + AssertHelper.Exception<VectoException>(() => { DeclarationData.ElectricSystem.Lookup(mission, technology); }); + } + + [TestCase("only the drive shaft of the PTO - shift claw, synchronizer, sliding gearwheel", 50), + TestCase("only the drive shaft of the PTO - multi-disc clutch", 1000), + TestCase("only the drive shaft of the PTO - multi-disc clutch, oil pump", 2000), + TestCase("drive shaft and/or up to 2 gear wheels - shift claw, synchronizer, sliding gearwheel", 300), + TestCase("drive shaft and/or up to 2 gear wheels - multi-disc clutch", 1500), + TestCase("drive shaft and/or up to 2 gear wheels - multi-disc clutch, oil pump", 3000), + TestCase("drive shaft and/or more than 2 gear wheels - shift claw, synchronizer, sliding gearwheel", 600), + TestCase("drive shaft and/or more than 2 gear wheels - multi-disc clutch", 2000), + TestCase("drive shaft and/or more than 2 gear wheels - multi-disc clutch, oil pump", 4000), + TestCase("only one engaged gearwheel above oil level", 0)] + public void AuxPTOTransmissionTest(string technology, double value) + { + AssertHelper.AreRelativeEqual(value, DeclarationData.PTOTransmission.Lookup(technology)); + } + + [TestCase("Superfluid")] + public void AuxPTOTransmission_NotExistingError(string technology) + { + AssertHelper.Exception<VectoException>(() => { DeclarationData.PTOTransmission.Lookup(technology); }); + } + + [TestCase("", new[] { 618, 671, 516, 566, 1037 }), + TestCase("Crankshaft mounted - Electronically controlled visco clutch", new[] { 618, 671, 516, 566, 1037 }), + TestCase("Crankshaft mounted - Bimetallic controlled visco clutch", new[] { 818, 871, 676, 766, 1277 }), + TestCase("Crankshaft mounted - Discrete step clutch", new[] { 668, 721, 616, 616, 1157 }), + TestCase("Crankshaft mounted - On/off clutch", new[] { 718, 771, 666, 666, 1237 }), + TestCase("Belt driven or driven via transm. - Electronically controlled visco clutch", + new[] { 989, 1044, 833, 933, 1478 }), + TestCase("Belt driven or driven via transm. - Bimetallic controlled visco clutch", + new[] { 1189, 1244, 993, 1133, 1718 }), + TestCase("Belt driven or driven via transm. - Discrete step clutch", new[] { 1039, 1094, 983, 983, 1598 }), + TestCase("Belt driven or driven via transm. - On/off clutch", new[] { 1089, 1144, 1033, 1033, 1678 }), + TestCase("Hydraulic driven - Variable displacement pump", new[] { 938, 1155, 832, 917, 1872 }), + TestCase("Hydraulic driven - Constant displacement pump", new[] { 1200, 1400, 1000, 1100, 2300 }), + TestCase("Hydraulic driven - Electronically controlled", new[] { 700, 800, 600, 600, 1400 }),] + public void AuxFanTechTest(string technology, int[] expected) + { + for (var i = 0; i < _missions.Length; i++) { + var value = DeclarationData.Fan.Lookup(_missions[i], technology); + Assert.AreEqual(expected[i], value.Value(), Tolerance); + } + } + + [TestCase("Superfluid Hydraulic", MissionType.LongHaul, TestName = "AuxFanTechError( wrong tech )"), + TestCase("Hydraulic driven - Electronically controlled", MissionType.Coach, + TestName = "AuxFanTechError( wrong mission )") + ] + public void AuxFanTechError(string technology, MissionType missionType) + { + AssertHelper.Exception<VectoException>(() => DeclarationData.Fan.Lookup(missionType, technology)); + } + + [TestCase(VehicleClass.Class1, new[] { 0, 150, 150, 0, 0 }), + TestCase(VehicleClass.Class2, new[] { 200, 200, 150, 0, 0 }), + TestCase(VehicleClass.Class3, new[] { 0, 200, 150, 0, 0 }), + TestCase(VehicleClass.Class4, new[] { 350, 200, 0, 300, 0 }), + TestCase(VehicleClass.Class5, new[] { 350, 200, 0, 0, 0 }), + TestCase(VehicleClass.Class9, new[] { 350, 200, 0, 300, 0 }), + TestCase(VehicleClass.Class10, new[] { 350, 200, 0, 0, 0 }), + TestCase(VehicleClass.Class11, new[] { 350, 200, 0, 300, 200 }), + TestCase(VehicleClass.Class12, new[] { 350, 200, 0, 0, 200 }), + TestCase(VehicleClass.Class16, new[] { 0, 0, 0, 0, 200 })] + public void AuxHeatingVentilationAirConditionTest_Default(VehicleClass vehicleClass, int[] expected) + { + for (var i = 0; i < expected.Length; i++) { + if (expected[i] > 0) { + AssertHelper.AreRelativeEqual(expected[i], + DeclarationData.HeatingVentilationAirConditioning.Lookup(_missions[i], "Default", vehicleClass)); + } else { + var i1 = i; + AssertHelper.Exception<VectoException>( + () => DeclarationData.HeatingVentilationAirConditioning.Lookup(_missions[i1], "Default", vehicleClass)); + } + } + } + + [TestCase(VehicleClass.Class1, new[] { 0, 0, 0, 0, 0 }), + TestCase(VehicleClass.Class2, new[] { 0, 0, 0, 0, 0 }), + TestCase(VehicleClass.Class3, new[] { 0, 0, 0, 0, 0 }), + TestCase(VehicleClass.Class4, new[] { 0, 0, 0, 0, 0 }), + TestCase(VehicleClass.Class5, new[] { 0, 0, 0, 0, 0 }), + TestCase(VehicleClass.Class9, new[] { 0, 0, 0, 0, 0 }), + TestCase(VehicleClass.Class10, new[] { 0, 0, 0, 0, 0 }), + TestCase(VehicleClass.Class11, new[] { 0, 0, 0, 0, 0 }), + TestCase(VehicleClass.Class12, new[] { 0, 0, 0, 0, 0 }), + TestCase(VehicleClass.Class16, new[] { 0, 0, 0, 0, 0 })] + public void AuxHeatingVentilationAirConditionTest_None(VehicleClass vehicleClass, int[] expected) + { + for (var i = 0; i < expected.Length; i++) { + AssertHelper.AreRelativeEqual(expected[i], + DeclarationData.HeatingVentilationAirConditioning.Lookup(_missions[i], "None", vehicleClass)); + } + } + + [TestCase()] + public void AuxHetingVentilationAirConditionTechnologyTest() + { + var tech = DeclarationData.HeatingVentilationAirConditioning.GetTechnologies(); + Assert.AreEqual(2, tech.Length); + Assert.IsTrue(tech.Contains("Default")); + Assert.IsTrue(tech.Contains("None")); + } + + [Test, + TestCase("Small", new[] { 1400, 1300, 1200, 1200, 1300 }), + TestCase("Small + ESS", new[] { 900, 800, 800, 800, 800 }), + TestCase("Small + visco clutch", new[] { 800, 700, 700, 700, 700 }), + TestCase("Small + mech. clutch", new[] { 600, 600, 650, 650, 600 }), + TestCase("Small + ESS + AMS", new[] { 500, 400, 500, 500, 400 }), + TestCase("Small + visco clutch + AMS", new[] { 400, 300, 400, 400, 300 }), + TestCase("Small + mech. clutch + AMS", new[] { 200, 200, 350, 350, 200 }), + TestCase("Medium Supply 1-stage", new[] { 1600, 1400, 1350, 1350, 1500 }), + TestCase("Medium Supply 1-stage + ESS", new[] { 1000, 900, 900, 900, 900 }), + TestCase("Medium Supply 1-stage + visco clutch", new[] { 850, 800, 800, 800, 750 }), + TestCase("Medium Supply 1-stage + mech. clutch", new[] { 600, 550, 550, 550, 600 }), + TestCase("Medium Supply 1-stage + ESS + AMS", new[] { 600, 700, 700, 700, 500 }), + TestCase("Medium Supply 1-stage + visco clutch + AMS", new[] { 450, 600, 600, 600, 350 }), + TestCase("Medium Supply 1-stage + mech. clutch + AMS", new[] { 200, 350, 350, 350, 200 }), + TestCase("Medium Supply 2-stage", new[] { 2100, 1750, 1700, 1700, 2100 }), + TestCase("Medium Supply 2-stage + ESS", new[] { 1100, 1050, 1000, 1000, 1000 }), + TestCase("Medium Supply 2-stage + visco clutch", new[] { 1000, 850, 800, 800, 900 }), + TestCase("Medium Supply 2-stage + mech. clutch", new[] { 700, 650, 600, 600, 800 }), + TestCase("Medium Supply 2-stage + ESS + AMS", new[] { 700, 850, 800, 800, 500 }), + TestCase("Medium Supply 2-stage + visco clutch + AMS", new[] { 600, 650, 600, 600, 400 }), + TestCase("Medium Supply 2-stage + mech. clutch + AMS", new[] { 300, 450, 400, 400, 300 }), + TestCase("Large Supply", new[] { 4300, 3600, 3500, 3500, 4100 }), + TestCase("Large Supply + ESS", new[] { 1600, 1300, 1200, 1200, 1500 }), + TestCase("Large Supply + visco clutch", new[] { 1300, 1100, 1000, 1000, 1200 }), + TestCase("Large Supply + mech. clutch", new[] { 800, 800, 700, 700, 900 }), + TestCase("Large Supply + ESS + AMS", new[] { 1100, 1000, 1000, 1000, 1000 }), + TestCase("Large Supply + visco clutch + AMS", new[] { 800, 800, 800, 800, 700 }), + TestCase("Large Supply + mech. clutch + AMS", new[] { 300, 500, 500, 500, 400 }), + TestCase("Vacuum pump", new[] { 190, 160, 130, 130, 130 }), + ] + public void AuxPneumaticSystemTest(string technology, int[] expected) + { + for (var i = 0; i < _missions.Length; i++) { + var value = DeclarationData.PneumaticSystem.Lookup(_missions[i], technology); + AssertHelper.AreRelativeEqual(expected[i], value); + } + } + + [ + TestCase(MissionType.LongHaul, VehicleClass.Class2, 370, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class4, 610, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class5, 720, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class9, 720, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class10, 570, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class11, 720, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class12, 570, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class1, 280, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 340, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class3, 370, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class4, 570, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class5, 670, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class9, 590, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class10, 570, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class11, 590, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class12, 570, "Fixed displacement", null, null, null), + TestCase(MissionType.UrbanDelivery, VehicleClass.Class1, 270, "Fixed displacement", null, null, null), + TestCase(MissionType.UrbanDelivery, VehicleClass.Class2, 310, "Fixed displacement", null, null, null), + TestCase(MissionType.UrbanDelivery, VehicleClass.Class3, 350, "Fixed displacement", null, null, null), + TestCase(MissionType.UrbanDelivery, VehicleClass.Class5, 620, "Fixed displacement", null, null, null), + TestCase(MissionType.MunicipalUtility, VehicleClass.Class4, 510, "Fixed displacement", null, null, null), + TestCase(MissionType.MunicipalUtility, VehicleClass.Class9, 510, "Fixed displacement", null, null, null), + TestCase(MissionType.MunicipalUtility, VehicleClass.Class11, 510, "Fixed displacement", null, null, null), + TestCase(MissionType.Construction, VehicleClass.Class11, 770, "Fixed displacement", null, null, null), + TestCase(MissionType.Construction, VehicleClass.Class12, 770, "Fixed displacement", null, null, null), + TestCase(MissionType.Construction, VehicleClass.Class16, 770, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 325.5, "Fixed displacement with elec. control", null, + null, + null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 289, "Dual displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 255, "Variable displacement mech. controlled", null, + null, + null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 204, "Variable displacement elec. controlled", null, + null, + null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 92.8571, "Electric", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 665, "Fixed displacement", "Fixed displacement", null, + null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 1295, "Fixed displacement", "Fixed displacement", + "Fixed displacement", "Fixed displacement"), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 1021.5, "Dual displacement", + "Variable displacement mech. controlled", "Fixed displacement with elec. control", + "Variable displacement elec. controlled"), + ] + public void Aux_SteeringPumpLookupValues(MissionType mission, VehicleClass hdvClass, double expected, string axle1, + string axle2, string axle3, string axle4) + { + // mk remark: made the test call with 4 axle params, so that the test name is clear in the test explorer. + AssertHelper.AreRelativeEqual(expected, + DeclarationData.SteeringPump.Lookup(mission, hdvClass, + new[] { axle1, axle2, axle3, axle4 }.TakeWhile(a => a != null).ToArray())); + } + + [TestCase(MissionType.LongHaul, VehicleClass.Class1, "Dual displacement", + TestName = "Aux_SteeringPumpLookupFail( No Value )"), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, "Super displacement", + TestName = "Aux_SteeringPumpLookupFail( Wrong Tech )"), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, "Dual displacement", "Dual displacement", + "Dual displacement", "Dual displacement", "Dual displacement", TestName = "Aux_SteeringPumpLookupFail( >4 Techs )"), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, TestName = "Aux_SteeringPumpLookupFail( Null Techs )"), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, new string[0], + TestName = "Aux_SteeringPumpLookupFail( 0 Techs )"), + ] + public void Aux_SteeringPumpLookupFail(MissionType mission, VehicleClass hdvClass, params string[] tech) + { + AssertHelper.Exception<VectoException>(() => DeclarationData.SteeringPump.Lookup(mission, hdvClass, tech)); + } + + [ + TestCase(0), + TestCase(1000), + TestCase(3500), + TestCase(7499) + ] + public void SegmentWeightOutOfRange4X2(double weight) + { + AssertHelper.Exception<VectoException>(() => + DeclarationData.Segments.Lookup( + VehicleCategory.RigidTruck, + AxleConfiguration.AxleConfig_4x2, + weight.SI<Kilogram>(), + 0.SI<Kilogram>()), + "Gross vehicle mass must be greater than 7.5 tons"); + } + + [ + TestCase(0), + TestCase(1000), + TestCase(3500), + TestCase(7499) + ] + public void SegmentWeightOutOfRange4X4(double weight) + { + AssertHelper.Exception<VectoException>(() => + DeclarationData.Segments.Lookup( + VehicleCategory.RigidTruck, + AxleConfiguration.AxleConfig_4x4, + weight.SI<Kilogram>(), + 0.SI<Kilogram>()), + "Gross vehicle mass must be greater than 7.5 tons"); + } + + [Test, + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 7500, 0, VehicleClass.Class1), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 7500, 0, VehicleClass.Class1), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 10001, 0, VehicleClass.Class2), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 10001, 0, VehicleClass.Class2), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12001, 0, VehicleClass.Class3), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 12001, 0, VehicleClass.Class3), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16001, 0, VehicleClass.Class4), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 99000, 0, VehicleClass.Class4), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16001, 0, VehicleClass.Class5), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 99000, 0, VehicleClass.Class5), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 7500, 0, VehicleClass.Class9), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 16000, 0, VehicleClass.Class9), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class9), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 99000, 0, VehicleClass.Class9), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 7500, 0, VehicleClass.Class10), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 16000, 0, VehicleClass.Class10), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class10), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 99000, 0, VehicleClass.Class10), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 7500, 0, VehicleClass.Class11), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 40000, 0, VehicleClass.Class11), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 7500, 0, VehicleClass.Class12), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 99000, 0, VehicleClass.Class12), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 7500, 0, VehicleClass.Class16), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 99000, 0, VehicleClass.Class16) + ] + public void SegmentLookupTest(VehicleCategory category, AxleConfiguration axleConfiguration, double grossWeight, + double curbWeight, VehicleClass expectedClass) + { + var segment = DeclarationData.Segments.Lookup(category, axleConfiguration, grossWeight.SI<Kilogram>(), + curbWeight.SI<Kilogram>()); + Assert.AreEqual(expectedClass, segment.VehicleClass); + } + + [TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 7500, 0, VehicleClass.Class1, 85), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 10001, 0, VehicleClass.Class2, 85), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12001, 0, VehicleClass.Class3, 85), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16001, 0, VehicleClass.Class4, 85), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16001, 0, VehicleClass.Class5, 85), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 7500, 0, VehicleClass.Class9, 85), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 7500, 0, VehicleClass.Class10, 85), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 7500, 0, VehicleClass.Class11, 85), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 7500, 0, VehicleClass.Class12, 85), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 7500, 0, VehicleClass.Class16, 85), + ] + public void SegmentDesignSpeedTest(VehicleCategory category, AxleConfiguration axleConfiguration, double grossWeight, + double curbWeight, VehicleClass expectedClass, double speed) + { + var segment = DeclarationData.Segments.Lookup(category, axleConfiguration, grossWeight.SI<Kilogram>(), + curbWeight.SI<Kilogram>()); + + Assert.AreEqual(speed.KMPHtoMeterPerSecond(), segment.DesignSpeed); + } + + [Test, + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1, 1600, null, + TestName = "SegmentLookupBodyWeight Class1 Rigid"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1, 1600, null, + TestName = "SegmentLookupBodyWeight Class1 Tractor"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, 1900, 3400, + TestName = "SegmentLookupBodyWeight Class2 Rigid"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, 1900, 3400, + TestName = "SegmentLookupBodyWeight Class2 Tractor"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, 2000, null, + TestName = "SegmentLookupBodyWeight Class3 Rigid"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, 2000, null, + TestName = "SegmentLookupBodyWeight Class3 Tractor"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class4, 2100, 5400, + TestName = "SegmentLookupBodyWeight Class4"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class5, null, 7500, + TestName = "SegmentLookupBodyWeight Class5"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class9, 2200, 5400, + TestName = "SegmentLookupBodyWeight Class9"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class10, null, 7500, + TestName = "SegmentLookupBodyWeight Class10"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 12000, 0, VehicleClass.Class11, 2200, 5400, + TestName = "SegmentLookupBodyWeight Class11"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 12000, 0, VehicleClass.Class12, null, 7500, + TestName = "SegmentLookupBodyWeight Class12"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 12000, 0, VehicleClass.Class16, null, null, + TestName = "SegmentLookupBodyWeight Class16")] + public void SegmentLookupBodyTest(VehicleCategory category, AxleConfiguration axleConfiguration, double grossWeight, + double curbWeight, VehicleClass expectedClass, int? expectedBodyWeight, int? expectedTrailerWeight) + { + var segment = DeclarationData.Segments.Lookup(category, axleConfiguration, grossWeight.SI<Kilogram>(), + curbWeight.SI<Kilogram>()); + Assert.AreEqual(expectedClass, segment.VehicleClass); + + if (expectedBodyWeight.HasValue) { + Assert.AreEqual(expectedBodyWeight, segment.Missions[0].BodyCurbWeight.Value()); + } + if (expectedTrailerWeight.HasValue) { + var trailerMission = segment.Missions.Where(m => m.Trailer.Count > 0).ToList(); + if (trailerMission.Count > 0) { + Assert.AreEqual(expectedTrailerWeight, trailerMission.First().Trailer.First().TrailerCurbWeight.Value()); + } + } + } + + [Test, + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1, 3.6, + TestName = "SegmentLookupHeight Class1 Rigid"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 10000, 0, VehicleClass.Class1, 3.6, + TestName = "SegmentLookupHeight Class1 Tractor"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, 3.75, + TestName = "SegmentLookupHeight Class2 Rigid"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, 3.75, + TestName = "SegmentLookupHeight Class2 Tractor"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, 3.9, + TestName = "SegmentLookupHeight Class3 Rigid"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, 3.9, + TestName = "SegmentLookupHeight Class3 Tractor"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class4, 4.0, + TestName = "SegmentLookupHeight Class4"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class5, 4.0, + TestName = "SegmentLookupHeight Class5"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 10000, 0, VehicleClass.Class9, 3.6, + TestName = "SegmentLookupHeight Class9 - 1"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 12000, 0, VehicleClass.Class9, 3.75, + TestName = "SegmentLookupHeight Class9 - 2"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 16000, 0, VehicleClass.Class9, 3.9, + TestName = "SegmentLookupHeight Class9 - 3"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 18000, 0, VehicleClass.Class9, 4.0, + TestName = "SegmentLookupHeight Class9 - 4"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class9, 4.0, + TestName = "SegmentLookupHeight Class9 - other"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 40000, 0, VehicleClass.Class10, 4.0, + TestName = "SegmentLookupHeight Class10"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 12000, 0, VehicleClass.Class11, 4.0, + TestName = "SegmentLookupHeight Class11"), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 12000, 0, VehicleClass.Class12, 4.0, + TestName = "SegmentLookupHeight Class12"), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 12000, 0, VehicleClass.Class16, 3.6, + TestName = "SegmentLookupHeight Class16")] + public void SegmentLookupHeightTest(VehicleCategory category, AxleConfiguration axleConfiguration, double grossWeight, + double curbWeight, VehicleClass expectedClass, double expectedHeight) + { + var segment = DeclarationData.Segments.Lookup(category, axleConfiguration, grossWeight.SI<Kilogram>(), + curbWeight.SI<Kilogram>()); + Assert.AreEqual(expectedClass, segment.VehicleClass); + AssertHelper.AreRelativeEqual(expectedHeight, segment.VehicleHeight); + } + + [Test, + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 7500, 0, VehicleClass.Class1, + new[] { 36.5, 36.5 }), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 7500, 0, VehicleClass.Class1, + new[] { 36.5, 36.5 }), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, + new[] { 85.0, 45.2, 45.2 }), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 12000, 0, VehicleClass.Class2, + new[] { 85.0, 45.2, 45.2 }), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, + new[] { 47.7, 47.7 }), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 16000, 0, VehicleClass.Class3, + new[] { 47.7, 47.7 }), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class4, + new[] { 98.9, 49.4, 49.4 }), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_4x2, 18000, 0, VehicleClass.Class5, + new[] { 91.0, 140.5, 91.0, 140.5 }), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x2, 16000, 0, VehicleClass.Class9, + new[] { 101.4, 142.9, 51.9, 142.9, 51.9 }), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x2, 16000, 0, VehicleClass.Class10, + new[] { 91.0, 140.5, 91.0, 140.5 }), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_6x4, 40000, 0, VehicleClass.Class11, + new[] { 101.4, 142.9, 51.9, 142.9, 51.9, 51.9 }), + TestCase(VehicleCategory.Tractor, AxleConfiguration.AxleConfig_6x4, 99000, 0, VehicleClass.Class12, + new[] { 91.0, 140.5, 91.0, 140.5, 91.0 }), + TestCase(VehicleCategory.RigidTruck, AxleConfiguration.AxleConfig_8x4, 99000, 0, VehicleClass.Class16, + new[] { 0.0 }) + ] + public void SegmentLookupCargoVolumeTest(VehicleCategory category, AxleConfiguration axleConfiguration, + double grossWeight, + double curbWeight, VehicleClass expectedClass, double[] expectedCargoVolume) + { + var segment = DeclarationData.Segments.Lookup(category, axleConfiguration, grossWeight.SI<Kilogram>(), + curbWeight.SI<Kilogram>()); + Assert.AreEqual(expectedClass, segment.VehicleClass); + Assert.AreEqual(expectedCargoVolume.Length, segment.Missions.Length); + for (var i = 0; i < expectedCargoVolume.Length; i++) { + Assert.AreEqual(expectedCargoVolume[i], segment.Missions[i].TotalCargoVolume.Value()); + } + } + + /// <summary> + /// trailer in longhaul, always pc formula + /// </summary> + [TestCase] + public void Segment2Test() + { + var vehicleData = new { + VehicleCategory = VehicleCategory.RigidTruck, + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + GrossVehicleMassRating = 11900.SI<Kilogram>(), + CurbWeight = 5850.SI<Kilogram>() + }; + + var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, + vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); + + Assert.AreEqual(VehicleClass.Class2, segment.VehicleClass); + + var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); + TestAcceleration(data); + + Assert.AreEqual(3, segment.Missions.Length); + + AssertMission(segment.Missions[0], + vehicleData: vehicleData, + missionType: MissionType.LongHaul, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.225, 0.325 }, + trailerAxleWeightDistribution: new[] { 0.45 }, + trailerAxleCount: new[] { 2 }, + bodyCurbWeight: 1900, + trailerCurbWeight: new[] { 3400.0 }, + trailerType: new[] { TrailerType.T1 }, + lowLoad: 1306.8235, + refLoad: 9813.2353, + trailerGrossVehicleWeight: new[] { 10500.0 }, + deltaCdA: 1.3, + maxLoad: 11250); + + AssertMission(segment.Missions[1], + vehicleData: vehicleData, + missionType: MissionType.RegionalDelivery, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.45, 0.55 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 1900, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 596.8235, + refLoad: 2984.1176, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 4150); + + AssertMission(segment.Missions[2], + vehicleData: vehicleData, + missionType: MissionType.UrbanDelivery, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.45, 0.55 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 1900, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 596.8235, + refLoad: 2984.1176, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 4150); + } + + /// <summary> + /// normal pc formula, no trailer + /// </summary> + [TestCase] + public void Segment3Test() + { + var vehicleData = new { + VehicleCategory = VehicleCategory.RigidTruck, + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + GrossVehicleMassRating = 14000.SI<Kilogram>(), + CurbWeight = 5850.SI<Kilogram>() + }; + + var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, + vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); + + Assert.AreEqual(VehicleClass.Class3, segment.VehicleClass); + + Assert.AreEqual(2, segment.Missions.Length); + + AssertMission(segment.Missions[0], + vehicleData: vehicleData, + missionType: MissionType.RegionalDelivery, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.4, 0.6 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 2000, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 762.3529, + refLoad: 3811.7647, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 6150); + + AssertMission(segment.Missions[1], + vehicleData: vehicleData, + missionType: MissionType.UrbanDelivery, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.4, 0.6 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 2000, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 762.3529, + refLoad: 3811.7647, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 6150); + } + + /// <summary> + /// fixed reference weight, trailer only in longhaul + /// </summary> + [TestCase] + public void Segment4Test() + { + var vehicleData = new { + VehicleCategory = VehicleCategory.RigidTruck, + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + GrossVehicleMassRating = 18000.SI<Kilogram>(), + CurbWeight = 7500.SI<Kilogram>() + }; + + var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, + vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); + + Assert.AreEqual(VehicleClass.Class4, segment.VehicleClass); + + var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); + TestAcceleration(data); + + Assert.AreEqual(3, segment.Missions.Length); + + AssertMission(segment.Missions[0], + vehicleData: vehicleData, + missionType: MissionType.LongHaul, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.2, 0.3 }, + trailerAxleWeightDistribution: new[] { 0.5 }, + trailerAxleCount: new[] { 2 }, + bodyCurbWeight: 2100, + trailerCurbWeight: new[] { 5400.0 }, + trailerType: new[] { TrailerType.T2 }, + lowLoad: 1900, + refLoad: 14000, + trailerGrossVehicleWeight: new[] { 18000.0 }, + deltaCdA: 1.5, + maxLoad: 21000); + + AssertMission(segment.Missions[1], + vehicleData: vehicleData, + missionType: MissionType.RegionalDelivery, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.45, 0.55 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 2100, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 900, + refLoad: 4400, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 8400); + + AssertMission(segment.Missions[2], + vehicleData: vehicleData, + missionType: MissionType.MunicipalUtility, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.45, 0.55 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 2100, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 600, + refLoad: 3000, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 8400); + } + + /// <summary> + /// Segment 5: fixed reference weight, trailer always used + /// </summary> + [TestCase] + public void Segment5Test() + { + var vehicleData = new { + VehicleCategory = VehicleCategory.Tractor, + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + GrossVehicleMassRating = 18000.SI<Kilogram>(), + CurbWeight = 7500.SI<Kilogram>() + }; + + var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, + vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); + + Assert.AreEqual(VehicleClass.Class5, segment.VehicleClass); + + var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); + TestAcceleration(data); + + Assert.AreEqual(4, segment.Missions.Length); + + AssertMission(segment.Missions[0], + vehicleData: vehicleData, + missionType: MissionType.LongHaul, + cosswindCorrection: "TractorSemitrailer", + axleWeightDistribution: new[] { 0.2, 0.25 }, + trailerAxleWeightDistribution: new[] { 0.55 }, + trailerAxleCount: new[] { 3 }, bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0 }, + trailerType: new[] { TrailerType.ST1 }, + lowLoad: 2600, + refLoad: 19300, + trailerGrossVehicleWeight: new[] { 24000.0 }, + deltaCdA: 0, + maxLoad: 25000); + + AssertMission(segment.Missions[1], + vehicleData: vehicleData, + missionType: MissionType.LongHaulEMS, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.15, 0.2 }, + trailerAxleWeightDistribution: new[] { 0.40, 0.25 }, + trailerAxleCount: new[] { 3, 2 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0, 5400 }, + trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, + lowLoad: 3500, + refLoad: 26500, + trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, + deltaCdA: 1.5, + maxLoad: 39600, + ems: true); + + AssertMission(segment.Missions[2], + vehicleData: vehicleData, + missionType: MissionType.RegionalDelivery, + cosswindCorrection: "TractorSemitrailer", + axleWeightDistribution: new[] { 0.25, 0.25 }, + trailerAxleWeightDistribution: new[] { 0.5 }, + trailerAxleCount: new[] { 3 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0 }, + trailerType: new[] { TrailerType.ST1 }, + lowLoad: 2600, + refLoad: 12900, + trailerGrossVehicleWeight: new[] { 24000.0 }, + deltaCdA: 0, maxLoad: 25000); + + AssertMission(segment.Missions[3], + vehicleData: vehicleData, + missionType: MissionType.RegionalDeliveryEMS, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.175, 0.25 }, + trailerAxleWeightDistribution: new[] { 0.35, 0.225 }, + trailerAxleCount: new[] { 3, 2 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0, 5400 }, + trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, + lowLoad: 3500, + refLoad: 17500, + trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, + deltaCdA: 1.5, + maxLoad: 39600, + ems: true); + } + + /// <summary> + /// Segment 9: fixed reference weight, trailer always used + /// </summary> + [TestCase] + public void Segment9Test() + { + var vehicleData = new { + VehicleCategory = VehicleCategory.RigidTruck, + AxleConfiguration = AxleConfiguration.AxleConfig_6x2, + GrossVehicleMassRating = 24000.SI<Kilogram>(), + CurbWeight = 7500.SI<Kilogram>() + }; + + var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, + vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); + + Assert.AreEqual(VehicleClass.Class9, segment.VehicleClass); + + var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); + TestAcceleration(data); + + Assert.AreEqual(5, segment.Missions.Length); + + AssertMission(segment.Missions[0], + vehicleData: vehicleData, + missionType: MissionType.LongHaul, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.2, 0.3, 0.15 }, + trailerAxleWeightDistribution: new[] { 0.35 }, + trailerAxleCount: new[] { 2 }, + bodyCurbWeight: 2200, + trailerCurbWeight: new[] { 5400.0 }, + trailerType: new[] { TrailerType.T2 }, + lowLoad: 2600, + refLoad: 19300, + trailerGrossVehicleWeight: new[] { 18000.0 }, + deltaCdA: 1.5, + maxLoad: 24900); + + AssertMission(segment.Missions[1], + vehicleData: vehicleData, + missionType: MissionType.LongHaulEMS, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.15, 0.2, 0.1 }, + trailerAxleWeightDistribution: new[] { 0.225, 0.325 }, + trailerAxleCount: new[] { 2, 3 }, + bodyCurbWeight: 2200, + trailerCurbWeight: new[] { 2500, 7500.0 }, + trailerType: new[] { TrailerType.Dolly, TrailerType.ST1 }, + lowLoad: 3500, + refLoad: 26500, + trailerGrossVehicleWeight: new[] { 12000.0, 24000 }, + deltaCdA: 2.1, + maxLoad: 40300, + ems: true); + + AssertMission(segment.Missions[2], + vehicleData: vehicleData, + missionType: MissionType.RegionalDelivery, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.35, 0.4, 0.25 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 2200, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 1400, + refLoad: 7100, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 14300); + + AssertMission(segment.Missions[3], + vehicleData: vehicleData, + missionType: MissionType.RegionalDeliveryEMS, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.175, 0.2, 0.1 }, + trailerAxleWeightDistribution: new[] { 0.225, 0.3 }, + trailerAxleCount: new[] { 2, 3 }, + bodyCurbWeight: 2200, + trailerCurbWeight: new[] { 2500, 7500.0 }, + trailerType: new[] { TrailerType.Dolly, TrailerType.ST1 }, + lowLoad: 3500, + refLoad: 17500, + trailerGrossVehicleWeight: new[] { 12000.0, 24000 }, + deltaCdA: 2.1, + maxLoad: 40300, + ems: true); + + AssertMission(segment.Missions[4], + vehicleData: vehicleData, + missionType: MissionType.MunicipalUtility, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.35, 0.4, 0.25 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 2200, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 1200, + refLoad: 6000, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 14300); + } + + /// <summary> + /// Segment 10: fixed reference weight, trailer always used + /// </summary> + [TestCase] + public void Segment10Test() + { + var vehicleData = new { + VehicleCategory = VehicleCategory.Tractor, + AxleConfiguration = AxleConfiguration.AxleConfig_6x2, + GrossVehicleMassRating = 24000.SI<Kilogram>(), + CurbWeight = 7500.SI<Kilogram>() + }; + + var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, + vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); + + Assert.AreEqual(VehicleClass.Class10, segment.VehicleClass); + + var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); + TestAcceleration(data); + + Assert.AreEqual(4, segment.Missions.Length); + + AssertMission(segment.Missions[0], + vehicleData: vehicleData, + missionType: MissionType.LongHaul, + cosswindCorrection: "TractorSemitrailer", + axleWeightDistribution: new[] { 0.15, 0.1, 0.2 }, + trailerAxleWeightDistribution: new[] { 0.55 }, + trailerAxleCount: new[] { 3 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0 }, + trailerType: new[] { TrailerType.ST1 }, + lowLoad: 2600, + refLoad: 19300, + trailerGrossVehicleWeight: new[] { 24000.0 }, + deltaCdA: 0, + maxLoad: 25000); + + AssertMission(segment.Missions[1], + vehicleData: vehicleData, + missionType: MissionType.LongHaulEMS, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.125, 0.15, 0.1 }, + trailerAxleWeightDistribution: new[] { 0.375, 0.25 }, + trailerAxleCount: new[] { 3, 2 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0, 5400 }, + trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, + lowLoad: 3500, + refLoad: 26500, + trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, + deltaCdA: 1.5, + maxLoad: 39600, + ems: true); + + AssertMission(segment.Missions[2], + vehicleData: vehicleData, + missionType: MissionType.RegionalDelivery, + cosswindCorrection: "TractorSemitrailer", + axleWeightDistribution: new[] { 0.2, 0.1, 0.2 }, + trailerAxleWeightDistribution: new[] { 0.5 }, + trailerAxleCount: new[] { 3 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0 }, + trailerType: new[] { TrailerType.ST1 }, + lowLoad: 2600, + refLoad: 12900, + trailerGrossVehicleWeight: new[] { 24000.0 }, + deltaCdA: 0, + maxLoad: 25000); + + AssertMission(segment.Missions[3], + vehicleData: vehicleData, + missionType: MissionType.RegionalDeliveryEMS, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.15, 0.15, 0.1 }, + trailerAxleWeightDistribution: new[] { 0.35, 0.25 }, + trailerAxleCount: new[] { 3, 2 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0, 5400 }, + trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, + lowLoad: 3500, + refLoad: 17500, + trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, + deltaCdA: 1.5, + maxLoad: 39600, + ems: true); + } + + /// <summary> + /// Segment 11: fixed reference weight, trailer always used + /// </summary> + [TestCase] + public void Segment11Test() + { + var vehicleData = new { + VehicleCategory = VehicleCategory.RigidTruck, + AxleConfiguration = AxleConfiguration.AxleConfig_6x4, + GrossVehicleMassRating = 24000.SI<Kilogram>(), + CurbWeight = 7500.SI<Kilogram>() + }; + + var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, + vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); + + Assert.AreEqual(VehicleClass.Class11, segment.VehicleClass); + + var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); + TestAcceleration(data); + + Assert.AreEqual(6, segment.Missions.Length); + + AssertMission(segment.Missions[0], + vehicleData: vehicleData, + missionType: MissionType.LongHaul, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.2, 0.225, 0.225 }, + trailerAxleWeightDistribution: new[] { 0.35 }, + trailerAxleCount: new[] { 2 }, + bodyCurbWeight: 2200, + trailerCurbWeight: new[] { 5400.0 }, + trailerType: new[] { TrailerType.T2 }, + lowLoad: 2600, + refLoad: 19300, + trailerGrossVehicleWeight: new[] { 18000.0 }, + deltaCdA: 1.5, + maxLoad: 24900); + + AssertMission(segment.Missions[1], + vehicleData: vehicleData, + missionType: MissionType.LongHaulEMS, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.15, 0.2, 0.1 }, + trailerAxleWeightDistribution: new[] { 0.225, 0.325 }, + trailerAxleCount: new[] { 2, 3 }, + bodyCurbWeight: 2200, + trailerCurbWeight: new[] { 2500, 7500.0 }, + trailerType: new[] { TrailerType.Dolly, TrailerType.ST1 }, + lowLoad: 3500, + refLoad: 26500, + trailerGrossVehicleWeight: new[] { 12000.0, 24000 }, + deltaCdA: 2.1, + maxLoad: 40300, + ems: true); + + AssertMission(segment.Missions[2], + vehicleData: vehicleData, + missionType: MissionType.RegionalDelivery, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.35, 0.35, 0.3 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, bodyCurbWeight: 2200, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 1400, + refLoad: 7100, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 14300); + + AssertMission(segment.Missions[3], + vehicleData: vehicleData, + missionType: MissionType.RegionalDeliveryEMS, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.175, 0.2, 0.1 }, + trailerAxleWeightDistribution: new[] { 0.225, 0.3 }, + trailerAxleCount: new[] { 2, 3 }, + bodyCurbWeight: 2200, + trailerCurbWeight: new[] { 2500, 7500.0 }, + trailerType: new[] { TrailerType.Dolly, TrailerType.ST1 }, + lowLoad: 3500, + refLoad: 17500, + trailerGrossVehicleWeight: new[] { 12000.0, 24000 }, + deltaCdA: 2.1, + maxLoad: 40300, + ems: true); + + AssertMission(segment.Missions[4], + vehicleData: vehicleData, + missionType: MissionType.MunicipalUtility, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.35, 0.35, 0.3 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 2200, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 1200, + refLoad: 6000, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 14300); + + AssertMission(segment.Missions[5], + vehicleData: vehicleData, + missionType: MissionType.Construction, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.35, 0.35, 0.3 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 2200, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 1400, + refLoad: 7100, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 14300); + } + + /// <summary> + /// Segment 10: fixed reference weight, trailer always used + /// </summary> + [TestCase] + public void Segment12Test() + { + var vehicleData = new { + VehicleCategory = VehicleCategory.Tractor, + AxleConfiguration = AxleConfiguration.AxleConfig_6x4, + GrossVehicleMassRating = 24000.SI<Kilogram>(), + CurbWeight = 7500.SI<Kilogram>() + }; + + var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, + vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); + + Assert.AreEqual(VehicleClass.Class12, segment.VehicleClass); + + var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); + TestAcceleration(data); + + Assert.AreEqual(5, segment.Missions.Length); + + AssertMission(segment.Missions[0], + vehicleData: vehicleData, + missionType: MissionType.LongHaul, + cosswindCorrection: "TractorSemitrailer", + axleWeightDistribution: new[] { 0.15, 0.15, 0.15 }, + trailerAxleWeightDistribution: new[] { 0.55 }, + trailerAxleCount: new[] { 3 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0 }, + trailerType: new[] { TrailerType.ST1 }, + lowLoad: 2600, + refLoad: 19300, + trailerGrossVehicleWeight: new[] { 24000.0 }, + deltaCdA: 0, + maxLoad: 25000); + + AssertMission(segment.Missions[1], + vehicleData: vehicleData, + missionType: MissionType.LongHaulEMS, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.125, 0.15, 0.1 }, + trailerAxleWeightDistribution: new[] { 0.375, 0.25 }, + trailerAxleCount: new[] { 3, 2 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0, 5400 }, + trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, + lowLoad: 3500, + refLoad: 26500, + trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, + deltaCdA: 1.5, + maxLoad: 39600, + ems: true); + + AssertMission(segment.Missions[2], + vehicleData: vehicleData, + missionType: MissionType.RegionalDelivery, + cosswindCorrection: "TractorSemitrailer", + axleWeightDistribution: new[] { 0.2, 0.15, 0.15 }, + trailerAxleWeightDistribution: new[] { 0.5 }, + trailerAxleCount: new[] { 3 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0 }, + trailerType: new[] { TrailerType.ST1 }, + lowLoad: 2600, + refLoad: 12900, + trailerGrossVehicleWeight: new[] { 24000.0 }, + deltaCdA: 0, + maxLoad: 25000); + + AssertMission(segment.Missions[3], + vehicleData: vehicleData, + missionType: MissionType.RegionalDeliveryEMS, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.15, 0.15, 0.1 }, + trailerAxleWeightDistribution: new[] { 0.35, 0.25 }, + trailerAxleCount: new[] { 3, 2 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0, 5400 }, + trailerType: new[] { TrailerType.ST1, TrailerType.T2 }, + lowLoad: 3500, + refLoad: 17500, + trailerGrossVehicleWeight: new[] { 24000.0, 18000 }, + deltaCdA: 1.5, + maxLoad: 39600, + ems: true); + + AssertMission(segment.Missions[4], + vehicleData: vehicleData, + missionType: MissionType.Construction, + cosswindCorrection: "TractorSemitrailer", + axleWeightDistribution: new[] { 0.2, 0.15, 0.15 }, + trailerAxleWeightDistribution: new[] { 0.5 }, + trailerAxleCount: new[] { 3 }, + bodyCurbWeight: 0, + trailerCurbWeight: new[] { 7500.0 }, + trailerType: new[] { TrailerType.ST1 }, + lowLoad: 2600, + refLoad: 12900, + trailerGrossVehicleWeight: new[] { 24000.0 }, + deltaCdA: 0, + maxLoad: 25000, + ems: false); + } + + /// <summary> + /// Segment 9: fixed reference weight, trailer always used + /// </summary> + [TestCase] + public void Segment16Test() + { + var vehicleData = new { + VehicleCategory = VehicleCategory.RigidTruck, + AxleConfiguration = AxleConfiguration.AxleConfig_8x4, + GrossVehicleMassRating = 36000.SI<Kilogram>(), + CurbWeight = 7500.SI<Kilogram>() + }; + + var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, + vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); + + Assert.AreEqual(VehicleClass.Class16, segment.VehicleClass); + + var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); + TestAcceleration(data); + + Assert.AreEqual(1, segment.Missions.Length); + + AssertMission(segment.Missions[0], + vehicleData: vehicleData, + missionType: MissionType.Construction, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.25, 0.25, 0.25, 0.25 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 0, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 2600, + refLoad: 12900, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 28500); + } + + public static void AssertMission(Mission m, dynamic vehicleData, MissionType missionType, string cosswindCorrection, + double[] axleWeightDistribution, double[] trailerAxleWeightDistribution, int[] trailerAxleCount, + double bodyCurbWeight, double[] trailerCurbWeight, TrailerType[] trailerType, double lowLoad, double refLoad, + double maxLoad, double[] trailerGrossVehicleWeight, double deltaCdA, bool ems = false) + { + Assert.AreEqual(missionType, m.MissionType); + Assert.AreEqual(cosswindCorrection, m.CrossWindCorrectionParameters); + CollectionAssert.AreEqual(axleWeightDistribution, m.AxleWeightDistribution, + "Axle distribution not equal.\nexpected: {0}\nactual: {1}", string.Join(",", axleWeightDistribution), + string.Join(",", m.AxleWeightDistribution)); + CollectionAssert.AreEqual(trailerAxleWeightDistribution, m.Trailer.Select(t => t.TrailerAxleWeightShare), + "Trailer axle distribution not equal.\nexpected: {0}\nactual: {1}", string.Join(",", trailerAxleWeightDistribution), + string.Join(",", m.Trailer.Select(t => t.TrailerAxleWeightShare))); + Assert.AreEqual(bodyCurbWeight.SI<Kilogram>(), m.BodyCurbWeight); + CollectionAssert.AreEqual(trailerCurbWeight, m.Trailer.Select(t => t.TrailerCurbWeight.Value())); + CollectionAssert.AreEqual(trailerType, m.Trailer.Select(t => t.TrailerType)); + CollectionAssert.AreEqual(trailerAxleCount, m.Trailer.Select(t => t.TrailerWheels.Count)); + Assert.IsNotNull(m.CycleFile); + Assert.IsTrue(!string.IsNullOrEmpty(new StreamReader(m.CycleFile).ReadLine())); + Assert.AreEqual(0.SI<Kilogram>(), m.MinLoad); + AssertHelper.AreRelativeEqual(lowLoad, m.LowLoad); + AssertHelper.AreRelativeEqual(refLoad, m.RefLoad); + Assert.AreEqual(maxLoad.SI<Kilogram>(), m.MaxLoad); + CollectionAssert.AreEqual(trailerGrossVehicleWeight, m.Trailer.Select(t => t.TrailerGrossVehicleWeight.Value())); + Assert.AreEqual( + VectoMath.Min( + vehicleData.GrossVehicleMassRating + + m.Trailer.Sum(t => t.TrailerGrossVehicleWeight).DefaultIfNull(0), + ems ? 60000.SI<Kilogram>() : 40000.SI<Kilogram>()) + - m.BodyCurbWeight - m.Trailer.Sum(t => t.TrailerCurbWeight).DefaultIfNull(0) - + vehicleData.CurbWeight, + m.MaxLoad); + Assert.AreEqual(deltaCdA.SI<SquareMeter>(), + m.Trailer.Sum(t => t.DeltaCdA).DefaultIfNull(0)); + } + + private static void EqualAcceleration(AccelerationCurveData data, double velocity, double acceleration, + double deceleration) + { + var entry = data.Lookup(velocity.KMPHtoMeterPerSecond()); + Assert.AreEqual(entry.Acceleration.Value(), acceleration, Tolerance); + Assert.AreEqual(entry.Deceleration.Value(), deceleration, Tolerance); + } + + private static void TestAcceleration(AccelerationCurveData data) + { + // FIXED POINTS + EqualAcceleration(data, 0, 1, -1); + EqualAcceleration(data, 25, 1, -1); + EqualAcceleration(data, 50, 0.642857143, -1); + EqualAcceleration(data, 60, 0.5, -0.5); + EqualAcceleration(data, 120, 0.5, -0.5); + + // INTERPOLATED POINTS + EqualAcceleration(data, 20, 1, -1); + EqualAcceleration(data, 40, 0.785714286, -1); + EqualAcceleration(data, 55, 0.571428572, -0.75); + EqualAcceleration(data, 80, 0.5, -0.5); + EqualAcceleration(data, 100, 0.5, -0.5); + + // EXTRAPOLATE + EqualAcceleration(data, -20, 1, -1); + EqualAcceleration(data, 140, 0.5, -0.5); + } + + [TestCase] + public void Declaration_WheelsForT1_Class2() + { + var dataProvider = + JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\12t Delivery Truck.vecto") as IDeclarationInputDataProvider; + var dataReader = new DeclarationModeVectoRunDataFactory(dataProvider, null); + + var runs = dataReader.NextRun().ToList(); + Assert.AreEqual(6, runs.Count); + var withT1 = new[] { 6.0, 6.0, 4.5, 4.5 }; + + CollectionAssert.AreEqual(withT1, runs[0].VehicleData.AxleData.Select(a => a.Inertia.Value())); + CollectionAssert.AreEqual(withT1, runs[1].VehicleData.AxleData.Select(a => a.Inertia.Value())); + + var bodyOnly = new[] { 6.0, 6.0 }; + + CollectionAssert.AreEqual(bodyOnly, runs[2].VehicleData.AxleData.Select(a => a.Inertia.Value())); + CollectionAssert.AreEqual(bodyOnly, runs[3].VehicleData.AxleData.Select(a => a.Inertia.Value())); + + CollectionAssert.AreEqual(bodyOnly, runs[4].VehicleData.AxleData.Select(a => a.Inertia.Value())); + CollectionAssert.AreEqual(bodyOnly, runs[5].VehicleData.AxleData.Select(a => a.Inertia.Value())); + } + + [TestCase] + public void Declaration_WheelsForT2_Class4() + { + var dataProvider = + JSONInputDataFactory.ReadJsonJob( + @"TestData\Jobs\Class4_40t_Long_Haul_Truck.vecto") as IDeclarationInputDataProvider; + var dataReader = new DeclarationModeVectoRunDataFactory(dataProvider, null); + + var runs = dataReader.NextRun().ToList(); + Assert.AreEqual(6, runs.Count); + var withT1 = new[] { 14.9, 14.9, 19.2, 19.2 }; + CollectionAssert.AreEqual(withT1, runs[0].VehicleData.AxleData.Select(a => a.Inertia.Value())); + CollectionAssert.AreEqual(withT1, runs[1].VehicleData.AxleData.Select(a => a.Inertia.Value())); + + var bodyOnly = new[] { 14.9, 14.9 }; + CollectionAssert.AreEqual(bodyOnly, runs[2].VehicleData.AxleData.Select(a => a.Inertia.Value())); + CollectionAssert.AreEqual(bodyOnly, runs[3].VehicleData.AxleData.Select(a => a.Inertia.Value())); + + CollectionAssert.AreEqual(bodyOnly, runs[4].VehicleData.AxleData.Select(a => a.Inertia.Value())); + CollectionAssert.AreEqual(bodyOnly, runs[5].VehicleData.AxleData.Select(a => a.Inertia.Value())); + } + + [TestCase] + public void Declaration_WheelsForDefault_Class5() + { + var dataProvider = + JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\40t_Long_Haul_Truck.vecto") as IDeclarationInputDataProvider; + var dataReader = new DeclarationModeVectoRunDataFactory(dataProvider, null); + + var runs = dataReader.NextRun().ToList(); + + Assert.AreEqual(VehicleClass.Class5, runs[0].VehicleData.VehicleClass); + Assert.AreEqual(8, runs.Count); + + //var bodyOnly = new[] { 14.9, 14.9 }; + var withST1 = new[] { 14.9, 14.9, 19.2, 19.2, 19.2 }; + var withST1andT2 = new[] { 14.9, 14.9, 19.2, 19.2, 19.2, 19.2, 19.2 }; + + CollectionAssert.AreEqual(withST1, runs[0].VehicleData.AxleData.Select(a => a.Inertia.Value())); + CollectionAssert.AreEqual(withST1, runs[1].VehicleData.AxleData.Select(a => a.Inertia.Value())); + + CollectionAssert.AreEqual(withST1andT2, runs[2].VehicleData.AxleData.Select(a => a.Inertia.Value())); + CollectionAssert.AreEqual(withST1andT2, runs[3].VehicleData.AxleData.Select(a => a.Inertia.Value())); + + CollectionAssert.AreEqual(withST1, runs[4].VehicleData.AxleData.Select(a => a.Inertia.Value())); + CollectionAssert.AreEqual(withST1, runs[5].VehicleData.AxleData.Select(a => a.Inertia.Value())); + + CollectionAssert.AreEqual(withST1andT2, runs[6].VehicleData.AxleData.Select(a => a.Inertia.Value())); + CollectionAssert.AreEqual(withST1andT2, runs[7].VehicleData.AxleData.Select(a => a.Inertia.Value())); + } + } } \ No newline at end of file