diff --git a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs index 5e77053a9c2028f49b534d5a561a4b6723c3d83b..dfdeb3a1572acdd88823e7ab94c45374ec2d581d 100644 --- a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs +++ b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs @@ -35,7 +35,7 @@ namespace TUGraz.VectoCommon.Models { public PerSecond GenSetSpeed { get; set; } } - [DebuggerDisplay("{U,nq}: {Score,nq} - G{Gear,nq} - {IgnoreReason,nq}")] + [DebuggerDisplay("{U.ToString(\"F4\"),nq}: {Score,nq} - G{Gear,nq} - {IgnoreReason,nq}")] public class HybridResultEntry { public Second SimulationInterval; diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index c887575c4540ba432108147070066f5c7435804e..81845ff30904b2726ea287ff8a808b29488feea7 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -35,7 +35,6 @@ using System.IO; using System.Linq; using Newtonsoft.Json.Linq; using System.Collections.Concurrent; -using Castle.DynamicProxy.Generators.Emitters.SimpleAST; using TUGraz.VectoCommon.BusAuxiliaries; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; diff --git a/VectoCore/VectoCore/Models/GenericModelData/GenericBusBatteryData.cs b/VectoCore/VectoCore/Models/GenericModelData/GenericBusBatteryData.cs index 3097eed69b70cdadbab6f21cf5b800d5b78619b3..613baf2654225e361724c28d02dce13fb1eac631 100644 --- a/VectoCore/VectoCore/Models/GenericModelData/GenericBusBatteryData.cs +++ b/VectoCore/VectoCore/Models/GenericModelData/GenericBusBatteryData.cs @@ -111,10 +111,10 @@ namespace TUGraz.VectoCore.Models.GenericModelData secIndex = i; } - var fstSoC = sortedOcvData[fstIndex].ParseDouble(XMLNames.REESS_OCV_SoC); - var secSoC = sortedOcvData[secIndex].ParseDouble(XMLNames.REESS_OCV_SoC); - var fstOCV = sortedOcvData[fstIndex].ParseDouble(XMLNames.REESS_OCV_OCV); - var secOCV = sortedOcvData[secIndex].ParseDouble(XMLNames.REESS_OCV_OCV); + var fstSoC = sortedOcvData[fstIndex].ParseDouble(BatterySOCReader.Fields.StateOfCharge); + var secSoC = sortedOcvData[secIndex].ParseDouble(BatterySOCReader.Fields.StateOfCharge); + var fstOCV = sortedOcvData[fstIndex].ParseDouble(BatterySOCReader.Fields.BatteryVoltage); + var secOCV = sortedOcvData[secIndex].ParseDouble(BatterySOCReader.Fields.BatteryVoltage); return VectoMath.Interpolate(fstSoC, secSoC, fstOCV, secOCV, 50).SI<Volt>(); } diff --git a/VectoCore/VectoCore/Models/GenericModelData/GenericRatedPointHelper.cs b/VectoCore/VectoCore/Models/GenericModelData/GenericRatedPointHelper.cs index df96a1fed9b62245679708e26d940795d0ebcdb9..ed97809858bec398d751a0a412a01f5f993e99c2 100644 --- a/VectoCore/VectoCore/Models/GenericModelData/GenericRatedPointHelper.cs +++ b/VectoCore/VectoCore/Models/GenericModelData/GenericRatedPointHelper.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Castle.Core.Internal; +using System.Linq; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Utils; @@ -117,7 +117,7 @@ namespace TUGraz.VectoCore.Models.GenericModelData var slopeValue = (fullLoadCurveEntries[r].PowerDrive.Value() - fullLoadCurveEntries[r - 1].PowerDrive.Value()) / (fullLoadCurveEntries[r].MotorSpeed.Value() - fullLoadCurveEntries[r - 1].MotorSpeed.Value()); - var deltaValue = slopeValue / (slopeValueEntries.IsNullOrEmpty() ? slopeValue : slopeValueEntries[0].Slope ) -1; + var deltaValue = slopeValue / (!slopeValueEntries.Any() ? slopeValue : slopeValueEntries[0].Slope ) -1; slopeValueEntries.Add(new SlopeValueEntry(slopeValue, deltaValue)); } diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IDriverInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IDriverInfo.cs index 0995064cb8fd55e555a1938c7a9fbb85352e68dc..9119340085f284bb1e24ca14c0bddd43989c89c7 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IDriverInfo.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IDriverInfo.cs @@ -54,5 +54,7 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus PCCStates PCCState { get; } MeterPerSecond NextBrakeTriggerSpeed { get; } + + MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs index d7e4a6069f8558802a8bbbc7a9dcfd58668852dd..a9674035ab032b7848ca1e8910853a0d53419a2e 100644 --- a/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs @@ -85,5 +85,7 @@ namespace TUGraz.VectoCore.Models.Simulation void AddPreprocessor(ISimulationPreprocessor simulationPreprocessor); void ResetComponents(); void FinishSingleSimulationRun(Exception e = null); + + IReadOnlyList<VectoSimulationComponent> Components { get; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PCCEcoRollEngineStopPreprocessor.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PCCEcoRollEngineStopPreprocessor.cs index e75d98c02b9967083c206c14c2bc982790baf8ed..f01232bc3d048fcde3f4ebca71b358e617b4a241 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PCCEcoRollEngineStopPreprocessor.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PCCEcoRollEngineStopPreprocessor.cs @@ -125,8 +125,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl var gradient = 0.SI<Radian>(); foreach (var motor in container.ElectricMotors.Values) { - if ((motor as ElectricMotor).Control is DummyElectricMotorControl emCtl) { - emCtl.EmTorque = null; + if ((motor as ElectricMotor).Control is SimpleElectricMotorControl emCtl) { + emCtl.EmOff = true; } } diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index fe5ef139f0d3b38297ce5b858fafec51ef1d3f6d..afa9ed449e3018f87c14bb2ba4c706efad7f6094 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -1785,6 +1785,13 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl default: throw new VectoException("Wrong CycleType for SimplePowertrain"); } + if ((data.SuperCapData != null || data.BatteryData != null) && data.EngineData.WHRType.IsElectrical()) { + var dcDcConverterEfficiency = DeclarationData.WHRChargerEfficiency; + var whrCharger = new WHRCharger(container, dcDcConverterEfficiency); + es.Connect(whrCharger); + engine.WHRCharger = whrCharger; + } + vehicle.AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) .AddComponent(ctl) .AddComponent(new Brakes(container)) @@ -1874,7 +1881,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) .AddComponent(data.GearboxData is null ? null : GetSimpleGearbox(container, data)) .AddComponent(GetElectricMachine(data.ElectricMachinesData.First(x => x.Item1 != PowertrainPosition.GEN).Item1, - data.ElectricMachinesData, container, es, new DummyElectricMotorControl())); + data.ElectricMachinesData, container, es, new SimpleElectricMotorControl())); if (data.AxleGearData == null) { new DummyAxleGearInfo(container); // necessary for certain IEPC configurations } @@ -2262,10 +2269,17 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public class SimpleElectricMotorControl : IElectricMotorControl { + public bool EmOff { get; set; } + public NewtonMeter MechanicalAssistPower(Second absTime, Second dt, NewtonMeter outTorque, PerSecond prevOutAngularVelocity, PerSecond currOutAngularVelocity, NewtonMeter maxDriveTorque, NewtonMeter maxRecuperationTorque, PowertrainPosition position, bool dryRun) { + if (EmOff) { + return null; + } + + if (dryRun) { return -outTorque; } @@ -2294,6 +2308,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl #endregion } + [Obsolete("Replaced with SimpleElectricMotorControl")] public class DummyElectricMotorControl : IElectricMotorControl { #region Implementation of IElectricMotorControl @@ -2338,6 +2353,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public MeterPerSquareSecond DriverAcceleration => 0.SI<MeterPerSquareSecond>(); public PCCStates PCCState => PCCStates.OutsideSegment; public MeterPerSecond NextBrakeTriggerSpeed => 0.SI<MeterPerSecond>(); + public MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed) => targetSpeed; #endregion diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index c2ad903f7072598f38de140333dbe38740229809..304727ca070c908d97de3bf04e6a2607d6427790 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -225,12 +225,16 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl target.UpdateFrom(source); } } else { + var realComponents = (realContainer as IVehicleContainer)?.Components; + if (realComponents == null) { + throw new VectoException("RealContainer has to implement IVehicleContainer interface!"); + } foreach (var (_, c) in _components) { #if DEBUG var found = false; #endif if (c is IUpdateable target) { - foreach (var (_, source) in (realContainer as VehicleContainer)._components) { + foreach (var source in realComponents) { if (target.UpdateFrom(source)) { ComponentUpdateList.Add((target, source)); #if DEBUG @@ -249,7 +253,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl #if DEBUG var sourceList = ComponentUpdateList.Select(st => st.Item2).ToArray(); - foreach (var (_, source) in (realContainer as VehicleContainer)._components) { + foreach (var source in realComponents) { if (!sourceList.Contains(source)){ Console.WriteLine("Real Component is not used for update: " + source.GetType()); } @@ -302,6 +306,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl Preprocessors.Add(simulationPreprocessor); } + public IReadOnlyList<VectoSimulationComponent> Components => _components.Select(x => x.Item2).ToList(); + public virtual void StartSimulationRun() { ModData?.Reset(); diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/WHRCharger.cs b/VectoCore/VectoCore/Models/Simulation/Impl/WHRCharger.cs index 533a22dce50e4ed01e9cf145d8fa998ad0ea6e58..5b02c4d9cc44e7a8270d963d572131a8b1b6bd0d 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/WHRCharger.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/WHRCharger.cs @@ -23,6 +23,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl protected override void DoCommitSimulationStep(Second time, Second simulationInterval) { AdvanceState(); + if (PreviousState.GeneratedEnergy == null && DataBus.IsTestPowertrain) { + // the method GeneratedEnergy is not called because there is no moddata to write and we are in a testpowertrain + // make sure the value is not null... + PreviousState.GeneratedEnergy = 0.SI<WattSecond>(); + } } #endregion diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/IDriverStrategy.cs index 73b382beeb21e3eaa85a8dae4f3399d642ba313a..2a3536504c606286d67725930efb530d957a48fa 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IDriverStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IDriverStrategy.cs @@ -51,5 +51,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent void CommitSimulationStep(); DrivingBehaviorEntry BrakeTrigger { get; } + + MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs index 4e63db4f49918c46e77b1395a7d57d1ce73c26bc..14895df513865844502fb8bae9848511fbeecec6 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs @@ -259,6 +259,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected override bool DoUpdateFrom(object other) { if (other is Clutch c) { PreviousState = c.PreviousState.Clone(); + return true; } return false; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index cddf1f60dd2be8b3ca89c10229ae77e07bab28c0..fd7d038a70df89e9535fd5e2c2e6e33942b62f4d 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -494,7 +494,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var (pWHRelMap, pWHRelCorr) = GetWHRPower(ModelData.ElectricalWHR, engineSpeed, engineTorque); var (pWHRmechMap, pWHRmechCorr) = GetWHRPower(ModelData.MechanicalWHR, engineSpeed, engineTorque); - + + if (DataBus.BatteryInfo != null && Math.Abs(DataBus.BatteryInfo.StateOfCharge - DataBus.BatteryInfo.MaxSoC) < 0.01) { + // we are close to the max charge - 'bypass' electric WHR... + pWHRelCorr = 0.SI<Watt>(); + } + container[ModalResultField.P_WHR_el_map] = pWHRelMap; container[ModalResultField.P_WHR_el_corr] = pWHRelCorr; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs index 52fff8b85e1456a91bd1223ae19505bdab929e15..15fcd43df1186a12adfb9f5280d5a49882a813e0 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs @@ -621,7 +621,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } - public MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed) + public virtual MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed) { return (targetSpeed + GetOverspeed()).LimitTo( 0.KMPHtoMeterPerSecond(), VehicleCategory.IsBus() ? Constants.BusParameters.MaxBusSpeed : 500.KMPHtoMeterPerSecond()); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs index 598d2b5af44c12dc2eb27d2f29efd6a7dde3ed67..606364b93d26b307db422528c6e49cab6408c1ca 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs @@ -185,8 +185,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var distanceToSpeedChange = nextSpeedChange - PreviousState.Distance; var estimatedTimeToSpeedChange = distanceToSpeedChange / DataBus.VehicleInfo.VehicleSpeed; if (estimatedTimeToSpeedChange.IsSmaller(Constants.SimulationSettings.LowerBoundTimeInterval / 2) && - DataBus.VehicleInfo.VehicleSpeed.IsSmaller(Left.VehicleTargetSpeed, 1.KMPHtoMeterPerSecond()) && - DataBus.VehicleInfo.VehicleSpeed.IsSmaller(Right.VehicleTargetSpeed, 1.KMPHtoMeterPerSecond())) { + DataBus.VehicleInfo.VehicleSpeed.IsSmaller(DataBus.DriverInfo.ApplyOverspeed(Left.VehicleTargetSpeed), 0.1.KMPHtoMeterPerSecond()) && + DataBus.VehicleInfo.VehicleSpeed.IsSmaller(DataBus.DriverInfo.ApplyOverspeed(Right.VehicleTargetSpeed), 0.1.KMPHtoMeterPerSecond())) { CurrentState.Response = DriveDistance(absTime, ds); return CurrentState.Response; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs index 09e094ccf84f63438f94d82a2fac52aa87b89b01..2fcda46cb9dd07c65b4164d5118544705b734013 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -1471,6 +1471,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public PCCStates PCCState => DriverStrategy.PCCState; public MeterPerSecond NextBrakeTriggerSpeed => DriverStrategy.BrakeTrigger?.NextTargetSpeed; + public MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed) => DriverStrategy.ApplyOverspeed(targetSpeed); protected override bool DoUpdateFrom(object other) => false; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs index 072b66c009da52271fc7004f107b8b0663839ec6..e440b96a276380d785760e64e8f08d1d8eceddf0 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs @@ -536,6 +536,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } if (ModelData.Overload.OverloadBuffer.Value() != 0) { // mk2021-08-03 overloadbuffer was 0 in Test Case: "ADASTestPEV.TestPCCEngineeringSampleCases G5Eng PCC12 Case A" container[ModalResultField.ElectricMotor_OvlBuffer_, Position] = VectoMath.Max(0, (ThermalBuffer + contribution) / ModelData.Overload.OverloadBuffer); + } else { + container[ModalResultField.ElectricMotor_OvlBuffer_, Position] = 0.SI<Scalar>(); } if (NextComponent == null && BusAux != null) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs index 8938ade47e6cb56e445dc7c4d4a9df140629772e..0fb8c7dbc5ddd6de226acb012d4f35a3fbe6f2b8 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs @@ -113,7 +113,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (retryCount > 10) { throw new VectoException("HybridStrategy: retry count exceeded! {0}", DebugData); } - + var engaged = DataBus.GearboxInfo.GearEngaged(absTime); retry = false; var strategyResponse = Strategy.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); DebugData.Add($"[HC-R-0-{retryCount}]", strategyResponse); @@ -162,6 +162,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl SelectedGear = strategySettings.NextGear; } + CurrentStrategySettings = strategySettings; retVal = NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); DebugData.Add($"HC.R-1-{retryCount}", new { @@ -207,6 +208,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl continue; } + if (retVal is ResponseOverload && DataBus.DriverInfo.DrivingAction == DrivingAction.Brake && + engaged != DataBus.GearboxInfo.GearEngaged(absTime)) { + retryCount++; + retry = true; + Strategy.OperatingpointChangedDuringRequest(absTime, dt, outTorque, outAngularVelocity, dryRun, + retVal); + continue; + } + if (retVal is ResponseInvalidOperatingPoint) { retryCount++; retry = true; @@ -435,9 +445,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected virtual GearshiftPosition InitStartGear(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity) { - if (!DataBus.EngineCtl.CombustionEngineOn) { - return _nextGear; - } + //if (!DataBus.EngineCtl.CombustionEngineOn) { + // return _nextGear; + //} foreach (var gear in GearList.IterateGears(MaxStartGear, GearList.First())) { //for (var gear = MaxStartGear; gear > 1; gear--) { @@ -450,12 +460,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl //var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity); TestPowertrain.UpdateComponents(); + TestPowertrain.Gearbox.Gear = gear; TestPowertrain.Gearbox._nextGear = gear; if (_controller.CurrentStrategySettings != null) { TestPowertrain.HybridController.ApplyStrategySettings(_controller.CurrentStrategySettings); } + TestPowertrain.CombustionEngine.CombustionEngineOn = true; + var response = TestPowertrain.Gearbox.Initialize(outTorque, outAngularVelocity); response = TestPowertrain.Gearbox.Request(absTime, Constants.SimulationSettings.MeasuredSpeedTargetTimeInterval, outTorque, outAngularVelocity, diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs index bac76f36413474f983a7f45e4d82c470c8f05c14..43a228a11524d25d24f096038ddb6e048b888adc 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs @@ -451,6 +451,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public PCCStates PCCState => PCCStates.OutsideSegment; public MeterPerSecond NextBrakeTriggerSpeed => 0.SI<MeterPerSecond>(); + public MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed) => targetSpeed; public Meter Distance => CurrentState.Distance; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs index 3b9c6810b8434671e041ef0a3a9601f9ffe7b4ad..f714f1cf1684609a46fae159bf8ff071fcc6ea97 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs @@ -181,6 +181,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public MeterPerSquareSecond DriverAcceleration => 0.SI<MeterPerSquareSecond>(); public PCCStates PCCState => PCCStates.OutsideSegment; public MeterPerSecond NextBrakeTriggerSpeed => 0.SI<MeterPerSecond>(); + public MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed) => targetSpeed; private void DetermineDriverAction() { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategyOptimized.cs index 363f901f80b621a26462e71041ae079a4ed0269d..fc818813a00de7d6e9e6d10907f167bbdae7310f 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategyOptimized.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategyOptimized.cs @@ -24,8 +24,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) { - return DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygon( + return DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon( i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius); + //return DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygon( + // i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius); } } public class AMTShiftStrategyOptimized : AMTShiftStrategy diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs index a95252c997b1074663503aa3d628aed9fe3d08a1..7757296b4a0446075bb74e765e14bd9ff6e9cdfc 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs @@ -144,6 +144,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies PowertrainBuilder.BuildSimplePowertrainElectric(runData, testContainer); TestPowertrain = new TestPowertrain<Gearbox>(testContainer, DataBus); + foreach (var motor in testContainer.ElectricMotors.Values) + { + if ((motor as ElectricMotor).Control is SimpleElectricMotorControl emCtl) { + emCtl.EmOff = false; //Make sure em is switched on + } + } } protected void SetupVelocityDropPreprocessor(IVehicleContainer dataBus) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimplePowertrainContainer.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimplePowertrainContainer.cs index 2696b4904738e581962df417053be2ebe788e12e..ca3134ab842489fc0aafd2214f1fbcc94228befd 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimplePowertrainContainer.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimplePowertrainContainer.cs @@ -34,6 +34,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { public MeterPerSquareSecond DriverAcceleration => 0.SI<MeterPerSquareSecond>(); public PCCStates PCCState => PCCStates.OutsideSegment; public MeterPerSecond NextBrakeTriggerSpeed => 0.SI<MeterPerSecond>(); + public MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed) => targetSpeed; #endregion diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs index 3a12c7e7f390760354f76183c2f21df9bda77f57..b932211fa10553f749370c8346da98c031869360 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs @@ -42,25 +42,29 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies testContainer, -grad, grad); } - protected override IResponse RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition nextGear, HybridStrategyResponse cfg) + protected override IResponse RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, + PerSecond outAngularVelocity, GearshiftPosition nextGear, HybridStrategyResponse cfg) { TestPowertrain.UpdateComponents(); + var useNextGear = nextGear; + if (nextGear.Gear == 0) { + useNextGear = Controller.ShiftStrategy.NextGear; + } - TestPowertrain.Gearbox.Gear = DataBus.VehicleInfo.VehicleStopped ? Controller.ShiftStrategy.NextGear : PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear; - TestPowertrain.Gearbox.Disengaged = !nextGear.Engaged; - TestPowertrain.Gearbox.DisengageGearbox = !nextGear.Engaged; + TestPowertrain.Gearbox.Gear = useNextGear; // DataBus.VehicleInfo.VehicleStopped ? Controller.ShiftStrategy.NextGear : PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear; + TestPowertrain.Gearbox.Disengaged = !useNextGear.Engaged; + TestPowertrain.Gearbox.DisengageGearbox = !useNextGear.Engaged; + TestPowertrain.Gearbox._nextGear = Controller.ShiftStrategy.NextGear; TestPowertrain.Container.VehiclePort.Initialize(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); TestPowertrain.HybridController.ApplyStrategySettings(cfg); - TestPowertrain.HybridController.Initialize(Controller.PreviousState.OutTorque, Controller.PreviousState.OutAngularVelocity); - - TestPowertrain.Brakes.BrakePower = DataBus.Brakes.BrakePower; - if (nextGear.Engaged && !nextGear.Equals(TestPowertrain.Gearbox.Gear)) { - if (!AllowEmergencyShift && ModelData.GearboxData.Gears[nextGear.Gear].Ratio > ModelData.GearshiftParameters.RatioEarlyUpshiftFC) { + + if (useNextGear.Engaged && !useNextGear.Equals(TestPowertrain.Gearbox.Gear)) { + if (!AllowEmergencyShift && ModelData.GearboxData.Gears[useNextGear.Gear].Ratio > ModelData.GearshiftParameters.RatioEarlyUpshiftFC) { return null; } - if (!AllowEmergencyShift && ModelData.GearboxData.Gears[nextGear.Gear].Ratio >= ModelData.GearshiftParameters.RatioEarlyDownshiftFC) { + if (!AllowEmergencyShift && ModelData.GearboxData.Gears[useNextGear.Gear].Ratio >= ModelData.GearshiftParameters.RatioEarlyDownshiftFC) { return null; } var estimatedVelocityPostShift = !VelocityDropData.Valid ? DataBus.VehicleInfo.VehicleSpeed : VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); @@ -68,22 +72,24 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return null; } - TestPowertrain.Gearbox.Gear = nextGear; + TestPowertrain.Gearbox.Gear = useNextGear; var init = TestPowertrain.Container.VehiclePort.Initialize(estimatedVelocityPostShift, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); if (!AllowEmergencyShift && init.Engine.EngineSpeed.IsSmaller(ModelData.EngineData.IdleSpeed)) { return null; } } - TestPowertrain.Gearbox._nextGear = Controller.ShiftStrategy.NextGear; - TestPowertrain.Gearbox.Disengaged = !nextGear.Engaged; - TestPowertrain.CombustionEngine.UpdateFrom(DataBus.EngineInfo); - TestPowertrain.Gearbox.UpdateFrom(DataBus.GearboxInfo); - TestPowertrain.Clutch.UpdateFrom(DataBus.ClutchInfo); - var pos = ModelData.ElectricMachinesData.FirstOrDefault().Item1; - TestPowertrain.ElectricMotor.UpdateFrom(DataBus.ElectricMotorInfo(pos)); - foreach (var emPos in TestPowertrain.ElectricMotorsUpstreamTransmission.Keys) { - TestPowertrain.ElectricMotorsUpstreamTransmission[pos].PreviousState.EMSpeed = DataBus.ElectricMotorInfo(emPos).ElectricMotorSpeed; + TestPowertrain.HybridController.Initialize(Controller.PreviousState.OutTorque, Controller.PreviousState.OutAngularVelocity); + + if (!PreviousState.GearboxEngaged || (useNextGear.Engaged && useNextGear.Equals(DataBus.GearboxInfo.Gear)) || !nextGear.Engaged) { + TestPowertrain.CombustionEngine.UpdateFrom(DataBus.EngineInfo); + TestPowertrain.Gearbox.UpdateFrom(DataBus.GearboxInfo); + TestPowertrain.Clutch.UpdateFrom(DataBus.ClutchInfo); + var pos = ModelData.ElectricMachinesData.FirstOrDefault().Item1; + TestPowertrain.ElectricMotor.UpdateFrom(DataBus.ElectricMotorInfo(pos)); + foreach (var emPos in TestPowertrain.ElectricMotorsUpstreamTransmission.Keys) { + TestPowertrain.ElectricMotorsUpstreamTransmission[pos].PreviousState.EMSpeed = DataBus.ElectricMotorInfo(emPos).ElectricMotorSpeed; + } } var retVal = TestPowertrain.HybridController.NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, true); @@ -128,6 +134,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies TestPowertrain.HybridController.Initialize(Controller.PreviousState.OutTorque, Controller.PreviousState.OutAngularVelocity); TestPowertrain.Brakes.BrakePower = DataBus.Brakes.BrakePower; + TestPowertrain.DCDCConverter?.UpdateFrom(DataBus.DCDCConverter); if (nextGear.Engaged && !nextGear.Equals(TestPowertrain.Gearbox.Gear)) { if (!AllowEmergencyShift && ModelData.GearboxData.Gears[nextGear.Gear].Ratio > ModelData.GearshiftParameters.RatioEarlyUpshiftFC) { @@ -808,322 +815,380 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies var vehiclespeedBelowThreshold = DataBus.VehicleInfo.VehicleSpeed.IsSmaller(disengageSpeedThreshold) && (DataBus.DriverInfo.NextBrakeTriggerSpeed?.IsEqual(0) ?? false); - if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime)) { - - if (vehiclespeedBelowThreshold && emPos.IsOneOf(PowertrainPosition.HybridP2, PowertrainPosition.HybridP1, PowertrainPosition.IHPC)) { - if (DataBus.GearboxInfo.GearboxType.AutomaticTransmission()) { - var firstgear = ResponseEmOff; - firstgear.Gear = GearList.First(); - eval.Add(firstgear); - return; - } else { - var off = ResponseEmOff; - off.Setting.GearboxInNeutral = true; - eval.Add(off); - return; - } - } - - GearshiftPosition nextGear; - if (!DataBus.GearboxInfo.GearEngaged(absTime)) { - nextGear = new GearshiftPosition(0); - } else if (PreviousState.GearboxEngaged) { - nextGear = DataBus.GearboxInfo.Gear; + if (!ElectricMotorCanPropellDuringTractionInterruption && !DataBus.GearboxInfo.GearEngaged(absTime)) { + var off = ResponseEmOff; + if (vehiclespeedBelowThreshold && + (emPos == PowertrainPosition.HybridP2 || emPos == PowertrainPosition.HybridP1)) { + off.Setting.GearboxInNeutral = true; } else { - nextGear = Controller.ShiftStrategy.NextGear; + off.Setting.GearboxInNeutral = PreviousState.Solution?.Setting.GearboxInNeutral ?? false; } - if (!nextGear.IsLockedGear()) { - eval.Add(ResponseEmOff); + eval.Add(off); + return; + } + + GearshiftPosition nextGear; + if (!DataBus.GearboxInfo.GearEngaged(absTime)) { + nextGear = new GearshiftPosition(0); + } else if (PreviousState.GearboxEngaged) { + nextGear = DataBus.GearboxInfo.Gear; + } else { + nextGear = Controller.ShiftStrategy.NextGear; + } + + if (vehiclespeedBelowThreshold && emPos.IsOneOf(PowertrainPosition.HybridP2, + PowertrainPosition.HybridP1, PowertrainPosition.IHPC)) { + if (DataBus.GearboxInfo.GearboxType.AutomaticTransmission()) { + var firstgear = ResponseEmOff; + firstgear.Gear = GearList.First(); + eval.Add(firstgear); return; } - var disengaged = nextGear.Gear == 0; - //if (!disengaged && outAngularVelocity.IsEqual(0)) { - // var stop = ResponseEmOff; - // stop.Gear = new GearshiftPosition(0); - // eval.Add(stop); - // return; - //} - var currentGear = nextGear; - var tmp = new HybridStrategyResponse { + var testDisengage = new HybridStrategyResponse { CombustionEngineOn = DataBus.EngineInfo.EngineOn, // AllowICEOff(absTime), GearboxInNeutral = false, NextGear = nextGear, MechanicalAssistPower = ElectricMotorsOff }; - var response = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, tmp); - debug.Add($"[AHS.HBA-0] DryRun Gear={nextGear}", response); - - var endSpeed = DataBus.VehicleInfo.VehicleSpeed + - DataBus.DriverInfo.DriverAcceleration * ModelData.GearboxData.TractionInterruption; - if (EngineSpeedTooLow(response) - && (DataBus.GearboxInfo.GearboxType.ManualTransmission() || DataBus.GearboxInfo.GearboxType == GearboxType.IHPC) - && endSpeed.IsSmallerOrEqual(disengageSpeedThreshold, 0.1.KMPHtoMeterPerSecond())) { - var responseEmOff = ResponseEmOff; - responseEmOff.Gear = new GearshiftPosition(0); - responseEmOff.Setting.GearboxEngaged = false; - responseEmOff.Setting.GearboxInNeutral = true; - eval.Add(responseEmOff); - return; + var testDisengageResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, + testDisengage); + + var off = ResponseEmOff; + + if (testDisengageResponse.Clutch.PowerRequest.IsSmaller(0)) { + // only disengage if the torque at the clutch is negative - i.e. no propulsion needed + off.Setting.GearboxInNeutral = true; } - if (GearList.HasPredecessor(nextGear) - && EngineSpeedTooLow(response) - && (!vehiclespeedBelowThreshold || AllowEmergencyShift)) { - // engine speed would fall below idling speed - consider downshift - var estimatedVelocityPostShift = VelocityDropData.Valid - ? VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, - DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()) - : DataBus.VehicleInfo.VehicleSpeed; - var postShiftBelowThreshold = estimatedVelocityPostShift.IsSmaller(disengageSpeedThreshold); - if (postShiftBelowThreshold) { - var downshift = ResponseEmOff; - downshift.Gear = GearList.Predecessor(nextGear); - eval.Add(downshift); - return; - } - do { - nextGear = GearList.Predecessor(nextGear); - response = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, tmp); - debug.Add($"[AHS.HBA-1] DryRun Gear={nextGear}", response); - } while (GearList.HasPredecessor(nextGear) && response == null); - } - - if (nextGear.Equals(GearList.First()) && EngineSpeedTooLow(response)) { - // disengage gearbox... - var responseEmOff = ResponseEmOff; - responseEmOff.Gear = new GearshiftPosition(0); - responseEmOff.Setting.GearboxEngaged = false; - responseEmOff.Setting.GearboxInNeutral = true; - eval.Add(responseEmOff); - return; + eval.Add(off); + return; + } + + if (!nextGear.IsLockedGear()) { + var off = ResponseEmOff; + var offResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, off.Setting); + if (offResponse.Source is ATGearbox && offResponse is ResponseOverload && GearList.HasPredecessor(nextGear)) { + off.Gear = GearList.Predecessor(nextGear); } + eval.Add(off); + return; + } - if (DataBus.GearboxInfo.GearboxType.AutomaticTransmission() && response == null && nextGear.Equals(GearList.First())) { + var disengaged = nextGear.Gear == 0; + //if (!disengaged && outAngularVelocity.IsEqual(0)) { + // var stop = ResponseEmOff; + // stop.Gear = new GearshiftPosition(0); + // eval.Add(stop); + // return; + //} + var currentGear = nextGear; + var tmp = new HybridStrategyResponse { + CombustionEngineOn = DataBus.EngineInfo.EngineOn, // AllowICEOff(absTime), + GearboxInNeutral = false, + NextGear = nextGear, + MechanicalAssistPower = ElectricMotorsOff + }; + var response = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, tmp); + debug.Add($"[AHS.HBA-0] DryRun Gear={nextGear}", response); + + var endSpeed = DataBus.VehicleInfo.VehicleSpeed + + DataBus.DriverInfo.DriverAcceleration * ModelData.GearboxData.TractionInterruption; + if (EngineSpeedTooLow(response) + && (DataBus.GearboxInfo.GearboxType.ManualTransmission() || + DataBus.GearboxInfo.GearboxType == GearboxType.IHPC) + && endSpeed.IsSmallerOrEqual(disengageSpeedThreshold, 0.1.KMPHtoMeterPerSecond())) { + var responseEmOff = ResponseEmOff; + // if the engine speed is too low but the gear is engaged in this timestep, use the gear as calculated before. + // on re-engage the engine speed is checked and a lower gear is engaged. then the hybrid strategy is called again. + responseEmOff.Gear = (!PreviousState.GearboxEngaged && DataBus.GearboxInfo.GearEngaged(absTime)) + ? currentGear + : new GearshiftPosition(0); + responseEmOff.Setting.GearboxEngaged = false; + responseEmOff.Setting.GearboxInNeutral = + (!PreviousState.GearboxEngaged && DataBus.GearboxInfo.GearEngaged(absTime)) ? false : true; + eval.Add(responseEmOff); + return; + } + + if (GearList.HasPredecessor(nextGear) + && EngineSpeedTooLow(response) + && (!vehiclespeedBelowThreshold || AllowEmergencyShift)) { + // engine speed would fall below idling speed - consider downshift + var estimatedVelocityPostShift = VelocityDropData.Valid + ? VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, + DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()) + : DataBus.VehicleInfo.VehicleSpeed; + var postShiftBelowThreshold = estimatedVelocityPostShift.IsSmaller(disengageSpeedThreshold); + if (postShiftBelowThreshold) { var downshift = ResponseEmOff; - downshift.Gear = nextGear; + downshift.Gear = GearList.Predecessor(nextGear); eval.Add(downshift); return; } - if (tmp.CombustionEngineOn) { - var firstEntry = new HybridResultEntry(); - CalculateCosts(response, dt, firstEntry, AllowICEOff(absTime), dryRun); - var minimumShiftTimePassed = (DataBus.GearboxInfo.LastShift + ModelData.GearshiftParameters.TimeBetweenGearshifts).IsSmallerOrEqual(absTime); - if (DataBus.GearboxInfo.GearEngaged(absTime) && !vehiclespeedBelowThreshold) { - var reEngaged = !PreviousState.GearboxEngaged && DataBus.GearboxInfo.GearEngaged(absTime); - if ((firstEntry.IgnoreReason.EngineSpeedBelowDownshift() && !firstEntry.IgnoreReason.EngineTorqueDemandTooHigh() || - firstEntry.IgnoreReason.EngineSpeedTooLow()) && !reEngaged) { - // ICE torque below FLD is OK as EM may regenerate and shift ICE operating point on drag line - // for negative torques the shift line is vertical anyway ;-) - var best = FindBestGearForBraking(nextGear, response); - if (!best.Equals(currentGear)) { - // downshift required! - var downshift = ResponseEmOff; - //downshift.Gear = GearList.Predecessor(nextGear); - downshift.Gear = best; // GearList.Predecessor(nextGear); - downshift.Setting.GearboxInNeutral = best.Gear == 0; - downshift.Setting.ShiftRequired = best.Gear == 0; - eval.Add(downshift); - return; - } + do { + nextGear = GearList.Predecessor(nextGear); + response = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, tmp); + debug.Add($"[AHS.HBA-1] DryRun Gear={nextGear}", response); + } while (GearList.HasPredecessor(nextGear) && response == null); + } + + if (nextGear.Equals(GearList.First()) && EngineSpeedTooLow(response)) { + // disengage gearbox... + var responseEmOff = ResponseEmOff; + responseEmOff.Gear = new GearshiftPosition(0); + responseEmOff.Setting.GearboxEngaged = false; + responseEmOff.Setting.GearboxInNeutral = true; + eval.Add(responseEmOff); + return; + } + + if (DataBus.GearboxInfo.GearboxType.AutomaticTransmission() && response == null && + nextGear.Equals(GearList.First())) { + var downshift = ResponseEmOff; + downshift.Gear = nextGear; + eval.Add(downshift); + return; + } + + if (tmp.CombustionEngineOn) { + var firstEntry = new HybridResultEntry(); + CalculateCosts(response, dt, firstEntry, AllowICEOff(absTime), dryRun); + var minimumShiftTimePassed = + (DataBus.GearboxInfo.LastShift + ModelData.GearshiftParameters.TimeBetweenGearshifts) + .IsSmallerOrEqual(absTime); + if (DataBus.GearboxInfo.GearEngaged(absTime) && !vehiclespeedBelowThreshold) { + var reEngaged = !PreviousState.GearboxEngaged && DataBus.GearboxInfo.GearEngaged(absTime); + if ((firstEntry.IgnoreReason.EngineSpeedBelowDownshift() && + !firstEntry.IgnoreReason.EngineTorqueDemandTooHigh() || + firstEntry.IgnoreReason.EngineSpeedTooLow()) && !reEngaged) { + // ICE torque below FLD is OK as EM may regenerate and shift ICE operating point on drag line + // for negative torques the shift line is vertical anyway ;-) + var best = FindBestGearForBraking(nextGear, response); + if (!best.Equals(currentGear)) { + // downshift required! + var downshift = ResponseEmOff; + //downshift.Gear = GearList.Predecessor(nextGear); + downshift.Gear = best; // GearList.Predecessor(nextGear); + downshift.Setting.GearboxInNeutral = best.Gear == 0; + downshift.Setting.ShiftRequired = best.Gear == 0; + eval.Add(downshift); + return; } } + } - if (!nextGear.Equals(currentGear) && !firstEntry.IgnoreReason.InvalidEngineSpeed()) { - firstEntry.Gear = nextGear; - firstEntry.Setting = tmp; - eval.Add(firstEntry); - } + if (!nextGear.Equals(currentGear) && !firstEntry.IgnoreReason.InvalidEngineSpeed()) { + firstEntry.Gear = nextGear; + firstEntry.Setting = tmp; + eval.Add(firstEntry); } + } - var deltaDragTqFirst = disengaged ? - (response as ResponseDryRun).DeltaDragLoadTorque - : response.Engine.TotalTorqueDemand - response.Engine.DragTorque; + var deltaDragTqFirst = disengaged + ? (response as ResponseDryRun).Gearbox.InputTorque //.DeltaDragLoadTorque + : response.Engine.TotalTorqueDemand - response.Engine.DragTorque; - if (!response.Engine.EngineOn && DataBus.GearboxInfo.GearboxType.AutomaticTransmission()) { - deltaDragTqFirst = response.Gearbox.InputTorque; - } + if (!response.Engine.EngineOn && DataBus.GearboxInfo.GearboxType.AutomaticTransmission()) { + deltaDragTqFirst = response.Gearbox.InputTorque; + } - if (deltaDragTqFirst.IsGreater(0)) { - // braking requested but engine operating point is not below drag curve. - if (ElectricMotorCanPropellDuringTractionInterruption) { - if (DataBus.GearboxInfo.GearEngaged(absTime)) { - eval.AddRange(FindSolution(absTime, dt, outTorque, outAngularVelocity, dryRun)); - } else { - EvaluateConfigsForGear( - absTime, dt, outTorque, outAngularVelocity, nextGear, AllowICEOff(absTime), eval, emPos, dryRun); - } - } else if (DataBus.GearboxInfo.GearEngaged(absTime)) { + if (deltaDragTqFirst.IsGreater(0)) { + // braking requested but engine operating point is not below drag curve. + if (ElectricMotorCanPropellDuringTractionInterruption) { + if (DataBus.GearboxInfo.GearEngaged(absTime)) { eval.AddRange(FindSolution(absTime, dt, outTorque, outAngularVelocity, dryRun)); } else { - eval.Add(ResponseEmOff); + EvaluateConfigsForGear( + absTime, dt, outTorque, outAngularVelocity, nextGear, AllowICEOff(absTime), eval, emPos, + dryRun); } - return; - } - - if (!response.Gearbox.Gear.Engaged && !ElectricMotorCanPropellDuringTractionInterruption) { - // we are disengaged and EM cannot recuperate - switch EM off + } else if (DataBus.GearboxInfo.GearEngaged(absTime)) { + eval.AddRange(FindSolution(absTime, dt, outTorque, outAngularVelocity, dryRun)); + } else { eval.Add(ResponseEmOff); - return; } - if (response.ElectricMotor.MaxRecuperationTorque == null) { - var retVal = ResponseEmOff; - retVal.Gear = response.Gearbox.Gear; - eval.Add(retVal); - return; - } - - var maxRecuperation = new HybridStrategyResponse { - CombustionEngineOn = DataBus.EngineInfo.EngineOn, // AllowICEOff(absTime), - GearboxInNeutral = false, - NextGear = nextGear, - MechanicalAssistPower = new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> { - { emPos, Tuple.Create(response.ElectricMotor.AngularVelocity, VectoMath.Max(response.ElectricMotor.MaxRecuperationTorque, 0.SI<NewtonMeter>())) } - } - }; - var maxRecuperationResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, maxRecuperation); - debug.Add("[AHS.HBA-2] DryRun maxRecuperationResponse", maxRecuperationResponse); - var deltaDragTqMaxRecuperation = disengaged - ? (maxRecuperationResponse as ResponseDryRun).DeltaDragLoadTorque - : maxRecuperationResponse.Engine.TotalTorqueDemand - maxRecuperationResponse.Engine.DragTorque; + return; + } - var isAPTWithTorqueConverter = DataBus.GearboxInfo.GearboxType.AutomaticTransmission() && - DataBus.GearboxInfo.GearboxType != GearboxType.IHPC; - if (!maxRecuperationResponse.Engine.EngineOn && isAPTWithTorqueConverter) { - deltaDragTqMaxRecuperation = maxRecuperationResponse.Gearbox.InputTorque; - } + if (!response.Gearbox.Gear.Engaged && !ElectricMotorCanPropellDuringTractionInterruption) { + // we are disengaged and EM cannot recuperate - switch EM off + eval.Add(ResponseEmOff); + return; + } - if (deltaDragTqMaxRecuperation.IsEqual(0)) { - // with max recuperation we are already at the drag curve (e.g. because search braking power was invoked before - eval.Add( - new HybridResultEntry { - ICEOff = !DataBus.EngineInfo.EngineOn, - Gear = nextGear, - Setting = maxRecuperation - }); - return; - } + if (response.ElectricMotor.MaxRecuperationTorque == null) { + var retVal = ResponseEmOff; + retVal.Gear = disengaged ? new GearshiftPosition(0) : response.Gearbox.Gear; + eval.Add(retVal); + return; + } - if (deltaDragTqMaxRecuperation.IsSmaller(0) && - maxRecuperationResponse.ElectricSystem.RESSPowerDemand.IsBetween(maxRecuperationResponse.ElectricSystem.MaxPowerDrag, maxRecuperationResponse.ElectricSystem.MaxPowerDrive)) { - // even with full recuperation (and no braking) the operating point is below the drag curve (and the battery can handle it) - use full recuperation - eval.Add( - new HybridResultEntry { - ICEOff = !DataBus.EngineInfo.EngineOn, - Gear = nextGear, - Setting = new HybridStrategyResponse { - CombustionEngineOn = DataBus.EngineInfo.EngineOn, - GearboxInNeutral = false, - NextGear = nextGear, - MechanicalAssistPower = new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> { - { emPos, Tuple.Create(response.ElectricMotor.AngularVelocity, response.ElectricMotor.MaxRecuperationTorque) } - } - } - }); - return; + var maxRecuperation = new HybridStrategyResponse { + CombustionEngineOn = DataBus.EngineInfo.EngineOn, // AllowICEOff(absTime), + GearboxInNeutral = false, + NextGear = nextGear, + MechanicalAssistPower = new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> { + { + emPos, + Tuple.Create(response.ElectricMotor.AngularVelocity, + VectoMath.Max(response.ElectricMotor.MaxRecuperationTorque, 0.SI<NewtonMeter>())) + } } + }; + var maxRecuperationResponse = + RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, maxRecuperation); + debug.Add("[AHS.HBA-2] DryRun maxRecuperationResponse", maxRecuperationResponse); + var deltaDragTqMaxRecuperation = disengaged + ? (maxRecuperationResponse as ResponseDryRun).Gearbox.InputTorque //.DeltaDragLoadTorque + : maxRecuperationResponse.Engine.TotalTorqueDemand - maxRecuperationResponse.Engine.DragTorque; + + var isAPTWithTorqueConverter = DataBus.GearboxInfo.GearboxType.AutomaticTransmission() && + DataBus.GearboxInfo.GearboxType != GearboxType.IHPC; + if (!maxRecuperationResponse.Engine.EngineOn && isAPTWithTorqueConverter) { + deltaDragTqMaxRecuperation = maxRecuperationResponse.Gearbox.InputTorque; + } + + if (deltaDragTqMaxRecuperation.IsEqual(0)) { + // with max recuperation we are already at the drag curve (e.g. because search braking power was invoked before + eval.Add( + new HybridResultEntry { + ICEOff = !DataBus.EngineInfo.EngineOn, + Gear = nextGear, + Setting = maxRecuperation + }); + return; + } - // full recuperation is not possible - ICE would need to propel - search max possible EM torque - var emRecuperationTq = SearchAlgorithm.Search( - maxRecuperationResponse.ElectricMotor.ElectricMotorPowerMech / - maxRecuperationResponse.ElectricMotor.AngularVelocity, - maxRecuperationResponse.Engine.TorqueOutDemand, maxRecuperationResponse.ElectricMotor.MaxRecuperationTorque * 0.1, - getYValue: resp => { - var r = resp as IResponse; - var deltaDragLoad = disengaged - ? (r as ResponseDryRun).DeltaDragLoadTorque - : r.Engine.TotalTorqueDemand - r.Engine.DragTorque; - if (!r.Engine.EngineOn && isAPTWithTorqueConverter) { - deltaDragLoad = r.Gearbox.InputTorque; - } - return deltaDragLoad; - }, - evaluateFunction: emTq => { - var cfg = new HybridStrategyResponse { - CombustionEngineOn = DataBus.EngineInfo.EngineOn, - GearboxInNeutral = false, - NextGear = nextGear, - MechanicalAssistPower = new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> { - { emPos, Tuple.Create(response.ElectricMotor.AngularVelocity, emTq) } - } - }; - return RequestDryRun(absTime, dt, outTorque, outAngularVelocity, DataBus.GearboxInfo.GearEngaged(absTime) ? nextGear : new GearshiftPosition(0), cfg); - }, - criterion: resp => { - var r = resp as IResponse; - var deltaDragLoad = disengaged - ? (r as ResponseDryRun).DeltaDragLoadTorque - : r.Engine.TotalTorqueDemand - r.Engine.DragTorque; - if (!r.Engine.EngineOn && isAPTWithTorqueConverter) { - deltaDragLoad = r.Gearbox.InputTorque; - } - return deltaDragLoad.Value(); - }, - searcher: this - ); - if (emRecuperationTq.IsBetween( - response.ElectricMotor.MaxDriveTorque ?? 0.SI<NewtonMeter>(), response.ElectricMotor.MaxRecuperationTorque ?? 0.SI<NewtonMeter>())) { - var entry = new HybridResultEntry { + if (deltaDragTqMaxRecuperation.IsSmaller(0) && + maxRecuperationResponse.ElectricSystem.RESSPowerDemand.IsBetween( + maxRecuperationResponse.ElectricSystem.MaxPowerDrag, + maxRecuperationResponse.ElectricSystem.MaxPowerDrive)) { + // even with full recuperation (and no braking) the operating point is below the drag curve (and the battery can handle it) - use full recuperation + eval.Add( + new HybridResultEntry { ICEOff = !DataBus.EngineInfo.EngineOn, Gear = nextGear, Setting = new HybridStrategyResponse { CombustionEngineOn = DataBus.EngineInfo.EngineOn, GearboxInNeutral = false, NextGear = nextGear, - MechanicalAssistPower = new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> { - { emPos, Tuple.Create(response.ElectricMotor.AngularVelocity, emRecuperationTq) } - } + MechanicalAssistPower = + new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> { + { + emPos, + Tuple.Create(response.ElectricMotor.AngularVelocity, + response.ElectricMotor.MaxRecuperationTorque) + } + } } - }; - entry.Response = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, entry.Setting); - if (entry.Response.ElectricSystem.ConsumerPower.IsGreater(0)) { - eval.Add(entry); - } else { - // for the found operating point, although recuperating no electric energy is generated. leave EM off - var off = ResponseEmOff; - if (vehiclespeedBelowThreshold && (emPos == PowertrainPosition.HybridP2 || emPos == PowertrainPosition.HybridP1)) { - off.Setting.GearboxInNeutral = true; - } else { - off.Setting.GearboxInNeutral = PreviousState.Solution?.Setting.GearboxInNeutral ?? false; + }); + return; + } + + // full recuperation is not possible - ICE would need to propel - search max possible EM torque + var emRecuperationTq = SearchAlgorithm.Search( + maxRecuperationResponse.ElectricMotor.ElectricMotorPowerMech / + maxRecuperationResponse.ElectricMotor.AngularVelocity, + maxRecuperationResponse.Engine.TorqueOutDemand, + maxRecuperationResponse.ElectricMotor.MaxRecuperationTorque * 0.1, + getYValue: resp => { + var r = resp as IResponse; + var deltaDragLoad = disengaged + ? (r as ResponseDryRun).Gearbox.InputTorque //.DeltaDragLoadTorque + : r.Engine.TotalTorqueDemand - r.Engine.DragTorque; + if (!r.Engine.EngineOn && isAPTWithTorqueConverter) { + deltaDragLoad = r.Gearbox.InputTorque; + } + + return deltaDragLoad; + }, + evaluateFunction: emTq => { + var cfg = new HybridStrategyResponse { + CombustionEngineOn = DataBus.EngineInfo.EngineOn, + GearboxInNeutral = false, + NextGear = nextGear, + MechanicalAssistPower = new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> { + { emPos, Tuple.Create(response.ElectricMotor.AngularVelocity, emTq) } } + }; + return RequestDryRun(absTime, dt, outTorque, outAngularVelocity, + DataBus.GearboxInfo.GearEngaged(absTime) ? nextGear : new GearshiftPosition(0), cfg); + }, + criterion: resp => { + var r = resp as IResponse; + var deltaDragLoad = disengaged + ? (r as ResponseDryRun).Gearbox.InputTorque //.DeltaDragLoadTorque + : r.Engine.TotalTorqueDemand - r.Engine.DragTorque; + if (!r.Engine.EngineOn && isAPTWithTorqueConverter) { + deltaDragLoad = r.Gearbox.InputTorque; + } - eval.Add(off); + return deltaDragLoad.Value(); + }, + searcher: this + ); + if (emRecuperationTq.IsBetween( + response.ElectricMotor.MaxDriveTorque ?? 0.SI<NewtonMeter>(), + response.ElectricMotor.MaxRecuperationTorque ?? 0.SI<NewtonMeter>())) { + var entry = new HybridResultEntry { + ICEOff = !DataBus.EngineInfo.EngineOn, + Gear = nextGear, + Setting = new HybridStrategyResponse { + CombustionEngineOn = DataBus.EngineInfo.EngineOn, + GearboxInNeutral = false, + NextGear = nextGear, + MechanicalAssistPower = new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> { + { emPos, Tuple.Create(response.ElectricMotor.AngularVelocity, emRecuperationTq) } + } } + }; + entry.Response = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, entry.Setting); + if (entry.Response.ElectricSystem.ConsumerPower.IsGreater(0)) { + eval.Add(entry); } else { - if (emRecuperationTq.IsGreater(0)) { - var voltage = DataBus.BatteryInfo.InternalVoltage; - var maxbatDragTq = DataBus.ElectricMotorInfo(emPos).GetTorqueForElectricPower(voltage, - response.ElectricSystem.MaxPowerDrag, response.ElectricMotor.AngularVelocity, dt, nextGear, - false); - eval.Add( - new HybridResultEntry { - ICEOff = !DataBus.EngineInfo.EngineOn, - Gear = nextGear, - Setting = new HybridStrategyResponse { - CombustionEngineOn = DataBus.EngineInfo.EngineOn, - GearboxInNeutral = false, - NextGear = nextGear, - MechanicalAssistPower = new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> { - { emPos, Tuple.Create(response.ElectricMotor.AngularVelocity, VectoMath.Min(maxbatDragTq, response.ElectricMotor.MaxRecuperationTorque)) } - } - } - }); + // for the found operating point, although recuperating no electric energy is generated. leave EM off + var off = ResponseEmOff; + if (vehiclespeedBelowThreshold && + (emPos == PowertrainPosition.HybridP2 || emPos == PowertrainPosition.HybridP1)) { + off.Setting.GearboxInNeutral = true; } else { - eval.Add(ResponseEmOff); + off.Setting.GearboxInNeutral = PreviousState.Solution?.Setting.GearboxInNeutral ?? false; } + + eval.Add(off); } } else { - var off = ResponseEmOff; - if (vehiclespeedBelowThreshold && (emPos == PowertrainPosition.HybridP2 || emPos == PowertrainPosition.HybridP1)) { - off.Setting.GearboxInNeutral = true; + if (emRecuperationTq.IsGreater(0)) { + var voltage = DataBus.BatteryInfo.InternalVoltage; + var maxbatDragTq = DataBus.ElectricMotorInfo(emPos).GetTorqueForElectricPower(voltage, + response.ElectricSystem.MaxPowerDrag, response.ElectricMotor.AngularVelocity, dt, nextGear, + false); + eval.Add( + new HybridResultEntry { + ICEOff = !DataBus.EngineInfo.EngineOn, + Gear = nextGear, + Setting = new HybridStrategyResponse { + CombustionEngineOn = DataBus.EngineInfo.EngineOn, + GearboxInNeutral = false, + NextGear = nextGear, + MechanicalAssistPower = + new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> { + { + emPos, + Tuple.Create(response.ElectricMotor.AngularVelocity, + VectoMath.Min(maxbatDragTq, + response.ElectricMotor.MaxRecuperationTorque)) + } + } + } + }); } else { - off.Setting.GearboxInNeutral = PreviousState.Solution?.Setting.GearboxInNeutral ?? false; + eval.Add(ResponseEmOff); } - - eval.Add(off); } } @@ -1439,6 +1504,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies } } if (DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate && allUnderload) { + var emPos = DataBus.PowertrainInfo.ElectricMotorPositions.First(x => x != PowertrainPosition.GEN); + if (DataBus.GearboxInfo.GearboxType.AutomaticTransmission() && DataBus.VehicleInfo.VehicleStopped && + emPos == PowertrainPosition.HybridP1) { + best = eval.First(x => double.IsNaN(x.U)); + return best; + } if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime)) { var filtered = eval.Where(x => !x.IgnoreReason.InvalidEngineSpeed()) .OrderBy(x => Math.Abs(GearList.Distance(currentGear, x.Gear))).ToArray(); @@ -1983,11 +2054,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies tmp.FuelCosts = iceOff ? 0 : double.NaN; tmp.IgnoreReason |= HybridConfigurationIgnoreReason.EngineSpeedTooHigh; } - if (resp.Engine.EngineSpeed.IsSmallerOrEqual(ModelData.EngineData.IdleSpeed)) { - tmp.FuelCosts = iceOff ? 0 : double.NaN; - tmp.IgnoreReason |= HybridConfigurationIgnoreReason.EngineSpeedTooLow; + + if (!ModelData.GearboxData.Type.AutomaticTransmission()) { + if (resp.Engine.EngineSpeed.IsSmallerOrEqual(ModelData.EngineData.IdleSpeed)) { + tmp.FuelCosts = iceOff ? 0 : double.NaN; + tmp.IgnoreReason |= HybridConfigurationIgnoreReason.EngineSpeedTooLow; + } + } else { + if (resp.Engine.EngineSpeed.IsSmaller(ModelData.EngineData.IdleSpeed)) { + tmp.FuelCosts = iceOff ? 0 : double.NaN; + tmp.IgnoreReason |= HybridConfigurationIgnoreReason.EngineSpeedTooLow; + } } + //if (resp.Engine.EngineSpeed != null && resp.Gearbox.Gear.Engaged && GearList.HasSuccessor(resp.Gearbox.Gear) && ModelData.GearboxData.Gears[resp.Gearbox.Gear.Gear].ShiftPolygon.IsAboveUpshiftCurve(resp.Engine.TorqueOutDemand, resp.Engine.EngineSpeed)) { // //lastShiftTime = absTime; // //tmp.FuelCosts = double.NaN; // Tuple.Create(true, response.Gearbox.Gear + 1); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs index 8fcefba0d8801f134f109730cf7e430a678d05db..a56ff6fe71f4ce3bc0013a24324bdd840bda4f0e 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs @@ -202,6 +202,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies public PCCStates PCCState => PCCStates.OutsideSegment; public MeterPerSecond NextBrakeTriggerSpeed => 0.SI<MeterPerSecond>(); + public MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed) => targetSpeed; + #endregion #region Overrides of VectoSimulationComponent diff --git a/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs index 3cd054bcf8f9e1c86fea271a987f5f89928b9d9b..2fd05d6e236d959e5995ad1da4f6c9e8d798b7db 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs @@ -137,7 +137,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent #region Overrides of Clutch - public override bool ClutchClosed(Second absTime) { return !ClutchOpen; } + //public override bool ClutchClosed(Second absTime) { return !ClutchOpen; } #endregion diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs index ba0a1a4436b6d50632e7b0eb58a7b5a249991fb3..bd3cab52a80f2bcccd43a2182cb18c0a389ee1cb 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs @@ -218,6 +218,7 @@ namespace TUGraz.VectoCore.OutputData.XML ActualChargeDepletingRange = ranges.ActualChargeDepletingRange; EquivalentAllElectricRange = ranges.EquivalentAllElectricRange; ZeroCO2EmissionsRange = ranges.ZeroCO2EmissionsRange; + ElectricEnergyConsumption = ranges.ElectricEnergyConsumption; } if (data.HasGearbox) { diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/IHPCTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/IHPCTest.cs index 12eca7ad53330cdb05e87f2796ec4137ce84cc8b..435d6371934a09d67daa8a3c884b8bfcbdd61fc1 100644 --- a/VectoCore/VectoCoreTest/Integration/Hybrid/IHPCTest.cs +++ b/VectoCore/VectoCoreTest/Integration/Hybrid/IHPCTest.cs @@ -27,27 +27,27 @@ public class IHPCTest public const string IHPCTEst_6speed = @"TestData\Hybrids\GenericIHPC\6SpeedGbx\IHPC Group 5.vecto"; [ - TestCase(IHPCTEst_12speed, 0, TestName = "IHPC 12spd Group 5 DriveCycle LongHaul"), - TestCase(IHPCTEst_12speed, 1, TestName = "IHPC 12spd Group 5 DriveCycle Coach"), - TestCase(IHPCTEst_12speed, 2, TestName = "IHPC 12spd Group 5 DriveCycle Construction"), - TestCase(IHPCTEst_12speed, 3, TestName = "IHPC 12spd Group 5 DriveCycle HeavyUrban"), - TestCase(IHPCTEst_12speed, 4, TestName = "IHPC 12spd Group 5 DriveCycle Interurban"), - TestCase(IHPCTEst_12speed, 5, TestName = "IHPC 12spd Group 5 DriveCycle MunicipalUtility"), - TestCase(IHPCTEst_12speed, 6, TestName = "IHPC 12spd Group 5 DriveCycle RegionalDelivery"), - TestCase(IHPCTEst_12speed, 7, TestName = "IHPC 12spd Group 5 DriveCycle Suburban"), - TestCase(IHPCTEst_12speed, 8, TestName = "IHPC 12spd Group 5 DriveCycle Urban"), - TestCase(IHPCTEst_12speed, 9, TestName = "IHPC 12spd Group 5 DriveCycle UrbanDelivery"), - - TestCase(IHPCTEst_6speed, 0, TestName = "IHPC 6spd Group 5 DriveCycle LongHaul"), - TestCase(IHPCTEst_6speed, 1, TestName = "IHPC 6spd Group 5 DriveCycle Coach"), - TestCase(IHPCTEst_6speed, 2, TestName = "IHPC 6spd Group 5 DriveCycle Construction"), - TestCase(IHPCTEst_6speed, 3, TestName = "IHPC 6spd Group 5 DriveCycle HeavyUrban"), - TestCase(IHPCTEst_6speed, 4, TestName = "IHPC 6spd Group 5 DriveCycle Interurban"), - TestCase(IHPCTEst_6speed, 5, TestName = "IHPC 6spd Group 5 DriveCycle MunicipalUtility"), - TestCase(IHPCTEst_6speed, 6, TestName = "IHPC 6spd Group 5 DriveCycle RegionalDelivery"), - TestCase(IHPCTEst_6speed, 7, TestName = "IHPC 6spd Group 5 DriveCycle Suburban"), - TestCase(IHPCTEst_6speed, 8, TestName = "IHPC 6spd Group 5 DriveCycle Urban"), - TestCase(IHPCTEst_6speed, 9, TestName = "IHPC 6spd Group 5 DriveCycle UrbanDelivery"), + TestCase(IHPCTEst_12speed, 0, TestName = "IHPC Hybrid 12spd Group 5 DriveCycle LongHaul"), + TestCase(IHPCTEst_12speed, 1, TestName = "IHPC Hybrid 12spd Group 5 DriveCycle Coach"), + TestCase(IHPCTEst_12speed, 2, TestName = "IHPC Hybrid 12spd Group 5 DriveCycle Construction"), + TestCase(IHPCTEst_12speed, 3, TestName = "IHPC Hybrid 12spd Group 5 DriveCycle HeavyUrban"), + TestCase(IHPCTEst_12speed, 4, TestName = "IHPC Hybrid 12spd Group 5 DriveCycle Interurban"), + TestCase(IHPCTEst_12speed, 5, TestName = "IHPC Hybrid 12spd Group 5 DriveCycle MunicipalUtility"), + TestCase(IHPCTEst_12speed, 6, TestName = "IHPC Hybrid 12spd Group 5 DriveCycle RegionalDelivery"), + TestCase(IHPCTEst_12speed, 7, TestName = "IHPC Hybrid 12spd Group 5 DriveCycle Suburban"), + TestCase(IHPCTEst_12speed, 8, TestName = "IHPC Hybrid 12spd Group 5 DriveCycle Urban"), + TestCase(IHPCTEst_12speed, 9, TestName = "IHPC Hybrid 12spd Group 5 DriveCycle UrbanDelivery"), + + TestCase(IHPCTEst_6speed, 0, TestName = "IHPC Hybrid 6spd Group 5 DriveCycle LongHaul"), + TestCase(IHPCTEst_6speed, 1, TestName = "IHPC Hybrid 6spd Group 5 DriveCycle Coach"), + TestCase(IHPCTEst_6speed, 2, TestName = "IHPC Hybrid 6spd Group 5 DriveCycle Construction"), + TestCase(IHPCTEst_6speed, 3, TestName = "IHPC Hybrid 6spd Group 5 DriveCycle HeavyUrban"), + TestCase(IHPCTEst_6speed, 4, TestName = "IHPC Hybrid 6spd Group 5 DriveCycle Interurban"), + TestCase(IHPCTEst_6speed, 5, TestName = "IHPC Hybrid 6spd Group 5 DriveCycle MunicipalUtility"), + TestCase(IHPCTEst_6speed, 6, TestName = "IHPC Hybrid 6spd Group 5 DriveCycle RegionalDelivery"), + TestCase(IHPCTEst_6speed, 7, TestName = "IHPC Hybrid 6spd Group 5 DriveCycle Suburban"), + TestCase(IHPCTEst_6speed, 8, TestName = "IHPC Hybrid 6spd Group 5 DriveCycle Urban"), + TestCase(IHPCTEst_6speed, 9, TestName = "IHPC Hybrid 6spd Group 5 DriveCycle UrbanDelivery"), ] public void P2HybridGroup5DriveCycle(string jobFile, int cycleIdx) { RunHybridJob(jobFile, cycleIdx); } diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs index c87ed4d0eec64e054274e672b9ddefebf4858c0a..ed5f2b0ce1113b336a47a39ff3fa6f55c2d08421 100644 --- a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs +++ b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs @@ -1526,7 +1526,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid graphWriter.Write(modFilename); } - public const string Group5_P4_AMT = @"TestData\Hybrids\GenericVehicle_Group5_P3\P3 Group 5.vecto"; + public const string Group5_P4_AMT = @"TestData\Hybrids\GenericVehicle_Group5_P4\P4 Group 5.vecto"; [ TestCase(Group5_P4_AMT, 0, TestName = "P4 Hybrid DriveCycle LongHaul"), @@ -1566,6 +1566,15 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid RunHybridJob(jobFile, cycleIdx); } + + [TestCase(@"E:\QUAM\tmp\HybridStrategy\P1_Group31aU_ll\P1_CityBusU_ll.vecto"), + TestCase(@"E:\QUAM\tmp\HybridStrategy\P1_Group31aU_rl\P1_CityBusU_rl.vecto"), + ] + public void HybridTestGerard(string jobfile) + { + RunHybridJob(jobfile, 0); + } + // ================================================= public static JobContainer CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, diff --git a/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs b/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs index 2127a1961f01ecd743099ec0d8c056fc9c0a1dac..ff0a6fc75313972b378efde1b9f4691617efd5d3 100644 --- a/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs +++ b/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs @@ -168,6 +168,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns var runData = new VectoRunData() { JobName = "Coach_FullPowertrain", + Cycle = cycleData, EngineData = engineData, VehicleData = vehicleData, AxleGearData = axleGearData, @@ -175,8 +176,10 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns GearshiftParameters = CreateGearshiftData(), AirdragData = airDragData, DriverData = driverData, + Retarder = new RetarderData() {Type = RetarderType.None }, SimulationType = SimulationType.DistanceCycle, - ElectricMachinesData = new List<Tuple<PowertrainPosition, ElectricMotorData>>() + ElectricMachinesData = new List<Tuple<PowertrainPosition, ElectricMotorData>>(), + Aux = new List<VectoRunData.AuxData>() }; var fileWriter = new FileOutputWriter("Coach_FullPowertrain"); var modData = new ModalDataContainer(runData, fileWriter, null); diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/BatteryDataAdapterTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/BatteryDataAdapterTest.cs index 95b56f4bc6ec636689d4bb2a5dceee17673abbba..c42705d251d0ea8aaf8d47a451ad84ec30ca3a8e 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/BatteryDataAdapterTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/BatteryDataAdapterTest.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Runtime.InteropServices.ComTypes; -using Castle.Core.Resource; using Moq; using NLog.LayoutRenderers; using NUnit.Framework; diff --git a/VectoCore/VectoCoreTest/Models/Declaration/TestGenericBusEMotorData.cs b/VectoCore/VectoCoreTest/Models/Declaration/TestGenericBusEMotorData.cs index f2e4645ab868c8b11c79de0b94fc566de17ac99f..6202a7a7c7c604e341d7eb9261b4f25c07331ae8 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/TestGenericBusEMotorData.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/TestGenericBusEMotorData.cs @@ -164,8 +164,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration Assert.AreEqual(2, batterySystemData.Batteries.Count); var battery0 = batterySystemData.Batteries[0]; - Assert.AreEqual(80, battery0.Item2.MaxSOC); - Assert.AreEqual(20, battery0.Item2.MinSOC); + Assert.AreEqual(0.80, battery0.Item2.MaxSOC, 1e-6); + Assert.AreEqual(0.20, battery0.Item2.MinSOC, 1e-6); Assert.AreEqual(72, battery0.Item2.Capacity.AsAmpHour); Assert.AreEqual(2, battery0.Item2.InternalResistance.Entries.Length); @@ -182,9 +182,9 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration Assert.AreEqual(resistance, battery0.Item2.InternalResistance.Entries[1].Resistance[1].Item2.Value()); Assert.AreEqual(resistance, battery0.Item2.InternalResistance.Entries[1].Resistance[2].Item2.Value()); - var battery1 = batterySystemData.Batteries[0]; - Assert.AreEqual(80, battery1.Item2.MaxSOC); - Assert.AreEqual(20, battery1.Item2.MinSOC); + var battery1 = batterySystemData.Batteries[1]; + Assert.AreEqual(0.80, battery1.Item2.MaxSOC, 1e-6); + Assert.AreEqual(0.20, battery1.Item2.MinSOC, 1e-6); Assert.AreEqual(72, battery1.Item2.Capacity.AsAmpHour); Assert.AreEqual(2, battery1.Item2.InternalResistance.Entries.Length); diff --git a/VectoCore/VectoCoreTest/Reports/TestXMLResultsWriting.cs b/VectoCore/VectoCoreTest/Reports/TestXMLResultsWriting.cs index 26936c16b27923a6e253dcb281ae997e86e16d53..e426ffb57fba258c0209544a88f04773abea5d6c 100644 --- a/VectoCore/VectoCoreTest/Reports/TestXMLResultsWriting.cs +++ b/VectoCore/VectoCoreTest/Reports/TestXMLResultsWriting.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Text; using System.Xml; using System.Xml.Linq; -using Castle.Components.DictionaryAdapter.Xml; using Moq; using Ninject; using NUnit.Framework; diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_S2_APTN/GenericGen.vem b/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_S2_APTN/GenericGen.vem index 8bce454f0ffcf15816a1bb5d813bce93b58a315d..a8648c91e901362361f66b9c270a35c6d0686d50 100644 --- a/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_S2_APTN/GenericGen.vem +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_S2_APTN/GenericGen.vem @@ -13,7 +13,7 @@ "ContinuousTorqueSpeed": 1850, "OverloadTorque": 1030, "OverloadTorqueSpeed": 1850, - "OverloadTime": 120, + "OverloadTime": 240, "ThermalOverloadRecoveryFactor": 0.9, "VoltageLevels": [ { diff --git a/VectoCore/VectoCoreTest/TestData/XML/XMLReaderDeclaration/SchemaVersion2.4/WithoutOptionalEntries/IEPC_heavyLorry_n_opt.xml b/VectoCore/VectoCoreTest/TestData/XML/XMLReaderDeclaration/SchemaVersion2.4/WithoutOptionalEntries/IEPC_heavyLorry_n_opt.xml index 9152cedae3433e213d71aaf5797a9155d1bcb22f..736e4bc38b38ac979275450533e0f88f3a16ec8e 100644 --- a/VectoCore/VectoCoreTest/TestData/XML/XMLReaderDeclaration/SchemaVersion2.4/WithoutOptionalEntries/IEPC_heavyLorry_n_opt.xml +++ b/VectoCore/VectoCoreTest/TestData/XML/XMLReaderDeclaration/SchemaVersion2.4/WithoutOptionalEntries/IEPC_heavyLorry_n_opt.xml @@ -13,7 +13,7 @@ <TechnicalPermissibleMaximumLadenMass>12000</TechnicalPermissibleMaximumLadenMass> <RetarderType>Losses included in Gearbox</RetarderType> <RetarderRatio>2.000</RetarderRatio> - <AngledriveType>Separate Angledrive</AngledriveType> + <AngledriveType>None</AngledriveType> <PTO xsi:type="PTOType"> <PTOShaftsGearWheels>none</PTOShaftsGearWheels> <PTOOtherElements>none</PTOOtherElements> diff --git a/VectoCore/VectoCoreTest/Utils/MockDriver.cs b/VectoCore/VectoCoreTest/Utils/MockDriver.cs index e387785e4c503e0c6621f292b43b0a8b5d713440..9de8644de96570ac0096fcf9c6a9ba37d56033fa 100644 --- a/VectoCore/VectoCoreTest/Utils/MockDriver.cs +++ b/VectoCore/VectoCoreTest/Utils/MockDriver.cs @@ -125,6 +125,7 @@ namespace TUGraz.VectoCore.Tests.Utils public MeterPerSquareSecond DriverAcceleration { get; set; } public PCCStates PCCState => PCCStates.OutsideSegment; public MeterPerSecond NextBrakeTriggerSpeed => 0.SI<MeterPerSecond>(); + public MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed) => targetSpeed; protected override bool DoUpdateFrom(object other) => false; diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs index c33a78edd39eda5a969bf02c8e5f24ac45437dd6..364c45fd638912be24d07a0187293f4670d47f6c 100644 --- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs @@ -52,7 +52,7 @@ namespace TUGraz.VectoCore.Tests.Utils { // only CycleData Lookup is set / accessed... - public List<VectoSimulationComponent> Components = new List<VectoSimulationComponent>(); + protected List<VectoSimulationComponent> MyComponents = new List<VectoSimulationComponent>(); private Watt _axlegearLoss = 0.SI<Watt>(); private bool _clutchClosed = true; @@ -239,6 +239,7 @@ namespace TUGraz.VectoCore.Tests.Utils public MeterPerSquareSecond DriverAcceleration { get; set; } public PCCStates PCCState => PCCStates.OutsideSegment; public MeterPerSecond NextBrakeTriggerSpeed => 0.SI<MeterPerSecond>(); + public MeterPerSecond ApplyOverspeed(MeterPerSecond targetSpeed) => targetSpeed; public CycleData CycleData { get; set; } @@ -266,7 +267,7 @@ namespace TUGraz.VectoCore.Tests.Utils public void AddComponent(VectoSimulationComponent component) { - Components.Add(component); + MyComponents.Add(component); ModalData?.RegisterComponent(component); //WriteSumData?.RegisterComponent(component, RunData); @@ -279,7 +280,7 @@ namespace TUGraz.VectoCore.Tests.Utils public void CommitSimulationStep(Second time, Second simulationInterval) { - foreach (var entry in Components) { + foreach (var entry in MyComponents) { entry.CommitSimulationStep(time, simulationInterval, ModalData); } } @@ -337,6 +338,8 @@ namespace TUGraz.VectoCore.Tests.Utils throw new NotImplementedException(); } + public IReadOnlyList<VectoSimulationComponent> Components => MyComponents; + public void ResetComponents() { throw new NotImplementedException();