diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs index b4c06afd39ce8e38c897ef239e253ef6025bbdc4..f3c15f6d89672412e3690248be68a20b099dbc06 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs @@ -62,7 +62,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON private string _filename; private IAxlesDeclarationInputData _axleWheelsDecl; private IAxlesEngineeringInputData _axleWheelsEng; - + private IBatteryPackEngineeringInputData Battery; + private IElectricMotorEngineeringInputData ElectricMotor; + public JSONComponentInputData(string filename, IJSONVehicleComponents job, bool tolerateMissing = false) { @@ -101,7 +103,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON .If<IPTOTransmissionInputData>(c => PTOTransmission = c) .If<IGearshiftEngineeringInputData>(c => GearshiftData = c) .If<IAxlesDeclarationInputData>(c => _axleWheelsDecl = c) - .If<IAxlesEngineeringInputData>(c => _axleWheelsEng = c); + .If<IAxlesEngineeringInputData>(c => _axleWheelsEng = c) + .If<IBatteryPackEngineeringInputData>(c => Battery = c) + .If<IElectricMotorEngineeringInputData>(c => { ElectricMotor = c; }); ; _filename = filename; } @@ -234,7 +238,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON get { return _axleWheelsDecl; } } - public IElectricStorageEngineeringInputData ElectricStorage { get { return VehicleData.Components.ElectricStorage; } } + public IElectricStorageEngineeringInputData ElectricStorage { get { return VehicleData?.Components?.ElectricStorage; } } public IElectricMachinesEngineeringInputData ElectricMachines { get { return VehicleData.Components.ElectricMachines; } } diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs index 1bed7966d1b9dda2b9dc6e31f5b57bf962ad16f8..a7aa9cb58488542455dfee81d759427f53b27bc0 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs @@ -103,7 +103,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON public class JSONElectricMotors : IElectricMachinesEngineeringInputData { private readonly IList<ElectricMachineEntry<IElectricMotorEngineeringInputData>> _entries; - public JSONElectricMotors(List<ElectricMachineEntry<IElectricMotorEngineeringInputData>> entries) + public JSONElectricMotors(IList<ElectricMachineEntry<IElectricMotorEngineeringInputData>> entries) { _entries = entries; } @@ -111,7 +111,6 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON IList<ElectricMachineEntry<IElectricMotorDeclarationInputData>> IElectricMachinesDeclarationInputData.Entries { get { return _entries.Cast<ElectricMachineEntry<IElectricMotorDeclarationInputData>>().ToList(); } - //get { return null; } } public virtual IList<ElectricMachineEntry<IElectricMotorEngineeringInputData>> Entries diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index f44ac87301127ccde21fe7d94368b669ddfe9c3e..ca0bdf7f757a91f45102ac71d50eb47558d05a90 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -43,12 +43,15 @@ using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Strategies; using TUGraz.VectoCore.OutputData; using TUGraz.VectoCore.Utils; using ElectricSystem = TUGraz.VectoCore.Models.SimulationComponent.ElectricSystem; using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; - -using StrategyCreator = System.Func<TUGraz.VectoCore.Models.Simulation.Data.VectoRunData, TUGraz.VectoCore.Models.Simulation.IVehicleContainer, TUGraz.VectoCore.Models.SimulationComponent.Impl.BaseShiftStrategy>; +using StrategyCreator = + System.Func<TUGraz.VectoCore.Models.Simulation.Data.VectoRunData, + TUGraz.VectoCore.Models.Simulation.IVehicleContainer, + TUGraz.VectoCore.Models.SimulationComponent.Impl.BaseShiftStrategy>; using GbxTypeList = System.Collections.Generic.List<TUGraz.VectoCommon.Models.GearboxType>; namespace TUGraz.VectoCore.Models.Simulation.Impl @@ -61,24 +64,38 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl private readonly IModalDataContainer _modData; private readonly WriteSumData _sumWriter; - private static List<Tuple<GbxTypeList, string, string, StrategyCreator>> ShiftStrategies = new List<Tuple<GbxTypeList, string, string, StrategyCreator>> - { - Tuple.Create<GbxTypeList, string, string ,StrategyCreator>(new GbxTypeList {GearboxType.MT}, typeof(MTShiftStrategy).FullName, MTShiftStrategy.Name, (r, c) => new MTShiftStrategy(r, c)), - Tuple.Create<GbxTypeList, string, string, StrategyCreator>( new GbxTypeList {GearboxType.AMT}, typeof(AMTShiftStrategy).FullName,AMTShiftStrategy.Name, (r, c) => new AMTShiftStrategy(r, c)), - Tuple.Create<GbxTypeList, string, string, StrategyCreator>( new GbxTypeList {GearboxType.AMT}, typeof(AMTShiftStrategyOptimized).FullName, AMTShiftStrategyOptimized.Name, (r, c) => new AMTShiftStrategyOptimized(r, c)), - Tuple.Create<GbxTypeList, string, string, StrategyCreator>( new GbxTypeList {GearboxType.AMT}, typeof(AMTShiftStrategyACEA).FullName, AMTShiftStrategyACEA.Name, (r, c) => new AMTShiftStrategyACEA(r, c)), - Tuple.Create<GbxTypeList, string, string, StrategyCreator>( new GbxTypeList {GearboxType.ATPowerSplit, GearboxType.ATSerial}, typeof(ATShiftStrategy).FullName, ATShiftStrategy.Name, (r, c) => new ATShiftStrategy(r, c)), - Tuple.Create<GbxTypeList, string, string, StrategyCreator>( new GbxTypeList {GearboxType.ATPowerSplit, GearboxType.ATSerial}, typeof(ATShiftStrategyVoith).FullName, ATShiftStrategyVoith.Name, (r, c) => new ATShiftStrategyVoith(r, c)), - Tuple.Create<GbxTypeList, string, string, StrategyCreator>( new GbxTypeList {GearboxType.ATPowerSplit, GearboxType.ATSerial}, typeof(ATShiftStrategyOptimized).FullName, ATShiftStrategyOptimized.Name, (r, c) => new ATShiftStrategyOptimized(r, c)), - }; + private static List<Tuple<GbxTypeList, string, string, StrategyCreator>> ShiftStrategies = + new List<Tuple<GbxTypeList, string, string, StrategyCreator>> { + Tuple.Create<GbxTypeList, string, string, StrategyCreator>(new GbxTypeList { GearboxType.MT }, + typeof(MTShiftStrategy).FullName, MTShiftStrategy.Name, (r, c) => new MTShiftStrategy(r, c)), + Tuple.Create<GbxTypeList, string, string, StrategyCreator>(new GbxTypeList { GearboxType.AMT }, + typeof(AMTShiftStrategy).FullName, AMTShiftStrategy.Name, (r, c) => new AMTShiftStrategy(r, c)), + Tuple.Create<GbxTypeList, string, string, StrategyCreator>(new GbxTypeList { GearboxType.AMT }, + typeof(AMTShiftStrategyOptimized).FullName, AMTShiftStrategyOptimized.Name, + (r, c) => new AMTShiftStrategyOptimized(r, c)), + Tuple.Create<GbxTypeList, string, string, StrategyCreator>(new GbxTypeList { GearboxType.AMT }, + typeof(AMTShiftStrategyACEA).FullName, AMTShiftStrategyACEA.Name, + (r, c) => new AMTShiftStrategyACEA(r, c)), + Tuple.Create<GbxTypeList, string, string, StrategyCreator>( + new GbxTypeList { GearboxType.ATPowerSplit, GearboxType.ATSerial }, + typeof(ATShiftStrategy).FullName, ATShiftStrategy.Name, (r, c) => new ATShiftStrategy(r, c)), + Tuple.Create<GbxTypeList, string, string, StrategyCreator>( + new GbxTypeList { GearboxType.ATPowerSplit, GearboxType.ATSerial }, + typeof(ATShiftStrategyVoith).FullName, ATShiftStrategyVoith.Name, + (r, c) => new ATShiftStrategyVoith(r, c)), + Tuple.Create<GbxTypeList, string, string, StrategyCreator>( + new GbxTypeList { GearboxType.ATPowerSplit, GearboxType.ATSerial }, + typeof(ATShiftStrategyOptimized).FullName, ATShiftStrategyOptimized.Name, + (r, c) => new ATShiftStrategyOptimized(r, c)), + }; - public PowertrainBuilder(IModalDataContainer modData, WriteSumData sumWriter = null) { if (modData == null) { throw new VectoException("Modal Data Container can't be null"); } + _modData = modData; _sumWriter = sumWriter; } @@ -99,7 +116,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl case CycleType.DistanceBased: return BuildFullPowertrain(data); default: - throw new VectoException("Powertrain Builder cannot build Powertrain for CycleType: {0}", data.Cycle.CycleType); + throw new VectoException("Powertrain Builder cannot build Powertrain for CycleType: {0}", + data.Cycle.CycleType); } } @@ -177,13 +195,12 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl //} powertrain.AddComponent(engine, idleController); - //.AddAuxiliaries(container, data); + //.AddAuxiliaries(container, data); return container; } - private IVehicleContainer BuildMeasuredSpeed(VectoRunData data) { if (data.Cycle.CycleType != CycleType.MeasuredSpeed) { @@ -236,6 +253,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl if (data.GearboxData.Type.ManualTransmission()) { powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); } + powertrain.AddComponent(new StopStartCombustionEngine(container, data.EngineData)) .AddAuxiliaries(container, data); @@ -246,27 +264,20 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl private IVehicleContainer BuildFullPowertrain(VectoRunData data) { - if (data.Cycle.CycleType != CycleType.DistanceBased) { - throw new VectoException("CycleType must be DistanceBased"); - } - - var container = new VehicleContainer(data.ExecutionMode, _modData, _sumWriter) { RunData = data }; - var isHybridVehicle = data.BatteryData != null && data.ElectricMachinesData != null && data.ElectricMachinesData.Count > 0; - ElectricSystem es = null; - HybridController ctl = null; - - if (isHybridVehicle) { - var battery = new Battery(container, data.BatteryData); - battery.Initialize(data.BatteryData.InitialSoC); + return isHybridVehicle ? BuildFullPowertrainHybrid(data) : BuildFullPowertrainConventional(data); + } - es = new ElectricSystem(container); - es.Connect(battery); - ctl = new HybridController(container); + private IVehicleContainer BuildFullPowertrainConventional(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.DistanceBased) { + throw new VectoException("CycleType must be DistanceBased"); } + var container = new VehicleContainer(data.ExecutionMode, _modData, _sumWriter) { RunData = data }; + // DistanceBasedDrivingCycle --> driver --> vehicle --> wheels // --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux var cycle = new DistanceBasedDrivingCycle(container, data.Cycle); @@ -275,27 +286,13 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) .AddComponent(new Brakes(container)) - .AddComponent(isHybridVehicle ? ctl : null) - .AddComponent(isHybridVehicle - ? GetElectricMachine(PowertrainPosition.HybridP4, data.ElectricMachinesData, container, es, ctl) - : null) .AddComponent(new AxleGear(container, data.AxleGearData)) - .AddComponent(isHybridVehicle - ? GetElectricMachine(PowertrainPosition.HybridP3, data.ElectricMachinesData, container, es, ctl) - : null) .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) - .AddComponent(GetGearbox(container, data), data.Retarder, container) - .AddComponent(isHybridVehicle - ? GetElectricMachine(PowertrainPosition.HybridP2, data.ElectricMachinesData, container, es, ctl) - : null); + .AddComponent(GetGearbox(container, data), data.Retarder, container); if (data.GearboxData.Type.ManualTransmission()) { powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); } - powertrain = powertrain.AddComponent(isHybridVehicle - ? GetElectricMachine(PowertrainPosition.HybridP1, data.ElectricMachinesData, container, es, ctl) - : null); - var engine = new StopStartCombustionEngine(container, data.EngineData); var idleController = GetIdleController(data.PTO, engine, container); cycle.IdleController = idleController as IdleControllerSwitcher; @@ -308,7 +305,65 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl return container; } - private IElectricMotor GetElectricMachine(PowertrainPosition pos, IList<Tuple<PowertrainPosition, ElectricMotorData>> electricMachinesData, VehicleContainer container, IElectricSystem es, HybridController ctl) + + private IVehicleContainer BuildFullPowertrainHybrid(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.DistanceBased) { + throw new VectoException("CycleType must be DistanceBased"); + } + + var container = new VehicleContainer(data.ExecutionMode, _modData, _sumWriter) { RunData = data }; + + var battery = new Battery(container, data.BatteryData); + battery.Initialize(data.BatteryData.InitialSoC); + + var es = new ElectricSystem(container); + es.Connect(battery); + + var gearbox = GetGearbox(container, data); + var gbx = gearbox as IHybridControlledGearbox; + if (gbx == null) { + throw new VectoException("Gearbox can not be used for parallel hybrid"); + } + + var strategy = new HybridStrategy(); + var clutch = data.GearboxData.Type.AutomaticTransmission() ? null : new SwitchableClutch(container, data.EngineData); + + var ctl = new HybridController(container, strategy, es, gbx, clutch); + + var engine = new StopStartCombustionEngine(container, data.EngineData); + var idleController = GetIdleController(data.PTO, engine, container); + + // DistanceBasedDrivingCycle --> driver --> vehicle --> wheels + // --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux + var cycle = new DistanceBasedDrivingCycle(container, data.Cycle); + cycle + .AddComponent(new Driver(container, data.DriverData, new DefaultDriverStrategy(container))) + .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) + .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(ctl) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP4, data.ElectricMachinesData, container, es, ctl)) + .AddComponent(new AxleGear(container, data.AxleGearData)) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP3, data.ElectricMachinesData, container, es, ctl)) + .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) + .AddComponent(gearbox, data.Retarder, container) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP2, data.ElectricMachinesData, container, es, ctl)) + .AddComponent(clutch) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP1, data.ElectricMachinesData, container, es, ctl)) + .AddComponent(engine, idleController) + .AddAuxiliaries(container, data); + + cycle.IdleController = idleController as IdleControllerSwitcher; + + _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); + + return container; + } + + private IElectricMotor GetElectricMachine(PowertrainPosition pos, + IList<Tuple<PowertrainPosition, ElectricMotorData>> electricMachinesData, VehicleContainer container, + IElectricSystem es, HybridController ctl) { var motorData = electricMachinesData.FirstOrDefault(x => x.Item1 == pos); if (motorData == null) { @@ -361,11 +416,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl //cycle.IdleController = idleController as IdleControllerSwitcher; powertrain.AddComponent(engine, idleController) - .AddAuxiliaries(container, data); - + .AddAuxiliaries(container, data); } - private DrivingCycleData GetMeasuredSpeedDummnCycle() { @@ -377,12 +430,14 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl foreach (var entry in entries) { writer.WriteLine(entry); } + writer.Flush(); cycleData.Seek(0, SeekOrigin.Begin); return DrivingCycleDataReader.ReadFromStream(cycleData, CycleType.MeasuredSpeed, "DummyCycle", false); } - private static IIdleController GetIdleController(PTOData pto, ICombustionEngine engine, IVehicleContainer container) + private static IIdleController GetIdleController(PTOData pto, ICombustionEngine engine, + IVehicleContainer container) { var controller = engine.IdleController; @@ -422,6 +477,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl default: throw new ArgumentOutOfRangeException("AuxiliaryDemandType", auxData.DemandType.ToString()); } + container.ModalData?.AddAuxiliary(id); } @@ -436,23 +492,26 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl container.ModalData?.AddAuxiliary(Constants.Auxiliaries.IDs.PTOConsumer, Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTOConsumer); } + return aux; } private EngineAuxiliary CreateSpeedDependentAuxiliaries(VectoRunData data, IVehicleContainer container) { var aux = new EngineAuxiliary(container); - + var auxData = data.Aux.ToArray(); - AddSwitchingAux(aux,container.ModalData,Constants.Auxiliaries.IDs.HeatingVentilationAirCondition, auxData); - AddSwitchingAux(aux,container.ModalData,Constants.Auxiliaries.IDs.SteeringPump, auxData); - AddSwitchingAux(aux,container.ModalData,Constants.Auxiliaries.IDs.ElectricSystem, auxData); + AddSwitchingAux(aux, container.ModalData, Constants.Auxiliaries.IDs.HeatingVentilationAirCondition, + auxData); + AddSwitchingAux(aux, container.ModalData, Constants.Auxiliaries.IDs.SteeringPump, auxData); + AddSwitchingAux(aux, container.ModalData, Constants.Auxiliaries.IDs.ElectricSystem, auxData); AddSwitchingAux(aux, container.ModalData, Constants.Auxiliaries.IDs.PneumaticSystem, auxData); - + return aux; } - private void AddSwitchingAux(EngineAuxiliary aux, IModalDataContainer modData, string auxId, VectoRunData.AuxData[] auxData) + private void AddSwitchingAux(EngineAuxiliary aux, IModalDataContainer modData, string auxId, + VectoRunData.AuxData[] auxData) { var urban = auxData.First(x => x.ID == auxId && x.MissionType == MissionType.UrbanDelivery); var rural = auxData.First(x => x.ID == auxId && x.MissionType == MissionType.RegionalDelivery); @@ -462,9 +521,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl if (entry.VehicleTargetSpeed >= Constants.SimulationSettings.HighwaySpeedThreshold) { return motorway.PowerDemand; } + if (entry.VehicleTargetSpeed >= Constants.SimulationSettings.RuralSpeedThreshold) { return rural.PowerDemand; } + return urban.PowerDemand; }); modData.AddAuxiliary(auxId); @@ -492,12 +553,13 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl if (string.IsNullOrWhiteSpace(shiftStrategy)) { shiftStrategy = DeclarationData.GearboxTCU.DefaultShiftStrategy; } + if (string.IsNullOrWhiteSpace(shiftStrategy)) { switch (runData.GearboxData.Type) { case GearboxType.AMT: runData.ShiftStrategy = AMTShiftStrategyOptimized.Name; return new AMTShiftStrategyOptimized(runData, container); - //return new AMTShiftStrategy(runData, container); + //return new AMTShiftStrategy(runData, container); case GearboxType.MT: runData.ShiftStrategy = MTShiftStrategy.Name; return new MTShiftStrategy(runData, container); @@ -505,16 +567,20 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl case GearboxType.ATSerial: runData.ShiftStrategy = ATShiftStrategyOptimized.Name; return new ATShiftStrategyOptimized(runData, container); - //return new ATShiftStrategy(runData, container); + //return new ATShiftStrategy(runData, container); default: - throw new ArgumentOutOfRangeException("GearboxType", string.Format("Unknown Gearbox Type {0}", runData.GearboxData.Type.ToString())); + throw new ArgumentOutOfRangeException("GearboxType", + string.Format("Unknown Gearbox Type {0}", runData.GearboxData.Type.ToString())); } - } - var selected = ShiftStrategies.FirstOrDefault(x => x.Item1.Contains(runData.GearboxData.Type) && x.Item2.Equals(shiftStrategy, StringComparison.InvariantCultureIgnoreCase)); + var selected = ShiftStrategies.FirstOrDefault(x => + x.Item1.Contains(runData.GearboxData.Type) && + x.Item2.Equals(shiftStrategy, StringComparison.InvariantCultureIgnoreCase)); if (selected == null) { - throw new ArgumentOutOfRangeException("ShiftStrategy", string.Format("Unknown Shiftstrategy {0} for Gearbox Type {1}", shiftStrategy, runData.GearboxData.Type.ToString())); + throw new ArgumentOutOfRangeException("ShiftStrategy", + string.Format("Unknown Shiftstrategy {0} for Gearbox Type {1}", shiftStrategy, + runData.GearboxData.Type.ToString())); } runData.ShiftStrategy = selected.Item3; @@ -523,7 +589,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl private static IGearbox GetSimpleGearbox(IVehicleContainer container, VectoRunData runData) { - return runData.GearboxData.Type.AutomaticTransmission() ? (IGearbox) new ATGearbox(container, null, runData) : new Gearbox(container, null, runData); + return runData.GearboxData.Type.AutomaticTransmission() + ? (IGearbox)new ATGearbox(container, null, runData) + : new Gearbox(container, null, runData); } @@ -532,7 +600,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl if (!type.HasValue) { return new List<Tuple<string, string>>(); } - return ShiftStrategies.Where(x => x.Item1.Contains(type.Value)).Select(x => Tuple.Create(x.Item2, x.Item3)).ToList(); + + return ShiftStrategies.Where(x => x.Item1.Contains(type.Value)).Select(x => Tuple.Create(x.Item2, x.Item3)) + .ToList(); } } } \ 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 30a650220c3191eb77be58df9e3f3fc926550041..ddc62a47d6d0689cb6efa7428965e1d6527698d6 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -518,6 +518,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl set { GearboxCtl.DisengageGearbox = value; } } + public bool GearEngaged(Second absTime) + { + return Gearbox.GearEngaged(absTime); + } + #endregion } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IClutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/IClutch.cs index ca4a70dec9310720896992e92632d4033a94ab1a..f3acd960df4e9c8e6d555dc156879548cdc71a4f 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IClutch.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IClutch.cs @@ -29,9 +29,11 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using TUGraz.VectoCore.Models.Simulation.DataBus; + namespace TUGraz.VectoCore.Models.SimulationComponent { - public interface IClutch : IPowerTrainComponent + public interface IClutch : IPowerTrainComponent, IClutchInfo { //ITnOutPort IdleControlPort { get; } IIdleController IdleController { get; set; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs index 07db48aae44fdddea2c074637981a0dbf56cfd50..f5ad30ef34cb2c5f6b16d1071632f1567e8ad403 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs @@ -36,5 +36,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent /// <summary> /// Defines interfaces for a gearbox. /// </summary> - public interface IGearbox : IPowerTrainComponent, IGearboxInfo, IGearboxControl, IHybridControlledGearbox { } + public interface IGearbox : IPowerTrainComponent, IGearboxInfo, IGearboxControl { } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs index 466bd6c03dd913380c0f6da7085bfb37900d5ab6..e50937130856522e779ece74abe472ac9fa557b1 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs @@ -54,7 +54,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DataBus = dataBus; } - public virtual bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, + public bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) { @@ -64,7 +64,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return retVal; } - public abstract bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, + protected abstract bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs index 9444387e51921d5d6fef63c04127898c0c6811e4..32e50ac647f8a924a5d1a8e518e81fc6eca822d2 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs @@ -45,8 +45,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public class Clutch : StatefulProviderComponent<Clutch.ClutchState, ITnOutPort, ITnInPort, ITnOutPort>, IClutch, ITnOutPort, ITnInPort { - private readonly PerSecond _idleSpeed; - private readonly PerSecond _ratedSpeed; + protected readonly PerSecond _idleSpeed; + protected readonly PerSecond _ratedSpeed; private bool firstInitialize = true; @@ -60,7 +60,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } - private readonly SI _clutchSpeedSlippingFactor; + protected readonly SI _clutchSpeedSlippingFactor; private IIdleController _idleController; public Clutch(IVehicleContainer container, CombustionEngineData engineData) : base(container) @@ -71,7 +71,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl (_idleSpeed + Constants.SimulationSettings.ClutchClosingSpeedNorm * (_ratedSpeed - _idleSpeed)); } - public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + public virtual IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) { NewtonMeter torqueIn; PerSecond engineSpeedIn; @@ -87,33 +87,39 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl //} var retVal = NextComponent.Initialize(torqueIn, engineSpeedIn); - retVal.Clutch.ClutchPowerRequest = outTorque * outAngularVelocity; + retVal.Clutch.PowerRequest = outTorque * outAngularVelocity; return retVal; } - public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + public virtual IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun = false) { firstInitialize = false; - var startClutch = DataBus.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0); if (!DataBus.ClutchClosed(absTime) && !dryRun) { Log.Debug("Invoking IdleController..."); var retval = IdleController.Request(absTime, dt, outTorque, null, dryRun); - retval.Clutch.ClutchPowerRequest = 0.SI<Watt>(); + retval.Clutch.PowerRequest = 0.SI<Watt>(); CurrentState.SetState(0.SI<NewtonMeter>(), retval.Engine.EngineSpeed, outTorque, outAngularVelocity); CurrentState.ClutchLoss = 0.SI<Watt>(); return retval; } + if (IdleController != null) { IdleController.Reset(); } Log.Debug("from Wheels: torque: {0}, angularVelocity: {1}, power {2}", outTorque, outAngularVelocity, Formulas.TorqueToPower(outTorque, outAngularVelocity)); + + return HandleClutchClosed(absTime, dt, outTorque, outAngularVelocity, dryRun); + } + protected virtual IResponse HandleClutchClosed(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) + { NewtonMeter torqueIn; PerSecond angularVelocityIn; + var startClutch = DataBus.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0); var slippingClutchWhenDriving = (DataBus.Gear <= 2 && DataBus.DriverBehavior != DrivingBehavior.Braking); var slippingClutchDuringBraking = DataBus.Gear == 1 && DataBus.DriverBehavior == DrivingBehavior.Braking && outTorque > 0 && DataBus.BrakePower.IsEqual(0); //var slippingClutchWhenDriving = (DataBus.Gear == 1 && outTorque > 0); @@ -137,12 +143,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl CurrentState.SetState(torqueIn, angularVelocityIn, outTorque, outAngularVelocity); CurrentState.ClutchLoss = torqueIn * avgInAngularVelocity - outTorque * avgOutAngularVelocity; } - retVal.Clutch.ClutchPowerRequest = outTorque * + retVal.Clutch.PowerRequest = outTorque * ((PreviousState.OutAngularVelocity ?? 0.SI<PerSecond>()) + CurrentState.OutAngularVelocity) / 2.0; return retVal; } - private void AddClutchLoss(NewtonMeter torque, PerSecond angularVelocity, bool allowSlipping, out NewtonMeter torqueIn, + protected virtual void AddClutchLoss(NewtonMeter torque, PerSecond angularVelocity, bool allowSlipping, out NewtonMeter torqueIn, out PerSecond angularVelocityIn) { if (DataBus.DriverBehavior == DrivingBehavior.Halted) { @@ -175,6 +181,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } + public virtual bool ClutchClosed(Second absTime) + { + return DataBus.GearEngaged(absTime); + } + public class ClutchState : SimpleComponentState { public Watt ClutchLoss = 0.SI<Watt>(); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs index 6eaef9474927d66c30199338a927b850c62e7100..411299e99064a2c68facb9079029c4794dd73692 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs @@ -8,7 +8,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { public class HybridController : StatefulProviderComponent<HybridController.HybridControllerState, ITnOutPort, ITnInPort, ITnOutPort>, IPowerTrainComponent, ITnInPort, ITnOutPort, IElectricMotorControl { - public HybridController(IVehicleContainer container) : base(container) { } + public HybridController(IVehicleContainer container, IHybridControlStrategy strategy, IElectricSystem es, IHybridControlledGearbox gbx, SwitchableClutch clutch) : base(container) { } public NewtonMeter MechanicalAssistPower(Second absTime, Second dt, NewtonMeter outTorque, PerSecond prevOutAngularVelocity, diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs index 54a0e185c70bac772953fce08802a0a7e8b9fb9c..9ca94d024cfd63a3a8a91084ad25cd00fdec21b6 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs @@ -1,6 +1,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies { - public class HybridStrategy + public class HybridStrategy : IHybridControlStrategy { } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs index 4775ebeed4112d74d0835a01f2aad2e702a8e2cc..55c6afcd93b7221ff3f66cfef012402c1612e1dc 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs @@ -1,7 +1,143 @@ -namespace TUGraz.VectoCore.Models.SimulationComponent +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent { - public class SwitchableClutch + public class SwitchableClutch : Clutch { - + public SwitchableClutch(IVehicleContainer container, CombustionEngineData engineData) : base(container, engineData) { } + + #region Overrides of Clutch + + + public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + if (ClutchOpen) + { + IResponse response = new ResponseSuccess(this); + if (outTorque * outAngularVelocity > 0) + { + response = new ResponseOverload(this) { Delta = outTorque * outAngularVelocity }; + + } + else if (outTorque * outAngularVelocity < 0) + { + response = new ResponseUnderload(this) { Delta = outTorque * outAngularVelocity }; + } + else + { + response = NextComponent.Initialize(0.SI<NewtonMeter>(), 0.RPMtoRad()); + } + return response; + } + if (DataBus.IgnitionOn) + return base.Initialize(outTorque, outAngularVelocity); + PreviousState.SetState(outTorque, outAngularVelocity, outTorque, outAngularVelocity); + return NextComponent.Initialize(outTorque, outAngularVelocity); + } + + public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun = false) + { + var avgOutSpeed = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + if (ClutchOpen) + { + + if (dryRun) + { + return new ResponseDryRun(this) + { + DeltaFullLoad = avgOutSpeed * outTorque, + DeltaDragLoad = avgOutSpeed * outTorque, + Clutch = {PowerRequest = avgOutSpeed * outTorque } + }; + } + var idleResponse = IdleController.Request(absTime, dt, 0.SI<NewtonMeter>(), null); + CurrentState.SetState(0.SI<NewtonMeter>(), idleResponse.Engine.EngineSpeed, outTorque, outAngularVelocity); + IResponse response = new ResponseSuccess(this); + if ((outTorque * avgOutSpeed).IsGreater(0, Constants.SimulationSettings.LineSearchTolerance)) + { + response = new ResponseOverload(this) { Delta = outTorque * avgOutSpeed }; + } + if ((outTorque * avgOutSpeed).IsSmaller(0, Constants.SimulationSettings.LineSearchTolerance)) + { + response = new ResponseUnderload(this) { Delta = outTorque * avgOutSpeed }; + } + response.Engine.EngineSpeed = idleResponse.Engine.EngineSpeed; + response.Clutch.PowerRequest = outTorque * avgOutSpeed; + return response; + } + + if (DataBus.IgnitionOn) + { + if (DataBus.DriverBehavior == DrivingBehavior.Halted && !ClutchOpen) + { + return HandleClutchClosed(absTime, dt, outTorque, outAngularVelocity, dryRun); + } + return base.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); + + } + + var retVal = NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); + + //if (retVal is ResponseEngineSpeedTooLow) + //{ + // var delta = ((ResponseEngineSpeedTooLow)retVal).DeltaEngineSpeed; + // var engineAngularVelocity = SearchAlgorithm.Search(outAngularVelocity, delta, delta * 0.1, + // result => ((ResponseDryRun)result).DeltaEngineSpeed, + // engineSpeed => NextComponent.Request(absTime, dt, outTorque, engineSpeed, true), + // result => ((ResponseDryRun)result).DeltaEngineSpeed.Value() * 1e3); + + // retVal = NextComponent.Request(absTime, dt, outTorque, engineAngularVelocity, dryRun); + //} + + if (!dryRun) + { + CurrentState.SetState(outTorque, retVal.Engine.EngineSpeed, outTorque, outAngularVelocity); + var avgInAngularVelocity = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2; + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2; + var clutchLoss = outTorque * (avgInAngularVelocity - avgOutAngularVelocity); + CurrentState.ClutchLoss = clutchLoss; + } + retVal.Clutch.PowerRequest = outTorque * avgOutSpeed; + return retVal; + } + + protected override void AddClutchLoss(NewtonMeter torque, PerSecond angularVelocity, bool allowSlipping, out NewtonMeter torqueIn, + out PerSecond angularVelocityIn) + { + if (ClutchOpen) + { + angularVelocityIn = _idleSpeed; + torqueIn = 0.SI<NewtonMeter>(); + return; + } + + torqueIn = torque; + angularVelocityIn = angularVelocity; + + var engineSpeedNorm = (angularVelocity - _idleSpeed) / (_ratedSpeed - _idleSpeed); + if (allowSlipping && engineSpeedNorm < Constants.SimulationSettings.ClutchClosingSpeedNorm) + { + var engineSpeed = VectoMath.Max(_idleSpeed, angularVelocity); + angularVelocityIn = _clutchSpeedSlippingFactor * engineSpeed + _idleSpeed; + } + } + + public bool ClutchOpen { get; set; } + + #region Overrides of Clutch + + public override bool ClutchClosed(Second absTime) { return !ClutchOpen; } + + #endregion + + #endregion } } \ No newline at end of file diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index ca308eb5689e89fd8950e43c83904ac060612d14..9726e50478a0b2b1435d17c0d6df6598360f2263 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -381,10 +381,14 @@ <Compile Include="Models\SimulationComponent\IBattery.cs" /> <Compile Include="Models\SimulationComponent\IElectricMotor.cs" /> <Compile Include="Models\SimulationComponent\IElectricMotorControl.cs" /> + <Compile Include="Models\SimulationComponent\IHybridControlledGearbox.cs" /> + <Compile Include="Models\SimulationComponent\IHybridControlStrategy.cs" /> <Compile Include="Models\SimulationComponent\Impl\Battery.cs" /> <Compile Include="Models\SimulationComponent\Impl\ElectricMotor.cs" /> <Compile Include="Models\SimulationComponent\Impl\HybridController.cs" /> <Compile Include="Models\SimulationComponent\Impl\StopStartCombustionEngine.cs" /> + <Compile Include="Models\SimulationComponent\Strategies\HybridStrategy.cs" /> + <Compile Include="Models\SimulationComponent\SwitchableClutch.cs" /> <Compile Include="Models\Simulation\DataBus\IBatteryInfo.cs" /> <Compile Include="Models\Simulation\DataBus\IElectricMotorInfo.cs" /> <Compile Include="Models\Simulation\DataBus\IEngineControl.cs" /> diff --git a/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs b/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs index 45457f74ea5e5af6d10390cd638e364fe2d6c4e8..2b5c37e2c7853d49f51d6666e05f626537168717 100644 --- a/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs +++ b/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs @@ -104,7 +104,7 @@ namespace TUGraz.VectoCore.Tests.FileIO } [TestCase()] - public void TestCreatePowertrain() + public void TestCreateHybridPowertrain() { var inputProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Hybrids\GenericVehicle_Group2_P2\Class2_RigidTruck_ParHyb_ENG.vecto"); diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/BatteryTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/BatteryTest.cs new file mode 100644 index 0000000000000000000000000000000000000000..228ed6c197ed07f27eec2f13dd32e77153bbf7ff --- /dev/null +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/BatteryTest.cs @@ -0,0 +1,204 @@ +using System.IO; +using NUnit.Framework; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.SimulationComponent; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Tests.Utils; + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponent +{ + [TestFixture] + public class BatteryTest + { + public const string componentFile = @"TestData\Hybrids\Battery\GenericBattery.vbat"; + + [OneTimeSetUp] + public void RunBeforeAnyTests() + { + Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory); + } + + [ + TestCase(0.5, 0.5, -500, 0.499985523), + TestCase(0.5, 1, -14000, 0.499175514), + TestCase(0.5, 1, 7000, 0.5004016980), + TestCase(0.35, 0.5, -200, 0.349994175), + TestCase(0.35, 0.5, -16000, 0.3495245545), + TestCase(0.75, 0.5, -300, 0.7499913702), + TestCase(0.75, 0.5, -14500, 0.7495755113), + ] + + public void BatteryRequestTest(double initialSoC, double simInterval, double powerDemand, double expectedSoC) + { + var inputData = JSONInputDataFactory.ReadBatteryData(componentFile, false); + Assert.NotNull(inputData); + + var dao = new EngineeringDataAdapter(); + var tmp = new MockBatteryInputData() + { + BatteryPack = inputData, + Count = 1 + }; + var batteryData = dao.CreateBatteryData(tmp, 0.8); + + var container = new MockVehicleContainer(); + var bat = new Battery(container, batteryData); + var modData = new MockModalDataContainer(); + bat.Initialize(initialSoC); + + //Assert.AreEqual(3.2*200, bat.Voltage.Value()); + + var absTime = 0.SI<Second>(); + var dt = simInterval.SI<Second>(); + var response = bat.Request(absTime, dt, powerDemand.SI<Watt>()); + Assert.IsInstanceOf<BatteryResponseSuccess>(response); + bat.CommitSimulationStep(absTime, dt, modData); + + Assert.AreEqual(expectedSoC, bat.StateOfCharge, 1e-9); + } + + [TestCase(0.5, 0.5, -500000, -169875, 70125), + TestCase(0.35, 0.5, -500000, -168375, 70125), + TestCase(0.75, 0.5, -500000, -171375, 70125), + TestCase(0.2001, 3, -500000, -563.00328, 0.40392), + TestCase(0.2001, 1, -500000, -1686.58632, 3.63528),] + public void BatteryOverloadTestNoAux(double initialSoC, double dt, double powerDemand, + double maxPowerDischarge, double battLoss) + { + + var inputData = JSONInputDataFactory.ReadBatteryData(componentFile, false); + Assert.NotNull(inputData); + + var dao = new EngineeringDataAdapter(); + var tmp = new MockBatteryInputData() + { + BatteryPack = inputData, + Count = 1 + }; + var batteryData = dao.CreateBatteryData(tmp, 0.8); + + var container = new MockVehicleContainer(); + var bat = new Battery(container, batteryData); + + bat.Initialize(initialSoC); + + var response = bat.Request(0.SI<Second>(), dt.SI<Second>(), powerDemand.SI<Watt>()); + Assert.IsInstanceOf<BatteryUnderloadResponse>(response); + + Assert.AreEqual(maxPowerDischarge, response.MaxBatteryLoadDischarge.Value(), 1e-2); + Assert.AreEqual(battLoss, response.BatteryLoss.Value(), 1e-2); + Assert.AreEqual(powerDemand, response.BatteryPower.Value(), 1e-2); + } + + [TestCase(0.5, 0.5, -500000, 10000, -169875, 70125), + TestCase(0.35, 0.5, -500000, 10000, -168375, 70125), + TestCase(0.75, 0.5, -500000, 10000, -171375, 70125), + TestCase(0.2001, 3, -500000, 10000, -563.00328, 0.40392), + TestCase(0.2001, 1, -500000, 10000, -1686.58632, 3.63528),] + public void BatteryOverloadTestAux(double initialSoC, double dt, double powerDemand, double auxPower, + double maxPowerDischarge, double battLoss) + { + + var inputData = JSONInputDataFactory.ReadBatteryData(componentFile, false); + Assert.NotNull(inputData); + + var dao = new EngineeringDataAdapter(); + var tmp = new MockBatteryInputData() + { + BatteryPack = inputData, + Count = 1 + }; + var batteryData = dao.CreateBatteryData(tmp, 0.8); + + var container = new MockVehicleContainer(); + var es = new ElectricSystem(container); + var bat = new Battery(container, batteryData); + es.Connect(bat); + es.Connect(new MockElectricConsumer(auxPower.SI<Watt>())); + bat.Initialize(initialSoC); + + var response = es.Request(0.SI<Second>(), dt.SI<Second>(), powerDemand.SI<Watt>()); + Assert.IsInstanceOf<ElectricSystemUnderloadResponse>(response); + + Assert.AreEqual(maxPowerDischarge, response.BatteryResponse.MaxBatteryLoadDischarge.Value(), 1e-2); + Assert.AreEqual(battLoss, response.BatteryResponse.BatteryLoss.Value(), 1e-2); + Assert.AreEqual(auxPower, response.AuxPower.Value(), 1e-2); + Assert.AreEqual(powerDemand - auxPower, response.BatteryResponse.BatteryPower.Value(), 1e-2); + } + + [TestCase(0.5, 0.5, 500000, 310125, 70125), + TestCase(0.35, 0.5, 500000, 308625, 70125), + TestCase(0.75, 0.5, 500000, 311625, 70125), + TestCase(0.2001, 3, 500000, 304878, 70125), + TestCase(0.7999, 1, 500000, 1747.82448, 3.63528), + TestCase(0.7999, 3, 500000, 581.80032, 0.40392)] + public void BatteryUnderloadTestNoAux(double initialSoC, double dt, double powerDemand, + double maxPowerDischarge, double battLoss) + { + + var inputData = JSONInputDataFactory.ReadBatteryData(componentFile, false); + Assert.NotNull(inputData); + + var dao = new EngineeringDataAdapter(); + var tmp = new MockBatteryInputData() + { + BatteryPack = inputData, + Count = 1 + }; + var batteryData = dao.CreateBatteryData(tmp, 0.8); + + var container = new MockVehicleContainer(); + var bat = new Battery(container, batteryData); + + bat.Initialize(initialSoC); + + var response = bat.Request(0.SI<Second>(), dt.SI<Second>(), powerDemand.SI<Watt>()); + Assert.IsInstanceOf<BatteryOverloadResponse>(response); + + Assert.AreEqual(maxPowerDischarge, response.MaxBatteryLoadCharge.Value(), 1e-2); + Assert.AreEqual(battLoss, response.BatteryLoss.Value(), 1e-2); + Assert.AreEqual(powerDemand, response.BatteryPower.Value(), 1e-2); + } + + [TestCase(0.5, 0.5, 500000, 10000, 310125, 70125), + TestCase(0.35, 0.5, 500000, 10000, 308625, 70125), + TestCase(0.75, 0.5, 500000, 10000, 311625, 70125), + TestCase(0.2001, 3, 500000, 10000, 304878, 70125), + TestCase(0.7999, 1, 500000, 10000, 1747.82448, 3.63528), + TestCase(0.7999, 3, 500000, 10000, 581.80032, 0.40392)] + public void BatteryUnderloadTestAux(double initialSoC, double dt, double powerDemand, double auxPower, + double maxPowerDischarge, double battLoss) + { + + var inputData = JSONInputDataFactory.ReadBatteryData(componentFile, false); + Assert.NotNull(inputData); + + var dao = new EngineeringDataAdapter(); + var tmp = new MockBatteryInputData() + { + BatteryPack = inputData, + Count = 1 + }; + var batteryData = dao.CreateBatteryData(tmp, 0.8); + + var container = new MockVehicleContainer(); + var bat = new Battery(container, batteryData); + var es = new ElectricSystem(container); + es.Connect(bat); + es.Connect(new MockElectricConsumer(auxPower.SI<Watt>())); + bat.Initialize(initialSoC); + + var response = es.Request(0.SI<Second>(), dt.SI<Second>(), powerDemand.SI<Watt>()); + Assert.IsInstanceOf<ElectricSystemOverloadResponse>(response); + + Assert.AreEqual(maxPowerDischarge, response.BatteryResponse.MaxBatteryLoadCharge.Value(), 1e-2); + Assert.AreEqual(battLoss, response.BatteryResponse.BatteryLoss.Value(), 1e-2); + Assert.AreEqual(auxPower, response.AuxPower.Value(), 1e-2); + Assert.AreEqual(powerDemand - auxPower, response.BatteryResponse.BatteryPower.Value(), 1e-2); + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs index 2a3a9e83f859e3c77a05cb169452b1feb192140f..9fd9f131043273beb806738e2fad2a8bd6c9981f 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs @@ -360,7 +360,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - Assert.AreEqual(105000, response.Engine.EnginePowerRequest.Value(), Tolerance); + Assert.AreEqual(105000, response.Engine.PowerRequest.Value(), Tolerance); container.CommitSimulationStep(absTime, dt); absTime += dt; @@ -418,7 +418,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - Assert.AreEqual(350000, response.Engine.EnginePowerRequest.Value(), Tolerance); + Assert.AreEqual(350000, response.Engine.PowerRequest.Value(), Tolerance); container.CommitSimulationStep(absTime, dt); absTime += dt; @@ -474,7 +474,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var response = (ResponseSuccess)requestPort.Initialize(torque, angularVelocity); response = (ResponseSuccess)requestPort.Request(absTime, dt, torque, angularVelocity); - Assert.AreEqual(-14829.79713, response.Engine.EnginePowerRequest.Value(), Tolerance); + Assert.AreEqual(-14829.79713, response.Engine.PowerRequest.Value(), Tolerance); container.CommitSimulationStep(absTime, dt); absTime += dt; diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/ElectricMotorTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/ElectricMotorTest.cs new file mode 100644 index 0000000000000000000000000000000000000000..139c9b275b0f3f23311a7aba38c209eabaffac5a --- /dev/null +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/ElectricMotorTest.cs @@ -0,0 +1,229 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using NUnit.Framework; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.SimulationComponent; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Tests.Utils; + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponent +{ + [TestFixture] + public class ElectricMotorTest + { + public const string MotorFile = @"TestData\Hybrids\ElectricMotor\GenericEMotor.vem"; + public const string BatFile = @"TestData\Hybrids\Battery\GenericBattery.vbat"; + + [OneTimeSetUp] + public void RunBeforeAnyTests() + { + Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory); + } + + [TestCase(100, 100, -1479.601019), + TestCase(100, 30, -494.148831), + TestCase(100, 300, -5033.132712), + TestCase(600, 100, -7290.510011), + TestCase(600, 300, -21431.717255), + TestCase(800, -100, 7178.770573), + TestCase(800, -300, 22444.155535)] + public void ElectricMotorOnlyRequestTest(double speed, double torque, double expectedBatteryPower) + { + var container = new MockVehicleContainer(); + + var inputData = JSONInputDataFactory.ReadElectricMotorData(MotorFile, false); + var dao = new EngineeringDataAdapter(); + var electricMachine = new MockElectricMachinesInputData() { + Entries = new List<ElectricMachineEntry<IElectricMotorEngineeringInputData>>() { + new ElectricMachineEntry<IElectricMotorEngineeringInputData>() { + ElectricMachine = inputData, + Count = 1 + } + } + }; + var data = dao.CreateElectricMachines(electricMachine); + var strategy = new MockHybridControl(); + + var battery = new MockBattery(); + var motor = new ElectricMotor(container, data.First().Item2, strategy, PowertrainPosition.HybridP2); + var es = new ElectricSystem(container); + es.Connect(battery); + motor.Connect(es); + + strategy.ElectricShare = -torque.SI<NewtonMeter>(); + motor.Initialize(0.SI<NewtonMeter>(), speed.RPMtoRad()); + + var response = motor.Request(0.SI<Second>(), 0.5.SI<Second>(), torque.SI<NewtonMeter>(), speed.RPMtoRad()); + + Assert.IsInstanceOf<ResponseSuccess>(response); + var enginePower = speed.RPMtoRad() * strategy.ElectricShare; + Assert.AreEqual(0, response.Engine.PowerRequest.Value(), 1e-6); + Assert.AreEqual(enginePower.Value(), response.ElectricMotor.ElectricMotorPowerMech.Value(), 1e-6); + Assert.AreEqual(expectedBatteryPower, response.ElectricSystem.ConsumerPower.Value(), 1e-6); + Assert.AreEqual(expectedBatteryPower, response.ElectricSystem.BatteryResponse.BatteryPower.Value(), 1e-6); + Assert.IsTrue(response.ElectricSystem.ConsumerPower.Value() < enginePower.Value()); + } + + + [TestCase(100, 100, -30, -494.148831), + TestCase(100, 300, -150, -2265.054223), + TestCase(600, 100, 100, 5368.366615), + TestCase(600, 300, -50, -3926.835416), + TestCase(800, -100, 200, 14945.984737), + TestCase(800, -300, 200, 14945.984737),] + public void ElectricMotorAssistingRequestTest(double speed, double torque, double electricTorque, double expectedBatteryPower) + { + var container = new MockVehicleContainer(); + + var inputData = JSONInputDataFactory.ReadElectricMotorData(MotorFile, false); + var dao = new EngineeringDataAdapter(); + var electricMachine = new MockElectricMachinesInputData() + { + Entries = new List<ElectricMachineEntry<IElectricMotorEngineeringInputData>>() { + new ElectricMachineEntry<IElectricMotorEngineeringInputData>() { + ElectricMachine = inputData, + Count = 1 + } + } + }; + var data = dao.CreateElectricMachines(electricMachine); + var strategy = new MockHybridControl(); + + var battery = new MockBattery(); + var motor = new ElectricMotor(container, data.First().Item2, strategy, PowertrainPosition.HybridP2); + var es = new ElectricSystem(container); + es.Connect(battery); + motor.Connect(es); + var tnPort = new MockTnOutPort(); + motor.Connect(tnPort); + + strategy.ElectricShare = electricTorque.SI<NewtonMeter>(); + motor.Initialize(0.SI<NewtonMeter>(), speed.RPMtoRad()); + + var response = motor.Request(0.SI<Second>(), 0.5.SI<Second>(), torque.SI<NewtonMeter>(), speed.RPMtoRad()); + + Assert.IsInstanceOf<ResponseSuccess>(response); + var enginePower = speed.RPMtoRad() * (torque + electricTorque).SI<NewtonMeter>(); + var motorMechPower = speed.RPMtoRad() * electricTorque.SI<NewtonMeter>(); + Assert.AreEqual(enginePower.Value(), response.Engine.PowerRequest.Value(), 1e-6); + Assert.AreEqual(motorMechPower, response.ElectricMotor.ElectricMotorPowerMech); + Assert.AreEqual(expectedBatteryPower, response.ElectricSystem.ConsumerPower.Value(), 1e-6); + Assert.AreEqual(expectedBatteryPower, response.ElectricSystem.BatteryResponse.BatteryPower.Value(), 1e-6); + Assert.IsTrue(response.ElectricSystem.ConsumerPower.Value() < response.ElectricMotor.ElectricMotorPowerMech.Value()); + } + + [TestCase(800, 300)] + public void ElectricMotorWithBatteryIdlingRequestTest(double speed, double torque) + { + var container = new MockVehicleContainer(); + + var inputData = JSONInputDataFactory.ReadElectricMotorData(MotorFile, false); + var dao = new EngineeringDataAdapter(); + var electricMachine = new MockElectricMachinesInputData() + { + Entries = new List<ElectricMachineEntry<IElectricMotorEngineeringInputData>>() { + new ElectricMachineEntry<IElectricMotorEngineeringInputData>() { + ElectricMachine = inputData, + Count = 1 + } + } + }; + var data = dao.CreateElectricMachines(electricMachine); + var strategy = new MockHybridControl(); + + var batInput = JSONInputDataFactory.ReadBatteryData(BatFile, false); + var tmp = new MockBatteryInputData() { + BatteryPack = batInput, + Count = 1 + }; + var batteryData = dao.CreateBatteryData(tmp, 0.8); + var battery = new Battery(container, batteryData); + var es = new ElectricSystem(container); + es.Connect(battery); + + battery.Initialize(0.5); + var motor = new ElectricMotor(container, data.First().Item2, strategy, PowertrainPosition.HybridP2); + motor.Connect(es); + var tnPort = new MockTnOutPort(); + motor.Connect(tnPort); + + strategy.ElectricShare = 0.SI<NewtonMeter>(); + motor.Initialize(0.SI<NewtonMeter>(), speed.RPMtoRad()); + + var absTime = 0.SI<Second>(); + var dt = 0.5.SI<Second>(); + var response = motor.Request(absTime, dt, torque.SI<NewtonMeter>(), speed.RPMtoRad()); + + Assert.IsInstanceOf<ResponseSuccess>(response); + var enginePower = speed.RPMtoRad() * torque.SI<NewtonMeter>(); + var motorMechPower = 0.SI<Watt>(); + Assert.AreEqual(enginePower.Value(), response.Engine.PowerRequest.Value(), 1e-6); + Assert.AreEqual(motorMechPower, response.ElectricMotor.ElectricMotorPowerMech); + Assert.AreEqual(0, response.ElectricSystem.ConsumerPower.Value(), 1e-6); + Assert.AreEqual(0, response.ElectricSystem.BatteryResponse.BatteryPower.Value(), 1e-6); + var modData = new MockModalDataContainer(); + battery.CommitSimulationStep(absTime, dt, modData); + } + + [TestCase(0.5, 100, 100, -1479.601019, 2.674905), + TestCase(0.5, 100, 300, -5033.132712, 31.224759), + TestCase(0.5, 600, 100, -7290.510011, 65.884061), + TestCase(0.5, 600, 300, -21431.717255, 590.431866), + TestCase(0.5, 800, -100, 7178.770573, 61.667578), + TestCase(0.5, 800, -300, 22444.155535, 581.889779) + ] + public void ElectricMotorOnlyWithBatteryRequestTest(double initialSoc, double speed, double torque, double expectedBatteryPower, double expectedBatteryLoss) + { + var container = new MockVehicleContainer(); + + var inputData = JSONInputDataFactory.ReadElectricMotorData(MotorFile, false); + var batInput = JSONInputDataFactory.ReadBatteryData(BatFile, false); + var dao = new EngineeringDataAdapter(); + var electricMachine = new MockElectricMachinesInputData() + { + Entries = new List<ElectricMachineEntry<IElectricMotorEngineeringInputData>>() { + new ElectricMachineEntry<IElectricMotorEngineeringInputData>() { + ElectricMachine = inputData, + Count = 1 + } + } + }; + var data = dao.CreateElectricMachines(electricMachine); + var strategy = new MockHybridControl(); + + var tmp = new MockBatteryInputData() + { + BatteryPack = batInput, + Count = 1 + }; + var batteryData = dao.CreateBatteryData(tmp, 0.8); + var battery = new Battery(container, batteryData); + var es = new ElectricSystem(container); + es.Connect(battery); + battery.Initialize(initialSoc); + var motor = new ElectricMotor(container, data.First().Item2, strategy, PowertrainPosition.HybridP2); + motor.Connect(es); + + strategy.ElectricShare = -torque.SI<NewtonMeter>(); + motor.Initialize(0.SI<NewtonMeter>(), speed.RPMtoRad()); + + var response = motor.Request(0.SI<Second>(), 0.5.SI<Second>(), torque.SI<NewtonMeter>(), speed.RPMtoRad()); + + Assert.IsInstanceOf<ResponseSuccess>(response); + var enginePower = speed.RPMtoRad() * strategy.ElectricShare; + Assert.AreEqual(0, response.Engine.PowerRequest.Value(), 1e-6); + Assert.AreEqual(enginePower.Value(), response.ElectricMotor.ElectricMotorPowerMech.Value(), 1e-6); + Assert.AreEqual(expectedBatteryPower, response.ElectricSystem.ConsumerPower.Value(), 1e-6); + Assert.AreEqual(expectedBatteryPower, response.ElectricSystem.BatteryResponse.BatteryPower.Value(), 1e-6); + Assert.IsTrue(response.ElectricSystem.ConsumerPower.Value() < enginePower.Value()); + Assert.AreEqual(expectedBatteryLoss, response.ElectricSystem.BatteryResponse.BatteryLoss.Value(), 1e-4); + } + } + +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Battery/GenericBattery.vbat b/VectoCore/VectoCoreTest/TestData/Hybrids/Battery/GenericBattery.vbat index cfc68df2e8d42c73e4fd573c1d2eaa19f8221f38..fe2e69719a6f34fa259e6adf71b53f63d4fe8d53 100644 --- a/VectoCore/VectoCoreTest/TestData/Hybrids/Battery/GenericBattery.vbat +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Battery/GenericBattery.vbat @@ -10,14 +10,14 @@ "Model": "Generic Battery", "SOC_min": 20, "SOC_max": 80, - "Capacity": 14, - "InternalResistance": 0.12, - "MaxCurrentFactor": 5, + "Capacity": 7.5, + "InternalResistance": 0.4986666, + "MaxCurrentFactor": 50, "SOC": [ [ 0, 590 ], [ 10, 614 ], [ 20, 626 ], - [ 30, 632 ], + [ 30, 634 ], [ 40, 638 ], [ 50, 640 ], [ 60, 640 ], diff --git a/VectoCore/VectoCoreTest/Utils/MockBattery.cs b/VectoCore/VectoCoreTest/Utils/MockBattery.cs new file mode 100644 index 0000000000000000000000000000000000000000..6d5d29546976d648d8d37323a37432a4ef721449 --- /dev/null +++ b/VectoCore/VectoCoreTest/Utils/MockBattery.cs @@ -0,0 +1,73 @@ +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.SimulationComponent; + +namespace TUGraz.VectoCore.Tests.Utils { + public class MockBattery : IBattery, IBatteryPort, IElectricAuxConnecor + { + public Volt InternalCellVoltage + { + get { return 640.SI<Volt>(); } + } + + public IBatteryResponse Request(Second absTime, Second dt, Watt powerdemand, bool dryRun = false) + { + return new BatteryResponseSuccess(this) + { + MaxBatteryLoadDischarge = InternalCellVoltage * MaxCurrent, + AbsTime = absTime, + BatteryLoss = 0.SI<Watt>(), + MaxBatteryLoadCharge = -InternalCellVoltage * MaxCurrent, + BatteryPower = powerdemand, + SimulationInterval = dt, + }; + } + + public double StateOfCharge { get; set; } + + public Ampere MaxCurrent + { + get { return 375.SI<Ampere>(); } + } + + public Watt MaxChargePower(Second dt) + { + throw new System.NotImplementedException(); + } + + public Watt MaxDischargePower(Second dt) + { + throw new System.NotImplementedException(); + } + + public IBatteryPort MainBatteryPort + { + get { return this; } + } + + public IElectricAuxConnecor AuxBatteryPort() + { + return this; + } + + public void Initialize(double initialSoC) + { + StateOfCharge = initialSoC; + } + + public void Connect(IBatteryAuxPort aux) + { + throw new System.NotImplementedException(); + } + + #region Implementation of IBatteryChargeProvider + + public void Connect(IBatteryChargePort charger) + { + throw new System.NotImplementedException(); + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Utils/MockBatteryInputData.cs b/VectoCore/VectoCoreTest/Utils/MockBatteryInputData.cs new file mode 100644 index 0000000000000000000000000000000000000000..da4e71a9bdac6dd974b9768c29eefc4f1c953be9 --- /dev/null +++ b/VectoCore/VectoCoreTest/Utils/MockBatteryInputData.cs @@ -0,0 +1,11 @@ +using TUGraz.VectoCommon.InputData; + +namespace TUGraz.VectoCore.Tests.Utils { + public class MockBatteryInputData : IElectricStorageEngineeringInputData + { + IBatteryPackDeclarationInputData IElectricStorageDeclarationInputData.BatteryPack => BatteryPack; + + public IBatteryPackEngineeringInputData BatteryPack { get; set; } + public int Count { get; set; } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Utils/MockElectricConsumer.cs b/VectoCore/VectoCoreTest/Utils/MockElectricConsumer.cs new file mode 100644 index 0000000000000000000000000000000000000000..b7dad2e02270fac6a04d9c9ce89138b54aaea112 --- /dev/null +++ b/VectoCore/VectoCoreTest/Utils/MockElectricConsumer.cs @@ -0,0 +1,25 @@ +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; + +namespace TUGraz.VectoCore.Tests.Utils { + public class MockElectricConsumer : IBatteryAuxPort + { + private Watt PowwerDemand; + + public MockElectricConsumer(Watt powerDemand) + { + PowwerDemand = powerDemand; + } + + public Watt Initialize() + { + return PowwerDemand; + } + + public Watt PowerDemand(Second absTime, Second dt, bool dryRun) + { + return PowwerDemand; + } + + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Utils/MockElectricMachinesInputData.cs b/VectoCore/VectoCoreTest/Utils/MockElectricMachinesInputData.cs new file mode 100644 index 0000000000000000000000000000000000000000..52126e4359f3ee8ff01d30e8a50e4002b07e1b14 --- /dev/null +++ b/VectoCore/VectoCoreTest/Utils/MockElectricMachinesInputData.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using TUGraz.VectoCommon.InputData; + +namespace TUGraz.VectoCore.Tests.Utils { + class MockElectricMachinesInputData : IElectricMachinesEngineeringInputData + { + IList<ElectricMachineEntry<IElectricMotorDeclarationInputData>> IElectricMachinesDeclarationInputData.Entries + { + get; + } + + public IList<ElectricMachineEntry<IElectricMotorEngineeringInputData>> Entries + { + get; + set; + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Utils/MockGearbox.cs b/VectoCore/VectoCoreTest/Utils/MockGearbox.cs index cfcc5d85fb3cf6fe83b20cf5cb4ee1293d152263..3e19509990f934ec48d9b9f5979e598e76742019 100644 --- a/VectoCore/VectoCoreTest/Utils/MockGearbox.cs +++ b/VectoCore/VectoCoreTest/Utils/MockGearbox.cs @@ -132,6 +132,11 @@ namespace TUGraz.VectoCore.Tests.Utils protected override void DoCommitSimulationStep() {} + public bool GearEngaged(Second absTime) + { + return _clutchClosed; + } + public bool ClutchClosed(Second absTime) { return _clutchClosed; diff --git a/VectoCore/VectoCoreTest/Utils/MockHybridControl.cs b/VectoCore/VectoCoreTest/Utils/MockHybridControl.cs new file mode 100644 index 0000000000000000000000000000000000000000..9cf922f6117b03d8fa92a96ee7effb3fb80087f5 --- /dev/null +++ b/VectoCore/VectoCoreTest/Utils/MockHybridControl.cs @@ -0,0 +1,24 @@ +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.SimulationComponent; + +namespace TUGraz.VectoCore.Tests.Utils { + public class MockHybridControl : IElectricMotorControl + { + public NewtonMeter ElectricShare { get; set; } + + public NewtonMeter MechanicalAssistPower(Second absTime, Second dt, NewtonMeter outTorque, PerSecond prevOutAngularVelocity, PerSecond curOutAngularVelocity, bool dryRun) + { + return ElectricShare; + } + + public NewtonMeter MaxDriveTorque(PerSecond avgSpeed, Second dt) + { + return -100000.SI<Watt>() / avgSpeed; + } + + public NewtonMeter MaxDragTorque(PerSecond avgSpeed, Second dt) + { + return 100.SI<NewtonMeter>(); + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs index 4567f706bbd8f5931f3de023a9a22253faa911d6..4702165426c6e83f193172f6b564703bd2793978 100644 --- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs @@ -249,6 +249,10 @@ namespace TUGraz.VectoCore.Tests.Utils #region Implementation of IGearboxControl public bool DisengageGearbox { get; set; } + public bool GearEngaged(Second absTime) + { + return ClutchClosed(absTime); + } #endregion diff --git a/VectoCore/VectoCoreTest/VectoCoreTest.csproj b/VectoCore/VectoCoreTest/VectoCoreTest.csproj index d1520bd46624aba2fed109c89dc1bece26baacfb..0705fedb1eae7c412b92ece9d4f8ab2c0f741965 100644 --- a/VectoCore/VectoCoreTest/VectoCoreTest.csproj +++ b/VectoCore/VectoCoreTest/VectoCoreTest.csproj @@ -135,8 +135,15 @@ <Compile Include="Models\SimulationComponentData\TorqueConverterDataTest.cs" /> <Compile Include="Models\SimulationComponentData\ValidationTest.cs" /> <Compile Include="Models\SimulationComponent\ATGearboxTest.cs" /> + <Compile Include="Models\SimulationComponent\BatteryTest.cs" /> + <Compile Include="Models\SimulationComponent\ElectricMotorTest.cs" /> <Compile Include="Models\SimulationComponent\EngineFanAuxTest.cs" /> <Compile Include="Models\SimulationComponent\GearboxShiftLossesTest.cs" /> + <Compile Include="Utils\MockElectricConsumer.cs" /> + <Compile Include="Utils\MockHybridControl.cs" /> + <Compile Include="Utils\MockBattery.cs" /> + <Compile Include="Utils\MockBatteryInputData.cs" /> + <Compile Include="Utils\MockElectricMachinesInputData.cs" /> <Compile Include="Models\SimulationComponent\VTPCycleValidationTest.cs" /> <Compile Include="Models\Simulation\FactoryTest.cs" /> <Compile Include="Models\Simulation\PTOIdleLossTest.cs" />