diff --git a/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs b/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs index fa04c1a336b3fd4185612b872ed0cd0014271564..cfcdf3764b88cdb0beb7c62295490d5710768d92 100644 --- a/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs @@ -400,7 +400,7 @@ namespace TUGraz.VectoCore.InputData.Reader crossWindRequired ? row.ParseDouble(Fields.AirSpeedRelativeToVehicle).KMPHtoMeterPerSecond() : null, WindYawAngle = crossWindRequired ? row.ParseDoubleOrGetDefault(Fields.WindYawAngle) : 0, AuxiliarySupplyPower = row.GetAuxiliaries(), - PTOActive = table.Columns.Contains(Fields.PTOActive) && row.Field<char>(Fields.PTOActive) == '1' + PTOActive = table.Columns.Contains(Fields.PTOActive) && row.Field<string>(Fields.PTOActive) == "1" }); } diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index a5d6fa2d4ff238460c39de55e9dfb33de8624d93..96dfeee4584008519c09735c203a6cda7bac2b9b 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -70,8 +70,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl return BuildMeasuredSpeed(data); case CycleType.MeasuredSpeedGear: return BuildMeasuredSpeedGear(data); + case CycleType.DistanceBased: + return BuildFullPowertrain(data); + default: + throw new VectoException("Powertrain Builder cannot build Powertrain for CycleType: {0}", data.Cycle.CycleType); } - return BuildFullPowertrain(data); } private VehicleContainer BuildEngineOnly(VectoRunData data) @@ -110,7 +113,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl .AddComponent(gearbox, data.Retarder, data.PTO, container) .AddComponent(new CycleClutch(container)); var engine = new CombustionEngine(container, data.EngineData, pt1Disabled: true); - var idleController = GetIdleController(data.PTO, engine, container); + var idleController = GetIdleController(data.PTO, engine); powertrain.AddComponent(engine, idleController, container) .AddAuxiliaries(container, data); @@ -141,7 +144,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl } var engine = new CombustionEngine(container, data.EngineData); - var idleController = GetIdleController(data.PTO, engine, container); + var idleController = GetIdleController(data.PTO, engine); powertrain.AddComponent(engine, idleController, container) .AddAuxiliaries(container, data); @@ -170,7 +173,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl .AddComponent(new CycleClutch(container)); var engine = new CombustionEngine(container, data.EngineData); - powertrain.AddComponent(engine, GetIdleController(data.PTO, engine, container), container) + powertrain.AddComponent(engine, GetIdleController(data.PTO, engine), container) .AddAuxiliaries(container, data); return container; @@ -199,7 +202,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl } var engine = new CombustionEngine(container, data.EngineData); - var idleController = GetIdleController(data.PTO, engine, container); + var idleController = GetIdleController(data.PTO, engine); cycle.IdleController = idleController as IdleControllerSwitcher; powertrain.AddComponent(engine, idleController, container) @@ -210,11 +213,14 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl return container; } - private static IIdleController GetIdleController(PTOData pto, CombustionEngine engine, IVehicleContainer container) + private static IIdleController GetIdleController(PTOData pto, ICombustionEngine engine) { - return pto == null - ? engine.IdleController - : new IdleControllerSwitcher(engine.IdleController, new PTOCycleController(container, pto.PTOCycle)); + if (pto == null) + return engine.IdleController; + else { + var ptoController = new PTOCycleController(pto.PTOCycle); + return new IdleControllerSwitcher(engine.IdleController, ptoController); + } } internal static IAuxInProvider CreateAdvancedAuxiliaries(VectoRunData data, IVehicleContainer container) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs index 7407267ad8220e1e55ce199fcc14e6ad5b25440b..c2ceae2d3bb52448e365ab90d7de3a163f3bcdff 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs @@ -57,6 +57,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private readonly DrivingCycleData _data; internal readonly DrivingCycleEnumerator CycleIntervalIterator; private bool _intervalProlonged; + internal IdleControllerSwitcher IdleController; public DistanceBasedDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) : base(container) { @@ -106,17 +107,38 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl throw new VectoSimulationException("Stopping Time only allowed when target speed is zero!"); } var dt = CycleIntervalIterator.LeftSample.StoppingTime - PreviousState.WaitTime; - if (CycleIntervalIterator.LeftSample.StoppingTime.IsGreater(3 * Constants.SimulationSettings.TargetTimeInterval)) { - // split into 3 parts + + if (CycleIntervalIterator.LeftSample.PTOActive) { if (PreviousState.WaitTime.IsEqual(0)) { + // waiting just started. Activate PTO + IdleController.Reset(); + IdleController.ActivatePTO(); + } else { + // we already started pto cycle and are now in the follow up call. + // So we have to manually commit the previous simulation step to go further. + IdleController.CommitSimulationStep(); + } + var nextCycleTime = IdleController.GetNextCycleTime(); + if (nextCycleTime == null) { + // PTO Cycle has finished. Switch to normal idle controller. + IdleController.ActivateIdle(); dt = Constants.SimulationSettings.TargetTimeInterval; } else { - if (dt > Constants.SimulationSettings.TargetTimeInterval) { - dt -= Constants.SimulationSettings.TargetTimeInterval; + // set dt to the next time interval in the pto cycle (to synchronize driving cycle with pto cycle) + dt = nextCycleTime - PreviousState.WaitTime; + } + } else { + if (CycleIntervalIterator.LeftSample.StoppingTime.IsGreater(3 * Constants.SimulationSettings.TargetTimeInterval)) { + // split into 3 parts or use idle controller time intervals + if (PreviousState.WaitTime.IsEqual(0)) { + dt = Constants.SimulationSettings.TargetTimeInterval; + } else { + if (dt > Constants.SimulationSettings.TargetTimeInterval) { + dt -= Constants.SimulationSettings.TargetTimeInterval; + } } } } - CurrentState.Response = DriveTimeInterval(absTime, dt); return CurrentState.Response; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/IdleControllerSwitcher.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/IdleControllerSwitcher.cs new file mode 100644 index 0000000000000000000000000000000000000000..ef0db2c6302b7a0768b7c4440b73859e93fee52b --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/IdleControllerSwitcher.cs @@ -0,0 +1,70 @@ +using System; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class IdleControllerSwitcher : IIdleController + { + private readonly IIdleController _idleController; + private readonly PTOCycleController _ptoController; + private IIdleController _currentController; + + public IdleControllerSwitcher(IIdleController idleController, PTOCycleController ptoController) + { + _idleController = idleController; + _ptoController = ptoController; + + // default state is idleController + _currentController = _idleController; + } + + public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun = false) + { + return _currentController.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); + } + + public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + throw new InvalidOperationException(string.Format("{0} cannot initialize.", GetType().FullName)); + } + + public ITnOutPort RequestPort + { + set + { + _idleController.RequestPort = value; + _ptoController.RequestPort = value; + } + } + + public void Reset() + { + _idleController.Reset(); + _ptoController.Reset(); + _currentController = _idleController; + } + + public void ActivatePTO() + { + _currentController = _ptoController; + } + + public void ActivateIdle() + { + _currentController = _idleController; + } + + public Second GetNextCycleTime() + { + return _ptoController.GetNextCycleTime(); + } + + public void CommitSimulationStep() + { + _ptoController.CommitSimulationStep(null); + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOCycleController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOCycleController.cs index 2ab8e025a11b8d8ba18e9ce1e862471fe2dcb308..17d894ad92f8ac9aa2597eb88830c4b9d4d46a2a 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOCycleController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOCycleController.cs @@ -3,7 +3,6 @@ using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.SimulationComponent.Data; namespace TUGraz.VectoCore.Models.SimulationComponent.Impl @@ -17,8 +16,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected Second IdleStart; - public PTOCycleController(IVehicleContainer container, DrivingCycleData cycle) - : base(container, cycle) {} + public PTOCycleController(DrivingCycleData cycle) : base(null, cycle) {} public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun = false) @@ -42,10 +40,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public void Reset() { - LeftSample = Data.Entries.GetEnumerator(); + LeftSample.Reset(); LeftSample.MoveNext(); - RightSample = Data.Entries.GetEnumerator(); + RightSample.Reset(); RightSample.MoveNext(); RightSample.MoveNext(); @@ -54,7 +52,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public Second GetNextCycleTime() { - return IdleStart + RightSample.Current.Time; + if (RightSample.Current == null) + return null; + + return RightSample.Current.Time; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs b/VectoCore/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs index 20cef18b86729a4bc145d9a7d53b5c037a3b6a7e..2ccd9340152c2014dc40af21c12fc8e0218ee621 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs @@ -52,7 +52,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent protected VectoSimulationComponent(IVehicleContainer dataBus) { DataBus = dataBus; - dataBus.AddComponent(this); + + // if a component doesn't want to be registered in DataBus, it supplies null to the constructor + // (mk 2016-08-31: currently the only example is PTOCycleController, to not interfere with the real DrivingCycle) + if (dataBus != null) + dataBus.AddComponent(this); } public virtual void CommitSimulationStep(IModalDataContainer container) diff --git a/VectoCore/VectoCore/Utils/ProviderExtensions.cs b/VectoCore/VectoCore/Utils/ProviderExtensions.cs index 053a66714a9faa2abbe67c07befac4de04ea3a0c..0eb11c65e20e444df066a28b6f938d572e8b833e 100644 --- a/VectoCore/VectoCore/Utils/ProviderExtensions.cs +++ b/VectoCore/VectoCore/Utils/ProviderExtensions.cs @@ -32,7 +32,6 @@ using System; using System.Collections.Generic; using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.InputData.Reader; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Declaration; @@ -134,62 +133,4 @@ namespace TUGraz.VectoCore.Utils } } } - - public class IdleControllerSwitcher : IIdleController - { - private readonly IIdleController _idleController; - private readonly PTOCycleController _ptoController; - private IIdleController _currentController; - - public IdleControllerSwitcher(IIdleController idleController, PTOCycleController ptoController) - { - _idleController = idleController; - _ptoController = ptoController; - - // default state is idleController - _currentController = _idleController; - } - - public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun = false) - { - return _currentController.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); - } - - public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) - { - throw new InvalidOperationException(string.Format("{0} cannot initialize.", GetType().FullName)); - } - - public ITnOutPort RequestPort - { - set - { - _idleController.RequestPort = value; - _ptoController.RequestPort = value; - } - } - - public void Reset() - { - _idleController.Reset(); - _ptoController.Reset(); - _currentController = _idleController; - } - - public void ActivatePTO() - { - _currentController = _ptoController; - } - - public void ActivateIdle() - { - _currentController = _idleController; - } - - public Second GetNextCycleTime() - { - return _ptoController.GetNextCycleTime(); - } - } } \ No newline at end of file diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index 5b1eccc80bf7a63dda447b36524a987606d305c8..c8fd7f14e100dc428de52a51774be290ea2f174a 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -153,6 +153,7 @@ <Compile Include="Models\SimulationComponent\Impl\PTOCycleController.cs" /> <Compile Include="Models\SimulationComponent\Impl\PWheelCycle.cs" /> <Compile Include="Models\SimulationComponent\Impl\TorqueConverter.cs" /> + <Compile Include="Models\SimulationComponent\Impl\IdleControllerSwitcher.cs" /> <Compile Include="Utils\ProviderExtensions.cs" /> <Compile Include="Models\Declaration\AirDrag.cs" /> <Compile Include="Models\Declaration\Fan.cs" />