From ae8a63dce5d1eef2ba7a23a821383318192bb7ca Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Mon, 3 Jul 2017 09:37:39 +0200 Subject: [PATCH] remove max-loading info field --- VECTO/GUI/VehicleForm.Designer.vb | 186 ++-- VECTO/GUI/VehicleForm.vb | 15 - .../Simulation/Impl/PowertrainBuilder.cs | 534 +++++----- .../SimulationComponent/Impl/CycleGearbox.cs | 920 +++++++++--------- .../SimulationComponent/Impl/PWheelCycle.cs | 268 ++--- .../Impl/PowertrainDrivingCycle.cs | 400 ++++---- .../SimulationComponent/Impl/Vehicle.cs | 448 ++++----- .../OutputData/FileIO/FileOutputWriter.cs | 170 ++-- .../Models/Simulation/PwheelModeTests.cs | 346 +++---- 9 files changed, 1618 insertions(+), 1669 deletions(-) diff --git a/VECTO/GUI/VehicleForm.Designer.vb b/VECTO/GUI/VehicleForm.Designer.vb index 434ffb244d..0db5e85b16 100644 --- a/VECTO/GUI/VehicleForm.Designer.vb +++ b/VECTO/GUI/VehicleForm.Designer.vb @@ -85,6 +85,7 @@ Partial Class VehicleForm Me.ColumnHeader1 = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) Me.ColumnHeader3 = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) Me.ColumnHeader4 = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) + Me.ColumnHeader10 = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) Me.ButAxlAdd = New System.Windows.Forms.Button() Me.PnWheelDiam = New System.Windows.Forms.Panel() Me.CbAxleConfig = New System.Windows.Forms.ComboBox() @@ -95,9 +96,6 @@ Partial Class VehicleForm Me.StatusStrip1 = New System.Windows.Forms.StatusStrip() Me.LbStatus = New System.Windows.Forms.ToolStripStatusLabel() Me.TbHDVclass = New System.Windows.Forms.TextBox() - Me.Label11 = New System.Windows.Forms.Label() - Me.TbLoadingMax = New System.Windows.Forms.TextBox() - Me.Label22 = New System.Windows.Forms.Label() Me.GroupBox1 = New System.Windows.Forms.GroupBox() Me.PnLoad = New System.Windows.Forms.Panel() Me.GrAirRes = New System.Windows.Forms.GroupBox() @@ -131,6 +129,11 @@ Partial Class VehicleForm Me.ToolTip1 = New System.Windows.Forms.ToolTip(Me.components) Me.TabControl1 = New System.Windows.Forms.TabControl() Me.TabPage1 = New System.Windows.Forms.TabPage() + Me.GroupBox4 = New System.Windows.Forms.GroupBox() + Me.Panel1 = New System.Windows.Forms.Panel() + Me.tbVehIdlingSpeed = New System.Windows.Forms.TextBox() + Me.Label18 = New System.Windows.Forms.Label() + Me.Label19 = New System.Windows.Forms.Label() Me.TabPage2 = New System.Windows.Forms.TabPage() Me.TabPage3 = New System.Windows.Forms.TabPage() Me.lvTorqueLimits = New System.Windows.Forms.ListView() @@ -139,12 +142,6 @@ Partial Class VehicleForm Me.Label17 = New System.Windows.Forms.Label() Me.btDelMaxTorqueEntry = New System.Windows.Forms.Button() Me.btAddMaxTorqueEntry = New System.Windows.Forms.Button() - Me.ColumnHeader10 = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) - Me.GroupBox4 = New System.Windows.Forms.GroupBox() - Me.Panel1 = New System.Windows.Forms.Panel() - Me.tbVehIdlingSpeed = New System.Windows.Forms.TextBox() - Me.Label18 = New System.Windows.Forms.Label() - Me.Label19 = New System.Windows.Forms.Label() Me.GroupBox6.SuspendLayout() Me.ToolStrip1.SuspendLayout() Me.GroupBox7.SuspendLayout() @@ -166,10 +163,10 @@ Partial Class VehicleForm CType(Me.PicVehicle, System.ComponentModel.ISupportInitialize).BeginInit() Me.TabControl1.SuspendLayout() Me.TabPage1.SuspendLayout() - Me.TabPage2.SuspendLayout() - Me.TabPage3.SuspendLayout() Me.GroupBox4.SuspendLayout() Me.Panel1.SuspendLayout() + Me.TabPage2.SuspendLayout() + Me.TabPage3.SuspendLayout() Me.SuspendLayout() ' 'Label1 @@ -239,7 +236,7 @@ Partial Class VehicleForm 'ButOK ' Me.ButOK.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) - Me.ButOK.Location = New System.Drawing.Point(431, 557) + Me.ButOK.Location = New System.Drawing.Point(431, 532) Me.ButOK.Name = "ButOK" Me.ButOK.Size = New System.Drawing.Size(75, 23) Me.ButOK.TabIndex = 5 @@ -250,7 +247,7 @@ Partial Class VehicleForm ' Me.ButCancel.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) Me.ButCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel - Me.ButCancel.Location = New System.Drawing.Point(512, 557) + Me.ButCancel.Location = New System.Drawing.Point(512, 532) Me.ButCancel.Name = "ButCancel" Me.ButCancel.Size = New System.Drawing.Size(75, 23) Me.ButCancel.TabIndex = 6 @@ -298,7 +295,7 @@ Partial Class VehicleForm ' Me.TbCdFile.Anchor = System.Windows.Forms.AnchorStyles.None Me.TbCdFile.Enabled = False - Me.TbCdFile.Location = New System.Drawing.Point(6, 68) + Me.TbCdFile.Location = New System.Drawing.Point(9, 65) Me.TbCdFile.Name = "TbCdFile" Me.TbCdFile.Size = New System.Drawing.Size(210, 20) Me.TbCdFile.TabIndex = 1 @@ -308,7 +305,7 @@ Partial Class VehicleForm Me.BtCdFileBrowse.Anchor = System.Windows.Forms.AnchorStyles.None Me.BtCdFileBrowse.Enabled = False Me.BtCdFileBrowse.Image = Global.TUGraz.VECTO.My.Resources.Resources.Open_icon - Me.BtCdFileBrowse.Location = New System.Drawing.Point(222, 65) + Me.BtCdFileBrowse.Location = New System.Drawing.Point(225, 62) Me.BtCdFileBrowse.Name = "BtCdFileBrowse" Me.BtCdFileBrowse.Size = New System.Drawing.Size(24, 24) Me.BtCdFileBrowse.TabIndex = 2 @@ -323,7 +320,7 @@ Partial Class VehicleForm Me.GroupBox6.Controls.Add(Me.TbCdFile) Me.GroupBox6.Location = New System.Drawing.Point(290, 70) Me.GroupBox6.Name = "GroupBox6" - Me.GroupBox6.Size = New System.Drawing.Size(281, 109) + Me.GroupBox6.Size = New System.Drawing.Size(281, 96) Me.GroupBox6.TabIndex = 5 Me.GroupBox6.TabStop = False Me.GroupBox6.Text = "Cross Wind Correction" @@ -333,7 +330,7 @@ Partial Class VehicleForm Me.BtCdFileOpen.Anchor = System.Windows.Forms.AnchorStyles.None Me.BtCdFileOpen.Enabled = False Me.BtCdFileOpen.Image = Global.TUGraz.VECTO.My.Resources.Resources.application_export_icon_small - Me.BtCdFileOpen.Location = New System.Drawing.Point(246, 65) + Me.BtCdFileOpen.Location = New System.Drawing.Point(249, 62) Me.BtCdFileOpen.Name = "BtCdFileOpen" Me.BtCdFileOpen.Size = New System.Drawing.Size(24, 24) Me.BtCdFileOpen.TabIndex = 3 @@ -343,7 +340,7 @@ Partial Class VehicleForm 'LbCdMode ' Me.LbCdMode.AutoSize = True - Me.LbCdMode.Location = New System.Drawing.Point(6, 48) + Me.LbCdMode.Location = New System.Drawing.Point(6, 47) Me.LbCdMode.Name = "LbCdMode" Me.LbCdMode.Size = New System.Drawing.Size(59, 13) Me.LbCdMode.TabIndex = 28 @@ -548,7 +545,7 @@ Partial Class VehicleForm Me.GroupBox8.Controls.Add(Me.ButAxlRem) Me.GroupBox8.Controls.Add(Me.LvRRC) Me.GroupBox8.Controls.Add(Me.ButAxlAdd) - Me.GroupBox8.Location = New System.Drawing.Point(7, 185) + Me.GroupBox8.Location = New System.Drawing.Point(6, 172) Me.GroupBox8.Name = "GroupBox8" Me.GroupBox8.Size = New System.Drawing.Size(564, 151) Me.GroupBox8.TabIndex = 2 @@ -624,6 +621,11 @@ Partial Class VehicleForm ' Me.ColumnHeader4.Text = "Inertia" ' + 'ColumnHeader10 + ' + Me.ColumnHeader10.Text = "Axle Type" + Me.ColumnHeader10.Width = 130 + ' 'ButAxlAdd ' Me.ButAxlAdd.Image = Global.TUGraz.VECTO.My.Resources.Resources.plus_circle_icon @@ -693,7 +695,7 @@ Partial Class VehicleForm 'StatusStrip1 ' Me.StatusStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.LbStatus}) - Me.StatusStrip1.Location = New System.Drawing.Point(0, 583) + Me.StatusStrip1.Location = New System.Drawing.Point(0, 558) Me.StatusStrip1.Name = "StatusStrip1" Me.StatusStrip1.Size = New System.Drawing.Size(599, 22) Me.StatusStrip1.SizingGrip = False @@ -716,33 +718,6 @@ Partial Class VehicleForm Me.TbHDVclass.TabStop = False Me.TbHDVclass.TextAlign = System.Windows.Forms.HorizontalAlignment.Center ' - 'Label11 - ' - Me.Label11.AutoSize = True - Me.Label11.Location = New System.Drawing.Point(89, 57) - Me.Label11.Name = "Label11" - Me.Label11.Size = New System.Drawing.Size(71, 13) - Me.Label11.TabIndex = 31 - Me.Label11.Text = "Max. Loading" - ' - 'TbLoadingMax - ' - Me.TbLoadingMax.Location = New System.Drawing.Point(166, 54) - Me.TbLoadingMax.Name = "TbLoadingMax" - Me.TbLoadingMax.ReadOnly = True - Me.TbLoadingMax.Size = New System.Drawing.Size(57, 20) - Me.TbLoadingMax.TabIndex = 2 - Me.TbLoadingMax.TabStop = False - ' - 'Label22 - ' - Me.Label22.AutoSize = True - Me.Label22.Location = New System.Drawing.Point(225, 57) - Me.Label22.Name = "Label22" - Me.Label22.Size = New System.Drawing.Size(25, 13) - Me.Label22.TabIndex = 24 - Me.Label22.Text = "[kg]" - ' 'GroupBox1 ' Me.GroupBox1.Controls.Add(Me.PnLoad) @@ -751,7 +726,7 @@ Partial Class VehicleForm Me.GroupBox1.Controls.Add(Me.Label14) Me.GroupBox1.Location = New System.Drawing.Point(6, 6) Me.GroupBox1.Name = "GroupBox1" - Me.GroupBox1.Size = New System.Drawing.Size(278, 120) + Me.GroupBox1.Size = New System.Drawing.Size(278, 104) Me.GroupBox1.TabIndex = 0 Me.GroupBox1.TabStop = False Me.GroupBox1.Text = "Weight / Loading" @@ -762,11 +737,8 @@ Partial Class VehicleForm Me.PnLoad.Controls.Add(Me.Label31) Me.PnLoad.Controls.Add(Me.TbLoad) Me.PnLoad.Controls.Add(Me.TbMassExtra) - Me.PnLoad.Controls.Add(Me.TbLoadingMax) Me.PnLoad.Controls.Add(Me.Label50) Me.PnLoad.Controls.Add(Me.Label46) - Me.PnLoad.Controls.Add(Me.Label22) - Me.PnLoad.Controls.Add(Me.Label11) Me.PnLoad.Location = New System.Drawing.Point(6, 43) Me.PnLoad.Name = "PnLoad" Me.PnLoad.Size = New System.Drawing.Size(256, 75) @@ -1048,7 +1020,7 @@ Partial Class VehicleForm Me.TabControl1.Location = New System.Drawing.Point(6, 173) Me.TabControl1.Name = "TabControl1" Me.TabControl1.SelectedIndex = 0 - Me.TabControl1.Size = New System.Drawing.Size(587, 376) + Me.TabControl1.Size = New System.Drawing.Size(587, 355) Me.TabControl1.TabIndex = 40 ' 'TabPage1 @@ -1062,11 +1034,57 @@ Partial Class VehicleForm Me.TabPage1.Location = New System.Drawing.Point(4, 22) Me.TabPage1.Name = "TabPage1" Me.TabPage1.Padding = New System.Windows.Forms.Padding(3) - Me.TabPage1.Size = New System.Drawing.Size(579, 350) + Me.TabPage1.Size = New System.Drawing.Size(579, 329) Me.TabPage1.TabIndex = 0 Me.TabPage1.Text = "General" Me.TabPage1.UseVisualStyleBackColor = True ' + 'GroupBox4 + ' + Me.GroupBox4.Controls.Add(Me.Panel1) + Me.GroupBox4.Location = New System.Drawing.Point(6, 116) + Me.GroupBox4.Name = "GroupBox4" + Me.GroupBox4.Size = New System.Drawing.Size(278, 50) + Me.GroupBox4.TabIndex = 2 + Me.GroupBox4.TabStop = False + Me.GroupBox4.Text = "Vehicle Idling Speed" + ' + 'Panel1 + ' + Me.Panel1.Controls.Add(Me.tbVehIdlingSpeed) + Me.Panel1.Controls.Add(Me.Label18) + Me.Panel1.Controls.Add(Me.Label19) + Me.Panel1.Dock = System.Windows.Forms.DockStyle.Fill + Me.Panel1.Location = New System.Drawing.Point(3, 16) + Me.Panel1.Name = "Panel1" + Me.Panel1.Size = New System.Drawing.Size(272, 31) + Me.Panel1.TabIndex = 0 + ' + 'tbVehIdlingSpeed + ' + Me.tbVehIdlingSpeed.Location = New System.Drawing.Point(169, 3) + Me.tbVehIdlingSpeed.Name = "tbVehIdlingSpeed" + Me.tbVehIdlingSpeed.Size = New System.Drawing.Size(57, 20) + Me.tbVehIdlingSpeed.TabIndex = 0 + ' + 'Label18 + ' + Me.Label18.AutoSize = True + Me.Label18.Location = New System.Drawing.Point(229, 6) + Me.Label18.Name = "Label18" + Me.Label18.Size = New System.Drawing.Size(30, 13) + Me.Label18.TabIndex = 24 + Me.Label18.Text = "[rpm]" + ' + 'Label19 + ' + Me.Label19.AutoSize = True + Me.Label19.Location = New System.Drawing.Point(69, 6) + Me.Label19.Name = "Label19" + Me.Label19.Size = New System.Drawing.Size(94, 13) + Me.Label19.TabIndex = 8 + Me.Label19.Text = "Engine Idle Speed" + ' 'TabPage2 ' Me.TabPage2.Controls.Add(Me.gbPTO) @@ -1147,64 +1165,13 @@ Partial Class VehicleForm Me.btAddMaxTorqueEntry.TabIndex = 4 Me.btAddMaxTorqueEntry.UseVisualStyleBackColor = True ' - 'ColumnHeader10 - ' - Me.ColumnHeader10.Text = "Axle Type" - Me.ColumnHeader10.Width = 130 - ' - 'GroupBox4 - ' - Me.GroupBox4.Controls.Add(Me.Panel1) - Me.GroupBox4.Location = New System.Drawing.Point(6, 129) - Me.GroupBox4.Name = "GroupBox4" - Me.GroupBox4.Size = New System.Drawing.Size(278, 50) - Me.GroupBox4.TabIndex = 2 - Me.GroupBox4.TabStop = False - Me.GroupBox4.Text = "Vehicle Idling Speed" - ' - 'Panel1 - ' - Me.Panel1.Controls.Add(Me.tbVehIdlingSpeed) - Me.Panel1.Controls.Add(Me.Label18) - Me.Panel1.Controls.Add(Me.Label19) - Me.Panel1.Dock = System.Windows.Forms.DockStyle.Fill - Me.Panel1.Location = New System.Drawing.Point(3, 16) - Me.Panel1.Name = "Panel1" - Me.Panel1.Size = New System.Drawing.Size(272, 31) - Me.Panel1.TabIndex = 0 - ' - 'tbVehIdlingSpeed - ' - Me.tbVehIdlingSpeed.Location = New System.Drawing.Point(169, 3) - Me.tbVehIdlingSpeed.Name = "tbVehIdlingSpeed" - Me.tbVehIdlingSpeed.Size = New System.Drawing.Size(57, 20) - Me.tbVehIdlingSpeed.TabIndex = 0 - ' - 'Label18 - ' - Me.Label18.AutoSize = True - Me.Label18.Location = New System.Drawing.Point(229, 6) - Me.Label18.Name = "Label18" - Me.Label18.Size = New System.Drawing.Size(30, 13) - Me.Label18.TabIndex = 24 - Me.Label18.Text = "[rpm]" - ' - 'Label19 - ' - Me.Label19.AutoSize = True - Me.Label19.Location = New System.Drawing.Point(69, 6) - Me.Label19.Name = "Label19" - Me.Label19.Size = New System.Drawing.Size(94, 13) - Me.Label19.TabIndex = 8 - Me.Label19.Text = "Engine Idle Speed" - ' 'VehicleForm ' Me.AcceptButton = Me.ButOK Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.CancelButton = Me.ButCancel - Me.ClientSize = New System.Drawing.Size(599, 605) + Me.ClientSize = New System.Drawing.Size(599, 580) Me.Controls.Add(Me.TabControl1) Me.Controls.Add(Me.ButCancel) Me.Controls.Add(Me.ButOK) @@ -1257,12 +1224,12 @@ Partial Class VehicleForm CType(Me.PicVehicle, System.ComponentModel.ISupportInitialize).EndInit() Me.TabControl1.ResumeLayout(False) Me.TabPage1.ResumeLayout(False) - Me.TabPage2.ResumeLayout(False) - Me.TabPage3.ResumeLayout(False) - Me.TabPage3.PerformLayout() Me.GroupBox4.ResumeLayout(False) Me.Panel1.ResumeLayout(False) Me.Panel1.PerformLayout() + Me.TabPage2.ResumeLayout(False) + Me.TabPage3.ResumeLayout(False) + Me.TabPage3.PerformLayout() Me.ResumeLayout(False) Me.PerformLayout() @@ -1316,9 +1283,6 @@ Partial Class VehicleForm Friend WithEvents LbStatus As System.Windows.Forms.ToolStripStatusLabel Friend WithEvents CbAxleConfig As System.Windows.Forms.ComboBox Friend WithEvents TbHDVclass As System.Windows.Forms.TextBox - Friend WithEvents Label11 As System.Windows.Forms.Label - Friend WithEvents TbLoadingMax As System.Windows.Forms.TextBox - Friend WithEvents Label22 As System.Windows.Forms.Label Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox Friend WithEvents GrAirRes As System.Windows.Forms.GroupBox Friend WithEvents PictureBox1 As System.Windows.Forms.PictureBox diff --git a/VECTO/GUI/VehicleForm.vb b/VECTO/GUI/VehicleForm.vb index d008a52fab..e850b7f9e2 100644 --- a/VECTO/GUI/VehicleForm.vb +++ b/VECTO/GUI/VehicleForm.vb @@ -59,7 +59,6 @@ Public Class VehicleForm 'Initialise form Private Sub VehicleFormLoad(sender As Object, e As EventArgs) Handles MyBase.Load - TbLoadingMax.Text = "-" PnLoad.Enabled = Not Cfg.DeclMode ButAxlAdd.Enabled = Not Cfg.DeclMode ButAxlRem.Enabled = Not Cfg.DeclMode @@ -631,7 +630,6 @@ Public Class VehicleForm End Function Private Sub TBmass_TextChanged(sender As Object, e As EventArgs) Handles TbMass.TextChanged - SetMaxLoad() Change() End Sub @@ -649,12 +647,10 @@ Public Class VehicleForm End Sub Private Sub TbMassTrailer_TextChanged(sender As Object, e As EventArgs) Handles TbMassExtra.TextChanged - SetMaxLoad() Change() End Sub Private Sub TbMassMax_TextChanged(sender As Object, e As EventArgs) Handles TbMassMass.TextChanged - SetMaxLoad() Change() SetHdVclass() DeclInit() @@ -669,17 +665,6 @@ Public Class VehicleForm #End Region - 'Update maximum load when truck/trailer mass was changed - Private Sub SetMaxLoad() - If Not Cfg.DeclMode Then - If IsNumeric(TbMass.Text) And IsNumeric(TbMassExtra.Text) And IsNumeric(TbMassMass.Text) Then - TbLoadingMax.Text = CStr(CSng(TbMassMass.Text) * 1000 - CSng(TbMass.Text) - CSng(TbMassExtra.Text)) - Else - TbLoadingMax.Text = "" - End If - End If - End Sub - #Region "Axle Configuration" Private Sub ButAxlAdd_Click(sender As Object, e As EventArgs) Handles ButAxlAdd.Click diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index d9368e83f6..9ffcefc470 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -29,271 +29,271 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Declaration; -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.OutputData; -using TUGraz.VectoCore.Utils; -using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; - -namespace TUGraz.VectoCore.Models.Simulation.Impl -{ - /// <summary> - /// Provides Methods to build a simulator with a powertrain step by step. - /// </summary> - public class PowertrainBuilder - { - private readonly IModalDataContainer _modData; - private readonly WriteSumData _sumWriter; - - public PowertrainBuilder(IModalDataContainer modData, WriteSumData sumWriter = null) - { - if (modData == null) { - throw new VectoException("Modal Data Container can't be null"); - } - _modData = modData; - _sumWriter = sumWriter; - } - - public VehicleContainer Build(VectoRunData data) - { - switch (data.Cycle.CycleType) { - case CycleType.EngineOnly: - return BuildEngineOnly(data); - case CycleType.PWheel: - return BuildPWheel(data); - case CycleType.MeasuredSpeed: - 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); - } - } - - private VehicleContainer BuildEngineOnly(VectoRunData data) - { - if (data.Cycle.CycleType != CycleType.EngineOnly) { - throw new VectoException("CycleType must be EngineOnly."); - } - - var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; - var cycle = new PowertrainDrivingCycle(container, data.Cycle); - - var directAux = new EngineAuxiliary(container); - directAux.AddCycle(Constants.Auxiliaries.Cycle); - container.ModalData.AddAuxiliary(Constants.Auxiliaries.Cycle); - var engine = new EngineOnlyCombustionEngine(container, data.EngineData); - engine.Connect(directAux.Port()); - - cycle.InPort().Connect(engine.OutPort()); - return container; - } - - private VehicleContainer BuildPWheel(VectoRunData data) - { - if (data.Cycle.CycleType != CycleType.PWheel) { - throw new VectoException("CycleType must be PWheel."); - } - - var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; - var gearbox = new CycleGearbox(container, data); - - // PWheelCycle --> AxleGear --> Clutch --> Engine <-- Aux - var powertrain = new PWheelCycle(container, data.Cycle, data.AxleGearData.AxleGear.Ratio, data.VehicleData, - gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio)) - .AddComponent(new AxleGear(container, data.AxleGearData)) - .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) - .AddComponent(gearbox, data.Retarder, container) - .AddComponent(new Clutch(container, data.EngineData)); - var engine = new CombustionEngine(container, data.EngineData, pt1Disabled: true); - var idleController = GetIdleController(data.PTO, engine, container); - - powertrain.AddComponent(engine, idleController) - .AddAuxiliaries(container, data); - - return container; - } - - private VehicleContainer BuildMeasuredSpeed(VectoRunData data) - { - if (data.Cycle.CycleType != CycleType.MeasuredSpeed) { - throw new VectoException("CycleType must be MeasuredSpeed."); - } - - var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; - - // MeasuredSpeedDrivingCycle --> vehicle --> wheels --> brakes - // --> axleGear --> (retarder) --> GearBox --> (retarder) --> Clutch --> engine <-- Aux - var cycle = new MeasuredSpeedDrivingCycle(container, data.Cycle); - var powertrain = cycle - .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) - .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, data.AxleGearData)) - .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) - .AddComponent(GetGearbox(container, data), data.Retarder, container); - if (data.GearboxData.Type.ManualTransmission()) { - powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); - } - - var engine = new CombustionEngine(container, data.EngineData); - var idleController = GetIdleController(data.PTO, engine, container); - - powertrain.AddComponent(engine, idleController) - .AddAuxiliaries(container, data); - _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); - - return container; - } - - private VehicleContainer BuildMeasuredSpeedGear(VectoRunData data) - { - if (data.Cycle.CycleType != CycleType.MeasuredSpeedGear) { - throw new VectoException("CycleType must be MeasuredSpeed with Gear."); - } - - var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; - - // MeasuredSpeedDrivingCycle --> vehicle --> wheels --> brakes - // --> axleGear --> (retarder) --> CycleGearBox --> (retarder) --> CycleClutch --> engine <-- Aux - var powertrain = new MeasuredSpeedDrivingCycle(container, data.Cycle) - .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) - .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, data.AxleGearData)) - .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) - .AddComponent(new CycleGearbox(container, data)); - if (data.GearboxData.Type.ManualTransmission()) { - powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); - } - powertrain.AddComponent(new CombustionEngine(container, data.EngineData)) - .AddAuxiliaries(container, data); - - _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); - - return container; - } - - private VehicleContainer 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 }; - - // DistanceBasedDrivingCycle --> driver --> vehicle --> wheels - // --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux - var cycle = new DistanceBasedDrivingCycle(container, data.Cycle); - var powertrain = cycle.AddComponent(new Driver(container, data.DriverData, new DefaultDriverStrategy())) - .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) - .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, data.AxleGearData)) - .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) - .AddComponent(GetGearbox(container, data), data.Retarder, container); - if (data.GearboxData.Type.ManualTransmission()) { - powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); - } - - var engine = new CombustionEngine(container, data.EngineData); - var idleController = GetIdleController(data.PTO, engine, container); - cycle.IdleController = idleController as IdleControllerSwitcher; - - powertrain.AddComponent(engine, idleController) - .AddAuxiliaries(container, data); - - _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); - - return container; - } - - private static IIdleController GetIdleController(PTOData pto, ICombustionEngine engine, IVehicleContainer container) - { - var controller = engine.IdleController; - - if (pto != null && pto.PTOCycle != null) { - var ptoController = new PTOCycleController(container, pto.PTOCycle); - controller = new IdleControllerSwitcher(engine.IdleController, ptoController); - } - - return controller; - } - - internal static IAuxInProvider CreateAdvancedAuxiliaries(VectoRunData data, IVehicleContainer container) - { - var conventionalAux = CreateAuxiliaries(data, container); - var busAux = new BusAuxiliariesAdapter(container, data.AdvancedAux.AdvancedAuxiliaryFilePath, data.Cycle.Name, - data.VehicleData.TotalVehicleWeight, data.EngineData.ConsumptionMap, data.EngineData.IdleSpeed, conventionalAux); - return busAux; - } - - internal static EngineAuxiliary CreateAuxiliaries(VectoRunData data, IVehicleContainer container) - { - var aux = new EngineAuxiliary(container); - foreach (var auxData in data.Aux) { - // id's in upper case - var id = auxData.ID.ToUpper(); - - switch (auxData.DemandType) { - case AuxiliaryDemandType.Constant: - aux.AddConstant(id, auxData.PowerDemand); - break; - case AuxiliaryDemandType.Direct: - aux.AddCycle(id); - break; - case AuxiliaryDemandType.Mapping: - aux.AddMapping(id, auxData.Data); - break; - default: - throw new ArgumentOutOfRangeException("AuxiliaryDemandType", auxData.DemandType.ToString()); - } - container.ModalData.AddAuxiliary(id); - } - - if (data.PTO != null) { - aux.AddConstant(Constants.Auxiliaries.IDs.PTOTransmission, - DeclarationData.PTOTransmission.Lookup(data.PTO.TransmissionType)); - container.ModalData.AddAuxiliary(Constants.Auxiliaries.IDs.PTOTransmission, - Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTOTransmission); - - aux.Add(Constants.Auxiliaries.IDs.PTOConsumer, - n => container.PTOActive ? null : data.PTO.LossMap.GetTorqueLoss(n) * n); - container.ModalData.AddAuxiliary(Constants.Auxiliaries.IDs.PTOConsumer, - Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTOConsumer); - } - - return aux; - } - - private static IGearbox GetGearbox(IVehicleContainer container, VectoRunData runData) - { - IShiftStrategy strategy; - switch (runData.GearboxData.Type) { - case GearboxType.AMT: - strategy = new AMTShiftStrategy(runData, container); - break; - case GearboxType.MT: - strategy = new MTShiftStrategy(runData, container); - break; - case GearboxType.ATPowerSplit: - case GearboxType.ATSerial: - strategy = new ATShiftStrategy(runData.GearboxData, container); - return new ATGearbox(container, strategy, runData); - default: - throw new ArgumentOutOfRangeException("Unknown Gearbox Type", runData.GearboxData.Type.ToString()); - } - return new Gearbox(container, strategy, runData); - } - } +using System; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Declaration; +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.OutputData; +using TUGraz.VectoCore.Utils; +using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + /// <summary> + /// Provides Methods to build a simulator with a powertrain step by step. + /// </summary> + public class PowertrainBuilder + { + private readonly IModalDataContainer _modData; + private readonly WriteSumData _sumWriter; + + public PowertrainBuilder(IModalDataContainer modData, WriteSumData sumWriter = null) + { + if (modData == null) { + throw new VectoException("Modal Data Container can't be null"); + } + _modData = modData; + _sumWriter = sumWriter; + } + + public VehicleContainer Build(VectoRunData data) + { + switch (data.Cycle.CycleType) { + case CycleType.EngineOnly: + return BuildEngineOnly(data); + case CycleType.PWheel: + return BuildPWheel(data); + case CycleType.MeasuredSpeed: + 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); + } + } + + private VehicleContainer BuildEngineOnly(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.EngineOnly) { + throw new VectoException("CycleType must be EngineOnly."); + } + + var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; + var cycle = new PowertrainDrivingCycle(container, data.Cycle); + + var directAux = new EngineAuxiliary(container); + directAux.AddCycle(Constants.Auxiliaries.Cycle); + container.ModalData.AddAuxiliary(Constants.Auxiliaries.Cycle); + var engine = new EngineOnlyCombustionEngine(container, data.EngineData); + engine.Connect(directAux.Port()); + + cycle.InPort().Connect(engine.OutPort()); + return container; + } + + private VehicleContainer BuildPWheel(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.PWheel) { + throw new VectoException("CycleType must be PWheel."); + } + + var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; + var gearbox = new CycleGearbox(container, data); + + // PWheelCycle --> AxleGear --> Clutch --> Engine <-- Aux + var powertrain = new PWheelCycle(container, data.Cycle, data.AxleGearData.AxleGear.Ratio, data.VehicleData, + gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio)) + .AddComponent(new AxleGear(container, data.AxleGearData)) + .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) + .AddComponent(gearbox, data.Retarder, container) + .AddComponent(new Clutch(container, data.EngineData)); + var engine = new CombustionEngine(container, data.EngineData, pt1Disabled: true); + var idleController = GetIdleController(data.PTO, engine, container); + + powertrain.AddComponent(engine, idleController) + .AddAuxiliaries(container, data); + + return container; + } + + private VehicleContainer BuildMeasuredSpeed(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.MeasuredSpeed) { + throw new VectoException("CycleType must be MeasuredSpeed."); + } + + var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; + + // MeasuredSpeedDrivingCycle --> vehicle --> wheels --> brakes + // --> axleGear --> (retarder) --> GearBox --> (retarder) --> Clutch --> engine <-- Aux + var cycle = new MeasuredSpeedDrivingCycle(container, data.Cycle); + var powertrain = cycle + .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) + .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, data.AxleGearData)) + .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) + .AddComponent(GetGearbox(container, data), data.Retarder, container); + if (data.GearboxData.Type.ManualTransmission()) { + powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); + } + + var engine = new CombustionEngine(container, data.EngineData); + var idleController = GetIdleController(data.PTO, engine, container); + + powertrain.AddComponent(engine, idleController) + .AddAuxiliaries(container, data); + _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); + + return container; + } + + private VehicleContainer BuildMeasuredSpeedGear(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.MeasuredSpeedGear) { + throw new VectoException("CycleType must be MeasuredSpeed with Gear."); + } + + var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; + + // MeasuredSpeedDrivingCycle --> vehicle --> wheels --> brakes + // --> axleGear --> (retarder) --> CycleGearBox --> (retarder) --> CycleClutch --> engine <-- Aux + var powertrain = new MeasuredSpeedDrivingCycle(container, data.Cycle) + .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) + .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, data.AxleGearData)) + .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) + .AddComponent(new CycleGearbox(container, data)); + if (data.GearboxData.Type.ManualTransmission()) { + powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); + } + powertrain.AddComponent(new CombustionEngine(container, data.EngineData)) + .AddAuxiliaries(container, data); + + _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); + + return container; + } + + private VehicleContainer 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 }; + + // DistanceBasedDrivingCycle --> driver --> vehicle --> wheels + // --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux + var cycle = new DistanceBasedDrivingCycle(container, data.Cycle); + var powertrain = cycle.AddComponent(new Driver(container, data.DriverData, new DefaultDriverStrategy())) + .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) + .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, data.AxleGearData)) + .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) + .AddComponent(GetGearbox(container, data), data.Retarder, container); + if (data.GearboxData.Type.ManualTransmission()) { + powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); + } + + var engine = new CombustionEngine(container, data.EngineData); + var idleController = GetIdleController(data.PTO, engine, container); + cycle.IdleController = idleController as IdleControllerSwitcher; + + powertrain.AddComponent(engine, idleController) + .AddAuxiliaries(container, data); + + _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); + + return container; + } + + private static IIdleController GetIdleController(PTOData pto, ICombustionEngine engine, IVehicleContainer container) + { + var controller = engine.IdleController; + + if (pto != null && pto.PTOCycle != null) { + var ptoController = new PTOCycleController(container, pto.PTOCycle); + controller = new IdleControllerSwitcher(engine.IdleController, ptoController); + } + + return controller; + } + + internal static IAuxInProvider CreateAdvancedAuxiliaries(VectoRunData data, IVehicleContainer container) + { + var conventionalAux = CreateAuxiliaries(data, container); + var busAux = new BusAuxiliariesAdapter(container, data.AdvancedAux.AdvancedAuxiliaryFilePath, data.Cycle.Name, + data.VehicleData.TotalVehicleWeight, data.EngineData.ConsumptionMap, data.EngineData.IdleSpeed, conventionalAux); + return busAux; + } + + internal static EngineAuxiliary CreateAuxiliaries(VectoRunData data, IVehicleContainer container) + { + var aux = new EngineAuxiliary(container); + foreach (var auxData in data.Aux) { + // id's in upper case + var id = auxData.ID.ToUpper(); + + switch (auxData.DemandType) { + case AuxiliaryDemandType.Constant: + aux.AddConstant(id, auxData.PowerDemand); + break; + case AuxiliaryDemandType.Direct: + aux.AddCycle(id); + break; + case AuxiliaryDemandType.Mapping: + aux.AddMapping(id, auxData.Data); + break; + default: + throw new ArgumentOutOfRangeException("AuxiliaryDemandType", auxData.DemandType.ToString()); + } + container.ModalData.AddAuxiliary(id); + } + + if (data.PTO != null) { + aux.AddConstant(Constants.Auxiliaries.IDs.PTOTransmission, + DeclarationData.PTOTransmission.Lookup(data.PTO.TransmissionType)); + container.ModalData.AddAuxiliary(Constants.Auxiliaries.IDs.PTOTransmission, + Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTOTransmission); + + aux.Add(Constants.Auxiliaries.IDs.PTOConsumer, + n => container.PTOActive ? null : data.PTO.LossMap.GetTorqueLoss(n) * n); + container.ModalData.AddAuxiliary(Constants.Auxiliaries.IDs.PTOConsumer, + Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTOConsumer); + } + + return aux; + } + + private static IGearbox GetGearbox(IVehicleContainer container, VectoRunData runData) + { + IShiftStrategy strategy; + switch (runData.GearboxData.Type) { + case GearboxType.AMT: + strategy = new AMTShiftStrategy(runData, container); + break; + case GearboxType.MT: + strategy = new MTShiftStrategy(runData, container); + break; + case GearboxType.ATPowerSplit: + case GearboxType.ATSerial: + strategy = new ATShiftStrategy(runData.GearboxData, container); + return new ATGearbox(container, strategy, runData); + default: + throw new ArgumentOutOfRangeException("Unknown Gearbox Type", runData.GearboxData.Type.ToString()); + } + return new Gearbox(container, strategy, runData); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs index 1b384fa2ae..b9feedcce9 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs @@ -29,464 +29,464 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class CycleGearbox : AbstractGearbox<CycleGearbox.CycleGearboxState> - { - /// <summary> - /// True if gearbox is disengaged (no gear is set). - /// </summary> - protected internal Second Disengaged; - - protected bool? TorqueConverterActive; - - protected internal readonly TorqueConverter TorqueConverter; - - public CycleGearbox(IVehicleContainer container, VectoRunData runData) - : base(container, runData) - { - if (!ModelData.Type.AutomaticTransmission()) { - return; - } - var strategy = new CycleShiftStrategy(ModelData, null); - TorqueConverter = new TorqueConverter(this, strategy, container, ModelData.TorqueConverterData, runData); - if (TorqueConverter == null) { - throw new VectoException("Torque Converter required for AT transmission!"); - } - } - - public override void Connect(ITnOutPort other) - { - base.Connect(other); - if (TorqueConverter != null) { - TorqueConverter.NextComponent = other; - } - } - - public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) - { - var dt = Constants.SimulationSettings.TargetTimeInterval; - - Gear = DataBus.CycleData.LeftSample.Gear; - TorqueConverterActive = DataBus.CycleData.LeftSample.TorqueConverterActive; - - if (TorqueConverter != null && TorqueConverterActive == null) { - throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!"); - } - - var inAngularVelocity = DataBus.EngineIdleSpeed; - var inTorque = 0.SI<NewtonMeter>(); - IResponse response; - - if (Gear != 0) { - inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; - var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque); - CurrentState.TorqueLossResult = inTorqueLossResult; - inTorque = outTorque / ModelData.Gears[Gear].Ratio + inTorqueLossResult.Value; - - var torqueLossInertia = outAngularVelocity.IsEqual(0) - ? 0.SI<NewtonMeter>() - : Formulas.InertiaPower(inAngularVelocity, PreviousState.InAngularVelocity, ModelData.Inertia, dt) / - inAngularVelocity; - - inTorque += torqueLossInertia; - - response = TorqueConverterActive != null && TorqueConverterActive.Value && TorqueConverter != null - ? TorqueConverter.Initialize(inTorque, inAngularVelocity) - : NextComponent.Initialize(inTorque, inAngularVelocity); - } else { - response = NextComponent.Initialize(inTorque, inAngularVelocity); - } - CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); - PreviousState.Gear = Gear; - - response.GearboxPowerRequest = inTorque * inAngularVelocity; - return response; - } - - /// <summary> - /// Requests the Gearbox to deliver torque and angularVelocity - /// </summary> - /// <returns> - /// <list type="bullet"> - /// <item><description>ResponseDryRun</description></item> - /// <item><description>ResponseOverload</description></item> - /// <item><description>ResponseGearshift</description></item> - /// </list> - /// </returns> - public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun = false) - { - Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); - var gear = GetGearFromCycle(); - - TorqueConverterActive = DataBus.DriverBehavior == DrivingBehavior.Braking - ? DataBus.CycleData.LeftSample.TorqueConverterActive - : DataBus.CycleData.RightSample.TorqueConverterActive; - - if (TorqueConverter != null && TorqueConverterActive == null) { - throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!"); - } - if (gear != 0 && !ModelData.Gears.ContainsKey(gear)) { - throw new VectoSimulationException("Requested Gear {0} from driving cycle is not available", gear); - } - - // mk 2016-11-30: added additional check for outAngularVelocity due to failing test: MeasuredSpeed_Gear_AT_PS_Run - // mq 2016-12-16: changed check to vehicle halted due to failing test: MeasuredSpeed_Gear_AT_* - var retVal = gear == 0 || DataBus.DriverBehavior == DrivingBehavior.Halted - //|| (outAngularVelocity.IsSmallerOrEqual(0, 1) && outTorque.IsSmallerOrEqual(0, 1)) - ? RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun) - : RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun); - - retVal.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2; - return retVal; - } - - private uint GetGearFromCycle() - { - return DataBus.DriverBehavior == DrivingBehavior.Braking - ? DataBus.CycleData.LeftSample.Gear - : DataBus.CycleData.RightSample.Gear; - } - - /// <summary> - /// Handles requests when a gear is engaged - /// </summary> - /// <param name="absTime"></param> - /// <param name="dt"></param> - /// <param name="outTorque"></param> - /// <param name="outAngularVelocity"></param> - /// <param name="dryRun"></param> - /// <returns></returns> - private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun) - { - Disengaged = null; - - Gear = GetGearFromCycle(); - - var torqueConverterLocked = TorqueConverterActive == null || !TorqueConverterActive.Value; - - var effectiveRatio = ModelData.Gears[Gear].Ratio; - var effectiveLossMap = ModelData.Gears[Gear].LossMap; - if (!torqueConverterLocked) { - effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio; - effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap; - } - - if (effectiveLossMap == null || double.IsNaN(effectiveRatio)) { - throw new VectoSimulationException("Ratio or loss-map for gear {0}{1} invalid. Please check input data", Gear, - torqueConverterLocked ? "L" : "C"); - } - - var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - var inTorqueLossResult = effectiveLossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque); - CurrentState.TorqueLossResult = inTorqueLossResult; - var inTorque = outTorque / effectiveRatio + inTorqueLossResult.Value; - CurrentState.TorqueLossResult = inTorqueLossResult; - - if (!torqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) { - throw new VectoSimulationException("Torque converter requested by cycle for gear without torque converter!"); - } - - var inAngularVelocity = outAngularVelocity * effectiveRatio; - - if (!inAngularVelocity.IsEqual(0)) { - // MQ 19.2.2016: check! inertia is related to output side, torque loss accounts to input side - CurrentState.InertiaTorqueLossOut = - Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / - avgOutAngularVelocity; - inTorque += CurrentState.InertiaTorqueLossOut / effectiveRatio; - } else { - CurrentState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); - } - if (Gear != PreviousState.Gear && - ConsiderShiftLosses(new GearInfo(Gear, torqueConverterLocked), outTorque)) { - CurrentState.PowershiftLosses = ComputeShiftLosses(outTorque, outAngularVelocity); - } - if (CurrentState.PowershiftLosses != null) { - var averageEngineSpeed = (DataBus.EngineSpeed + outAngularVelocity * ModelData.Gears[Gear].Ratio) / 2; - inTorque += CurrentState.PowershiftLosses / dt / averageEngineSpeed; - } - if (dryRun) { - if (TorqueConverter != null && !torqueConverterLocked) { - return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, true); - } - - var dryRunResponse = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, true); - dryRunResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; - return dryRunResponse; - } - - CurrentState.TransmissionTorqueLoss = inTorque * effectiveRatio - outTorque; - - CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - CurrentState.Gear = Gear; - // end critical section - - if (TorqueConverter != null && !torqueConverterLocked) { - CurrentState.TorqueConverterActive = true; - return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity); - } - - if (TorqueConverter != null) { - TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity, CurrentState.InTorque, - CurrentState.InAngularVelocity); - } - var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity); - response.GearboxPowerRequest = outTorque * avgOutAngularVelocity; - return response; - } - - /// <summary> - /// Handles Requests when no gear is disengaged - /// </summary> - /// <param name="absTime"></param> - /// <param name="dt"></param> - /// <param name="outTorque"></param> - /// <param name="outAngularVelocity"></param> - /// <param name="dryRun"></param> - /// <returns></returns> - private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun) - { - if (Disengaged == null) { - Disengaged = absTime; - } - - var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - if (dryRun) { - // if gearbox is disengaged the 0-line is the limit for drag and full load - return new ResponseDryRun { - Source = this, - GearboxPowerRequest = outTorque * avgOutAngularVelocity, - DeltaDragLoad = outTorque * avgOutAngularVelocity, - DeltaFullLoad = outTorque * avgOutAngularVelocity, - }; - } - - if ((outTorque * avgOutAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance) && - !outAngularVelocity.IsEqual(0)) { - return new ResponseOverload { - Source = this, - Delta = outTorque * avgOutAngularVelocity, - GearboxPowerRequest = outTorque * avgOutAngularVelocity - }; - } - - if ((outTorque * avgOutAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) { - return new ResponseUnderload { - Source = this, - Delta = outTorque * avgOutAngularVelocity, - GearboxPowerRequest = outTorque * avgOutAngularVelocity - }; - } - - IResponse disengagedResponse; - if (GearboxType.AutomaticTransmission()) { - disengagedResponse = EngineIdleRequest(absTime, dt); - } else { - disengagedResponse = NextGear.Gear > 0 - ? NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), - outAngularVelocity * ModelData.Gears[NextGear.Gear].Ratio) - : EngineIdleRequest(absTime, dt); - } - if (TorqueConverter != null) { - if (DataBus.VehicleStopped) { - TorqueConverter.Locked(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, CurrentState.InTorque, - outAngularVelocity); - } else { - TorqueConverter.Locked(CurrentState.InTorque, disengagedResponse.EngineSpeed, CurrentState.InTorque, - disengagedResponse.EngineSpeed); - } - } - disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; - CurrentState.SetState(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, 0.SI<NewtonMeter>(), outAngularVelocity); - CurrentState.Gear = Gear; - - return disengagedResponse; - } - - private IResponse EngineIdleRequest(Second absTime, Second dt) - { - var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed); - if (disengagedResponse is ResponseSuccess) { - return disengagedResponse; - } - var motoringSpeed = DataBus.EngineSpeed; - if (motoringSpeed.IsGreater(DataBus.EngineIdleSpeed)) { - var first = (ResponseDryRun)NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed, true); - try { - motoringSpeed = SearchAlgorithm.Search(motoringSpeed, first.DeltaDragLoad, - Constants.SimulationSettings.EngineIdlingSearchInterval, - getYValue: result => ((ResponseDryRun)result).DeltaDragLoad, - evaluateFunction: n => NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), n, true), - criterion: result => ((ResponseDryRun)result).DeltaDragLoad.Value()); - } catch (VectoException) { - Log.Warn("CycleGearbox could not find motoring speed for disengaged state."); - } - motoringSpeed = motoringSpeed.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineSpeed); - } - disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed); - return disengagedResponse; - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; - var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; - container[ModalResultField.Gear] = Disengaged != null ? 0 : Gear; - container[ModalResultField.P_gbx_loss] = CurrentState.TransmissionTorqueLoss * avgOutAngularSpeed; - container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed; - container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed; - container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity + - CurrentState.OutAngularVelocity) / 2.0; - container[ModalResultField.T_gbx_out] = CurrentState.OutTorque; - - if (ModelData.Type.AutomaticTransmission()) { - container[ModalResultField.TC_Locked] = !CurrentState.TorqueConverterActive; - container[ModalResultField.P_gbx_shift_loss] = CurrentState.PowershiftLosses == null - ? 0.SI<Watt>() - : CurrentState.PowershiftLosses * avgInAngularSpeed; - } - // torque converter fields are written by TorqueConverter (if present), called from Vehicle container - } - - protected override void DoCommitSimulationStep() - { - if (Gear != 0) { - if (CurrentState.TorqueLossResult != null && CurrentState.TorqueLossResult.Extrapolated) { - Log.Warn( - "Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}", - Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque); - if (DataBus.ExecutionMode == ExecutionMode.Declaration) { - throw new VectoException( - "Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}", - Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque); - } - } - } - base.DoCommitSimulationStep(); - } - - #region ICluchInfo - - public override GearInfo NextGear - { - get { - if (Disengaged == null) { - return new GearInfo(Gear, !TorqueConverterActive ?? true); - } - var future = DataBus.LookAhead(ModelData.TractionInterruption * 5); - var nextGear = 0u; - var torqueConverterLocked = false; - foreach (var entry in future) { - if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) { - // vehicle is stopped, no next gear, engine should go to idle - break; - } - if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) { - // vehicle is stopped, no next gear, engine should go to idle - break; - } - if (entry.Gear == 0) { - continue; - } - nextGear = entry.Gear; - torqueConverterLocked = !entry.TorqueConverterActive ?? false; - break; - } - return new GearInfo(nextGear, torqueConverterLocked); - } - } - - public override Second TractionInterruption - { - get { - if (Disengaged == null) { - return ModelData.TractionInterruption; - } - var future = DataBus.LookAhead(ModelData.TractionInterruption * 5); - foreach (var entry in future) { - if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) { - // vehicle is stopped, no next gear, engine should go to idle - break; - } - if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) { - // vehicle is stopped, no next gear, engine should go to idle - break; - } - if (entry.Gear == 0) { - continue; - } - return entry.Time - Disengaged; - } - return ModelData.TractionInterruption; - } - } - - public override bool ClutchClosed(Second absTime) - { - return (DataBus.DriverBehavior == DrivingBehavior.Braking - ? DataBus.CycleData.LeftSample.Gear - : DataBus.CycleData.RightSample.Gear) != 0; - } - - #endregion - - public class CycleGearboxState : GearboxState - { - public bool TorqueConverterActive; - public WattSecond PowershiftLosses { get; set; } - } - - public class CycleShiftStrategy : BaseShiftStrategy - { - public CycleShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {} - - public override IGearbox Gearbox { get; set; } - - public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, - PerSecond inAngularVelocity, uint gear, Second lastShiftTime) - { - return false; - } - - public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) - { - throw new System.NotImplementedException(); - } - - public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - throw new System.NotImplementedException(); - } - - public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) - { - throw new System.NotImplementedException(); - } - - public override GearInfo NextGear - { - get { throw new System.NotImplementedException(); } - } - } - } +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class CycleGearbox : AbstractGearbox<CycleGearbox.CycleGearboxState> + { + /// <summary> + /// True if gearbox is disengaged (no gear is set). + /// </summary> + protected internal Second Disengaged; + + protected bool? TorqueConverterActive; + + protected internal readonly TorqueConverter TorqueConverter; + + public CycleGearbox(IVehicleContainer container, VectoRunData runData) + : base(container, runData) + { + if (!ModelData.Type.AutomaticTransmission()) { + return; + } + var strategy = new CycleShiftStrategy(ModelData, null); + TorqueConverter = new TorqueConverter(this, strategy, container, ModelData.TorqueConverterData, runData); + if (TorqueConverter == null) { + throw new VectoException("Torque Converter required for AT transmission!"); + } + } + + public override void Connect(ITnOutPort other) + { + base.Connect(other); + if (TorqueConverter != null) { + TorqueConverter.NextComponent = other; + } + } + + public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + var dt = Constants.SimulationSettings.TargetTimeInterval; + + Gear = DataBus.CycleData.LeftSample.Gear; + TorqueConverterActive = DataBus.CycleData.LeftSample.TorqueConverterActive; + + if (TorqueConverter != null && TorqueConverterActive == null) { + throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!"); + } + + var inAngularVelocity = DataBus.EngineIdleSpeed; + var inTorque = 0.SI<NewtonMeter>(); + IResponse response; + + if (Gear != 0) { + inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; + var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque); + CurrentState.TorqueLossResult = inTorqueLossResult; + inTorque = outTorque / ModelData.Gears[Gear].Ratio + inTorqueLossResult.Value; + + var torqueLossInertia = outAngularVelocity.IsEqual(0) + ? 0.SI<NewtonMeter>() + : Formulas.InertiaPower(inAngularVelocity, PreviousState.InAngularVelocity, ModelData.Inertia, dt) / + inAngularVelocity; + + inTorque += torqueLossInertia; + + response = TorqueConverterActive != null && TorqueConverterActive.Value && TorqueConverter != null + ? TorqueConverter.Initialize(inTorque, inAngularVelocity) + : NextComponent.Initialize(inTorque, inAngularVelocity); + } else { + response = NextComponent.Initialize(inTorque, inAngularVelocity); + } + CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); + PreviousState.Gear = Gear; + + response.GearboxPowerRequest = inTorque * inAngularVelocity; + return response; + } + + /// <summary> + /// Requests the Gearbox to deliver torque and angularVelocity + /// </summary> + /// <returns> + /// <list type="bullet"> + /// <item><description>ResponseDryRun</description></item> + /// <item><description>ResponseOverload</description></item> + /// <item><description>ResponseGearshift</description></item> + /// </list> + /// </returns> + public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun = false) + { + Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); + var gear = GetGearFromCycle(); + + TorqueConverterActive = DataBus.DriverBehavior == DrivingBehavior.Braking + ? DataBus.CycleData.LeftSample.TorqueConverterActive + : DataBus.CycleData.RightSample.TorqueConverterActive; + + if (TorqueConverter != null && TorqueConverterActive == null) { + throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!"); + } + if (gear != 0 && !ModelData.Gears.ContainsKey(gear)) { + throw new VectoSimulationException("Requested Gear {0} from driving cycle is not available", gear); + } + + // mk 2016-11-30: added additional check for outAngularVelocity due to failing test: MeasuredSpeed_Gear_AT_PS_Run + // mq 2016-12-16: changed check to vehicle halted due to failing test: MeasuredSpeed_Gear_AT_* + var retVal = gear == 0 || DataBus.DriverBehavior == DrivingBehavior.Halted + //|| (outAngularVelocity.IsSmallerOrEqual(0, 1) && outTorque.IsSmallerOrEqual(0, 1)) + ? RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun) + : RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun); + + retVal.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2; + return retVal; + } + + private uint GetGearFromCycle() + { + return DataBus.DriverBehavior == DrivingBehavior.Braking + ? DataBus.CycleData.LeftSample.Gear + : DataBus.CycleData.RightSample.Gear; + } + + /// <summary> + /// Handles requests when a gear is engaged + /// </summary> + /// <param name="absTime"></param> + /// <param name="dt"></param> + /// <param name="outTorque"></param> + /// <param name="outAngularVelocity"></param> + /// <param name="dryRun"></param> + /// <returns></returns> + private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun) + { + Disengaged = null; + + Gear = GetGearFromCycle(); + + var torqueConverterLocked = TorqueConverterActive == null || !TorqueConverterActive.Value; + + var effectiveRatio = ModelData.Gears[Gear].Ratio; + var effectiveLossMap = ModelData.Gears[Gear].LossMap; + if (!torqueConverterLocked) { + effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio; + effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap; + } + + if (effectiveLossMap == null || double.IsNaN(effectiveRatio)) { + throw new VectoSimulationException("Ratio or loss-map for gear {0}{1} invalid. Please check input data", Gear, + torqueConverterLocked ? "L" : "C"); + } + + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + var inTorqueLossResult = effectiveLossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque); + CurrentState.TorqueLossResult = inTorqueLossResult; + var inTorque = outTorque / effectiveRatio + inTorqueLossResult.Value; + CurrentState.TorqueLossResult = inTorqueLossResult; + + if (!torqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) { + throw new VectoSimulationException("Torque converter requested by cycle for gear without torque converter!"); + } + + var inAngularVelocity = outAngularVelocity * effectiveRatio; + + if (!inAngularVelocity.IsEqual(0)) { + // MQ 19.2.2016: check! inertia is related to output side, torque loss accounts to input side + CurrentState.InertiaTorqueLossOut = + Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / + avgOutAngularVelocity; + inTorque += CurrentState.InertiaTorqueLossOut / effectiveRatio; + } else { + CurrentState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); + } + if (Gear != PreviousState.Gear && + ConsiderShiftLosses(new GearInfo(Gear, torqueConverterLocked), outTorque)) { + CurrentState.PowershiftLosses = ComputeShiftLosses(outTorque, outAngularVelocity); + } + if (CurrentState.PowershiftLosses != null) { + var averageEngineSpeed = (DataBus.EngineSpeed + outAngularVelocity * ModelData.Gears[Gear].Ratio) / 2; + inTorque += CurrentState.PowershiftLosses / dt / averageEngineSpeed; + } + if (dryRun) { + if (TorqueConverter != null && !torqueConverterLocked) { + return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, true); + } + + var dryRunResponse = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, true); + dryRunResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; + return dryRunResponse; + } + + CurrentState.TransmissionTorqueLoss = inTorque * effectiveRatio - outTorque; + + CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + CurrentState.Gear = Gear; + // end critical section + + if (TorqueConverter != null && !torqueConverterLocked) { + CurrentState.TorqueConverterActive = true; + return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity); + } + + if (TorqueConverter != null) { + TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity, CurrentState.InTorque, + CurrentState.InAngularVelocity); + } + var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity); + response.GearboxPowerRequest = outTorque * avgOutAngularVelocity; + return response; + } + + /// <summary> + /// Handles Requests when no gear is disengaged + /// </summary> + /// <param name="absTime"></param> + /// <param name="dt"></param> + /// <param name="outTorque"></param> + /// <param name="outAngularVelocity"></param> + /// <param name="dryRun"></param> + /// <returns></returns> + private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun) + { + if (Disengaged == null) { + Disengaged = absTime; + } + + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + if (dryRun) { + // if gearbox is disengaged the 0-line is the limit for drag and full load + return new ResponseDryRun { + Source = this, + GearboxPowerRequest = outTorque * avgOutAngularVelocity, + DeltaDragLoad = outTorque * avgOutAngularVelocity, + DeltaFullLoad = outTorque * avgOutAngularVelocity, + }; + } + + if ((outTorque * avgOutAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance) && + !outAngularVelocity.IsEqual(0)) { + return new ResponseOverload { + Source = this, + Delta = outTorque * avgOutAngularVelocity, + GearboxPowerRequest = outTorque * avgOutAngularVelocity + }; + } + + if ((outTorque * avgOutAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) { + return new ResponseUnderload { + Source = this, + Delta = outTorque * avgOutAngularVelocity, + GearboxPowerRequest = outTorque * avgOutAngularVelocity + }; + } + + IResponse disengagedResponse; + if (GearboxType.AutomaticTransmission()) { + disengagedResponse = EngineIdleRequest(absTime, dt); + } else { + disengagedResponse = NextGear.Gear > 0 + ? NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), + outAngularVelocity * ModelData.Gears[NextGear.Gear].Ratio) + : EngineIdleRequest(absTime, dt); + } + if (TorqueConverter != null) { + if (DataBus.VehicleStopped) { + TorqueConverter.Locked(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, CurrentState.InTorque, + outAngularVelocity); + } else { + TorqueConverter.Locked(CurrentState.InTorque, disengagedResponse.EngineSpeed, CurrentState.InTorque, + disengagedResponse.EngineSpeed); + } + } + disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; + CurrentState.SetState(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, 0.SI<NewtonMeter>(), outAngularVelocity); + CurrentState.Gear = Gear; + + return disengagedResponse; + } + + private IResponse EngineIdleRequest(Second absTime, Second dt) + { + var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed); + if (disengagedResponse is ResponseSuccess) { + return disengagedResponse; + } + var motoringSpeed = DataBus.EngineSpeed; + if (motoringSpeed.IsGreater(DataBus.EngineIdleSpeed)) { + var first = (ResponseDryRun)NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed, true); + try { + motoringSpeed = SearchAlgorithm.Search(motoringSpeed, first.DeltaDragLoad, + Constants.SimulationSettings.EngineIdlingSearchInterval, + getYValue: result => ((ResponseDryRun)result).DeltaDragLoad, + evaluateFunction: n => NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), n, true), + criterion: result => ((ResponseDryRun)result).DeltaDragLoad.Value()); + } catch (VectoException) { + Log.Warn("CycleGearbox could not find motoring speed for disengaged state."); + } + motoringSpeed = motoringSpeed.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineSpeed); + } + disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed); + return disengagedResponse; + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; + var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; + container[ModalResultField.Gear] = Disengaged != null ? 0 : Gear; + container[ModalResultField.P_gbx_loss] = CurrentState.TransmissionTorqueLoss * avgOutAngularSpeed; + container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed; + container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed; + container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity + + CurrentState.OutAngularVelocity) / 2.0; + container[ModalResultField.T_gbx_out] = CurrentState.OutTorque; + + if (ModelData.Type.AutomaticTransmission()) { + container[ModalResultField.TC_Locked] = !CurrentState.TorqueConverterActive; + container[ModalResultField.P_gbx_shift_loss] = CurrentState.PowershiftLosses == null + ? 0.SI<Watt>() + : CurrentState.PowershiftLosses * avgInAngularSpeed; + } + // torque converter fields are written by TorqueConverter (if present), called from Vehicle container + } + + protected override void DoCommitSimulationStep() + { + if (Gear != 0) { + if (CurrentState.TorqueLossResult != null && CurrentState.TorqueLossResult.Extrapolated) { + Log.Warn( + "Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}", + Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque); + if (DataBus.ExecutionMode == ExecutionMode.Declaration) { + throw new VectoException( + "Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}", + Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque); + } + } + } + base.DoCommitSimulationStep(); + } + + #region ICluchInfo + + public override GearInfo NextGear + { + get { + if (Disengaged == null) { + return new GearInfo(Gear, !TorqueConverterActive ?? true); + } + var future = DataBus.LookAhead(ModelData.TractionInterruption * 5); + var nextGear = 0u; + var torqueConverterLocked = false; + foreach (var entry in future) { + if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) { + // vehicle is stopped, no next gear, engine should go to idle + break; + } + if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) { + // vehicle is stopped, no next gear, engine should go to idle + break; + } + if (entry.Gear == 0) { + continue; + } + nextGear = entry.Gear; + torqueConverterLocked = !entry.TorqueConverterActive ?? false; + break; + } + return new GearInfo(nextGear, torqueConverterLocked); + } + } + + public override Second TractionInterruption + { + get { + if (Disengaged == null) { + return ModelData.TractionInterruption; + } + var future = DataBus.LookAhead(ModelData.TractionInterruption * 5); + foreach (var entry in future) { + if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) { + // vehicle is stopped, no next gear, engine should go to idle + break; + } + if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) { + // vehicle is stopped, no next gear, engine should go to idle + break; + } + if (entry.Gear == 0) { + continue; + } + return entry.Time - Disengaged; + } + return ModelData.TractionInterruption; + } + } + + public override bool ClutchClosed(Second absTime) + { + return (DataBus.DriverBehavior == DrivingBehavior.Braking + ? DataBus.CycleData.LeftSample.Gear + : DataBus.CycleData.RightSample.Gear) != 0; + } + + #endregion + + public class CycleGearboxState : GearboxState + { + public bool TorqueConverterActive; + public WattSecond PowershiftLosses { get; set; } + } + + public class CycleShiftStrategy : BaseShiftStrategy + { + public CycleShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {} + + public override IGearbox Gearbox { get; set; } + + public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear, Second lastShiftTime) + { + return false; + } + + public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) + { + throw new System.NotImplementedException(); + } + + public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + throw new System.NotImplementedException(); + } + + public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) + { + throw new System.NotImplementedException(); + } + + public override GearInfo NextGear + { + get { throw new System.NotImplementedException(); } + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs index de4431d73f..098c05e6f8 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs @@ -29,138 +29,138 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - /// <summary> - /// Driving Cycle for the PWheel driving cycle. - /// </summary> - public class PWheelCycle : PowertrainDrivingCycle, IDriverInfo, IVehicleInfo - { - private readonly VehicleData _vehicleData; - - /// <summary> - /// Initializes a new instance of the <see cref="PWheelCycle"/> class. - /// </summary> - /// <param name="container">The container.</param> - /// <param name="cycle">The cycle.</param> - /// <param name="axleRatio">The axle ratio.</param> - /// <param name="vehicleData"></param> - /// <param name="gearRatios"></param> - public PWheelCycle(IVehicleContainer container, IDrivingCycleData cycle, double axleRatio, VehicleData vehicleData, - IDictionary<uint, double> gearRatios) : base(container, cycle) - { - // just to ensure that null-gear has ratio 1 - gearRatios[0] = 1; - _vehicleData = vehicleData; - foreach (var entry in Data.Entries) { - entry.WheelAngularVelocity = entry.AngularVelocity / (axleRatio * gearRatios[entry.Gear]); - entry.Torque = entry.PWheel / entry.WheelAngularVelocity; - } - } - - public override IResponse Initialize() - { - var first = Data.Entries[0]; - AbsTime = first.Time; - var response = NextComponent.Initialize(first.Torque, first.WheelAngularVelocity); - response.AbsTime = AbsTime; - return response; - } - - public override IResponse Request(Second absTime, Second dt) - { - if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) { - return new ResponseCycleFinished { Source = this }; - } - - // interval exceeded - if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) { - return new ResponseFailTimeInterval { - AbsTime = absTime, - Source = this, - DeltaT = CycleIterator.RightSample.Time - absTime - }; - } - - return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.WheelAngularVelocity); - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - container[ModalResultField.P_wheel_in] = CycleIterator.LeftSample.PWheel; - base.DoWriteModalResults(container); - } - - #region IDriverInfo - - public MeterPerSecond VehicleSpeed { get; private set; } - - /// <summary> - /// True if the angularVelocity at the wheels is 0. - /// </summary> - public bool VehicleStopped - { - get { return CycleIterator.LeftSample.WheelAngularVelocity.IsEqual(0); } - } - - public Kilogram VehicleMass - { - get { return _vehicleData.TotalCurbWeight; } - } - - public Kilogram VehicleLoading - { - get { return _vehicleData.Loading; } - } - - public Kilogram TotalMass - { - get { return _vehicleData.TotalVehicleWeight; } - } - - public CubicMeter CargoVolume - { - get { return _vehicleData.CargoVolume; } - } - - public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) - { - throw new System.NotImplementedException(); - } - - public Newton RollingResistance(Radian gradient) - { - throw new System.NotImplementedException(); - } - - public Newton SlopeResistance(Radian gradient) - { - throw new System.NotImplementedException(); - } - - /// <summary> - /// Always Driving. - /// </summary> - public DrivingBehavior DriverBehavior - { - get { return DrivingBehavior.Driving; } - } - - public MeterPerSquareSecond DriverAcceleration - { - get { return 0.SI<MeterPerSquareSecond>(); } - } - - #endregion - } +using System.Collections.Generic; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + /// <summary> + /// Driving Cycle for the PWheel driving cycle. + /// </summary> + public class PWheelCycle : PowertrainDrivingCycle, IDriverInfo, IVehicleInfo + { + private readonly VehicleData _vehicleData; + + /// <summary> + /// Initializes a new instance of the <see cref="PWheelCycle"/> class. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="cycle">The cycle.</param> + /// <param name="axleRatio">The axle ratio.</param> + /// <param name="vehicleData"></param> + /// <param name="gearRatios"></param> + public PWheelCycle(IVehicleContainer container, IDrivingCycleData cycle, double axleRatio, VehicleData vehicleData, + IDictionary<uint, double> gearRatios) : base(container, cycle) + { + // just to ensure that null-gear has ratio 1 + gearRatios[0] = 1; + _vehicleData = vehicleData; + foreach (var entry in Data.Entries) { + entry.WheelAngularVelocity = entry.AngularVelocity / (axleRatio * gearRatios[entry.Gear]); + entry.Torque = entry.PWheel / entry.WheelAngularVelocity; + } + } + + public override IResponse Initialize() + { + var first = Data.Entries[0]; + AbsTime = first.Time; + var response = NextComponent.Initialize(first.Torque, first.WheelAngularVelocity); + response.AbsTime = AbsTime; + return response; + } + + public override IResponse Request(Second absTime, Second dt) + { + if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) { + return new ResponseCycleFinished { Source = this }; + } + + // interval exceeded + if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) { + return new ResponseFailTimeInterval { + AbsTime = absTime, + Source = this, + DeltaT = CycleIterator.RightSample.Time - absTime + }; + } + + return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.WheelAngularVelocity); + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + container[ModalResultField.P_wheel_in] = CycleIterator.LeftSample.PWheel; + base.DoWriteModalResults(container); + } + + #region IDriverInfo + + public MeterPerSecond VehicleSpeed { get; private set; } + + /// <summary> + /// True if the angularVelocity at the wheels is 0. + /// </summary> + public bool VehicleStopped + { + get { return CycleIterator.LeftSample.WheelAngularVelocity.IsEqual(0); } + } + + public Kilogram VehicleMass + { + get { return _vehicleData.TotalCurbWeight; } + } + + public Kilogram VehicleLoading + { + get { return _vehicleData.Loading; } + } + + public Kilogram TotalMass + { + get { return _vehicleData.TotalVehicleWeight; } + } + + public CubicMeter CargoVolume + { + get { return _vehicleData.CargoVolume; } + } + + public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) + { + throw new System.NotImplementedException(); + } + + public Newton RollingResistance(Radian gradient) + { + throw new System.NotImplementedException(); + } + + public Newton SlopeResistance(Radian gradient) + { + throw new System.NotImplementedException(); + } + + /// <summary> + /// Always Driving. + /// </summary> + public DrivingBehavior DriverBehavior + { + get { return DrivingBehavior.Driving; } + } + + public MeterPerSquareSecond DriverAcceleration + { + get { return 0.SI<MeterPerSquareSecond>(); } + } + + #endregion + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs index 67e0e91255..17fd58fa90 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs @@ -29,204 +29,204 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -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; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - /// <summary> - /// Represents a driving cycle which directly is connected to the powertrain (e.g. engine, or axle gear). - /// </summary> - public class PowertrainDrivingCycle : - StatefulProviderComponent<SimpleComponentState, ISimulationOutPort, ITnInPort, ITnOutPort>, - IDrivingCycleInfo, ISimulationOutPort, ITnInProvider, ITnInPort - { - protected readonly IDrivingCycleData Data; - protected internal readonly DrivingCycleEnumerator CycleIterator; - - protected Second AbsTime { get; set; } - - /// <summary> - /// Initializes a new instance of the <see cref="PowertrainDrivingCycle"/> class. - /// </summary> - /// <param name="container">The container.</param> - /// <param name="cycle">The cycle.</param> - public PowertrainDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) : base(container) - { - Data = cycle; - CycleIterator = new DrivingCycleEnumerator(Data); - - AbsTime = 0.SI<Second>(); - } - - public virtual IResponse Initialize() - { - var first = Data.Entries[0]; - AbsTime = first.Time; - var response = NextComponent.Initialize(first.Torque, first.AngularVelocity); - response.AbsTime = AbsTime; - return response; - } - - #region ISimulationOutPort - - public IResponse Request(Second absTime, Meter ds) - { - throw new VectoSimulationException("Powertrain Only Simulation can not handle distance request."); - } - - public virtual IResponse Request(Second absTime, Second dt) - { - // cycle finished (no more entries in cycle) - if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) { - return new ResponseCycleFinished { Source = this }; - } - - // interval exceeded - if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) { - return new ResponseFailTimeInterval { - AbsTime = absTime, - Source = this, - DeltaT = CycleIterator.RightSample.Time - absTime - }; - } - - return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.AngularVelocity); - } - - protected IResponse DoHandleRequest(Second absTime, Second dt, PerSecond angularVelocity) - { - var debug = new DebugData(); - - IResponse response; - var responseCount = 0; - do { - response = NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, angularVelocity); - CurrentState.InAngularVelocity = angularVelocity; - CurrentState.InTorque = CycleIterator.LeftSample.Torque; - debug.Add(response); - response.Switch() - .Case<ResponseGearShift>( - () => response = NextComponent.Request(absTime, dt, CurrentState.InTorque, angularVelocity)) - .Case<ResponseUnderload>(r => { - var torqueInterval = -r.Delta / (angularVelocity.IsEqual(0) ? 10.RPMtoRad() : angularVelocity); - var torque = SearchAlgorithm.Search(CycleIterator.LeftSample.Torque, r.Delta, torqueInterval, - getYValue: result => ((ResponseDryRun)result).DeltaDragLoad, - evaluateFunction: t => NextComponent.Request(absTime, dt, t, angularVelocity, true), - criterion: y => ((ResponseDryRun)y).DeltaDragLoad.Value()); - response = NextComponent.Request(absTime, dt, torque, angularVelocity); - CurrentState.InTorque = torque; - }) - .Case<ResponseOverload>(r => { - var torque = SearchAlgorithm.Search(CycleIterator.LeftSample.Torque, r.Delta, 50.SI<NewtonMeter>(), - getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, - evaluateFunction: t => NextComponent.Request(absTime, dt, t, angularVelocity, true), - criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value()); - response = NextComponent.Request(absTime, dt, torque, angularVelocity); - CurrentState.InAngularVelocity = angularVelocity; - }) - .Case<ResponseEngineSpeedTooHigh>(r => { - angularVelocity = SearchAlgorithm.Search(angularVelocity, r.DeltaEngineSpeed, - 1.RPMtoRad(), - getYValue: result => ((ResponseDryRun)result).DeltaEngineSpeed, - evaluateFunction: x => NextComponent.Request(absTime, dt, CurrentState.InTorque, x, true), - criterion: y => ((ResponseDryRun)y).DeltaEngineSpeed.Value()); - }) - .Case<ResponseFailTimeInterval>(r => { dt = r.DeltaT; }) - .Case<ResponseSuccess>(() => { }) - .Default( - r => { throw new UnexpectedResponseException("PowertrainDrivingCycle received an unexpected response.", r); }); - } while (!(response is ResponseSuccess || response is ResponseFailTimeInterval) && (++responseCount < 10)); - - AbsTime = absTime + dt; - response.SimulationInterval = dt; - debug.Add(response); - return response; - } - - public double Progress - { - get { return AbsTime.Value() / Data.Entries.Last().Time.Value(); } - } - - #endregion - - #region VectoSimulationComponent - - protected override void DoWriteModalResults(IModalDataContainer container) {} - - protected override void DoCommitSimulationStep() - { - CycleIterator.MoveNext(); - AdvanceState(); - } - - #endregion - - public CycleData CycleData - { - get { - return new CycleData { - AbsTime = CycleIterator.LeftSample.Time, - AbsDistance = null, - LeftSample = CycleIterator.LeftSample, - RightSample = CycleIterator.RightSample, - }; - } - } - - public bool PTOActive - { - get { return true; } - } - - public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) - { - return new DrivingCycleData.DrivingCycleEntry() { - Altitude = 0.SI<Meter>() - }; - } - - public Meter Altitude - { - get { return 0.SI<Meter>(); } - } - - public Meter CycleStartDistance - { - get { return 0.SI<Meter>(); } - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) - { - throw new NotImplementedException(); - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) - { - var retVal = new List<DrivingCycleData.DrivingCycleEntry>(); - - var iterator = CycleIterator.Clone(); - do { - retVal.Add(iterator.RightSample); - } while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time); - - return retVal; - } - - public void FinishSimulation() - { - Data.Finish(); - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +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; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + /// <summary> + /// Represents a driving cycle which directly is connected to the powertrain (e.g. engine, or axle gear). + /// </summary> + public class PowertrainDrivingCycle : + StatefulProviderComponent<SimpleComponentState, ISimulationOutPort, ITnInPort, ITnOutPort>, + IDrivingCycleInfo, ISimulationOutPort, ITnInProvider, ITnInPort + { + protected readonly IDrivingCycleData Data; + protected internal readonly DrivingCycleEnumerator CycleIterator; + + protected Second AbsTime { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="PowertrainDrivingCycle"/> class. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="cycle">The cycle.</param> + public PowertrainDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) : base(container) + { + Data = cycle; + CycleIterator = new DrivingCycleEnumerator(Data); + + AbsTime = 0.SI<Second>(); + } + + public virtual IResponse Initialize() + { + var first = Data.Entries[0]; + AbsTime = first.Time; + var response = NextComponent.Initialize(first.Torque, first.AngularVelocity); + response.AbsTime = AbsTime; + return response; + } + + #region ISimulationOutPort + + public IResponse Request(Second absTime, Meter ds) + { + throw new VectoSimulationException("Powertrain Only Simulation can not handle distance request."); + } + + public virtual IResponse Request(Second absTime, Second dt) + { + // cycle finished (no more entries in cycle) + if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) { + return new ResponseCycleFinished { Source = this }; + } + + // interval exceeded + if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) { + return new ResponseFailTimeInterval { + AbsTime = absTime, + Source = this, + DeltaT = CycleIterator.RightSample.Time - absTime + }; + } + + return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.AngularVelocity); + } + + protected IResponse DoHandleRequest(Second absTime, Second dt, PerSecond angularVelocity) + { + var debug = new DebugData(); + + IResponse response; + var responseCount = 0; + do { + response = NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, angularVelocity); + CurrentState.InAngularVelocity = angularVelocity; + CurrentState.InTorque = CycleIterator.LeftSample.Torque; + debug.Add(response); + response.Switch() + .Case<ResponseGearShift>( + () => response = NextComponent.Request(absTime, dt, CurrentState.InTorque, angularVelocity)) + .Case<ResponseUnderload>(r => { + var torqueInterval = -r.Delta / (angularVelocity.IsEqual(0) ? 10.RPMtoRad() : angularVelocity); + var torque = SearchAlgorithm.Search(CycleIterator.LeftSample.Torque, r.Delta, torqueInterval, + getYValue: result => ((ResponseDryRun)result).DeltaDragLoad, + evaluateFunction: t => NextComponent.Request(absTime, dt, t, angularVelocity, true), + criterion: y => ((ResponseDryRun)y).DeltaDragLoad.Value()); + response = NextComponent.Request(absTime, dt, torque, angularVelocity); + CurrentState.InTorque = torque; + }) + .Case<ResponseOverload>(r => { + var torque = SearchAlgorithm.Search(CycleIterator.LeftSample.Torque, r.Delta, 50.SI<NewtonMeter>(), + getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, + evaluateFunction: t => NextComponent.Request(absTime, dt, t, angularVelocity, true), + criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value()); + response = NextComponent.Request(absTime, dt, torque, angularVelocity); + CurrentState.InAngularVelocity = angularVelocity; + }) + .Case<ResponseEngineSpeedTooHigh>(r => { + angularVelocity = SearchAlgorithm.Search(angularVelocity, r.DeltaEngineSpeed, + 1.RPMtoRad(), + getYValue: result => ((ResponseDryRun)result).DeltaEngineSpeed, + evaluateFunction: x => NextComponent.Request(absTime, dt, CurrentState.InTorque, x, true), + criterion: y => ((ResponseDryRun)y).DeltaEngineSpeed.Value()); + }) + .Case<ResponseFailTimeInterval>(r => { dt = r.DeltaT; }) + .Case<ResponseSuccess>(() => { }) + .Default( + r => { throw new UnexpectedResponseException("PowertrainDrivingCycle received an unexpected response.", r); }); + } while (!(response is ResponseSuccess || response is ResponseFailTimeInterval) && (++responseCount < 10)); + + AbsTime = absTime + dt; + response.SimulationInterval = dt; + debug.Add(response); + return response; + } + + public double Progress + { + get { return AbsTime.Value() / Data.Entries.Last().Time.Value(); } + } + + #endregion + + #region VectoSimulationComponent + + protected override void DoWriteModalResults(IModalDataContainer container) {} + + protected override void DoCommitSimulationStep() + { + CycleIterator.MoveNext(); + AdvanceState(); + } + + #endregion + + public CycleData CycleData + { + get { + return new CycleData { + AbsTime = CycleIterator.LeftSample.Time, + AbsDistance = null, + LeftSample = CycleIterator.LeftSample, + RightSample = CycleIterator.RightSample, + }; + } + } + + public bool PTOActive + { + get { return true; } + } + + public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) + { + return new DrivingCycleData.DrivingCycleEntry() { + Altitude = 0.SI<Meter>() + }; + } + + public Meter Altitude + { + get { return 0.SI<Meter>(); } + } + + public Meter CycleStartDistance + { + get { return 0.SI<Meter>(); } + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) + { + throw new NotImplementedException(); + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) + { + var retVal = new List<DrivingCycleData.DrivingCycleEntry>(); + + var iterator = CycleIterator.Clone(); + do { + retVal.Add(iterator.RightSample); + } while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time); + + return retVal; + } + + public void FinishSimulation() + { + Data.Finish(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs index 5a749e071f..57cdd58380 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs @@ -29,228 +29,228 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class Vehicle : StatefulProviderComponent<Vehicle.VehicleState, IDriverDemandOutPort, IFvInPort, IFvOutPort>, - IVehicle, IMileageCounter, IFvInPort, - IDriverDemandOutPort - { - internal readonly VehicleData ModelData; - - public readonly AirdragData AirdragData; - - - public Vehicle(IVehicleContainer container, VehicleData modelData, AirdragData airdrag) : base(container) - { - ModelData = modelData; - AirdragData = airdrag; - if (AirdragData.CrossWindCorrectionCurve != null) { - AirdragData.CrossWindCorrectionCurve.SetDataBus(container); - } - } - - - public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient) - { - PreviousState = new VehicleState { - Distance = DataBus.CycleStartDistance, - Velocity = vehicleSpeed, - RollingResistance = RollingResistance(roadGradient), - SlopeResistance = SlopeResistance(roadGradient), - AirDragResistance = AirDragResistance(vehicleSpeed, vehicleSpeed), - }; - PreviousState.VehicleTractionForce = PreviousState.RollingResistance - + PreviousState.AirDragResistance - + PreviousState.SlopeResistance; - - return NextComponent.Initialize(PreviousState.VehicleTractionForce, vehicleSpeed); - } - - public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient, MeterPerSquareSecond startAcceleration) - { - //CurrentState.Velocity = vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval; - var vehicleAccelerationForce = DriverAcceleration(startAcceleration) - + RollingResistance(roadGradient) - + - AirDragResistance(vehicleSpeed, - vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval) - + SlopeResistance(roadGradient); - - var retVal = NextComponent.Initialize(vehicleAccelerationForce, vehicleSpeed); - return retVal; - } - - public IResponse Request(Second absTime, Second dt, MeterPerSquareSecond acceleration, Radian gradient, - bool dryRun = false) - { - Log.Debug("Vehicle: acceleration: {0}", acceleration); - CurrentState.SimulationInterval = dt; - CurrentState.Acceleration = acceleration; - CurrentState.Velocity = PreviousState.Velocity + acceleration * dt; - if (CurrentState.Velocity.IsEqual(0.SI<MeterPerSecond>(), - Constants.SimulationSettings.VehicleSpeedHaltTolerance)) { - CurrentState.Velocity = 0.SI<MeterPerSecond>(); - } - CurrentState.Distance = PreviousState.Distance + PreviousState.Velocity * dt + acceleration * dt * dt / 2; - - CurrentState.DriverAcceleration = DriverAcceleration(acceleration); - CurrentState.RollingResistance = RollingResistance(gradient); - try { - CurrentState.AirDragResistance = AirDragResistance(PreviousState.Velocity, CurrentState.Velocity); - } catch (VectoException ex) { - Log.Warn("Exception during calculation of AirDragResistance: absTime: {0}, dist: {1}, v: {2}. {3}", absTime, - CurrentState.Distance, CurrentState.Velocity, ex); - CurrentState.AirDragResistance = AirDragResistance(VectoMath.Max(0, PreviousState.Velocity), - VectoMath.Max(0, CurrentState.Velocity)); - } - CurrentState.SlopeResistance = SlopeResistance(gradient); - - // DriverAcceleration = vehicleTractionForce - RollingResistance - AirDragResistance - SlopeResistance - CurrentState.VehicleTractionForce = CurrentState.DriverAcceleration - + CurrentState.RollingResistance - + CurrentState.AirDragResistance - + CurrentState.SlopeResistance; - - var retval = NextComponent.Request(absTime, dt, CurrentState.VehicleTractionForce, - CurrentState.Velocity, dryRun); - return retval; - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - var averageVelocity = (PreviousState.Velocity + CurrentState.Velocity) / 2.0; - - container[ModalResultField.v_act] = averageVelocity; - - container[ModalResultField.P_veh_inertia] = CurrentState.DriverAcceleration * averageVelocity; - container[ModalResultField.P_roll] = CurrentState.RollingResistance * averageVelocity; - container[ModalResultField.P_air] = CurrentState.AirDragResistance * averageVelocity; - container[ModalResultField.P_slope] = CurrentState.SlopeResistance * averageVelocity; - container[ModalResultField.P_trac] = CurrentState.VehicleTractionForce * averageVelocity; - - // sanity check: is the vehicle in step with the cycle? - if (container[ModalResultField.dist] == DBNull.Value) { - Log.Warn("Distance field is not set!"); - } else { - var distance = (SI)container[ModalResultField.dist]; - if (!distance.IsEqual(CurrentState.Distance)) { - Log.Warn("Vehicle Distance diverges from Cycle by {0} [m]. Distance: {1}", - (distance - CurrentState.Distance).Value(), distance); - } - } - } - - public Newton RollingResistance(Radian gradient) - { - var weight = ModelData.TotalVehicleWeight; - var gravity = Physics.GravityAccelleration; - var rollCoefficient = ModelData.TotalRollResistanceCoefficient; - - var retVal = Math.Cos(gradient.Value()) * weight * gravity * rollCoefficient; - Log.Debug("RollingResistance: {0}", retVal); - return retVal; - } - - protected internal Newton DriverAcceleration(MeterPerSquareSecond accelleration) - { - var retVal = ModelData.TotalVehicleWeight * accelleration; - Log.Debug("DriverAcceleration: {0}", retVal); - return retVal; - } - - public Newton SlopeResistance(Radian gradient) - { - var retVal = ModelData.TotalVehicleWeight * Physics.GravityAccelleration * Math.Sin(gradient.Value()); - Log.Debug("SlopeResistance: {0}", retVal); - return retVal; - } - - public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) - { - var vAverage = (previousVelocity + nextVelocity) / 2; - if (vAverage.IsEqual(0)) { - return 0.SI<Newton>(); - } - var result = ComputeAirDragPowerLoss(previousVelocity, nextVelocity) / vAverage; - - Log.Debug("AirDragResistance: {0}", result); - return result; - } - - private Watt ComputeAirDragPowerLoss(MeterPerSecond v1, MeterPerSecond v2) - { - return AirdragData.CrossWindCorrectionCurve.AverageAirDragPowerLoss(v1, v2); - } - - public Meter Distance - { - get { return PreviousState.Distance; } - } - - public MeterPerSecond VehicleSpeed - { - get { return PreviousState.Velocity; } - } - - public bool VehicleStopped - { - get { return PreviousState.Velocity.IsEqual(0.SI<MeterPerSecond>(), 0.01.SI<MeterPerSecond>()); } - } - - public Kilogram VehicleMass - { - get { return ModelData.TotalCurbWeight; } - } - - public Kilogram VehicleLoading - { - get { return ModelData.Loading; } - } - - public Kilogram TotalMass - { - get { return ModelData.TotalVehicleWeight; } - } - - public CubicMeter CargoVolume - { - get { return ModelData.CargoVolume; } - } - - public class VehicleState - { - public Meter Distance = 0.SI<Meter>(); - public Second SimulationInterval = 0.SI<Second>(); - public Newton AirDragResistance = 0.SI<Newton>(); - public Newton DriverAcceleration = 0.SI<Newton>(); - public Newton RollingResistance = 0.SI<Newton>(); - public Newton SlopeResistance = 0.SI<Newton>(); - public Newton VehicleTractionForce = 0.SI<Newton>(); - public MeterPerSecond Velocity = 0.SI<MeterPerSecond>(); - public MeterPerSquareSecond Acceleration = 0.SI<MeterPerSquareSecond>(); - - public override string ToString() - { - return - string.Format( - "v: {0} a: {1}, dt: {2}, driver_acc: {3}, roll_res: {4}, slope_res: {5}, air_drag: {6}, traction force: {7}", - Velocity, Acceleration, SimulationInterval, DriverAcceleration, RollingResistance, SlopeResistance, - AirDragResistance, - VehicleTractionForce); - } - } - } +using System; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class Vehicle : StatefulProviderComponent<Vehicle.VehicleState, IDriverDemandOutPort, IFvInPort, IFvOutPort>, + IVehicle, IMileageCounter, IFvInPort, + IDriverDemandOutPort + { + internal readonly VehicleData ModelData; + + public readonly AirdragData AirdragData; + + + public Vehicle(IVehicleContainer container, VehicleData modelData, AirdragData airdrag) : base(container) + { + ModelData = modelData; + AirdragData = airdrag; + if (AirdragData.CrossWindCorrectionCurve != null) { + AirdragData.CrossWindCorrectionCurve.SetDataBus(container); + } + } + + + public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient) + { + PreviousState = new VehicleState { + Distance = DataBus.CycleStartDistance, + Velocity = vehicleSpeed, + RollingResistance = RollingResistance(roadGradient), + SlopeResistance = SlopeResistance(roadGradient), + AirDragResistance = AirDragResistance(vehicleSpeed, vehicleSpeed), + }; + PreviousState.VehicleTractionForce = PreviousState.RollingResistance + + PreviousState.AirDragResistance + + PreviousState.SlopeResistance; + + return NextComponent.Initialize(PreviousState.VehicleTractionForce, vehicleSpeed); + } + + public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient, MeterPerSquareSecond startAcceleration) + { + //CurrentState.Velocity = vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval; + var vehicleAccelerationForce = DriverAcceleration(startAcceleration) + + RollingResistance(roadGradient) + + + AirDragResistance(vehicleSpeed, + vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval) + + SlopeResistance(roadGradient); + + var retVal = NextComponent.Initialize(vehicleAccelerationForce, vehicleSpeed); + return retVal; + } + + public IResponse Request(Second absTime, Second dt, MeterPerSquareSecond acceleration, Radian gradient, + bool dryRun = false) + { + Log.Debug("Vehicle: acceleration: {0}", acceleration); + CurrentState.SimulationInterval = dt; + CurrentState.Acceleration = acceleration; + CurrentState.Velocity = PreviousState.Velocity + acceleration * dt; + if (CurrentState.Velocity.IsEqual(0.SI<MeterPerSecond>(), + Constants.SimulationSettings.VehicleSpeedHaltTolerance)) { + CurrentState.Velocity = 0.SI<MeterPerSecond>(); + } + CurrentState.Distance = PreviousState.Distance + PreviousState.Velocity * dt + acceleration * dt * dt / 2; + + CurrentState.DriverAcceleration = DriverAcceleration(acceleration); + CurrentState.RollingResistance = RollingResistance(gradient); + try { + CurrentState.AirDragResistance = AirDragResistance(PreviousState.Velocity, CurrentState.Velocity); + } catch (VectoException ex) { + Log.Warn("Exception during calculation of AirDragResistance: absTime: {0}, dist: {1}, v: {2}. {3}", absTime, + CurrentState.Distance, CurrentState.Velocity, ex); + CurrentState.AirDragResistance = AirDragResistance(VectoMath.Max(0, PreviousState.Velocity), + VectoMath.Max(0, CurrentState.Velocity)); + } + CurrentState.SlopeResistance = SlopeResistance(gradient); + + // DriverAcceleration = vehicleTractionForce - RollingResistance - AirDragResistance - SlopeResistance + CurrentState.VehicleTractionForce = CurrentState.DriverAcceleration + + CurrentState.RollingResistance + + CurrentState.AirDragResistance + + CurrentState.SlopeResistance; + + var retval = NextComponent.Request(absTime, dt, CurrentState.VehicleTractionForce, + CurrentState.Velocity, dryRun); + return retval; + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + var averageVelocity = (PreviousState.Velocity + CurrentState.Velocity) / 2.0; + + container[ModalResultField.v_act] = averageVelocity; + + container[ModalResultField.P_veh_inertia] = CurrentState.DriverAcceleration * averageVelocity; + container[ModalResultField.P_roll] = CurrentState.RollingResistance * averageVelocity; + container[ModalResultField.P_air] = CurrentState.AirDragResistance * averageVelocity; + container[ModalResultField.P_slope] = CurrentState.SlopeResistance * averageVelocity; + container[ModalResultField.P_trac] = CurrentState.VehicleTractionForce * averageVelocity; + + // sanity check: is the vehicle in step with the cycle? + if (container[ModalResultField.dist] == DBNull.Value) { + Log.Warn("Distance field is not set!"); + } else { + var distance = (SI)container[ModalResultField.dist]; + if (!distance.IsEqual(CurrentState.Distance)) { + Log.Warn("Vehicle Distance diverges from Cycle by {0} [m]. Distance: {1}", + (distance - CurrentState.Distance).Value(), distance); + } + } + } + + public Newton RollingResistance(Radian gradient) + { + var weight = ModelData.TotalVehicleWeight; + var gravity = Physics.GravityAccelleration; + var rollCoefficient = ModelData.TotalRollResistanceCoefficient; + + var retVal = Math.Cos(gradient.Value()) * weight * gravity * rollCoefficient; + Log.Debug("RollingResistance: {0}", retVal); + return retVal; + } + + protected internal Newton DriverAcceleration(MeterPerSquareSecond accelleration) + { + var retVal = ModelData.TotalVehicleWeight * accelleration; + Log.Debug("DriverAcceleration: {0}", retVal); + return retVal; + } + + public Newton SlopeResistance(Radian gradient) + { + var retVal = ModelData.TotalVehicleWeight * Physics.GravityAccelleration * Math.Sin(gradient.Value()); + Log.Debug("SlopeResistance: {0}", retVal); + return retVal; + } + + public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) + { + var vAverage = (previousVelocity + nextVelocity) / 2; + if (vAverage.IsEqual(0)) { + return 0.SI<Newton>(); + } + var result = ComputeAirDragPowerLoss(previousVelocity, nextVelocity) / vAverage; + + Log.Debug("AirDragResistance: {0}", result); + return result; + } + + private Watt ComputeAirDragPowerLoss(MeterPerSecond v1, MeterPerSecond v2) + { + return AirdragData.CrossWindCorrectionCurve.AverageAirDragPowerLoss(v1, v2); + } + + public Meter Distance + { + get { return PreviousState.Distance; } + } + + public MeterPerSecond VehicleSpeed + { + get { return PreviousState.Velocity; } + } + + public bool VehicleStopped + { + get { return PreviousState.Velocity.IsEqual(0.SI<MeterPerSecond>(), 0.01.SI<MeterPerSecond>()); } + } + + public Kilogram VehicleMass + { + get { return ModelData.TotalCurbWeight; } + } + + public Kilogram VehicleLoading + { + get { return ModelData.Loading; } + } + + public Kilogram TotalMass + { + get { return ModelData.TotalVehicleWeight; } + } + + public CubicMeter CargoVolume + { + get { return ModelData.CargoVolume; } + } + + public class VehicleState + { + public Meter Distance = 0.SI<Meter>(); + public Second SimulationInterval = 0.SI<Second>(); + public Newton AirDragResistance = 0.SI<Newton>(); + public Newton DriverAcceleration = 0.SI<Newton>(); + public Newton RollingResistance = 0.SI<Newton>(); + public Newton SlopeResistance = 0.SI<Newton>(); + public Newton VehicleTractionForce = 0.SI<Newton>(); + public MeterPerSecond Velocity = 0.SI<MeterPerSecond>(); + public MeterPerSquareSecond Acceleration = 0.SI<MeterPerSquareSecond>(); + + public override string ToString() + { + return + string.Format( + "v: {0} a: {1}, dt: {2}, driver_acc: {3}, roll_res: {4}, slope_res: {5}, air_drag: {6}, traction force: {7}", + Velocity, Acceleration, SimulationInterval, DriverAcceleration, RollingResistance, SlopeResistance, + AirDragResistance, + VehicleTractionForce); + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs b/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs index 51f3e6f89c..0520e1b177 100644 --- a/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs +++ b/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs @@ -29,89 +29,89 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Data; -using System.IO; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.OutputData.FileIO -{ - public class FileOutputWriter : LoggingObject, IOutputDataWriter - { - private readonly string _jobFile; - - private string BasePath - { - get { return Path.GetDirectoryName(_jobFile); } - } - - public string PDFReportName - { - get { return Path.ChangeExtension(_jobFile, Constants.FileExtensions.PDFReport); } - } - - public string XMLFullReportName - { - get { return Path.ChangeExtension(_jobFile, "RSLT_MANUFACTURER.xml"); } - } - - public string XMLCustomerReportName - { - get { return Path.ChangeExtension(_jobFile, "RSLT_CUSTOMER.xml"); } - } - - - public string SumFileName - { - get { return Path.ChangeExtension(_jobFile, Constants.FileExtensions.SumFile); } - } - - /// <summary> - /// - /// </summary> - /// <param name="jobFile">full path of the json job-file. jobName and basePath are extracted.</param> - public FileOutputWriter(string jobFile) - { - _jobFile = jobFile; - } - - public void WriteSumData(DataTable data) - { - VectoCSVFile.Write(SumFileName, data, true); - } - - public string GetModDataFileName(string runName, string cycleName, string runSuffix) - { - string modFileName; - if (!string.IsNullOrWhiteSpace(cycleName) || !string.IsNullOrWhiteSpace(runSuffix)) { - modFileName = string.Format("{0}_{1}{2}{3}", runName, cycleName, runSuffix, Constants.FileExtensions.ModDataFile); - } else { - modFileName = string.Format("{0}{1}", runName, Constants.FileExtensions.ModDataFile); - } - - return Path.Combine(BasePath, modFileName); - } - - public void WriteModData(string runName, string cycleName, string runSuffix, DataTable modData) - { - VectoCSVFile.Write(GetModDataFileName(runName, cycleName, runSuffix), modData, true); - } - - public Stream WriteStream(ReportType type) - { - switch (type) { - case ReportType.DeclarationReportPdf: - return new FileStream(PDFReportName, FileMode.Create); - case ReportType.DeclarationReportXMLFulll: - return new FileStream(XMLFullReportName, FileMode.Create); - case ReportType.DeclarationReportXMLCOC: - return new FileStream(XMLCustomerReportName, FileMode.Create); - default: - - throw new ArgumentOutOfRangeException("type"); - } - } - } +using System; +using System.Data; +using System.IO; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.OutputData.FileIO +{ + public class FileOutputWriter : LoggingObject, IOutputDataWriter + { + private readonly string _jobFile; + + private string BasePath + { + get { return Path.GetDirectoryName(_jobFile); } + } + + public string PDFReportName + { + get { return Path.ChangeExtension(_jobFile, Constants.FileExtensions.PDFReport); } + } + + public string XMLFullReportName + { + get { return Path.ChangeExtension(_jobFile, "RSLT_MANUFACTURER.xml"); } + } + + public string XMLCustomerReportName + { + get { return Path.ChangeExtension(_jobFile, "RSLT_CUSTOMER.xml"); } + } + + + public string SumFileName + { + get { return Path.ChangeExtension(_jobFile, Constants.FileExtensions.SumFile); } + } + + /// <summary> + /// + /// </summary> + /// <param name="jobFile">full path of the json job-file. jobName and basePath are extracted.</param> + public FileOutputWriter(string jobFile) + { + _jobFile = jobFile; + } + + public void WriteSumData(DataTable data) + { + VectoCSVFile.Write(SumFileName, data, true); + } + + public string GetModDataFileName(string runName, string cycleName, string runSuffix) + { + string modFileName; + if (!string.IsNullOrWhiteSpace(cycleName) || !string.IsNullOrWhiteSpace(runSuffix)) { + modFileName = string.Format("{0}_{1}{2}{3}", runName, cycleName, runSuffix, Constants.FileExtensions.ModDataFile); + } else { + modFileName = string.Format("{0}{1}", runName, Constants.FileExtensions.ModDataFile); + } + + return Path.Combine(BasePath, modFileName); + } + + public void WriteModData(string runName, string cycleName, string runSuffix, DataTable modData) + { + VectoCSVFile.Write(GetModDataFileName(runName, cycleName, runSuffix), modData, true); + } + + public Stream WriteStream(ReportType type) + { + switch (type) { + case ReportType.DeclarationReportPdf: + return new FileStream(PDFReportName, FileMode.Create); + case ReportType.DeclarationReportXMLFulll: + return new FileStream(XMLFullReportName, FileMode.Create); + case ReportType.DeclarationReportXMLCOC: + return new FileStream(XMLCustomerReportName, FileMode.Create); + default: + + throw new ArgumentOutOfRangeException("type"); + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs index 2467116af3..b2d433c1cc 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs @@ -29,177 +29,177 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.IO; -using System.Text; -using System.Data; -using System.Linq; -using System.Collections.Generic; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.InputData.FileIO.JSON; -using TUGraz.VectoCore.Models.Simulation.Impl; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; - -namespace TUGraz.VectoCore.Tests.Models.Simulation -{ - [TestClass] - public class PwheelModeTests - { - /// <summary> - /// Test if the cycle file can be read. - /// </summary> - /// <remarks>VECTO-177</remarks> - [TestMethod] - public void Pwheel_ReadCycle_Test() - { - var container = new VehicleContainer(ExecutionMode.Engineering); - var inputData = @"<t>,<Pwheel>,<gear>,<n>,<Padd> - 1,89,2,1748,1.300 - 2,120,2,1400,0.4"; - - var cycleFile = new MemoryStream(Encoding.UTF8.GetBytes(inputData)); - var drivingCycle = DrivingCycleDataReader.ReadFromStream(cycleFile, CycleType.PWheel, "", false); - - var gearbox = new CycleGearbox(container, new VectoRunData() { - GearboxData = new GearboxData { - Gears = new Dictionary<uint, GearData> { { 1, new GearData { Ratio = 2.0 } }, { 2, new GearData { Ratio = 3.5 } } } - } - }); - - var cycle = new PWheelCycle(container, drivingCycle, 2.3, null, - gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio)); - - Assert.AreEqual(container.CycleData.LeftSample.Time, 1.SI<Second>()); - Assert.AreEqual(container.CycleData.RightSample.Time, 2.SI<Second>()); - - Assert.AreEqual(1748.RPMtoRad() / (2.3 * 3.5), container.CycleData.LeftSample.WheelAngularVelocity); - Assert.AreEqual(1400.RPMtoRad() / (2.3 * 3.5), container.CycleData.RightSample.WheelAngularVelocity); - - Assert.AreEqual(89.SI().Kilo.Watt, container.CycleData.LeftSample.PWheel); - Assert.AreEqual(120.SI().Kilo.Watt, container.CycleData.RightSample.PWheel); - - Assert.AreEqual(2u, container.CycleData.LeftSample.Gear); - Assert.AreEqual(2u, container.CycleData.RightSample.Gear); - - Assert.AreEqual(1300.SI<Watt>(), container.CycleData.LeftSample.AdditionalAuxPowerDemand); - Assert.AreEqual(400.SI<Watt>(), container.CycleData.RightSample.AdditionalAuxPowerDemand); - - Assert.AreEqual(89.SI().Kilo.Watt / (1748.RPMtoRad() / (2.3 * 3.5)), container.CycleData.LeftSample.Torque); - Assert.AreEqual(120.SI().Kilo.Watt / (1400.RPMtoRad() / (2.3 * 3.5)), container.CycleData.RightSample.Torque); - } - - /// <summary> - /// Tests if the powertrain can be created in P_wheel_in mode. - /// </summary> - /// <remarks>VECTO-177</remarks> - [TestMethod] - public void Pwheel_CreatePowertrain_Test() - { - // prepare input data - var inputData = @"<t>,<Pwheel>,<gear>,<n>, <Padd> - 1, 89, 2, 1748, 1.3 - 2, 120, 2, 1400, 0.4"; - - var cycleFile = new MemoryStream(Encoding.UTF8.GetBytes(inputData)); - var drivingCycle = DrivingCycleDataReader.ReadFromStream(cycleFile, CycleType.PWheel, "", false); - - var fuelConsumption = new DataTable(); - fuelConsumption.Columns.Add(""); - fuelConsumption.Columns.Add(""); - fuelConsumption.Columns.Add(""); - fuelConsumption.Rows.Add("1", "1", "1"); - fuelConsumption.Rows.Add("2", "2", "2"); - fuelConsumption.Rows.Add("3", "3", "3"); - - var fullLoad = new DataTable(); - fullLoad.Columns.Add("Engine speed"); - fullLoad.Columns.Add("max torque"); - fullLoad.Columns.Add("drag torque"); - fullLoad.Columns.Add("PT1"); - fullLoad.Rows.Add("0", "5000", "-5000", "0"); - fullLoad.Rows.Add("3000", "5000", "-5000", "0"); - - var fullLoadCurve = FullLoadCurveReader.Create(fullLoad); - var data = new VectoRunData { - Cycle = drivingCycle, - AxleGearData = new AxleGearData { AxleGear = new GearData { Ratio = 2.3 } }, - EngineData = - new CombustionEngineData { - IdleSpeed = 560.RPMtoRad(), - FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>() { { 0, fullLoadCurve }, { 1, fullLoadCurve } } - }, - GearboxData = new GearboxData { Gears = new Dictionary<uint, GearData> { { 2, new GearData { Ratio = 3.5 } } } }, - Retarder = new RetarderData() - }; - - // call builder (actual test) - var builder = new PowertrainBuilder(new MockModalDataContainer()); - var jobContainer = builder.Build(data); - } - - /// <summary> - /// Tests if the simulation works and the modfile and sumfile are correct in P_wheel_in mode. - /// </summary> - /// <remarks>VECTO-177</remarks> - [TestMethod] - public void Pwheel_Run_Test() - { - var jobFile = @"TestData\Pwheel\Pwheel.vecto"; - var fileWriter = new FileOutputWriter(jobFile); - var sumWriter = new SummaryDataContainer(fileWriter); - var jobContainer = new JobContainer(sumWriter); - - var inputData = JSONInputDataFactory.ReadJsonJob(jobFile); - var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter); - - jobContainer.AddRuns(runsFactory); - jobContainer.Execute(); - - jobContainer.WaitFinished(); - - Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException))); - - ResultFileHelper.TestSumFile(@"TestData\Pwheel\Results\Pwheel.vsum", @"TestData\Pwheel\Pwheel.vsum"); - - ResultFileHelper.TestModFile(@"TestData\Pwheel\Results\Pwheel_Gear2_pt1_rep1_actual.vmod", - @"TestData\Pwheel\Pwheel_Gear2_pt1_rep1_actual.vmod"); - } - - /// <summary> - /// Tests if the simulation works and the modfile and sumfile are correct in P_wheel_in mode. - /// </summary> - /// <remarks>VECTO-177</remarks> - [TestMethod] - public void Pwheel_ultimate_Run_Test() - { - var jobFile = @"TestData\Pwheel\Pwheel_ultimate.vecto"; - var fileWriter = new FileOutputWriter(jobFile); - var sumWriter = new SummaryDataContainer(fileWriter); - var jobContainer = new JobContainer(sumWriter); - - var inputData = JSONInputDataFactory.ReadJsonJob(jobFile); - var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter); - - jobContainer.AddRuns(runsFactory); - jobContainer.Execute(); - - jobContainer.WaitFinished(); - - Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException))); - - ResultFileHelper.TestSumFile(@"TestData\Pwheel\Results\Pwheel_ultimate.vsum", @"TestData\Pwheel\Pwheel_ultimate.vsum"); - - ResultFileHelper.TestModFile(@"TestData\Pwheel\Results\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod", - @"TestData\Pwheel\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod"); - } - } +using System.IO; +using System.Text; +using System.Data; +using System.Linq; +using System.Collections.Generic; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.Models.Simulation.Impl; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; + +namespace TUGraz.VectoCore.Tests.Models.Simulation +{ + [TestClass] + public class PwheelModeTests + { + /// <summary> + /// Test if the cycle file can be read. + /// </summary> + /// <remarks>VECTO-177</remarks> + [TestMethod] + public void Pwheel_ReadCycle_Test() + { + var container = new VehicleContainer(ExecutionMode.Engineering); + var inputData = @"<t>,<Pwheel>,<gear>,<n>,<Padd> + 1,89,2,1748,1.300 + 2,120,2,1400,0.4"; + + var cycleFile = new MemoryStream(Encoding.UTF8.GetBytes(inputData)); + var drivingCycle = DrivingCycleDataReader.ReadFromStream(cycleFile, CycleType.PWheel, "", false); + + var gearbox = new CycleGearbox(container, new VectoRunData() { + GearboxData = new GearboxData { + Gears = new Dictionary<uint, GearData> { { 1, new GearData { Ratio = 2.0 } }, { 2, new GearData { Ratio = 3.5 } } } + } + }); + + var cycle = new PWheelCycle(container, drivingCycle, 2.3, null, + gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio)); + + Assert.AreEqual(container.CycleData.LeftSample.Time, 1.SI<Second>()); + Assert.AreEqual(container.CycleData.RightSample.Time, 2.SI<Second>()); + + Assert.AreEqual(1748.RPMtoRad() / (2.3 * 3.5), container.CycleData.LeftSample.WheelAngularVelocity); + Assert.AreEqual(1400.RPMtoRad() / (2.3 * 3.5), container.CycleData.RightSample.WheelAngularVelocity); + + Assert.AreEqual(89.SI().Kilo.Watt, container.CycleData.LeftSample.PWheel); + Assert.AreEqual(120.SI().Kilo.Watt, container.CycleData.RightSample.PWheel); + + Assert.AreEqual(2u, container.CycleData.LeftSample.Gear); + Assert.AreEqual(2u, container.CycleData.RightSample.Gear); + + Assert.AreEqual(1300.SI<Watt>(), container.CycleData.LeftSample.AdditionalAuxPowerDemand); + Assert.AreEqual(400.SI<Watt>(), container.CycleData.RightSample.AdditionalAuxPowerDemand); + + Assert.AreEqual(89.SI().Kilo.Watt / (1748.RPMtoRad() / (2.3 * 3.5)), container.CycleData.LeftSample.Torque); + Assert.AreEqual(120.SI().Kilo.Watt / (1400.RPMtoRad() / (2.3 * 3.5)), container.CycleData.RightSample.Torque); + } + + /// <summary> + /// Tests if the powertrain can be created in P_wheel_in mode. + /// </summary> + /// <remarks>VECTO-177</remarks> + [TestMethod] + public void Pwheel_CreatePowertrain_Test() + { + // prepare input data + var inputData = @"<t>,<Pwheel>,<gear>,<n>, <Padd> + 1, 89, 2, 1748, 1.3 + 2, 120, 2, 1400, 0.4"; + + var cycleFile = new MemoryStream(Encoding.UTF8.GetBytes(inputData)); + var drivingCycle = DrivingCycleDataReader.ReadFromStream(cycleFile, CycleType.PWheel, "", false); + + var fuelConsumption = new DataTable(); + fuelConsumption.Columns.Add(""); + fuelConsumption.Columns.Add(""); + fuelConsumption.Columns.Add(""); + fuelConsumption.Rows.Add("1", "1", "1"); + fuelConsumption.Rows.Add("2", "2", "2"); + fuelConsumption.Rows.Add("3", "3", "3"); + + var fullLoad = new DataTable(); + fullLoad.Columns.Add("Engine speed"); + fullLoad.Columns.Add("max torque"); + fullLoad.Columns.Add("drag torque"); + fullLoad.Columns.Add("PT1"); + fullLoad.Rows.Add("0", "5000", "-5000", "0"); + fullLoad.Rows.Add("3000", "5000", "-5000", "0"); + + var fullLoadCurve = FullLoadCurveReader.Create(fullLoad); + var data = new VectoRunData { + Cycle = drivingCycle, + AxleGearData = new AxleGearData { AxleGear = new GearData { Ratio = 2.3 } }, + EngineData = + new CombustionEngineData { + IdleSpeed = 560.RPMtoRad(), + FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>() { { 0, fullLoadCurve }, { 1, fullLoadCurve } } + }, + GearboxData = new GearboxData { Gears = new Dictionary<uint, GearData> { { 2, new GearData { Ratio = 3.5 } } } }, + Retarder = new RetarderData() + }; + + // call builder (actual test) + var builder = new PowertrainBuilder(new MockModalDataContainer()); + var jobContainer = builder.Build(data); + } + + /// <summary> + /// Tests if the simulation works and the modfile and sumfile are correct in P_wheel_in mode. + /// </summary> + /// <remarks>VECTO-177</remarks> + [TestMethod] + public void Pwheel_Run_Test() + { + var jobFile = @"TestData\Pwheel\Pwheel.vecto"; + var fileWriter = new FileOutputWriter(jobFile); + var sumWriter = new SummaryDataContainer(fileWriter); + var jobContainer = new JobContainer(sumWriter); + + var inputData = JSONInputDataFactory.ReadJsonJob(jobFile); + var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter); + + jobContainer.AddRuns(runsFactory); + jobContainer.Execute(); + + jobContainer.WaitFinished(); + + Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException))); + + ResultFileHelper.TestSumFile(@"TestData\Pwheel\Results\Pwheel.vsum", @"TestData\Pwheel\Pwheel.vsum"); + + ResultFileHelper.TestModFile(@"TestData\Pwheel\Results\Pwheel_Gear2_pt1_rep1_actual.vmod", + @"TestData\Pwheel\Pwheel_Gear2_pt1_rep1_actual.vmod"); + } + + /// <summary> + /// Tests if the simulation works and the modfile and sumfile are correct in P_wheel_in mode. + /// </summary> + /// <remarks>VECTO-177</remarks> + [TestMethod] + public void Pwheel_ultimate_Run_Test() + { + var jobFile = @"TestData\Pwheel\Pwheel_ultimate.vecto"; + var fileWriter = new FileOutputWriter(jobFile); + var sumWriter = new SummaryDataContainer(fileWriter); + var jobContainer = new JobContainer(sumWriter); + + var inputData = JSONInputDataFactory.ReadJsonJob(jobFile); + var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter); + + jobContainer.AddRuns(runsFactory); + jobContainer.Execute(); + + jobContainer.WaitFinished(); + + Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException))); + + ResultFileHelper.TestSumFile(@"TestData\Pwheel\Results\Pwheel_ultimate.vsum", @"TestData\Pwheel\Pwheel_ultimate.vsum"); + + ResultFileHelper.TestModFile(@"TestData\Pwheel\Results\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod", + @"TestData\Pwheel\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod"); + } + } } \ No newline at end of file -- GitLab