diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs index 72e6c0eb97275baee9c8065ba9011451c4e1c17b..dd915e3fe9cf2085f9319a7029c6c2177e30b294 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs @@ -29,38 +29,38 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.ComponentModel; -using System.Data; -using System.Runtime.Serialization; -using TUGraz.VectoCommon.Utils; - -// ReSharper disable InconsistentNaming - -namespace TUGraz.VectoCore.Models.Simulation.Data -{ - [DesignerCategory("")] // Full qualified attribute needed to disable design view in VisualStudio - [Serializable] - public class ModalResults : DataTable - { - public static class ExtendedPropertyNames - { - public const string Decimals = "decimals"; - public const string OutputFactor = "outputFactor"; - public const string ShowUnit = "showUnit"; - } - - protected ModalResults(SerializationInfo info, StreamingContext context) : base(info, context) {} - - public ModalResults() - { - foreach (var value in EnumHelper.GetValues<ModalResultField>()) { - var col = new DataColumn(value.GetName(), value.GetAttribute().DataType) { Caption = value.GetCaption() }; - col.ExtendedProperties[ExtendedPropertyNames.Decimals] = value.GetAttribute().Decimals; - col.ExtendedProperties[ExtendedPropertyNames.OutputFactor] = value.GetAttribute().OutputFactor; - col.ExtendedProperties[ExtendedPropertyNames.ShowUnit] = value.GetAttribute().ShowUnit; - Columns.Add(col); - } - } - } +using System; +using System.ComponentModel; +using System.Data; +using System.Runtime.Serialization; +using TUGraz.VectoCommon.Utils; + +// ReSharper disable InconsistentNaming + +namespace TUGraz.VectoCore.Models.Simulation.Data +{ + [DesignerCategory("")] // Full qualified attribute needed to disable design view in VisualStudio + [Serializable] + public class ModalResults : DataTable + { + public static class ExtendedPropertyNames + { + public const string Decimals = "decimals"; + public const string OutputFactor = "outputFactor"; + public const string ShowUnit = "showUnit"; + } + + protected ModalResults(SerializationInfo info, StreamingContext context) : base(info, context) {} + + public ModalResults() + { + foreach (var value in EnumHelper.GetValues<ModalResultField>()) { + var col = new DataColumn(value.GetName(), value.GetAttribute().DataType) { Caption = value.GetCaption() }; + col.ExtendedProperties[ExtendedPropertyNames.Decimals] = value.GetAttribute().Decimals; + col.ExtendedProperties[ExtendedPropertyNames.OutputFactor] = value.GetAttribute().OutputFactor; + col.ExtendedProperties[ExtendedPropertyNames.ShowUnit] = value.GetAttribute().ShowUnit; + Columns.Add(col); + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/ISimulationPreprocessor.cs b/VectoCore/VectoCore/Models/Simulation/ISimulationPreprocessor.cs new file mode 100644 index 0000000000000000000000000000000000000000..b1470873c879cc1e0ae7550c5601c513c91f6e27 --- /dev/null +++ b/VectoCore/VectoCore/Models/Simulation/ISimulationPreprocessor.cs @@ -0,0 +1,8 @@ +using TUGraz.VectoCore.Models.Simulation.Impl; + +namespace TUGraz.VectoCore.Models.Simulation { + public interface ISimulationPreprocessor + { + void RunPreprocessing(VectoRun container); + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs index 38548b02517ba68567e7faa3e4529b03d6656f60..084bf3e5372edea6f3cbef76403d8536496088b9 100644 --- a/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs @@ -30,6 +30,7 @@ */ using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Connector.Ports; @@ -37,6 +38,7 @@ using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.DataBus; using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.Models.SimulationComponent; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Models.Simulation @@ -56,6 +58,8 @@ namespace TUGraz.VectoCore.Models.Simulation VectoRun.Status RunStatus { get; set; } + + /// <summary> /// Adds a component to the vehicle container. /// </summary> @@ -72,5 +76,10 @@ namespace TUGraz.VectoCore.Models.Simulation /// </summary> /// <param name="exception"></param> void FinishSimulationRun(Exception exception = null); + + void StartSimulationRun(); + + IEnumerable<ISimulationPreprocessor> GetPreprocessingRuns { get; } + void AddPreprocessor(ISimulationPreprocessor simulationPreprocessor); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs index c66eee78a9855d7a5dd3c460e2b1e4ac65416064..7124f6ce7c71e1a3a95622ea19bcdd92513b40b0 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs @@ -106,6 +106,14 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl } var debug = new DebugData(); + Log.Info("VectoJob preprocessing."); + + foreach (var preprocessing in Container.GetPreprocessingRuns) { + preprocessing.RunPreprocessing(this); + } + + + Container.StartSimulationRun(); Log.Info("VectoJob started running."); Container.AbsTime = AbsTime; diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index 48467a2291bf74ab0e1835cb4c2f9ac2ddba78fb..63b828b6d74bbac1ee080f35f9bcab7a06a99da8 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -74,6 +74,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl internal WriteSumData WriteSumData; + internal readonly IList<ISimulationPreprocessor> Preprocessors = new List<ISimulationPreprocessor>(); + #region IGearCockpit public GearboxType GearboxType @@ -335,6 +337,21 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl DrivingCycle.FinishSimulation(); } + public void StartSimulationRun() + { + ModData?.Reset(); + } + + public IEnumerable<ISimulationPreprocessor> GetPreprocessingRuns + { + get { return new ReadOnlyCollection<ISimulationPreprocessor>(Preprocessors); } + } + + public void AddPreprocessor(ISimulationPreprocessor simulationPreprocessor) + { + Preprocessors.Add(simulationPreprocessor); + } + public void FinishSimulation() { throw new NotImplementedException(); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyV2.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyV2.cs new file mode 100644 index 0000000000000000000000000000000000000000..a06d9d6ee94e5d4eb383472529aade8ca9bcd6d7 --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyV2.cs @@ -0,0 +1,73 @@ +using System; +using System.Data; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class AMTShiftStrategyV2 : ShiftStrategy + { + private uint _nextGear; + + public AMTShiftStrategyV2(VectoRunData data, IVehicleContainer dataBus) : base(data.GearboxData, dataBus) + { + var velocityDropData = new VelocityRollingLookup(); + dataBus.AddPreprocessor(new VelocitySpeedGearshiftPreprocessor(velocityDropData, data.GearboxData.TractionInterruption)); + } + + #region Overrides of BaseShiftStrategy + + public override bool ShiftRequired( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear, Second lastShiftTime) + { + throw new System.NotImplementedException(); + + + } + + public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) + { + if (DataBus.VehicleSpeed.IsEqual(0)) { + return InitStartGear(torque, outAngularVelocity); + } + + for (var gear = (uint)ModelData.Gears.Count; gear > 1; gear--) { + var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio; + if (DataBus.EngineSpeed < inAngularVelocity && inAngularVelocity < DataBus.EngineRatedSpeed) { + _nextGear = gear; + return gear; + } + } + + return 1; + } + + private uint InitStartGear(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + return 1; + } + + public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + throw new System.NotImplementedException(); + } + + public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) + { + throw new System.NotImplementedException(); + } + + public override GearInfo NextGear + { + get { return new GearInfo(_nextGear, true); } + } + + #endregion + } +} diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Retarder.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Retarder.cs index f72c63bad8e106e335a86a1b976f78af19211840..ae2223f9e0620a6b1c695100da53b9f31e2c3ca8 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Retarder.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Retarder.cs @@ -91,15 +91,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected override void DoCommitSimulationStep() { - var avgAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; + var avgAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0 * _ratio; if (!avgAngularSpeed.IsBetween(_lossMap.MinSpeed, _lossMap.MaxSpeed)) { Log.Warn( "Retarder LossMap data was extrapolated: range for loss map is not sufficient: n:{0} (min:{1}, max:{2}), ratio:{3}", - CurrentState.OutAngularVelocity.AsRPM, _lossMap.MinSpeed.AsRPM, _lossMap.MaxSpeed.AsRPM, _ratio); + avgAngularSpeed.AsRPM, _lossMap.MinSpeed.AsRPM, _lossMap.MaxSpeed.AsRPM, _ratio); if (DataBus.ExecutionMode == ExecutionMode.Declaration) { throw new VectoException( "Retarder LossMap data was extrapolated in Declaration mode: range for loss map is not sufficient: n:{0} (min:{1}, max:{2}), ratio:{3}", - CurrentState.OutAngularVelocity.AsRPM, _lossMap.MinSpeed.AsRPM, _lossMap.MaxSpeed.AsRPM, _ratio); + avgAngularSpeed.AsRPM, _lossMap.MinSpeed.AsRPM, _lossMap.MaxSpeed.AsRPM, _ratio); } } base.DoCommitSimulationStep(); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocityRollingLookup.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocityRollingLookup.cs new file mode 100644 index 0000000000000000000000000000000000000000..4d7090b17d5b63498147c50681995a8a1122dde2 --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocityRollingLookup.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { + public class VelocityRollingLookup : Interpolate2D<MeterPerSecond, Radian, MeterPerSecond, + VelocitySpeedGearshiftPreprocessor.Entry> + { + public VelocitySpeedGearshiftPreprocessor.Entry[] Data + { + set { + Valid = value != null && value.Length > 0; + if (Valid) { + SetData(value); + } + } + } + + public bool Valid { get; set; } + + #region Overrides of Interpolate2D<MeterPerSecond,Radian,MeterPerSecond,Entry> + + protected override MeterPerSecond GetXValue(VelocitySpeedGearshiftPreprocessor.Entry entry) + { + return entry.StartVelocity; + } + + protected override Radian GetYValue(VelocitySpeedGearshiftPreprocessor.Entry entry) + { + return entry.Gradient; + } + + protected override MeterPerSecond GetZValue(VelocitySpeedGearshiftPreprocessor.Entry entry) + { + return entry.EndVelocity; + } + + protected override IEnumerable<MeterPerSecond> GetXValuesSorted(VelocitySpeedGearshiftPreprocessor.Entry[] entries) + { + return entries.Select(x => x.StartVelocity).OrderBy(x => x); + } + + protected override IEnumerable<Radian> GetYValuesSorted(VelocitySpeedGearshiftPreprocessor.Entry[] entries) + { + return entries.Select(x => x.Gradient).OrderBy(x => x); + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocitySpeedGearshiftPreprocessor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocitySpeedGearshiftPreprocessor.cs new file mode 100644 index 0000000000000000000000000000000000000000..d73f14ddb7738fe33f4b13558533f2fefd537024 --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocitySpeedGearshiftPreprocessor.cs @@ -0,0 +1,129 @@ +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { + public class VelocitySpeedGearshiftPreprocessor : ISimulationPreprocessor + { + protected readonly Second TractionInterruption; + private readonly VelocityRollingLookup VehicleVelocityDropLookup; + + public VelocitySpeedGearshiftPreprocessor(VelocityRollingLookup velocityDropData, Second tracktionInterruption, int minGradient = -24, int maxGradient = 24, int gradientStep = 2) + { + VehicleVelocityDropLookup = velocityDropData; + TractionInterruption = tracktionInterruption; + MinGradient = minGradient; + MaxGradient = maxGradient; + GradientStep = gradientStep; + + var speeds = Enumerable.Range(1, 12).Select(x => (x * 10).KMPHtoMeterPerSecond()).ToList(); + speeds.Insert(0, 5.KMPHtoMeterPerSecond()); + Speeds = speeds; + } + + + #region Implementation of ISimulationPreprocessor + + public void RunPreprocessing(VectoRun container) + { + VehicleVelocityDropLookup.Data = IterateVehicleSpeedAndGradient(container); + } + + #endregion + + public int MinGradient { get; set; } + + public int MaxGradient { get; set; } + public int GradientStep { get; set; } + + protected Entry[] IterateVehicleSpeedAndGradient(VectoRun run) + { + var container = run.GetContainer() as VehicleContainer; + var vehicle = container?.Vehicle as Vehicle; + + if (vehicle == null) { + throw new VectoException("no vehicle found..."); + } + + var modData = container.ModalData as ModalDataContainer; + + var tmp = new List<Entry>(); + foreach (var speed in Speeds) { + for (var grad = MinGradient; grad <= MaxGradient; grad+=GradientStep) { + var gradient = VectoMath.InclinationToAngle(grad / 100.0); + vehicle.Initialize(speed, gradient); + (container.Gearbox as Gearbox).Gear = 0; + var vehicleSpeed = SimulateRollingVehicle(vehicle, gradient, container); + modData?.Reset(); + tmp.Add(new Entry() { StartVelocity = speed, Gradient = gradient, EndVelocity = vehicleSpeed }); + } + } + + return tmp.ToArray(); + } + + public IList<MeterPerSecond> Speeds { get; } + + protected MeterPerSecond SimulateRollingVehicle( + Vehicle vehicle, Radian gradient, IVehicleContainer container) + { + var simulationInterval = Constants.SimulationSettings.TargetTimeInterval; + + var acceleration = 0.SI<MeterPerSquareSecond>(); + var absTime = 0.SI<Second>(); + while (absTime < TractionInterruption) { + var initialResponse = vehicle.Request(absTime, simulationInterval, acceleration, gradient); + var delta = initialResponse.GearboxPowerRequest; + try { + var time = absTime; + acceleration = SearchAlgorithm.Search( + acceleration, delta, Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, + getYValue: response => { + var r = (ResponseDryRun)response; + return r.GearboxPowerRequest; + }, + evaluateFunction: acc => { + var response = vehicle.Request(time, simulationInterval, acc, gradient, true); + response.Acceleration = acc; + return response; + }, + criterion: response => { + var r = (ResponseDryRun)response; + return r.GearboxPowerRequest.Value(); + }, + abortCriterion: (response, cnt) => { + var r = (ResponseDryRun)response; + return r != null && (vehicle.VehicleSpeed + r.Acceleration * simulationInterval) < 0.KMPHtoMeterPerSecond(); + } + ); + var step = vehicle.Request(absTime, simulationInterval, acceleration, gradient); + if (!(step is ResponseSuccess)) { + throw new VectoSimulationException("failed to find acceleration for rolling"); + } + + absTime += simulationInterval; + } catch (VectoSearchAbortedException) { + return 0.KMPHtoMeterPerSecond(); + } + + container.CommitSimulationStep(absTime, simulationInterval); + } + + return vehicle.VehicleSpeed; + } + + public class Entry + { + public MeterPerSecond StartVelocity; + public Radian Gradient; + public MeterPerSecond EndVelocity; + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs index f3c087df64d22f40d70a59fd3dd6b046a72cf324..b1ea488551199e30ce072675687a110ba74c3835 100644 --- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs @@ -102,6 +102,8 @@ namespace TUGraz.VectoCore.OutputData /// called after the simulation is finished and the sum-entries have been written /// </summary> void FinishSimulation(); + + void Reset(); } public static class ModalDataContainerExtensions diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index d089ff8e198a48929c4eeacf0ada344476845dfe..52e8001005b810438ec826091f85499cf3389f2f 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -112,6 +112,11 @@ namespace TUGraz.VectoCore.OutputData WriteAdvancedAux = false; } + public void Reset() + { + Data.Rows.Clear(); + CurrentRow = Data.NewRow(); + } public bool HasTorqueConverter { get; set; } diff --git a/VectoCore/VectoCore/Utils/Interpolate2D.cs b/VectoCore/VectoCore/Utils/Interpolate2D.cs new file mode 100644 index 0000000000000000000000000000000000000000..5f12027e4a705e573193772984ed2bc320b1a37e --- /dev/null +++ b/VectoCore/VectoCore/Utils/Interpolate2D.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Utils +{ + public abstract class Interpolate2D<TKeyX, TKeyY, TValZ, TEntry> + where TKeyX : SI + where TKeyY : SI + where TValZ : SIBase<TValZ> + { + private DataTable _data; + + private KeyValuePair<TKeyX, int>[] entriesX; + private KeyValuePair<TKeyY, int>[] entriesY; + + protected void SetData(TEntry[] entries) + { + _data = new DataTable(); + var xEntries = new List<KeyValuePair<TKeyX, int>>(); + var idx = 0; + foreach (var xValue in GetXValuesSorted(entries).Distinct()) { + _data.Columns.Add(xValue.ToOutputFormat(), typeof(TKeyX)); + xEntries.Add(new KeyValuePair<TKeyX, int>(xValue, idx++)); + } + + entriesX = xEntries.OrderBy(x => x.Key).ToArray(); + + idx = 0; + var yEntries = new List<KeyValuePair<TKeyY, int>>(); + foreach (var yValue in GetYValuesSorted(entries).Distinct()) { + var row = _data.NewRow(); + _data.Rows.Add(row); + yEntries.Add(new KeyValuePair<TKeyY, int>(yValue, idx++)); + } + + entriesY = yEntries.OrderBy(x => x.Key).ToArray(); + + foreach (var entry in entries) { + var col = entriesX.First(x => x.Key.IsEqual(GetXValue(entry))); + var row = entriesY.First(x => x.Key.IsEqual(GetYValue(entry))); + _data.Rows[row.Value][col.Value] = GetZValue(entry); + } + } + + protected abstract TKeyX GetXValue(TEntry entry); + + protected abstract TKeyY GetYValue(TEntry entry); + + protected abstract TValZ GetZValue(TEntry entry); + + protected abstract IEnumerable<TKeyX> GetXValuesSorted(TEntry[] entries); + + protected abstract IEnumerable<TKeyY> GetYValuesSorted(TEntry[] entries); + + + public TValZ Interpolate(TKeyX valX, TKeyY valY) + { + var speedIdx = -1; + for (var i = 0; i < entriesX.Length; i++) { + if (entriesX[i].Key.CompareTo(valX) >= 0) { + speedIdx = i; + break; + } + } + + var gradientIdx = -1; + for (var i = 0; i < entriesY.Length; i++) { + if (entriesY[i].Key.CompareTo(valY) >= 0) { + gradientIdx = i; + break; + } + } + + var v1 = _data.Rows[entriesY[gradientIdx - 1].Value][entriesX[speedIdx - 1].Value] as TValZ; + var v2 = _data.Rows[entriesY[gradientIdx - 1].Value][entriesX[speedIdx].Value] as TValZ; + var v3 = _data.Rows[entriesY[gradientIdx].Value][entriesX[speedIdx - 1].Value] as TValZ; + var v4 = _data.Rows[entriesY[gradientIdx].Value][entriesX[speedIdx].Value] as TValZ; + var speed1 = VectoMath.Interpolate(entriesX[speedIdx - 1].Key, entriesX[speedIdx].Key, v1, v2, valX); + var speed2 = VectoMath.Interpolate(entriesX[speedIdx - 1].Key, entriesX[speedIdx].Key, v3, v4, valX); + + return VectoMath.Interpolate( + entriesY[gradientIdx - 1].Key, entriesY[gradientIdx].Key, speed1, speed2, valY); + } + } +} diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index 9d297de84f79077a83d9ce41eb3588fcb21d674b..fa0105351100d5e92cc8020092c99fa84e6171ad 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -179,6 +179,7 @@ <Compile Include="Models\SimulationComponent\ILossMap.cs" /> <Compile Include="Models\SimulationComponent\Data\PTOLossMap.cs" /> <Compile Include="Models\SimulationComponent\Impl\AbstractGearbox.cs" /> + <Compile Include="Models\SimulationComponent\Impl\AMTShiftStrategyV2.cs" /> <Compile Include="Models\SimulationComponent\Impl\ATGearbox.cs" /> <Compile Include="Models\SimulationComponent\Impl\ATShiftStrategy.cs" /> <Compile Include="Models\SimulationComponent\Impl\BaseShiftStrategy.cs" /> @@ -186,6 +187,8 @@ <Compile Include="Models\SimulationComponent\Impl\DrivingCycleEnumerator.cs" /> <Compile Include="Models\SimulationComponent\Impl\EngineFanAuxiliary.cs" /> <Compile Include="Models\SimulationComponent\Impl\TorqueConverterWrapper.cs" /> + <Compile Include="Models\SimulationComponent\Impl\VelocityRollingLookup.cs" /> + <Compile Include="Models\SimulationComponent\Impl\VelocitySpeedGearshiftPreprocessor.cs" /> <Compile Include="Models\SimulationComponent\Impl\VTPCombustionEngine.cs" /> <Compile Include="Models\SimulationComponent\Impl\MeasuredSpeedDrivingCycle.cs" /> <Compile Include="Models\SimulationComponent\Impl\PTOCycleController.cs" /> @@ -196,6 +199,7 @@ <Compile Include="Models\Simulation\Data\ModalResultField.cs" /> <Compile Include="InputData\Reader\Impl\EngineeringVTPModeVectoRunDataFactory.cs" /> <Compile Include="Models\SimulationComponent\Impl\VTPCycle.cs" /> + <Compile Include="Models\Simulation\ISimulationPreprocessor.cs" /> <Compile Include="OutputData\XML\XMLVTPReport.cs" /> <Compile Include="OutputData\VTPReport.cs" /> <Compile Include="OutputData\ModFilter\ActualModalDataFilter.cs" /> @@ -207,6 +211,7 @@ <Compile Include="OutputData\XML\XMLDeclarationWriter.cs" /> <Compile Include="OutputData\XML\XMLEngineeringWriter.cs" /> <Compile Include="OutputData\XML\XMLManufacturerReport.cs" /> + <Compile Include="Utils\Interpolate2D.cs" /> <Compile Include="Utils\ProviderExtensions.cs" /> <Compile Include="Models\Declaration\AirDrag.cs" /> <Compile Include="Models\Declaration\Fan.cs" /> diff --git a/VectoCore/VectoCoreTest/Models/Simulation/LossMapRangeValidationTest.cs b/VectoCore/VectoCoreTest/Models/Simulation/LossMapRangeValidationTest.cs index b946802f98896242b493f575aa144c442f64c5fd..59c7cdf426e5a309ce43cfdfd38be27522fcae21 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/LossMapRangeValidationTest.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/LossMapRangeValidationTest.cs @@ -34,33 +34,33 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.IO; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.FileIO.JSON; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.Tests.Utils; - -namespace TUGraz.VectoCore.Tests.Models.Simulation -{ - [TestFixture] - public class LossMapRangeValidationTest - { - public const string ShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; - public const string AccelerationFile = @"TestData\Components\Truck.vacc"; - public const string EngineFile = @"TestData\Components\40t_Long_Haul_Truck.veng"; - public const string AxleGearLossMap = @"TestData\Components\Axle 40t Truck.vtlm"; - public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm"; - public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm"; - public const string GearboxLimited = @"TestData\Components\limited.vtlm"; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Tests.Utils; + +namespace TUGraz.VectoCore.Tests.Models.Simulation +{ + [TestFixture] + public class LossMapRangeValidationTest + { + public const string ShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; + public const string AccelerationFile = @"TestData\Components\Truck.vacc"; + public const string EngineFile = @"TestData\Components\40t_Long_Haul_Truck.veng"; + public const string AxleGearLossMap = @"TestData\Components\Axle 40t Truck.vtlm"; + public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm"; + public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm"; + public const string GearboxLimited = @"TestData\Components\limited.vtlm"; public const string GearboxShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; //public const string GearboxFullLoadCurveFile = @"TestData\Components\Gearbox.vfld"; @@ -71,241 +71,241 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory); } - /// <summary> - /// VECTO-173 - /// </summary> - [TestCase] - public void LossMapValid() - { - var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); - var axleGearData = CreateAxleGearData(AxleGearLossMap); - var vehicleData = new VehicleData { - DynamicTyreRadius = 0.85.SI<Meter>(), - Loading = 0.SI<Kilogram>(), - CurbWeight = 2000.SI<Kilogram>(), - AxleData = - new List<Axle> { - new Axle { - TwinTyres = false, - AxleWeightShare = 1, - TyreTestLoad = 50000.SI<Newton>(), - Inertia = 10.SI<KilogramSquareMeter>() - } - } - }; - - var runData = new VectoRunData { - GearboxData = gearboxData, - EngineData = engineData, - AxleGearData = axleGearData, - VehicleData = vehicleData, - Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() } - }; - - var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData)); - Assert.IsTrue(ValidationResult.Success == result); - Assert.IsFalse(runData.IsValid()); - } - - /// <summary> - /// VECTO-173 - /// </summary> - [TestCase] - public void LossMapInvalidAxle() - { - var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); - var axleGearData = CreateAxleGearData(GearboxLimited); - - var runData = new VectoRunData { GearboxData = gearboxData, EngineData = engineData, AxleGearData = axleGearData }; - Assert.IsFalse(runData.IsValid()); - } - - /// <summary> - /// VECTO-173 - /// </summary> - [TestCase] - public void LossMapLimited() - { - var gearboxData = CreateGearboxData(GearboxLimited, GearboxLimited); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); - var axleGearData = CreateAxleGearData(AxleGearLossMap); - var runData = new VectoRunData { GearboxData = gearboxData, EngineData = engineData, AxleGearData = axleGearData }; - var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData)); - Assert.IsFalse(ValidationResult.Success == result); - } - - /// <summary> - /// VECTO-173 - /// </summary> - [TestCase] - public void LossMapAxleLossMapMissing() - { - var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); - var vehicleData = new VehicleData { - DynamicTyreRadius = 0.85.SI<Meter>(), - Loading = 0.SI<Kilogram>(), - CurbWeight = 2000.SI<Kilogram>(), - AxleData = - new List<Axle> { - new Axle { - TwinTyres = false, - AxleWeightShare = 1, - TyreTestLoad = 50000.SI<Newton>(), - Inertia = 10.SI<KilogramSquareMeter>() - } - } - }; - var runData = new VectoRunData { - GearboxData = gearboxData, - EngineData = engineData, - VehicleData = vehicleData, - Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() } - }; - var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData)); - Assert.IsTrue(ValidationResult.Success == result); - Assert.IsFalse(runData.IsValid()); - } - - /// <summary> - /// VECTO-173 - /// </summary> - [TestCase] - public void LossMapGearLossMapMissing() - { - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 0); - var axleGearData = CreateAxleGearData(AxleGearLossMap); - - var runData = new VectoRunData { - EngineData = engineData, - AxleGearData = axleGearData, - Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() } - }; - var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData)); - Assert.IsTrue(ValidationResult.Success == result); - Assert.IsFalse(runData.IsValid()); - } - - private static GearboxData CreateGearboxData(string directlossMap, string indirectLossMap) - { - var ratios = new[] { 14.93, 11.64, 9.02, 7.04, 5.64, 4.4, 3.39, 2.65, 2.05, 1.6, 1.28, 1.0 }; - return new GearboxData { - Gears = ratios.Select((ratio, i) => - Tuple.Create((uint)i, - new GearData { -// MaxTorque = 2300.SI<NewtonMeter>(), - LossMap = TransmissionLossMapReader.ReadFromFile(!ratio.IsEqual(1.0) ? directlossMap : indirectLossMap, ratio, - string.Format("Gear {0}", i)), - Ratio = ratio, - ShiftPolygon = ShiftPolygonReader.ReadFromFile(ShiftPolygonFile) - })) - .ToDictionary(k => k.Item1 + 1, v => v.Item2) - }; - } - - private static AxleGearData CreateAxleGearData(string lossMap) - { - const double ratio = 2.59; - return new AxleGearData { - AxleGear = new GearData { - Ratio = ratio, - LossMap = TransmissionLossMapReader.ReadFromFile(lossMap, ratio, "AxleGear") - } - }; - } - - /// <summary> - /// VECTO-230 - /// </summary> - [TestCase] - public void TestLossMapValuesWithEfficiency() - { - var lossMap = TransmissionLossMapReader.Create(0.95, 1.0, "Dummy"); - - AssertHelper.AreRelativeEqual(0.SI<NewtonMeter>(), - lossMap.GetTorqueLoss(0.RPMtoRad(), 0.SI<NewtonMeter>()).Value); - - AssertHelper.AreRelativeEqual(50.SI<NewtonMeter>(), - lossMap.GetTorqueLoss(1000.RPMtoRad(), 950.SI<NewtonMeter>()).Value); - - AssertHelper.AreRelativeEqual(40.SI<NewtonMeter>(), - lossMap.GetTorqueLoss(1000.RPMtoRad(), 760.SI<NewtonMeter>()).Value); - - AssertHelper.AreRelativeEqual(25.SI<NewtonMeter>(), - lossMap.GetTorqueLoss(1000.RPMtoRad(), 475.SI<NewtonMeter>()).Value); - - AssertHelper.AreRelativeEqual(5.SI<NewtonMeter>(), - lossMap.GetTorqueLoss(1000.RPMtoRad(), 95.SI<NewtonMeter>()).Value); - - AssertHelper.AreRelativeEqual(50.SI<NewtonMeter>(), - lossMap.GetTorqueLoss(500.RPMtoRad(), 950.SI<NewtonMeter>()).Value); - - AssertHelper.AreRelativeEqual(25.SI<NewtonMeter>(), - lossMap.GetTorqueLoss(500.RPMtoRad(), 475.SI<NewtonMeter>()).Value); - - AssertHelper.AreRelativeEqual(5.SI<NewtonMeter>(), - lossMap.GetTorqueLoss(100.RPMtoRad(), 95.SI<NewtonMeter>()).Value); - } - - /// <summary> - /// VECTO-230 - /// </summary> - [TestCase] - public void CreateJobWithLossMapEfficiency_Engineering() - { - var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\12t Delivery Truck Engineering Efficiency.vecto"); - var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, dataProvider, null); - var jobContainer = new JobContainer(null); - jobContainer.AddRuns(runsFactory); - } - - /// <summary> - /// VECTO-230 - /// </summary> - [TestCase] - public void RunJobWithLossMapEfficiency_Engineering() - { - const string jobFileName = @"TestData\Jobs\12t Delivery Truck Engineering Efficiency.vecto"; - var fileWriter = new FileOutputWriter(jobFileName); - - var dataProvider = JSONInputDataFactory.ReadJsonJob(jobFileName); - var factory = new SimulatorFactory(ExecutionMode.Engineering, dataProvider, fileWriter); - var jobContainer = new JobContainer(new MockSumWriter()); - jobContainer.AddRuns(factory); - jobContainer.Execute(); - jobContainer.WaitFinished(); - - foreach (var r in jobContainer.Runs) { - Assert.IsTrue(r.Run.FinishedWithoutErrors, string.Format("{0}", r.ExecException)); - } - } - - /// <summary> - /// VECTO-230 - /// </summary> - [TestCase] - public void CreateJobWith_Axle_LossMapEfficiency_Declaration() - { - var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\40t_Long_Haul_Truck with AxleEfficiency.vecto"); - var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, null); - var jobContainer = new JobContainer(null); - - AssertHelper.Exception<InvalidFileFormatException>(() => jobContainer.AddRuns(runsFactory)); - } - - /// <summary> - /// VECTO-230 - /// </summary> - [TestCase] - public void CreateJobWith_Gear_LossMapEfficiency_Declaration() - { - var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\40t_Long_Haul_Truck with GearEfficiency.vecto"); - var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, null); - var jobContainer = new JobContainer(null); - - AssertHelper.Exception<InvalidFileFormatException>(() => jobContainer.AddRuns(runsFactory)); - } - } + /// <summary> + /// VECTO-173 + /// </summary> + [TestCase] + public void LossMapValid() + { + var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); + var axleGearData = CreateAxleGearData(AxleGearLossMap); + var vehicleData = new VehicleData { + DynamicTyreRadius = 0.85.SI<Meter>(), + Loading = 0.SI<Kilogram>(), + CurbWeight = 2000.SI<Kilogram>(), + AxleData = + new List<Axle> { + new Axle { + TwinTyres = false, + AxleWeightShare = 1, + TyreTestLoad = 50000.SI<Newton>(), + Inertia = 10.SI<KilogramSquareMeter>() + } + } + }; + + var runData = new VectoRunData { + GearboxData = gearboxData, + EngineData = engineData, + AxleGearData = axleGearData, + VehicleData = vehicleData, + Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() } + }; + + var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData)); + Assert.IsTrue(ValidationResult.Success == result); + Assert.IsFalse(runData.IsValid()); + } + + /// <summary> + /// VECTO-173 + /// </summary> + [TestCase] + public void LossMapInvalidAxle() + { + var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); + var axleGearData = CreateAxleGearData(GearboxLimited); + + var runData = new VectoRunData { GearboxData = gearboxData, EngineData = engineData, AxleGearData = axleGearData }; + Assert.IsFalse(runData.IsValid()); + } + + /// <summary> + /// VECTO-173 + /// </summary> + [TestCase] + public void LossMapLimited() + { + var gearboxData = CreateGearboxData(GearboxLimited, GearboxLimited); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); + var axleGearData = CreateAxleGearData(AxleGearLossMap); + var runData = new VectoRunData { GearboxData = gearboxData, EngineData = engineData, AxleGearData = axleGearData }; + var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData)); + Assert.IsFalse(ValidationResult.Success == result); + } + + /// <summary> + /// VECTO-173 + /// </summary> + [TestCase] + public void LossMapAxleLossMapMissing() + { + var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count); + var vehicleData = new VehicleData { + DynamicTyreRadius = 0.85.SI<Meter>(), + Loading = 0.SI<Kilogram>(), + CurbWeight = 2000.SI<Kilogram>(), + AxleData = + new List<Axle> { + new Axle { + TwinTyres = false, + AxleWeightShare = 1, + TyreTestLoad = 50000.SI<Newton>(), + Inertia = 10.SI<KilogramSquareMeter>() + } + } + }; + var runData = new VectoRunData { + GearboxData = gearboxData, + EngineData = engineData, + VehicleData = vehicleData, + Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() } + }; + var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData)); + Assert.IsTrue(ValidationResult.Success == result); + Assert.IsFalse(runData.IsValid()); + } + + /// <summary> + /// VECTO-173 + /// </summary> + [TestCase] + public void LossMapGearLossMapMissing() + { + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 0); + var axleGearData = CreateAxleGearData(AxleGearLossMap); + + var runData = new VectoRunData { + EngineData = engineData, + AxleGearData = axleGearData, + Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() } + }; + var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData)); + Assert.IsTrue(ValidationResult.Success == result); + Assert.IsFalse(runData.IsValid()); + } + + private static GearboxData CreateGearboxData(string directlossMap, string indirectLossMap) + { + var ratios = new[] { 14.93, 11.64, 9.02, 7.04, 5.64, 4.4, 3.39, 2.65, 2.05, 1.6, 1.28, 1.0 }; + return new GearboxData { + Gears = ratios.Select((ratio, i) => + Tuple.Create((uint)i, + new GearData { +// MaxTorque = 2300.SI<NewtonMeter>(), + LossMap = TransmissionLossMapReader.ReadFromFile(!ratio.IsEqual(1.0) ? directlossMap : indirectLossMap, ratio, + string.Format("Gear {0}", i)), + Ratio = ratio, + ShiftPolygon = ShiftPolygonReader.ReadFromFile(ShiftPolygonFile) + })) + .ToDictionary(k => k.Item1 + 1, v => v.Item2) + }; + } + + private static AxleGearData CreateAxleGearData(string lossMap) + { + const double ratio = 2.59; + return new AxleGearData { + AxleGear = new GearData { + Ratio = ratio, + LossMap = TransmissionLossMapReader.ReadFromFile(lossMap, ratio, "AxleGear") + } + }; + } + + /// <summary> + /// VECTO-230 + /// </summary> + [TestCase] + public void TestLossMapValuesWithEfficiency() + { + var lossMap = TransmissionLossMapReader.Create(0.95, 1.0, "Dummy"); + + AssertHelper.AreRelativeEqual(0.SI<NewtonMeter>(), + lossMap.GetTorqueLoss(0.RPMtoRad(), 0.SI<NewtonMeter>()).Value); + + AssertHelper.AreRelativeEqual(50.SI<NewtonMeter>(), + lossMap.GetTorqueLoss(1000.RPMtoRad(), 950.SI<NewtonMeter>()).Value); + + AssertHelper.AreRelativeEqual(40.SI<NewtonMeter>(), + lossMap.GetTorqueLoss(1000.RPMtoRad(), 760.SI<NewtonMeter>()).Value); + + AssertHelper.AreRelativeEqual(25.SI<NewtonMeter>(), + lossMap.GetTorqueLoss(1000.RPMtoRad(), 475.SI<NewtonMeter>()).Value); + + AssertHelper.AreRelativeEqual(5.SI<NewtonMeter>(), + lossMap.GetTorqueLoss(1000.RPMtoRad(), 95.SI<NewtonMeter>()).Value); + + AssertHelper.AreRelativeEqual(50.SI<NewtonMeter>(), + lossMap.GetTorqueLoss(500.RPMtoRad(), 950.SI<NewtonMeter>()).Value); + + AssertHelper.AreRelativeEqual(25.SI<NewtonMeter>(), + lossMap.GetTorqueLoss(500.RPMtoRad(), 475.SI<NewtonMeter>()).Value); + + AssertHelper.AreRelativeEqual(5.SI<NewtonMeter>(), + lossMap.GetTorqueLoss(100.RPMtoRad(), 95.SI<NewtonMeter>()).Value); + } + + /// <summary> + /// VECTO-230 + /// </summary> + [TestCase] + public void CreateJobWithLossMapEfficiency_Engineering() + { + var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\12t Delivery Truck Engineering Efficiency.vecto"); + var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, dataProvider, null); + var jobContainer = new JobContainer(null); + jobContainer.AddRuns(runsFactory); + } + + /// <summary> + /// VECTO-230 + /// </summary> + [TestCase] + public void RunJobWithLossMapEfficiency_Engineering() + { + const string jobFileName = @"TestData\Jobs\12t Delivery Truck Engineering Efficiency.vecto"; + var fileWriter = new FileOutputWriter(jobFileName); + + var dataProvider = JSONInputDataFactory.ReadJsonJob(jobFileName); + var factory = new SimulatorFactory(ExecutionMode.Engineering, dataProvider, fileWriter); + var jobContainer = new JobContainer(new MockSumWriter()); + jobContainer.AddRuns(factory); + jobContainer.Execute(); + jobContainer.WaitFinished(); + + foreach (var r in jobContainer.Runs) { + Assert.IsTrue(r.Run.FinishedWithoutErrors, string.Format("{0}", r.ExecException)); + } + } + + /// <summary> + /// VECTO-230 + /// </summary> + [TestCase] + public void CreateJobWith_Axle_LossMapEfficiency_Declaration() + { + var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\40t_Long_Haul_Truck with AxleEfficiency.vecto"); + var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, null); + var jobContainer = new JobContainer(null); + + AssertHelper.Exception<InvalidFileFormatException>(() => jobContainer.AddRuns(runsFactory)); + } + + /// <summary> + /// VECTO-230 + /// </summary> + [TestCase] + public void CreateJobWith_Gear_LossMapEfficiency_Declaration() + { + var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\40t_Long_Haul_Truck with GearEfficiency.vecto"); + var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, null); + var jobContainer = new JobContainer(null); + + AssertHelper.Exception<InvalidFileFormatException>(() => jobContainer.AddRuns(runsFactory)); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/Simulation/SimulationPreprocessingTest.cs b/VectoCore/VectoCoreTest/Models/Simulation/SimulationPreprocessingTest.cs new file mode 100644 index 0000000000000000000000000000000000000000..ce61f93576fc17e3f65ca61ce1b7c163c3d5901b --- /dev/null +++ b/VectoCore/VectoCoreTest/Models/Simulation/SimulationPreprocessingTest.cs @@ -0,0 +1,101 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using NUnit.Framework; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.InputData.FileIO.XML.Declaration; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Tests.Models.Simulation +{ + [TestFixture] + public class SimulationPreprocessingTest + { + + public const string Class9Decl = + @"TestData\Generic Vehicles\Declaration Mode\Class9_RigidTruck_6x2\Class9_RigidTruck_DECL.vecto"; + + [OneTimeSetUp] + public void RunBeforeAnyTests() + { + Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory); + } + + [TestCase(Class9Decl, 20, 2, 19.04812), + TestCase(Class9Decl, 20, 3, 18.71013), + TestCase(Class9Decl, 20, 2.5, 18.87913), + TestCase(Class9Decl, 25, 0, 24.71184), + TestCase(Class9Decl, 25, 1, 24.3735), + TestCase(Class9Decl, 25, 0.5, 24.5427), + TestCase(Class9Decl, 87, -4, 87.6266), + TestCase(Class9Decl, 87, -5, 87.9629), + TestCase(Class9Decl, 87, -4.65, 87.84524) + ] + public void TestSimulationPreprocessing(string jobFile, double vPre, double grad, double vPost) + { + var fileWriter = new FileOutputWriter(jobFile); + var sumWriter = new SummaryDataContainer(fileWriter); + var jobContainer = new JobContainer(sumWriter); + var dataProvider = JSONInputDataFactory.ReadJsonJob(jobFile); + var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, fileWriter) { + ModalResults1Hz = false, + WriteModalResults = true, + ActualModalData = false, + Validate = false, + }; + + jobContainer.AddRuns(runsFactory); + + + var i = 0; + //jobContainer.Runs[i].Run.Run(); + + var lookup = SimulationRunPreprocessing(jobContainer.Runs[i].Run); + + var velocityDrop = lookup.Interpolate(vPre.KMPHtoMeterPerSecond(), VectoMath.InclinationToAngle(grad / 100.0)); + Assert.AreEqual(vPost, velocityDrop.AsKmph, 1e-3); + + + //var rnd = new Random(99); + //var t = Stopwatch.StartNew(); + //for (var j = 0; j < 100000; j++) { + // var vEnd = lookup.Interpolate( + // (5 + rnd.NextDouble() * 110).KMPHtoMeterPerSecond(), + // VectoMath.InclinationToAngle((rnd.NextDouble() * 20 - 10) / 100.0)); + //} + //t.Stop(); + //Console.WriteLine(t.ElapsedMilliseconds); + + } + + + protected virtual VelocityRollingLookup SimulationRunPreprocessing(IVectoRun run) + { + var tmp = new VelocityRollingLookup(); + var preprocessor = new VelocitySpeedGearshiftPreprocessor(tmp, 1.SI<Second>(), minGradient: -12, maxGradient: 12); + var t = Stopwatch.StartNew(); + + preprocessor.RunPreprocessing(run as VectoRun); + t.Stop(); + //Console.WriteLine(t.ElapsedMilliseconds); + + t = Stopwatch.StartNew(); + t.Stop(); + //Console.WriteLine(t.ElapsedMilliseconds); + + return tmp; + } + + } +} diff --git a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs index 1629bf64d7612829b97f7b37e310b185abb66dd2..0043cdba5b4ad366759f08275d3c30e6fae74abc 100644 --- a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs @@ -96,6 +96,8 @@ namespace TUGraz.VectoCore.Tests.Utils } public void Finish(VectoRun.Status runStatus, Exception exception = null) {} + public void Reset() + { } public bool WriteModalResults { get; set; } diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs index df365a62f56c98810aa04bd6a0fff5cdfa6acca1..89c3b8cb8283d86e767610dd315c2f082c6d34c0 100644 --- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs @@ -219,6 +219,14 @@ namespace TUGraz.VectoCore.Tests.Utils public void FinishSimulation() {} public void FinishSimulationRun(Exception e) {} + public void StartSimulationRun() + { } + + public IEnumerable<ISimulationPreprocessor> GetPreprocessingRuns { get { return new ISimulationPreprocessor[] { }; } } + public void AddPreprocessor(ISimulationPreprocessor simulationPreprocessor) + { + throw new NotImplementedException(); + } public Watt SetAxlegearLoss { diff --git a/VectoCore/VectoCoreTest/VectoCoreTest.csproj b/VectoCore/VectoCoreTest/VectoCoreTest.csproj index aa3df9078678da8149c27d7c908ac70efad5f438..a97a3edacd070695097c0eec811aa1260ebcee41 100644 --- a/VectoCore/VectoCoreTest/VectoCoreTest.csproj +++ b/VectoCore/VectoCoreTest/VectoCoreTest.csproj @@ -114,6 +114,7 @@ <Compile Include="Models\Simulation\MockSumWriter.cs" /> <Compile Include="Models\Simulation\GetSectionTest.cs" /> <Compile Include="Models\Simulation\DeclarationSimulationFactoryTest.cs" /> + <Compile Include="Models\Simulation\SimulationPreprocessingTest.cs" /> <Compile Include="Reports\ActualModalSimulationDataTest.cs" /> <Compile Include="Reports\GearshiftCountTest.cs" /> <Compile Include="Reports\ModDataTest.cs" />