diff --git a/VectoCommon/VectoCommon/Models/PowertrainPosition.cs b/VectoCommon/VectoCommon/Models/PowertrainPosition.cs index 0f67189569e097355af22185139cb3607ad7600a..51e06d7a3a5f68166f7927000435fa1ce27510a3 100644 --- a/VectoCommon/VectoCommon/Models/PowertrainPosition.cs +++ b/VectoCommon/VectoCommon/Models/PowertrainPosition.cs @@ -1,4 +1,6 @@ -using TUGraz.VectoCommon.Utils; +using System; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Utils; namespace TUGraz.VectoCommon.InputData { public enum PowertrainPosition @@ -17,16 +19,24 @@ namespace TUGraz.VectoCommon.InputData { public static class PowertrainPositionHelper { - public const string Prefix = "Hybrid"; + public const string HybridPrefix = "Hybrid"; + public const string BatteryElectriPrefix = "BatteryElectric"; public static PowertrainPosition Parse(string pos) { - return (Prefix + pos).ParseEnum<PowertrainPosition>(); + if (pos.StartsWith("P",StringComparison.InvariantCultureIgnoreCase)) { + return (HybridPrefix + pos).ParseEnum<PowertrainPosition>(); + } + + if (pos.StartsWith("B", StringComparison.InvariantCultureIgnoreCase)) { + return (BatteryElectriPrefix + pos).ParseEnum<PowertrainPosition>(); + } + throw new VectoException("invalid powertrain position {0}", pos); } public static string GetName(this PowertrainPosition pos) { - return pos.ToString().Replace(Prefix, ""); + return pos.ToString().Replace(HybridPrefix, "").Replace(BatteryElectriPrefix, ""); } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs index 73c3ddf680ee7b66a1e7acab90b29dbb87bce212..673abe5f5706cc53057981233011757787ac49e4 100644 --- a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs +++ b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs @@ -129,6 +129,11 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl public ResponseSuccess(object source) : base(source) { } } + public class ResponseBatteryEmpty : AbstractResponse + { + public ResponseBatteryEmpty(object source) : base(source) { } + } + /// <summary> /// Response when the request resulted in an engine or gearbox overload. /// </summary> diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs index 400ea653426bf78caa43489d13881d19d7f9efdc..b54c4c8e5b7fa71cdea918d27a71f375617cead7 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs @@ -399,6 +399,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Data P_electricMotor_mech_P3, [ModalResultField(typeof(SI), caption: "P_em-P4_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_P4, + + [ModalResultField(typeof(SI), caption: "P_em-B4_mech [kW]", outputFactor: 1e-3)] + P_electricMotor_mech_B4, // --> [ModalResultField(typeof(SI), caption: "P_bat_T [kW]", outputFactor: 1e-3)] P_battery_terminal, diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs index 282ad87280290e9d39b1a887ab034414e3794454..4f85633b7c626a73ee2f6c2b79fa53b90fd330f1 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs @@ -77,6 +77,13 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus IBatteryInfo BatteryInfo { get; } ITorqueConverterControl TorqueConverterCtl { get; } + IPowertainInfo PowertrainInfo { get; } } + public interface IPowertainInfo + { + bool HasCombustionEngine { get; } + + //PowertrainArchitecture A + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/DistanceRun.cs b/VectoCore/VectoCore/Models/Simulation/Impl/DistanceRun.cs index 08523584bc4416cc1c00911ad98ea5df5cd5bcd7..9e43578795a8fcdcc7b31adcc518ada2c9e2b4f9 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/DistanceRun.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/DistanceRun.cs @@ -71,12 +71,17 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl FinishedWithoutErrors = true; Log.Info("========= Driving Cycle Finished"); }). + Case<ResponseBatteryEmpty>( + r => { + FinishedWithoutErrors = true; + Log.Info("========= REESS empty"); + }). Default(r => { throw new VectoException("DistanceRun got an unexpected response: {0}", r); }); if (loopCount++ > Constants.SimulationSettings.MaximumIterationCountForSimulationStep) { throw new VectoSimulationException("Maximum iteration count for a single simulation interval reached! Aborting!"); } debug.Add(new {Response = response}); - } while (!(response is ResponseSuccess || response is ResponseCycleFinished)); + } while (!(response is ResponseSuccess || response is ResponseCycleFinished || response is ResponseBatteryEmpty)); IterationStatistics.Increment(this, "Distance", Container.MileageCounter.Distance.Value()); IterationStatistics.Increment(this, "Time", AbsTime.Value()); diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs index eec59a0ec317bc64aed52f9ec00ff41a59be6d02..b3b21458d2d3923b077c5c0b55d023cc46b4b419 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs @@ -121,8 +121,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl Container.AbsTime = AbsTime; Initialize(); + IResponse response; try { - IResponse response; + do { response = DoSimulationStep(); debug.Add(response); @@ -139,11 +140,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl } } while (response is ResponseSuccess); if (!GetContainer().RunData.Exempted) { - foreach (var fuel in GetContainer().RunData.EngineData.Fuels) { + //foreach (var fuel in GetContainer().RunData.EngineData.Fuels) { // calculate vehicleline correction here in local thread context because writing sum-data and report afterwards is synchronized //var cf = GetContainer().ModalData.VehicleLineCorrectionFactor(fuel.FuelData); GetContainer().ModalData.CalculateAggregateValues(); - } + //} } PostProcessingDone = true; @@ -188,11 +189,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl Container.RunStatus = Container.RunData.Exempted ? Status.Success : CyclePort.Progress < 1 - ? Status.Aborted + ? (response is ResponseBatteryEmpty ? Status.REESSEmpty : Status.Aborted) : Status.Success; Container.FinishSimulationRun(); WritingResultsDone = true; - if (Progress.IsSmaller(1, 1e-9)) { + if (Progress.IsSmaller(1, 1e-9) && !(response is ResponseBatteryEmpty)) { throw new VectoSimulationException( "{5} ({6} {7}) Progress: {8} - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4}", AbsTime, Container.MileageCounter.Distance, dt, Container.VehicleInfo.VehicleSpeed, TryCatch(() => Container.GearboxInfo.Gear), RunIdentifier, CycleName, @@ -232,6 +233,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl Success, Canceled, Aborted, + REESSEmpty } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index 7b8ebae7ea58e7867e58850680f2475716686b01..b89f881ed291b00429b7229ed5338ec91ef76e8d 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -50,7 +50,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Simulation.Impl { - public class VehicleContainer : LoggingObject, IVehicleContainer + public class VehicleContainer : LoggingObject, IVehicleContainer, IPowertainInfo { private List<Tuple<int, VectoSimulationComponent>> _components = new List<Tuple<int, VectoSimulationComponent>>(); @@ -117,6 +117,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public virtual ITorqueConverterControl TorqueConverterCtl { get; private set; } + public IPowertainInfo PowertrainInfo + { + get { return this; } + } + public virtual void AddComponent(VectoSimulationComponent component) { var commitPriority = 0; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotorControl.cs b/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotorControl.cs index 6f13b1a493b7532e741b51cf5686f17f81757e22..bede2f65d9ca988cb424c36671147a580d9acbdc 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotorControl.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotorControl.cs @@ -15,11 +15,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent /// <param name="outTorque"></param> /// <param name="prevOutAngularVelocity"></param> /// <param name="currOutAngularVelocity"></param> + /// <param name="maxRecuperationTorque"></param> /// <param name="position"></param> /// <param name="dryRun"></param> + /// <param name="maxDriveTorque"></param> /// <returns></returns> NewtonMeter MechanicalAssistPower(Second absTime, Second dt, NewtonMeter outTorque, PerSecond prevOutAngularVelocity, PerSecond currOutAngularVelocity, + NewtonMeter maxDriveTorque, NewtonMeter maxRecuperationTorque, PowertrainPosition position, bool dryRun); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BatteryElectricMotorController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BatteryElectricMotorController.cs index 70ab19bc429113a93bf2fef219ea6694dbb601f3..c1ecf2b3e00c94f263493099d77d0b6ab9a02484 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BatteryElectricMotorController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BatteryElectricMotorController.cs @@ -18,9 +18,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { public NewtonMeter MechanicalAssistPower( Second absTime, Second dt, NewtonMeter outTorque, PerSecond prevOutAngularVelocity, PerSecond currOutAngularVelocity, + NewtonMeter maxDriveTorque, NewtonMeter maxRecuperationTorque, PowertrainPosition position, bool dryRun) { - throw new System.NotImplementedException(); + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Coast || + DataBus.DriverInfo.DrivingAction == DrivingAction.Roll) { + return null; + } + + if (maxDriveTorque == null) { + return null; + } + + return (-outTorque).LimitTo(maxDriveTorque, maxRecuperationTorque); } #endregion diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs index f00ba0bcd58f3477a77b9c955d501401ebe16390..eb07caafaa40c12da83d0a4620554b6277bdec5c 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -322,6 +322,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl }; }). Case<ResponseSuccess>(() => operatingPoint = limitedOperatingPoint). + Case<ResponseBatteryEmpty>(() => { }). Default( r => { throw new UnexpectedResponseException( diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs index 307702310fb09ed4ca511114aea31ae6a8787fcb..7645f3f5752121a6b3201cc67f29f030768ad2ca 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs @@ -123,10 +123,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } if (ElectricPower == null) { - var retVal = ForwardRequest(absTime, dt, inTorque, inTorque, outAngularVelocity, dryRun); + var retVal = ForwardRequest(absTime, dt, inTorque, inTorque, outAngularVelocity, null, dryRun); return retVal; } - var eMotorTorque = Control.MechanicalAssistPower(absTime, dt, inTorque, PreviousState.OutAngularVelocity, outAngularVelocity, Position, dryRun); + var eMotorTorque = Control.MechanicalAssistPower(absTime, dt, inTorque, PreviousState.OutAngularVelocity, outAngularVelocity, maxDriveTorque, maxRecuperationTorque, Position, dryRun); if (Position == PowertrainPosition.HybridP2 && !DataBus.GearboxInfo.GearEngaged(absTime)/* && !DataBus.ClutchInfo.ClutchClosed(absTime)*/) { // electric motor is between gearbox and clutch, but no gear is engaged... @@ -184,7 +184,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl eMotorTorque < 0 ? electricSupplyResponse.MaxPowerDrive : electricSupplyResponse.MaxPowerDrag, electricSupplyResponse.ConsumerPower); } - var response = ForwardRequest(absTime, dt, inTorque, inTorque + eMotorTorque, outAngularVelocity, dryRun); + var response = ForwardRequest(absTime, dt, inTorque, inTorque + eMotorTorque, outAngularVelocity, electricSupplyResponse, dryRun); response.ElectricSystem = electricSupplyResponse; response.ElectricMotor.InertiaPowerDemand = inertiaTorqueLoss * avgSpeed; @@ -202,20 +202,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl SetState(inTorque, outAngularVelocity); } var electricSystemResponse = ElectricPower.Request(absTime, dt, 0.SI<Watt>(), dryRun); - - var retVal = NextComponent.Request(absTime, dt, inTorque, outAngularVelocity, dryRun); + + var retVal = NextComponent == null + ? RequestElectricMotorOnly(absTime, dt, outTorque, inTorque, outAngularVelocity, dryRun, avgSpeed, electricSystemResponse) + : NextComponent.Request(absTime, dt, inTorque, outAngularVelocity, dryRun); retVal.ElectricMotor.ElectricMotorPowerMech = (inTorque - outTorque) * avgSpeed; retVal.ElectricSystem = electricSystemResponse; return retVal; } public IResponse ForwardRequest(Second absTime, Second dt, NewtonMeter outTorque, NewtonMeter inTorque, PerSecond outAngularVelocity, - bool dryRun = false) + IElectricSystemResponse electricSystemResponse, bool dryRun = false) { var avgSpeed = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2; if (NextComponent == null) { - return RequestElectricMotorOnly(absTime, dt, outTorque, inTorque, outAngularVelocity, dryRun, avgSpeed); + return RequestElectricMotorOnly(absTime, dt, outTorque, inTorque, outAngularVelocity, dryRun, avgSpeed, electricSystemResponse); } if (!dryRun) { @@ -226,7 +228,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return retVal; } - private IResponse RequestElectricMotorOnly(Second absTime, Second dt, NewtonMeter outTorque, NewtonMeter inTorque, PerSecond outAngularVelocity, bool dryRun, PerSecond avgSpeed) + private IResponse RequestElectricMotorOnly(Second absTime, Second dt, NewtonMeter outTorque, NewtonMeter inTorque, PerSecond outAngularVelocity, bool dryRun, PerSecond avgSpeed, IElectricSystemResponse electricSystemResponse) { var remainingPower = inTorque * avgSpeed; if (dryRun) @@ -239,12 +241,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl EngineSpeed = avgSpeed, }, DeltaFullLoad = remainingPower, //powerDemand + driveTorque * avgSpeed, - DeltaDragLoad = powerDemand + dragTorque * avgSpeed, + DeltaDragLoad = remainingPower, // powerDemand + dragTorque * avgSpeed, }; } if ((inTorque * avgSpeed).IsEqual(0, Constants.SimulationSettings.LineSearchTolerance)) { SetState(inTorque, outAngularVelocity); + if (electricSystemResponse.MaxPowerDrive.IsGreaterOrEqual(0)) { + return new ResponseBatteryEmpty(this); + } return new ResponseSuccess(this) { ElectricMotor = { ElectricMotorPowerMech = (inTorque - outTorque) * avgSpeed, diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs index a3cecbd47ef946efe904c2e826cf10c202ba3882..94f0ff16668d7fedcc46ec0daef4b5480e4c5b2f 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs @@ -168,8 +168,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } public NewtonMeter MechanicalAssistPower(Second absTime, Second dt, NewtonMeter outTorque, - PerSecond prevOutAngularVelocity, - PerSecond currOutAngularVelocity, PowertrainPosition position, bool dryRun) + PerSecond prevOutAngularVelocity, PerSecond currOutAngularVelocity, + NewtonMeter maxDriveTorque, NewtonMeter maxRecuperationTorque, PowertrainPosition position, bool dryRun) { return _controller.MechanicalAssistPower(position, absTime, dt, outTorque, prevOutAngularVelocity, currOutAngularVelocity, dryRun); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs index 0d54cb86e1fa21cff488aa0ed85d72da00716981..ea348f81005cf0531afdbe3ed5a2007f5973ca67 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs @@ -149,6 +149,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { public NewtonMeter MechanicalAssistPower( Second absTime, Second dt, NewtonMeter outTorque, PerSecond prevOutAngularVelocity, PerSecond currOutAngularVelocity, + NewtonMeter maxDriveTorque, NewtonMeter maxRecuperationTorque, PowertrainPosition position, bool dryRun) { return _controller.MechanicalAssistPower(position, absTime, dt, outTorque, prevOutAngularVelocity, diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs index d8e7ea05033e918776d2fef0bad310761eb10674..a826bf8aedd7c74cb93b6a4138930ddfabbe230e 100644 --- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs @@ -124,6 +124,7 @@ namespace TUGraz.VectoCore.OutputData void CalculateAggregateValues(); void AddElectricMotor(PowertrainPosition pos); KilogramPerWattSecond VehicleLineSlope(IFuelProperties fuel); + bool HasCombustionEngine { get; } } public static class ModalDataContainerExtensions diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index 8320df82ccf37ca1692472eac1778bb17ec99e0d..b4ae1f97afc767430ea7d659d8cf5d9a0c3e1e11 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -123,6 +123,7 @@ namespace TUGraz.VectoCore.OutputData Action<ModalDataContainer> addReportResult, bool writeEngineOnly, params IModalDataFilter[] filters) { HasTorqueConverter = false; + HasCombustionEngine = true; RunName = runName; CycleName = cycleName; RunSuffix = runSuffix; @@ -226,6 +227,8 @@ namespace TUGraz.VectoCore.OutputData return null; } + public bool HasCombustionEngine { get; set; } + public void CalculateAggregateValues() { var duration = Duration; @@ -234,22 +237,26 @@ namespace TUGraz.VectoCore.OutputData var speed = distance / duration; } - foreach (var fuel in FuelColumns.Keys) { - EngineLineCorrectionFactor(fuel); - VehicleLineSlope(fuel); - TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCMap)); - TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCNCVc)); - TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCWHTCc)); - //TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCAAUX)); - TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCMap)); - TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCICEStopStart)); - TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCFinal)); - + if (HasCombustionEngine) { + foreach (var fuel in FuelColumns.Keys) { + EngineLineCorrectionFactor(fuel); + VehicleLineSlope(fuel); + TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCMap)); + TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCNCVc)); + TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCWHTCc)); + + //TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCAAUX)); + TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCMap)); + TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCICEStopStart)); + TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCFinal)); + + } + + TimeIntegral<WattSecond>(ModalResultField.P_WHR_el_corr); + TimeIntegral<WattSecond>(ModalResultField.P_WHR_mech_corr); + TimeIntegral<WattSecond>(ModalResultField.P_aux_ice_off); + TimeIntegral<WattSecond>(ModalResultField.P_ice_start); } - TimeIntegral<WattSecond>(ModalResultField.P_WHR_el_corr); - TimeIntegral<WattSecond>(ModalResultField.P_WHR_mech_corr); - TimeIntegral<WattSecond>(ModalResultField.P_aux_ice_off); - TimeIntegral<WattSecond>(ModalResultField.P_ice_start); TimeIntegral<WattSecond>(ModalResultField.P_clutch_loss); TimeIntegral<WattSecond>(ModalResultField.P_gbx_shift_loss); diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs index f2ee8b3a9cf9d5590b77ad65ec3a18cf727d1be2..f899c7307eb83191d9368040fae8241f40ebf550 100644 --- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs @@ -317,7 +317,9 @@ namespace TUGraz.VectoCore.OutputData row[Fields.ALTITUDE_DELTA] = (ConvertedSI)modData.AltitudeDelta(); - WriteFuelconsumptionEntries(modData, row, vehicleLoading, cargoVolume, passengerCount, runData); + if (modData.HasCombustionEngine) { + WriteFuelconsumptionEntries(modData, row, vehicleLoading, cargoVolume, passengerCount, runData); + } if (runData.Mission?.MissionType == MissionType.VerificationTest) { var fuelsWhtc = runData.EngineData.Fuels.Select( @@ -329,9 +331,11 @@ namespace TUGraz.VectoCore.OutputData row[Fields.P_WHEEL_POS] = modData.PowerWheelPositive().ConvertToKiloWatt(); row[Fields.P_WHEEL] = modData.PowerWheel().ConvertToKiloWatt(); - - row[Fields.P_FCMAP_POS] = modData.TotalPowerEnginePositiveAverage().ConvertToKiloWatt(); - row[Fields.P_FCMAP] = modData.TotalPowerEngineAverage().ConvertToKiloWatt(); + + if (modData.HasCombustionEngine) { + row[Fields.P_FCMAP_POS] = modData.TotalPowerEnginePositiveAverage().ConvertToKiloWatt(); + row[Fields.P_FCMAP] = modData.TotalPowerEngineAverage().ConvertToKiloWatt(); + } WriteAuxiliaries(modData, row, runData.BusAuxiliaries != null); diff --git a/VectoCore/VectoCoreTest/Integration/BatteryElectric/BatteryElectricTest.cs b/VectoCore/VectoCoreTest/Integration/BatteryElectric/BatteryElectricTest.cs index 33d8916379b03a3ca65956fdb7d503acd8232bc2..8265e7b93c61b6c31499f3162a2ee50abbd7dbea 100644 --- a/VectoCore/VectoCoreTest/Integration/BatteryElectric/BatteryElectricTest.cs +++ b/VectoCore/VectoCoreTest/Integration/BatteryElectric/BatteryElectricTest.cs @@ -12,6 +12,7 @@ using TUGraz.VectoCore.InputData.Impl; using TUGraz.VectoCore.InputData.Reader.ComponentData; using TUGraz.VectoCore.Models.Declaration; 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.Data; @@ -64,7 +65,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric Yfields = new[] { ModalResultField.v_act, ModalResultField.altitude, ModalResultField.acc, ModalResultField.Gear, - ModalResultField.P_ice_out, ModalResultField.BatterySOC, ModalResultField.FCMap + ModalResultField.BatterySOC, }; GraphWriter.Series1Label = "Hybrid"; GraphWriter.PlotIgnitionState = true; @@ -72,13 +73,64 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric [ - TestCase(30, 0.7, 0, TestName = "B4 Hybrid DriveOff 30km/h SoC: 0.7, level"), - TestCase(80, 0.7, 0, TestName = "B4 Hybrid DriveOff 80km/h SoC: 0.7, level"), - TestCase(30, 0.25, 0, TestName = "B4 Hybrid DriveOff 30km/h SoC: 0.25, level") + TestCase(30, 0.7, 0, 0, TestName = "B4 BEV ConstantSpeed 30km/h SoC: 0.7, level"), + TestCase(50, 0.7, 0, 0, TestName = "B4 BEV ConstantSpeed 50km/h SoC: 0.7, level"), + TestCase(80, 0.7, 0, 0, TestName = "B4 BEV ConstantSpeed 80km/h SoC: 0.7, level"), + + TestCase(30, 0.25, 0, 0, TestName = "B4 BEV ConstantSpeed 30km/h SoC: 0.25, level"), + TestCase(50, 0.25, 0, 0, TestName = "B4 BEV ConstantSpeed 50km/h SoC: 0.25, level"), + TestCase(80, 0.25, 0, 0, TestName = "B4 BEV ConstantSpeed 80km/h SoC: 0.25, level"), + + TestCase(30, 0.5, 5, 0, TestName = "B4 BEV ConstantSpeed 30km/h SoC: 0.5, UH 5%"), + TestCase(50, 0.5, 5, 0, TestName = "B4 BEV ConstantSpeed 50km/h SoC: 0.5, UH 5%"), + TestCase(80, 0.5, 5, 0, TestName = "B4 BEV ConstantSpeed 80km/h SoC: 0.5, UH 5%"), + + TestCase(30, 0.5, -5, 0, TestName = "B4 BEV ConstantSpeed 30km/h SoC: 0.5, DH 5%"), + TestCase(50, 0.5, -5, 0, TestName = "B4 BEV ConstantSpeed 50km/h SoC: 0.5, DH 5%"), + TestCase(80, 0.5, -5, 0, TestName = "B4 BEV ConstantSpeed 80km/h SoC: 0.5, DH 5%"), + + TestCase(30, 0.25, 0, 1000, TestName = "B4 BEV ConstantSpeed 30km/h SoC: 0.25, level P_auxEl: 1kW"), + TestCase(30, 0.25, 0, 5000, TestName = "B4 BEV ConstantSpeed 30km/h SoC: 0.25, level P_auxEl: 5kW"), ] - public void B4HybridDriveOff(double vmax, double initialSoC, double slope) + public void B4BEVConstantSpeed(double vmax, double initialSoC, double slope, double pAuxEl) { - GraphWriter.Yfields = Yfields.Concat(new[] { ModalResultField.P_electricMotor_mech_P2 }).ToArray(); + GraphWriter.Yfields = Yfields.Concat(new[] { ModalResultField.P_electricMotor_mech_B4 }).ToArray(); + + var cycleData = string.Format( + @" 0, {0}, {1}, 0 + 7000, {0}, {1}, 0", vmax, slope); + var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); + + const bool largeMotor = true; + + var modFilename = string.Format("SimpleBatteryElectric-B4_constant_{0}-{1}_{2}_{3}.vmod", vmax, initialSoC, slope, pAuxEl); + const PowertrainPosition pos = PowertrainPosition.BatteryElectricB4; + var run = CreateEngineeringRun( + cycle, modFilename, initialSoC, pos, largeMotor: true, pAuxEl: pAuxEl); + + var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data; + + var data = run.GetContainer().RunData; + //File.WriteAllText( + // $"{modFilename}.json", + // JsonConvert.SerializeObject(data, Formatting.Indented)); + + run.Run(); + Assert.IsTrue(run.FinishedWithoutErrors); + + Assert.IsTrue(modData.Rows.Count > 0); + GraphWriter.Write(modFilename); + } + + + [ + TestCase(30, 0.7, 0, TestName = "B4 BEV DriveOff 30km/h SoC: 0.7, level"), + TestCase(80, 0.7, 0, TestName = "B4 BEV DriveOff 80km/h SoC: 0.7, level"), + TestCase(30, 0.25, 0, TestName = "B4 BEV DriveOff 30km/h SoC: 0.25, level") + ] + public void B4BEVDriveOff(double vmax, double initialSoC, double slope) + { + GraphWriter.Yfields = Yfields.Concat(new[] { ModalResultField.P_electricMotor_mech_B4 }).ToArray(); var cycleData = string.Format( @" 0, 0, {1}, 3 700, {0}, {1}, 0", vmax, slope); @@ -91,9 +143,6 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric var run = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, largeMotor: true); - var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController; - Assert.NotNull(hybridController); - var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data; run.Run(); @@ -124,6 +173,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric modFileName, new IFuelProperties[] { FuelData.Diesel }, fileWriter, filters: modDataFilter) { WriteModalResults = true, + HasCombustionEngine = false, }; var gearboxData = CreateGearboxData(); @@ -201,6 +251,8 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric case PowertrainPosition.BatteryElectricB4: powertrain.AddComponent( GetElectricMachine(PowertrainPosition.BatteryElectricB4, runData.ElectricMachinesData, container, es, ctl)); + new MockGearboxInfo(container); + new ATClutchInfo(container); break; case PowertrainPosition.BatteryElectricB3: powertrain.AddComponent(new AxleGear(container, runData.AxleGearData)) @@ -379,4 +431,99 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric return retVal; } } + + public class MockGearboxInfo : VectoSimulationComponent, IGearboxInfo + { + public MockGearboxInfo(VehicleContainer container) : base(container) + { + + } + + #region Overrides of VectoSimulationComponent + + protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) { } + + protected override void DoCommitSimulationStep(Second time, Second simulationInterval) { } + + #endregion + + #region Implementation of IGearboxInfo + + public GearboxType GearboxType + { + get { return GearboxType.AMT; } + } + + public uint Gear + { + get { return 1; } + } + + public bool TCLocked + { + get { return true; } + } + + public MeterPerSecond StartSpeed + { + get { return DeclarationData.GearboxTCU.StartSpeed; } + } + + public MeterPerSquareSecond StartAcceleration + { + get { return DeclarationData.GearboxTCU.StartAcceleration; } + } + + public Watt GearboxLoss() + { + return 0.SI<Watt>(); + } + + public Second LastShift + { + get { return -double.MaxValue.SI<Second>(); } + } + + public Second LastUpshift + { + get { return -double.MaxValue.SI<Second>(); } + } + + public Second LastDownshift + { + get { return -double.MaxValue.SI<Second>(); } + } + + public GearData GetGearData(uint gear) + { + throw new NotImplementedException(); + } + + public GearInfo NextGear + { + get { throw new NotImplementedException(); } + } + + public Second TractionInterruption + { + get { return 0.SI<Second>(); } + } + + public uint NumGears + { + get { return 1; } + } + + public bool DisengageGearbox + { + get { return false; } + } + + public bool GearEngaged(Second absTime) + { + return true; + } + + #endregion + } } diff --git a/VectoCore/VectoCoreTest/Utils/MockHybridControl.cs b/VectoCore/VectoCoreTest/Utils/MockHybridControl.cs index 882c6849af5aa6c081044cc201d195ea999d1552..bc8f80febbd7026d353b7ede2a6581d9523a9a64 100644 --- a/VectoCore/VectoCoreTest/Utils/MockHybridControl.cs +++ b/VectoCore/VectoCoreTest/Utils/MockHybridControl.cs @@ -8,7 +8,9 @@ namespace TUGraz.VectoCore.Tests.Utils { public NewtonMeter ElectricShare { get; set; } public NewtonMeter MechanicalAssistPower(Second absTime, Second dt, NewtonMeter outTorque, - PerSecond prevOutAngularVelocity, PerSecond curOutAngularVelocity, PowertrainPosition position, bool dryRun) + PerSecond prevOutAngularVelocity, PerSecond curOutAngularVelocity, + NewtonMeter maxDriveTorque, NewtonMeter maxRecuperationTorque, + PowertrainPosition position, bool dryRun) { return ElectricShare; } diff --git a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs index cf20409522db20e5dd90d9b09e28eec8ef6cf9e2..a8c1d2980902cb3467ec7abcc60569b4bcba2099 100644 --- a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs @@ -270,6 +270,8 @@ namespace TUGraz.VectoCore.Tests.Utils return 0.SI<KilogramPerWattSecond>(); } + public bool HasCombustionEngine { get; set; } + public string RunName { get; set; } public string CycleName { get; set; } public string RunSuffix { get; set; } diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs index 3881c1538ceee6bb4681570179e3562304b04170..f602db41ea5927201c64f1cd3d1a9dbbbe6acec9 100644 --- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs @@ -48,7 +48,7 @@ using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Tests.Utils { - public class MockVehicleContainer : IVehicleContainer, IEngineInfo, IEngineControl, IVehicleInfo, IClutchInfo, IBrakes, IAxlegearInfo, IWheelsInfo, IDriverInfo, IDrivingCycleInfo, IMileageCounter, IGearboxInfo, IGearboxControl + public class MockVehicleContainer : IVehicleContainer, IEngineInfo, IEngineControl, IVehicleInfo, IClutchInfo, IBrakes, IAxlegearInfo, IWheelsInfo, IDriverInfo, IDrivingCycleInfo, IMileageCounter, IGearboxInfo, IGearboxControl, IPowertainInfo { // only CycleData Lookup is set / accessed... @@ -154,6 +154,11 @@ namespace TUGraz.VectoCore.Tests.Utils get { return _torqueConverter; } } + public IPowertainInfo PowertrainInfo + { + get { return this; } + } + public Watt GearboxLoss() { throw new System.NotImplementedException(); @@ -372,6 +377,14 @@ namespace TUGraz.VectoCore.Tests.Utils throw new NotImplementedException(); } - + + #region Implementation of IPowertainInfo + + public bool HasCombustionEngine + { + get { throw new NotImplementedException(); } + } + + #endregion } } \ No newline at end of file