diff --git a/VectoCommon/VectoCommon/Utils/SI.cs b/VectoCommon/VectoCommon/Utils/SI.cs index cc77faa2cf5c99360b4325bec5e876163f67f5c5..c81e31d71976bdcbe4abc03adadce237f3e2fb20 100644 --- a/VectoCommon/VectoCommon/Utils/SI.cs +++ b/VectoCommon/VectoCommon/Utils/SI.cs @@ -642,6 +642,11 @@ namespace TUGraz.VectoCommon.Utils return SIBase<PerSquareSecond>.Create(perSecond.Val / second.Value()); } + public static MeterPerSecond operator *(PerSecond perSecond, Meter meter) + { + return SIBase<MeterPerSecond>.Create(perSecond.Val * meter.Value()); + } + public double AsRPM { get { return Val * 60 / (2 * Math.PI); } diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs index 4d63d274f73340f70a75198c5775019255425beb..3bd7b74aa016db79d13e08b9dc2f080f96dfa85d 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs @@ -38,6 +38,7 @@ using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.InputData.Reader.ShiftStrategy; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; @@ -473,5 +474,22 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter CrossWindCorrectionMode.DeclarationModeCorrection) }; } + + public ShiftStrategyParameters CreateGearshiftData() + { + var retVal = new ShiftStrategyParameters { + ShareTorque99L = ShareTorque99lLookupReader.ReadFromStream( + RessourceHelper.ReadStream( + DeclarationData.DeclarationDataResourcePrefix + ".GearshiftParameters.ShareTq99L.csv") + ), + PredictionDurationLookup = PredictionDurationLookupReader.ReadFromStream( + RessourceHelper.ReadStream( + DeclarationData.DeclarationDataResourcePrefix + ".GearshiftParameters.PredictionTimeLookup.csv") + ) + }; + + + return retVal; + } } } diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs index a50d9c242175ab7a8a44d31d158e68cc57f5ff45..805dbe8ca8cd8cf96565e92452ec5018b9a101c1 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs @@ -69,6 +69,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl private PTOData _ptoTransmissionData; private PTOData _municipalPtoTransmissionData; private Exception InitException; + private ShiftStrategyParameters _gearshiftData; internal DeclarationModeVectoRunDataFactory(IDeclarationInputDataProvider dataProvider, IDeclarationReport report) { @@ -117,8 +118,11 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl _ptoTransmissionData = _dao.CreatePTOTransmissionData(InputDataProvider.JobInputData.Vehicle.PTOTransmissionInputData); _municipalPtoTransmissionData = CreateDefaultPTOData(); + + _gearshiftData = _dao.CreateGearshiftData(); } + private void InitializeReport() { var powertrainConfig = new VectoRunData() { @@ -186,8 +190,8 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl ? _municipalPtoTransmissionData : _ptoTransmissionData, InputDataHash = InputDataProvider.XMLHash, - SimulationType = SimulationType.DistanceCycle - + SimulationType = SimulationType.DistanceCycle, + GearshiftParameters = _gearshiftData }; simulationRunData.EngineData.FuelConsumptionCorrectionFactor = DeclarationData.WHTCCorrection.Lookup( mission.MissionType.GetNonEMSMissionType(), _engineData.WHTCRural, _engineData.WHTCUrban, _engineData.WHTCMotorway) * diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ShiftStrategyParameters.cs b/VectoCore/VectoCore/Models/Simulation/Data/ShiftStrategyParameters.cs index eaa913769f70495058e6eed920bf87bd5fb2d3fb..d8aa908fb6ecbcee74d2d3e4718fa0b042c8e4d3 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/ShiftStrategyParameters.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/ShiftStrategyParameters.cs @@ -1,8 +1,11 @@ -using TUGraz.VectoCore.Models.SimulationComponent.Data.ShiftStrategy; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader.ShiftStrategy; +using TUGraz.VectoCore.Models.SimulationComponent.Data.ShiftStrategy; namespace TUGraz.VectoCore.Models.Simulation.Data { public class ShiftStrategyParameters { public PredictionDurationLookup PredictionDurationLookup { get; internal set; } + public ShareTorque99lLookup ShareTorque99L { get; internal set; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyV2.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyV2.cs index a06d9d6ee94e5d4eb383472529aade8ca9bcd6d7..51074acccc14e96092e5da2dd4ce8794aea81c84 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyV2.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyV2.cs @@ -1,11 +1,9 @@ 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 @@ -18,6 +16,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { var velocityDropData = new VelocityRollingLookup(); dataBus.AddPreprocessor(new VelocitySpeedGearshiftPreprocessor(velocityDropData, data.GearboxData.TractionInterruption)); + + var maxGradability = new MaxGradabilityLookup(); + dataBus.AddPreprocessor(new MaxGradabilityPreprocessor(maxGradability, data)); } #region Overrides of BaseShiftStrategy @@ -50,7 +51,30 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private uint InitStartGear(NewtonMeter outTorque, PerSecond outAngularVelocity) { - return 1; + var maxStartGear = (int)Math.Round(ModelData.Gears.Count / 2.0, MidpointRounding.AwayFromZero); + + var startGear = 1u; + var minRating = double.MaxValue; + for (uint i = (uint)maxStartGear; i > 0; i--) { + if (StartGearAllowed(i)) { + var rating = RatingStartGear(i); + if (rating < minRating) { + minRating = rating; + startGear = i; + } + } + } + return startGear; + } + + private double RatingStartGear(uint u) + { + throw new NotImplementedException(); + } + + private bool StartGearAllowed(uint gear) + { + throw new NotImplementedException(); } public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 5881f2ae2f25a93d436d659f71b1a1ad4f894a2f..a2250b3176e8cdc24befeb96fe81f9c312555ab6 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -334,6 +334,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return new ResponseSuccess { Source = this, EnginePowerRequest = PreviousState.EnginePower, + DynamicFullLoadPower = PreviousState.DynamicFullLoadTorque * PreviousState.EngineSpeed, EngineSpeed = outAngularVelocity }; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MaxGradabilityLookup.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MaxGradabilityLookup.cs new file mode 100644 index 0000000000000000000000000000000000000000..b07e95444763b8bee0ec14efc0e823bdf8311777 --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MaxGradabilityLookup.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class MaxGradabilityLookup + { + protected internal Dictionary<uint, Tuple<Radian, Radian>> _data; + + public MaxGradabilityLookup() + { + } + + public Dictionary<uint, Tuple<Radian, Radian>> Data + { + set { _data = value; } + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MaxGradabilityPreprocessor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MaxGradabilityPreprocessor.cs new file mode 100644 index 0000000000000000000000000000000000000000..35c2a493af91bafc1bcc295e9c4c552c49a8e0e5 --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MaxGradabilityPreprocessor.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { + public class MaxGradabilityPreprocessor : ISimulationPreprocessor + { + protected MaxGradabilityLookup GradabilityLookup; + protected VectoRunData ModelData; + + public MaxGradabilityPreprocessor(MaxGradabilityLookup maxGradability, VectoRunData modelData) + { + GradabilityLookup = maxGradability; + ModelData = modelData; + } + + + #region Implementation of ISimulationPreprocessor + + public void RunPreprocessing(VectoRun container) + { + GradabilityLookup.Data = SearchMaxRoadGradient(container); + } + + private Dictionary<uint, Tuple<Radian, Radian>> SearchMaxRoadGradient(VectoRun run) + { + var container = run.GetContainer() as VehicleContainer; + var vehicle = container?.Vehicle as Vehicle; + if (vehicle == null) { + throw new VectoException("no vehicle found..."); + } + + var gearbox = container.Gearbox as Gearbox; + if (gearbox == null) { + throw new VectoException("no gearbox found..."); + } + + var driver = container.Driver as Driver; + if (driver == null) { + throw new VectoException("no driver found..."); + } + driver.DriverBehavior = DrivingBehavior.Driving; + + var retVal = new Dictionary<uint, Tuple<Radian, Radian>>(); + foreach (var gearData in ModelData.GearboxData.Gears) { + var engineSpeed = ModelData.EngineData.FullLoadCurves[0].NTq99lSpeed; + var vehicleSpeed = CalcVehicleSpeed(engineSpeed, gearData); + gearbox.Gear = gearData.Key; + var gradMaxTorque = SearchGradient(vehicle, vehicleSpeed, ModelData.EngineData.FullLoadCurves[0].MaxTorque * 0.99); + + engineSpeed = (ModelData.EngineData.FullLoadCurves[0].NTq99lSpeed + + ModelData.EngineData.FullLoadCurves[0].NTq99hSpeed) / 2.0; + vehicleSpeed = CalcVehicleSpeed(engineSpeed, gearData); + var torqueFactor = ModelData.GearshiftParameters.ShareTorque99L.Lookup(vehicleSpeed); + var gradRedTorque = SearchGradient(vehicle, vehicleSpeed, ModelData.EngineData.FullLoadCurves[0].FullLoadStationaryTorque(engineSpeed) * torqueFactor); + + retVal.Add(gearData.Key, Tuple.Create(gradMaxTorque, gradRedTorque)); + } + + return retVal; + } + + private Radian SearchGradient(Vehicle vehicle, MeterPerSecond vehicleSpeed, NewtonMeter maxTorque) + { + var gradient = VectoMath.InclinationToAngle(0); + var response = vehicle.Initialize(vehicleSpeed, gradient); + + var delta = response.EnginePowerRequest / response.EngineSpeed - maxTorque; + gradient = SearchAlgorithm.Search( + gradient, delta, VectoMath.InclinationToAngle(1), + getYValue: r => { + var rs = r as ResponseSuccess; + if (rs != null) { + return rs.EnginePowerRequest / rs.EngineSpeed - maxTorque; + } + + return 0.SI<NewtonMeter>(); + }, + evaluateFunction: g => { + return vehicle.Initialize(vehicleSpeed, g); + }, + criterion: r => { + var rs = r as ResponseSuccess; + if (rs != null) { + return (rs.EnginePowerRequest / rs.EngineSpeed - maxTorque).Value(); + } + return 0; + } + + ); + + return gradient; + } + + private MeterPerSecond CalcVehicleSpeed(PerSecond engineSpeed, KeyValuePair<uint, GearData> gearData) + { + return engineSpeed / gearData.Value.Ratio / ModelData.AxleGearData.AxleGear.Ratio / + (ModelData.AngledriveData?.Angledrive.Ratio ?? 1.0) * ModelData.VehicleData.DynamicTyreRadius; + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index 435433a031e7d4795a1c3f8ac0c915c88f80f110..60d25f5a49b37ffea977a97e4f19b313cd3ffbb3 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -197,6 +197,8 @@ <Compile Include="Models\SimulationComponent\Impl\CycleTorqueConverter.cs" /> <Compile Include="Models\SimulationComponent\Impl\DrivingCycleEnumerator.cs" /> <Compile Include="Models\SimulationComponent\Impl\EngineFanAuxiliary.cs" /> + <Compile Include="Models\SimulationComponent\Impl\MaxGradabilityLookup.cs" /> + <Compile Include="Models\SimulationComponent\Impl\MaxGradabilityPreprocessor.cs" /> <Compile Include="Models\SimulationComponent\Impl\TorqueConverterWrapper.cs" /> <Compile Include="Models\SimulationComponent\Impl\VelocityRollingLookup.cs" /> <Compile Include="Models\SimulationComponent\Impl\VelocitySpeedGearshiftPreprocessor.cs" /> diff --git a/VectoCore/VectoCoreTest/Models/Simulation/SimulationPreprocessingTest.cs b/VectoCore/VectoCoreTest/Models/Simulation/SimulationPreprocessingTest.cs index ce61f93576fc17e3f65ca61ce1b7c163c3d5901b..f2f175dd44dbc680465c8cbc25e1eeb67f748035 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/SimulationPreprocessingTest.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/SimulationPreprocessingTest.cs @@ -42,7 +42,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation TestCase(Class9Decl, 87, -5, 87.9629), TestCase(Class9Decl, 87, -4.65, 87.84524) ] - public void TestSimulationPreprocessing(string jobFile, double vPre, double grad, double vPost) + public void TestSimulationPreprocessingVelocityDuringTractionInterruption(string jobFile, double vPre, double grad, double vPost) { var fileWriter = new FileOutputWriter(jobFile); var sumWriter = new SummaryDataContainer(fileWriter); @@ -61,7 +61,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var i = 0; //jobContainer.Runs[i].Run.Run(); - var lookup = SimulationRunPreprocessing(jobContainer.Runs[i].Run); + var lookup = SimulationRunPreprocessingVelocityTractionInterruption(jobContainer.Runs[i].Run); var velocityDrop = lookup.Interpolate(vPre.KMPHtoMeterPerSecond(), VectoMath.InclinationToAngle(grad / 100.0)); Assert.AreEqual(vPost, velocityDrop.AsKmph, 1e-3); @@ -79,8 +79,8 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation } - - protected virtual VelocityRollingLookup SimulationRunPreprocessing(IVectoRun run) + + protected virtual VelocityRollingLookup SimulationRunPreprocessingVelocityTractionInterruption(IVectoRun run) { var tmp = new VelocityRollingLookup(); var preprocessor = new VelocitySpeedGearshiftPreprocessor(tmp, 1.SI<Second>(), minGradient: -12, maxGradient: 12); @@ -97,5 +97,61 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation return tmp; } + + [TestCase(Class9Decl), + ] + public void TestSimulationPreprocessingGradability(string jobFile) + { + 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 = 1; + //jobContainer.Runs[i].Run.Run(); + + var lookup = SimulationRunPreprocessingGradability(jobContainer.Runs[i].Run); + + foreach (var tuple in lookup._data) { + Console.WriteLine("gear: {0}, maxTorque gradability: {1}, redTorque gradeabitlity: {2}", tuple.Key, tuple.Value.Item1, tuple.Value.Item2); + } + + Assert.AreEqual(0.2004, lookup._data[4].Item1.Value(), 1e-3); + Assert.AreEqual(0.1225, lookup._data[4].Item2.Value(), 1e-3); + + Assert.AreEqual(0.0710, lookup._data[8].Item1.Value(), 1e-3); + Assert.AreEqual(0.0719, lookup._data[8].Item2.Value(), 1e-3); + + Assert.AreEqual(0.0187, lookup._data[12].Item1.Value(), 1e-3); + Assert.AreEqual(0.0176, lookup._data[12].Item2.Value(), 1e-3); + + } + + + protected virtual MaxGradabilityLookup SimulationRunPreprocessingGradability(IVectoRun run) + { + var tmp = new MaxGradabilityLookup(); + var preprocessor = new MaxGradabilityPreprocessor(tmp, run.GetContainer().RunData); + 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; + } } }