diff --git a/Documentation/User Manual Source/Release Notes Vecto3.x.pdf b/Documentation/User Manual Source/Release Notes Vecto3.x.pdf index b1bbe4f01a3de416ce98b0db1ec2d4701875a51b..4df7d3f6eb9d833d7d9a745eb8fc8bebf1aa5d7c 100644 Binary files a/Documentation/User Manual Source/Release Notes Vecto3.x.pdf and b/Documentation/User Manual Source/Release Notes Vecto3.x.pdf differ diff --git a/Documentation/User Manual Source/material User Manual.pptx b/Documentation/User Manual Source/material User Manual.pptx index b7776eaa3d8be31b1a2a28f3b1457a35a565eada..a3f5a0a78e18a538105222dac7fd93bbaca9f2f0 100644 Binary files a/Documentation/User Manual Source/material User Manual.pptx and b/Documentation/User Manual Source/material User Manual.pptx differ diff --git a/VECTO/GUI/HybridStratebyParamsForm.Designer.vb b/VECTO/GUI/HybridStratebyParamsForm.Designer.vb index 718225417aea9eaaedfccd7fb36ee47a9840c361..a24808fbc1ae5c69234401bb6e1923f23ba8a1a7 100644 --- a/VECTO/GUI/HybridStratebyParamsForm.Designer.vb +++ b/VECTO/GUI/HybridStratebyParamsForm.Designer.vb @@ -37,9 +37,9 @@ Partial Class HybridStrategyParamsForm Private Sub InitializeComponent() Me.components = New System.ComponentModel.Container() Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(HybridStrategyParamsForm)) - Me.tbEquivalenceFactor = New System.Windows.Forms.TextBox() + Me.tbEquivalenceFactorDischarge = New System.Windows.Forms.TextBox() Me.lblEquivFactorUnit = New System.Windows.Forms.Label() - Me.lblEvquivFactor = New System.Windows.Forms.Label() + Me.lblEvquivFactorDischg = New System.Windows.Forms.Label() Me.ButCancel = New System.Windows.Forms.Button() Me.ButOK = New System.Windows.Forms.Button() Me.ToolStrip1 = New System.Windows.Forms.ToolStrip() @@ -83,6 +83,10 @@ Partial Class HybridStrategyParamsForm Me.lblMinIceOnTime = New System.Windows.Forms.Label() Me.lblMinIceOnTimeUnit = New System.Windows.Forms.Label() Me.tbMinICEOnTime = New System.Windows.Forms.TextBox() + Me.Panel2 = New System.Windows.Forms.Panel() + Me.EquivalenceFactorChg = New System.Windows.Forms.Label() + Me.lblEquivFactorChargeUnit = New System.Windows.Forms.Label() + Me.tbEquivalenceFactorCharge = New System.Windows.Forms.TextBox() Me.ToolStrip1.SuspendLayout Me.StatusStrip1.SuspendLayout CType(Me.PictureBox1,System.ComponentModel.ISupportInitialize).BeginInit @@ -94,14 +98,15 @@ Partial Class HybridStrategyParamsForm Me.pnAuxBufferTime.SuspendLayout Me.pnAuxBufferChgTime.SuspendLayout Me.Panel1.SuspendLayout + Me.Panel2.SuspendLayout Me.SuspendLayout ' - 'tbEquivalenceFactor + 'tbEquivalenceFactorDischarge ' - Me.tbEquivalenceFactor.Location = New System.Drawing.Point(181, 4) - Me.tbEquivalenceFactor.Name = "tbEquivalenceFactor" - Me.tbEquivalenceFactor.Size = New System.Drawing.Size(57, 20) - Me.tbEquivalenceFactor.TabIndex = 3 + Me.tbEquivalenceFactorDischarge.Location = New System.Drawing.Point(181, 4) + Me.tbEquivalenceFactorDischarge.Name = "tbEquivalenceFactorDischarge" + Me.tbEquivalenceFactorDischarge.Size = New System.Drawing.Size(57, 20) + Me.tbEquivalenceFactorDischarge.TabIndex = 3 ' 'lblEquivFactorUnit ' @@ -112,20 +117,20 @@ Partial Class HybridStrategyParamsForm Me.lblEquivFactorUnit.TabIndex = 24 Me.lblEquivFactorUnit.Text = "[-]" ' - 'lblEvquivFactor + 'lblEvquivFactorDischg ' - Me.lblEvquivFactor.AutoSize = true - Me.lblEvquivFactor.Location = New System.Drawing.Point(3, 7) - Me.lblEvquivFactor.Name = "lblEvquivFactor" - Me.lblEvquivFactor.Size = New System.Drawing.Size(99, 13) - Me.lblEvquivFactor.TabIndex = 0 - Me.lblEvquivFactor.Text = "Equivalence Factor" + Me.lblEvquivFactorDischg.AutoSize = true + Me.lblEvquivFactorDischg.Location = New System.Drawing.Point(3, 7) + Me.lblEvquivFactorDischg.Name = "lblEvquivFactorDischg" + Me.lblEvquivFactorDischg.Size = New System.Drawing.Size(150, 13) + Me.lblEvquivFactorDischg.TabIndex = 0 + Me.lblEvquivFactorDischg.Text = "Equivalence Factor Discharge" ' 'ButCancel ' 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(362, 291) + Me.ButCancel.Location = New System.Drawing.Point(362, 355) Me.ButCancel.Name = "ButCancel" Me.ButCancel.Size = New System.Drawing.Size(75, 23) Me.ButCancel.TabIndex = 13 @@ -135,7 +140,7 @@ Partial Class HybridStrategyParamsForm '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(281, 291) + Me.ButOK.Location = New System.Drawing.Point(281, 355) Me.ButOK.Name = "ButOK" Me.ButOK.Size = New System.Drawing.Size(75, 23) Me.ButOK.TabIndex = 12 @@ -224,7 +229,7 @@ Partial Class HybridStrategyParamsForm 'StatusStrip1 ' Me.StatusStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.LbStatus}) - Me.StatusStrip1.Location = New System.Drawing.Point(0, 317) + Me.StatusStrip1.Location = New System.Drawing.Point(0, 381) Me.StatusStrip1.Name = "StatusStrip1" Me.StatusStrip1.Size = New System.Drawing.Size(449, 22) Me.StatusStrip1.SizingGrip = false @@ -267,9 +272,9 @@ Partial Class HybridStrategyParamsForm ' 'pnEquivFactor ' - Me.pnEquivFactor.Controls.Add(Me.lblEvquivFactor) + Me.pnEquivFactor.Controls.Add(Me.lblEvquivFactorDischg) Me.pnEquivFactor.Controls.Add(Me.lblEquivFactorUnit) - Me.pnEquivFactor.Controls.Add(Me.tbEquivalenceFactor) + Me.pnEquivFactor.Controls.Add(Me.tbEquivalenceFactorDischarge) Me.pnEquivFactor.Location = New System.Drawing.Point(12, 74) Me.pnEquivFactor.Name = "pnEquivFactor" Me.pnEquivFactor.Size = New System.Drawing.Size(288, 28) @@ -291,7 +296,7 @@ Partial Class HybridStrategyParamsForm Me.pnMinSoC.Controls.Add(Me.lblMinSoC) Me.pnMinSoC.Controls.Add(Me.lblMinSoCUnit) Me.pnMinSoC.Controls.Add(Me.tbMinSoC) - Me.pnMinSoC.Location = New System.Drawing.Point(12, 104) + Me.pnMinSoC.Location = New System.Drawing.Point(12, 134) Me.pnMinSoC.Name = "pnMinSoC" Me.pnMinSoC.Size = New System.Drawing.Size(288, 28) Me.pnMinSoC.TabIndex = 25 @@ -326,7 +331,7 @@ Partial Class HybridStrategyParamsForm Me.pnMaxSoC.Controls.Add(Me.lblMaxSoC) Me.pnMaxSoC.Controls.Add(Me.lblMaxSoCUnit) Me.pnMaxSoC.Controls.Add(Me.tbMaxSoC) - Me.pnMaxSoC.Location = New System.Drawing.Point(12, 134) + Me.pnMaxSoC.Location = New System.Drawing.Point(12, 164) Me.pnMaxSoC.Name = "pnMaxSoC" Me.pnMaxSoC.Size = New System.Drawing.Size(288, 28) Me.pnMaxSoC.TabIndex = 26 @@ -361,7 +366,7 @@ Partial Class HybridStrategyParamsForm Me.pnTargetSoC.Controls.Add(Me.lblTargetSoC) Me.pnTargetSoC.Controls.Add(Me.lblTargetSoCUnit) Me.pnTargetSoC.Controls.Add(Me.tbTargetSoC) - Me.pnTargetSoC.Location = New System.Drawing.Point(12, 164) + Me.pnTargetSoC.Location = New System.Drawing.Point(12, 194) Me.pnTargetSoC.Name = "pnTargetSoC" Me.pnTargetSoC.Size = New System.Drawing.Size(288, 28) Me.pnTargetSoC.TabIndex = 27 @@ -396,7 +401,7 @@ Partial Class HybridStrategyParamsForm Me.pnAuxBufferTime.Controls.Add(Me.lblAuxBufferTime) Me.pnAuxBufferTime.Controls.Add(Me.lblAuxBufferTimeUnit) Me.pnAuxBufferTime.Controls.Add(Me.tbauxBufferTime) - Me.pnAuxBufferTime.Location = New System.Drawing.Point(12, 224) + Me.pnAuxBufferTime.Location = New System.Drawing.Point(12, 254) Me.pnAuxBufferTime.Name = "pnAuxBufferTime" Me.pnAuxBufferTime.Size = New System.Drawing.Size(288, 28) Me.pnAuxBufferTime.TabIndex = 28 @@ -431,7 +436,7 @@ Partial Class HybridStrategyParamsForm Me.pnAuxBufferChgTime.Controls.Add(Me.Label1) Me.pnAuxBufferChgTime.Controls.Add(Me.lblAuxBufferChgTimeUnit) Me.pnAuxBufferChgTime.Controls.Add(Me.tbAuxBufferChargeTime) - Me.pnAuxBufferChgTime.Location = New System.Drawing.Point(12, 254) + Me.pnAuxBufferChgTime.Location = New System.Drawing.Point(12, 284) Me.pnAuxBufferChgTime.Name = "pnAuxBufferChgTime" Me.pnAuxBufferChgTime.Size = New System.Drawing.Size(288, 28) Me.pnAuxBufferChgTime.TabIndex = 29 @@ -466,7 +471,7 @@ Partial Class HybridStrategyParamsForm Me.Panel1.Controls.Add(Me.lblMinIceOnTime) Me.Panel1.Controls.Add(Me.lblMinIceOnTimeUnit) Me.Panel1.Controls.Add(Me.tbMinICEOnTime) - Me.Panel1.Location = New System.Drawing.Point(12, 194) + Me.Panel1.Location = New System.Drawing.Point(12, 224) Me.Panel1.Name = "Panel1" Me.Panel1.Size = New System.Drawing.Size(288, 28) Me.Panel1.TabIndex = 29 @@ -496,13 +501,49 @@ Partial Class HybridStrategyParamsForm Me.tbMinICEOnTime.Size = New System.Drawing.Size(57, 20) Me.tbMinICEOnTime.TabIndex = 3 ' + 'Panel2 + ' + Me.Panel2.Controls.Add(Me.EquivalenceFactorChg) + Me.Panel2.Controls.Add(Me.lblEquivFactorChargeUnit) + Me.Panel2.Controls.Add(Me.tbEquivalenceFactorCharge) + Me.Panel2.Location = New System.Drawing.Point(12, 104) + Me.Panel2.Name = "Panel2" + Me.Panel2.Size = New System.Drawing.Size(288, 28) + Me.Panel2.TabIndex = 25 + ' + 'EquivalenceFactorChg + ' + Me.EquivalenceFactorChg.AutoSize = true + Me.EquivalenceFactorChg.Location = New System.Drawing.Point(3, 7) + Me.EquivalenceFactorChg.Name = "EquivalenceFactorChg" + Me.EquivalenceFactorChg.Size = New System.Drawing.Size(136, 13) + Me.EquivalenceFactorChg.TabIndex = 0 + Me.EquivalenceFactorChg.Text = "Equivalence Factor Charge" + ' + 'lblEquivFactorChargeUnit + ' + Me.lblEquivFactorChargeUnit.AutoSize = true + Me.lblEquivFactorChargeUnit.Location = New System.Drawing.Point(244, 7) + Me.lblEquivFactorChargeUnit.Name = "lblEquivFactorChargeUnit" + Me.lblEquivFactorChargeUnit.Size = New System.Drawing.Size(16, 13) + Me.lblEquivFactorChargeUnit.TabIndex = 24 + Me.lblEquivFactorChargeUnit.Text = "[-]" + ' + 'tbEquivalenceFactorCharge + ' + Me.tbEquivalenceFactorCharge.Location = New System.Drawing.Point(181, 4) + Me.tbEquivalenceFactorCharge.Name = "tbEquivalenceFactorCharge" + Me.tbEquivalenceFactorCharge.Size = New System.Drawing.Size(57, 20) + Me.tbEquivalenceFactorCharge.TabIndex = 3 + ' 'HybridStrategyParamsForm ' Me.AcceptButton = Me.ButOK Me.AutoScaleDimensions = New System.Drawing.SizeF(6!, 13!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.CancelButton = Me.ButCancel - Me.ClientSize = New System.Drawing.Size(449, 339) + Me.ClientSize = New System.Drawing.Size(449, 403) + Me.Controls.Add(Me.Panel2) Me.Controls.Add(Me.Panel1) Me.Controls.Add(Me.pnAuxBufferChgTime) Me.Controls.Add(Me.pnAuxBufferTime) @@ -543,13 +584,15 @@ Partial Class HybridStrategyParamsForm Me.pnAuxBufferChgTime.PerformLayout Me.Panel1.ResumeLayout(false) Me.Panel1.PerformLayout + Me.Panel2.ResumeLayout(false) + Me.Panel2.PerformLayout Me.ResumeLayout(false) Me.PerformLayout End Sub - Friend WithEvents tbEquivalenceFactor As TextBox + Friend WithEvents tbEquivalenceFactorDischarge As TextBox Friend WithEvents lblEquivFactorUnit As Label - Friend WithEvents lblEvquivFactor As Label + Friend WithEvents lblEvquivFactorDischg As Label Friend WithEvents ButCancel As Button Friend WithEvents ButOK As Button Friend WithEvents ToolStrip1 As ToolStrip @@ -593,4 +636,8 @@ End Sub Friend WithEvents lblMinIceOnTime As Label Friend WithEvents lblMinIceOnTimeUnit As Label Friend WithEvents tbMinICEOnTime As TextBox + Friend WithEvents Panel2 As Panel + Friend WithEvents EquivalenceFactorChg As Label + Friend WithEvents lblEquivFactorChargeUnit As Label + Friend WithEvents tbEquivalenceFactorCharge As TextBox End Class diff --git a/VECTO/GUI/HybridStratebyParamsForm.vb b/VECTO/GUI/HybridStratebyParamsForm.vb index 105d60891b5f1e43621bdf66529aa8dbc62d4ceb..a399335630632c0e6d344492e78d4fccfd93f57b 100644 --- a/VECTO/GUI/HybridStratebyParamsForm.vb +++ b/VECTO/GUI/HybridStratebyParamsForm.vb @@ -135,7 +135,7 @@ Public Class HybridStrategyParamsForm If ChangeCheckCancel() Then Exit Sub - tbEquivalenceFactor.Text = "" + tbEquivalenceFactorDischarge.Text = "" tbMinSoC.Text = "" tbMaxSoC.Text = "" tbTargetSoC.Text = "" @@ -175,9 +175,9 @@ Public Class HybridStrategyParamsForm Dim basePath As String = Path.GetDirectoryName(file) - tbEquivalenceFactor.Text = strategyParams.EquivalenceFactor.ToGUIFormat() + tbEquivalenceFactorDischarge.Text = strategyParams.EquivalenceFactorDischarge.ToGUIFormat() - tbEquivalenceFactor.Text = strategyParams.EquivalenceFactor.ToGUIFormat() + tbEquivalenceFactorDischarge.Text = strategyParams.EquivalenceFactorDischarge.ToGUIFormat() tbMinSoC.Text = (strategyParams.MinSoC * 100).ToGUIFormat() tbMaxSoC.Text = (strategyParams.MaxSoC * 100).ToGUIFormat() tbTargetSoC.Text = (strategyParams.TargetSoC * 100).ToGUIFormat() @@ -216,7 +216,8 @@ Public Class HybridStrategyParamsForm strategyParams.FilePath = file - strategyParams.EquivalenceFactor = tbEquivalenceFactor.Text.ToDouble(0) + strategyParams.EquivalenceFactorDischarge = tbEquivalenceFactorDischarge.Text.ToDouble(0) + strategyParams.EquivalenceFactorCharge = tbEquivalenceFactorCharge.Text.ToDouble(0) strategyParams.MinSoC = tbMinSoC.Text.ToDouble(0) / 100 strategyParams.MaxSoC = tbMaxSoC.Text.ToDouble(0) / 100 @@ -352,7 +353,7 @@ Public Class HybridStrategyParamsForm Change() End Sub - Private Sub tbEquivalenceFactor_TextChanged(sender As Object, e As EventArgs) Handles tbEquivalenceFactor.TextChanged + Private Sub tbEquivalenceFactor_TextChanged(sender As Object, e As EventArgs) Handles tbEquivalenceFactorDischarge.TextChanged Change() End Sub diff --git a/VECTO/Input Files/HybridStrategyParams.vb b/VECTO/Input Files/HybridStrategyParams.vb index 9cc60d567025bf9c40f87f00facc38cc33eadb5d..bf320c38c60b792ca044a064f21e8ec570029de6 100644 --- a/VECTO/Input Files/HybridStrategyParams.vb +++ b/VECTO/Input Files/HybridStrategyParams.vb @@ -66,7 +66,12 @@ Public Class HybridStrategyParams End Set End Property - Public Property EquivalenceFactor As Double + + Public Property EquivalenceFactorCharge As Double Implements IHybridStrategyParameters.EquivalenceFactorCharge + + + Public Property EquivalenceFactorDischarge As Double Implements IHybridStrategyParameters.EquivalenceFactorDischarge + Public Property MinSoC As Double @@ -102,11 +107,7 @@ Public Class HybridStrategyParams Public Property AuxiliaryBufferChgTime As Double - Private ReadOnly Property IHybridStrategyParameters_EquivalenceFactor As Double Implements IHybridStrategyParameters.EquivalenceFactor - Get - Return EquivalenceFactor - End Get - End Property + Private ReadOnly Property IHybridStrategyParameters_MinSoC As Double Implements IHybridStrategyParameters.MinSoC Get diff --git a/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs b/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs index 0541f0ecda211ef9db82cfec04b9d6491f368a85..926515746821b4cbb641ed9d67b6a58296d30b0b 100644 --- a/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs +++ b/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs @@ -69,7 +69,9 @@ namespace TUGraz.VectoCommon.InputData public interface IHybridStrategyParameters { - double EquivalenceFactor { get; } + double EquivalenceFactorDischarge { get; } + + double EquivalenceFactorCharge { get; } double MinSoC { get; } diff --git a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs index f2754896471defc0126786fe3c3fa3e232bde9c9..d1c887d17b554d48cd43b59f567fbbcaa38b3d6b 100644 --- a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs +++ b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs @@ -41,7 +41,7 @@ namespace TUGraz.VectoCommon.Models { public IResponse Response { get; set; } - public double Score { get { return (FuelCosts + EqualityFactor * (BatCosts + ICEStartPenalty1) * SoCPenalty + ICEStartPenalty2) / GearshiftPenalty; } } + public double Score { get { return (FuelCosts + EquivalenceFactor * (BatCosts + ICEStartPenalty1) * SoCPenalty + ICEStartPenalty2) / GearshiftPenalty; } } public double FuelCosts { get; set; } @@ -49,7 +49,7 @@ namespace TUGraz.VectoCommon.Models { public double SoCPenalty { get; set; } - public double EqualityFactor { get; set; } + public double EquivalenceFactor { get; set; } public double GearshiftPenalty { get; set; } @@ -200,6 +200,11 @@ namespace TUGraz.VectoCommon.Models { { return (x & HybridConfigurationIgnoreReason.Evaluated) == HybridConfigurationIgnoreReason.Evaluated; } + + public static bool Evaluated(this HybridConfigurationIgnoreReason x) + { + return x != HybridConfigurationIgnoreReason.NotEvaluated; + } } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/Models/IResponse.cs b/VectoCommon/VectoCommon/Models/IResponse.cs index 6ceda8a5297c5d92d4888ec6f24cfe2cc89a640c..1da0a60cdb578a8f8d4d2329c0e186fa976f07e8 100644 --- a/VectoCommon/VectoCommon/Models/IResponse.cs +++ b/VectoCommon/VectoCommon/Models/IResponse.cs @@ -147,6 +147,8 @@ namespace TUGraz.VectoCommon.Models public SIBase<Watt> InertiaPowerDemand { get; set; } public NewtonMeter TotalTorqueDemand { get; set; } + public NewtonMeter TorqueRequest { get; set; } + public NewtonMeter InertiaTorque { get; set; } } diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONHybridStrategyParameters.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONHybridStrategyParameters.cs index 3474c05f98f78978fbbc166f692bc6d347a8a3d9..bc392525d0efffc165dcf2f87273f749eb0b922e 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONHybridStrategyParameters.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONHybridStrategyParameters.cs @@ -9,11 +9,19 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON public JSONHybridStrategyParameters(JObject json, string filename, bool tolerateMissing) : base(json, filename, tolerateMissing) { } - public double EquivalenceFactor + public double EquivalenceFactorDischarge { get { - return Body.GetEx<double>("EquivalenceFactor"); + return Body["EquivalenceFactor"] == null ? Body.GetEx<double>("EquivalenceFactorDischarge") : + Body.GetEx<double>("EquivalenceFactor"); + } + } + + public double EquivalenceFactorCharge { + get { + return Body["EquivalenceFactor"] == null ? Body.GetEx<double>("EquivalenceFactorCharge") : + Body.GetEx<double>("EquivalenceFactor"); } } diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs index de54aeceddd18826dcdb41445b3c58a7f25ae261..2c381e3af888a8403356327ce5a134af29e3b1a6 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs @@ -699,7 +699,8 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter IEngineeringInputDataProvider inputData) { var retVal = new HybridStrategyParameters() { - EquivalenceFactor = hybridStrategyParameters.EquivalenceFactor, + EquivalenceFactorDischarge = hybridStrategyParameters.EquivalenceFactorDischarge, + EquivalenceFactorCharge = hybridStrategyParameters.EquivalenceFactorCharge, MinSoC = hybridStrategyParameters.MinSoC, MaxSoC = hybridStrategyParameters.MaxSoC, TargetSoC = hybridStrategyParameters.TargetSoC, diff --git a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs index b2a4f086f23f97af51ba2ed16af77dcd94d857f5..3f0d3bf899b3a5f97a4bb3c026f8aeb6d3a6a799 100644 --- a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs +++ b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs @@ -183,7 +183,12 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl public ResponseDryRun(object source, IResponse subResponse) : base(source, subResponse) { } public Watt DeltaFullLoad { get; set; } + + public NewtonMeter DeltaFullLoadTorque { get; set; } public Watt DeltaDragLoad { get; set; } + + public NewtonMeter DeltaDragLoadTorque { get; set; } + public PerSecond DeltaEngineSpeed { get; set; } } diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs index 28b329b9c3b25adf47fa881693920bc12e8812ad..62293bc2c8fc9d8ec5cce17b3c1318545a7a6b38 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs @@ -407,6 +407,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Data // only for graphDrawing Testcase + [ModalResultField(typeof(SI), caption: "P_P1_mech [kW]", outputFactor: 1e-3)] + P_electricMotor_mech_P1, [ModalResultField(typeof(SI), caption: "P_P2_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_P2, [ModalResultField(typeof(SI), caption: "P_P3_mech [kW]", outputFactor: 1e-3)] diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs index 729be51228375f377546f4cb49dcedcc89786dab..a99137445b37e3a7ccb9e4b755a1d08bf3f434d7 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs @@ -74,13 +74,18 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus IRESSInfo BatteryInfo { get; } + ITorqueConverterInfo TorqueConverterInfo { get; } + ITorqueConverterControl TorqueConverterCtl { get; } + IPowertainInfo PowertrainInfo { get; } IHybridControllerInfo HybridControllerInfo { get; } IHybridControllerCtl HybridControllerCtl { get; } IAngledriveInfo AngledriveInfo { get; } + + bool IsTestPowertrain { get; } } public interface IPowertainInfo diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs index 91d50d8a13dd39c79b8abda78bc3a6e7b374ab9d..481476c7796efa52764dca63c72bf5f8cda19aa1 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs @@ -86,9 +86,15 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus void TriggerGearshift(Second absTime, Second dt); } - public interface ITorqueConverterControl + public interface ITorqueConverterInfo { Tuple<TorqueConverterOperatingPoint, NewtonMeter> CalculateOperatingPoint(PerSecond inSpeed, PerSecond outSpeed); + + } + + public interface ITorqueConverterControl + { + TorqueConverterOperatingPoint SetOperatingPoint { get; set; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 936439e746fcd699c1a3aa34feff13666c0e5837..8ab4cfafafd7ac092df47a1fe2931509a1123605 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -406,6 +406,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl var strategy = new HybridStrategyAT(data, container); ctl = new HybridController(container, strategy, es); + new ATClutchInfo(container); } // add engine before gearbox so that gearbox can obtain if an ICE is available already in constructor @@ -661,6 +662,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl .AddComponent( new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) .AddComponent(ctl) + .AddComponent(new Brakes(container)) .AddComponent(GetElectricMachine(PowertrainPosition.HybridP4, data.ElectricMachinesData, container, es, ctl)) .AddComponent(new AxleGear(container, data.AxleGearData)) .AddComponent(GetElectricMachine(PowertrainPosition.HybridP3, data.ElectricMachinesData, container, es, ctl)) @@ -696,6 +698,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl if (data.ElectricMachinesData.Any(x => x.Item1 == PowertrainPosition.HybridP1)) { if (gearbox is ATGearbox atGbx) { atGbx.IdleController = idleController; + new ATClutchInfo(container); } } } diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index d6ac7800998326f41ee230daa9e5d2fbc346aca4..9cc9bad6e024fde781c8783fd562738658db3c53 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -74,7 +74,14 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public virtual IDrivingCycleInfo DrivingCycleInfo { get; protected set; } public IRESSInfo BatteryInfo { get; protected set; } + public ITorqueConverterInfo TorqueConverterInfo { get; protected set; } + public virtual ITorqueConverterControl TorqueConverterCtl { get; private set; } + + public virtual bool IsTestPowertrain + { + get { return false; } + } internal ISimulationOutPort Cycle; @@ -112,11 +119,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public virtual Second AbsTime { get; set; } public IElectricMotorInfo ElectricMotorInfo(PowertrainPosition pos) { - return ElectricMotors[pos]; + return ElectricMotors.ContainsKey(pos) ? ElectricMotors[pos] : null; } - public virtual ITorqueConverterControl TorqueConverterCtl { get; private set; } public IPowertainInfo PowertrainInfo { @@ -153,7 +159,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl HasGearbox = true; }) .If<IGearboxControl>(c => GearboxCtl = c) - .If<ITorqueConverterControl>(c => TorqueConverterCtl = c) + .If<ITorqueConverterInfo>(c => TorqueConverterInfo = c) + .If<ITorqueConverterControl>(c => TorqueConverterCtl = c) .If<IAxlegearInfo>(c => AxlegearInfo = c) .If<IAngledriveInfo>(c => AngledriveInfo = c) .If<IWheelsInfo>(c => WheelsInfo = c) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/HybridStrategyParameters.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/HybridStrategyParameters.cs index 7b87dc390749de4ddfcaedfb007446aa0ccd5c2f..5b55c23f29756dbe91359d024ceabed313fc9542 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/HybridStrategyParameters.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/HybridStrategyParameters.cs @@ -3,7 +3,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data { public class HybridStrategyParameters { - public double EquivalenceFactor { get; set; } + public double EquivalenceFactorDischarge { get; set; } + + public double EquivalenceFactorCharge { get; set; } public double MinSoC { get; set; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs index f5ad30ef34cb2c5f6b16d1071632f1567e8ad403..8dcd793535eef9573aa9899a12dae281d6cbd5c9 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs @@ -37,4 +37,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent /// Defines interfaces for a gearbox. /// </summary> public interface IGearbox : IPowerTrainComponent, IGearboxInfo, IGearboxControl { } + + public interface ITorqueConverter : ITorqueConverterInfo, ITorqueConverterControl { } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs index 43801dc2aaf0623c9633edc40d25b458b0f9ce54..2b20583029dfc759687f8e9751bcc731d86bde84 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs @@ -50,15 +50,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected internal readonly IShiftStrategy _strategy; protected internal readonly TorqueConverter TorqueConverter; private IIdleController _idleController; - protected bool RequestAfterGearshift; + protected internal bool RequestAfterGearshift; - private WattSecond _powershiftLossEnergy; + internal WattSecond _powershiftLossEnergy; protected internal KilogramSquareMeter EngineInertia; - public bool TorqueConverterLocked { - get { return CurrentState.Gear.TorqueConverterLocked.Value; } - //set { CurrentState.TorqueConverterLocked = value; } - } + public bool TorqueConverterLocked { + get { return CurrentState.Gear.TorqueConverterLocked.Value; } + //set { CurrentState.TorqueConverterLocked = value; } + } public override bool TCLocked { get { return Gear.TorqueConverterLocked.Value; } } @@ -107,13 +107,21 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public override Second LastUpshift { - get { throw new System.NotImplementedException(); } + get + { + return -double.MaxValue.SI<Second>(); + //throw new System.NotImplementedException(); + } protected internal set { throw new System.NotImplementedException(); } } public override Second LastDownshift { - get { throw new System.NotImplementedException(); } + get + { + return -double.MaxValue.SI<Second>(); + //throw new System.NotImplementedException(); + } protected internal set { throw new System.NotImplementedException(); } } @@ -147,7 +155,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public override bool DisengageGearbox { get; set; } public override void TriggerGearshift(Second absTime, Second dt) { - throw new System.NotImplementedException(); + //throw new System.NotImplementedException(); + RequestAfterGearshift = true; } public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) @@ -301,7 +310,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { if (RequestAfterGearshift /*&& Gear != PreviousState.Gear*/) { LastShift = absTime; - Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity); + Gear = _strategy?.Engage(absTime, dt, outTorque, outAngularVelocity) ?? Gear; _powershiftLossEnergy = ComputeShiftLosses(outTorque, outAngularVelocity, Gear); } else { if (PreviousState.PowershiftLossEnergy != null && PreviousState.PowershiftLossEnergy.IsGreater(0)) { @@ -399,6 +408,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl }, DeltaDragLoad = outTorque * avgAngularVelocity, DeltaFullLoad = outTorque * avgAngularVelocity, + DeltaFullLoadTorque = outTorque, + DeltaDragLoadTorque = outTorque, }; } if ((outTorque * avgAngularVelocity).IsGreater(0.SI<Watt>(), @@ -495,8 +506,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public class ATGearboxState : GearboxState { - - public bool Disengaged = true; + + public bool Disengaged = true; public WattSecond PowershiftLossEnergy; public NewtonMeter PowershiftLoss; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs index 7da8a761912f7bf362aed12a772dfb7ebff0d071..41bd38c1d723eb2e7a420ae4d025d0afe1b21c98 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs @@ -522,12 +522,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Gear = nextGearState.Gear; } - public NextGearState(Second absTime, ATGearbox gearbox) - { - SetState(absTime, gearbox); - } + public NextGearState(Second absTime, ATGearbox gearbox) + { + SetState(absTime, gearbox); + } - public void SetState(Second absTime, bool disengaged, GearshiftPosition gear) + public void SetState(Second absTime, bool disengaged, GearshiftPosition gear) { AbsTime = absTime; Disengaged = disengaged; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs index f2661a971ebd6929036909149ca7d8b3550c16a5..2b93654877837415599470b6c3f41c14a83fd591 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs @@ -240,8 +240,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl foreach (var next in Gears.IterateGears(Gears.Successor(currentGear), Gears.Successor(currentGear, (uint)shiftStrategyParameters.AllowedGearRangeFC))) { if (next == null) { - // no further gear - continue; + // no further gear + continue; } if (current.TorqueConverterLocked != next.TorqueConverterLocked && current.Gear != next.Gear) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs index 2fe040e5deb5cfd2d87d4a51554a390493a63fb9..0940f53b170785415e4333cb40bfe8e2e4cd54a7 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs @@ -107,7 +107,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl PreviousState.InertiaTorqueLossOut) / ratio * PreviousState.InAngularVelocity; } - public virtual Second LastShift { get; protected set; } + public virtual Second LastShift { get; protected internal set; } public abstract Second LastUpshift { get; protected internal set; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Brakes.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Brakes.cs index 83841e2169192c997af6a7775d15b73e19327dd7..bf6ef7e401733830f8742026bdc155343526774e 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Brakes.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Brakes.cs @@ -71,7 +71,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } - if (!dryRun && BrakePower < 0) { + if (!dryRun && !DataBus.IsTestPowertrain && BrakePower < 0) { throw new VectoSimulationException("Negative Braking Power is not allowed! P_br: {0}", BrakePower); } CurrentState.SetState(outTorque + brakeTorque, outAngularVelocity, outTorque, outAngularVelocity); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs index a036c322a92ac1292d5b8caf0b233259467eca01..a527465e34f377cc509ceb20663035ba1d6f3d51 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs @@ -130,6 +130,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Gearbox = { PowerRequest = delta }, DeltaDragLoad = delta, DeltaFullLoad = delta, + DeltaFullLoadTorque = outTorque, + DeltaDragLoadTorque = outTorque, Clutch = { PowerRequest = delta, OutputSpeed = outAngularVelocity @@ -174,7 +176,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl NewtonMeter torqueIn; PerSecond angularVelocityIn; - var startClutch = DataBus.VehicleInfo.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0, 1e-3) || (outAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineSpeed) && !DataBus.EngineInfo.EngineOn); // || (PreviousState.ClutchLoss.IsEqual(0) && outAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineIdleSpeed)); + var startClutch = DataBus.VehicleInfo.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0, 1e-3) || (outAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineSpeed, 1e-3) && !DataBus.EngineInfo.EngineOn); // || (PreviousState.ClutchLoss.IsEqual(0) && outAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineIdleSpeed)); var slippingClutchWhenDriving = (DataBus.GearboxInfo.Gear.Gear <= 2 && DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Braking); var slippingClutchDuringBraking = DataBus.GearboxInfo.Gear.Gear == 1 && DataBus.DriverInfo.DriverBehavior == DrivingBehavior.Braking && outTorque > 0 && DataBus.Brakes.BrakePower.IsEqual(0); //var slippingClutchWhenDriving = (DataBus.Gear == 1 && outTorque > 0); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index aec5830468ec67833333914f5c6ff03030031588..7b87a8c5d8f1db901cc5316166427c11ddebfb1c 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -197,18 +197,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var avgEngineSpeed = GetEngineSpeed(angularVelocity); var engineSpeedLimit = GetEngineSpeedLimit(absTime); - if (!dryRun && !angularVelocity.IsSmallerOrEqual(engineSpeedLimit)) { - if (DataBus.HybridControllerInfo?.ICESpeed != null && DataBus.HybridControllerInfo.ICESpeed != angularVelocity) { - return new ResponseInvalidOperatingPoint(this); - } - return new ResponseEngineSpeedTooHigh(this) { - DeltaEngineSpeed = avgEngineSpeed - engineSpeedLimit, - Engine = { - EngineSpeed = angularVelocity - } - }; - } - + var fullDragTorque = ModelData.FullLoadCurves[DataBus.GearboxInfo.Gear.Gear].DragLoadStationaryTorque(avgEngineSpeed); var stationaryFullLoadTorque = ModelData.FullLoadCurves[DataBus.GearboxInfo.Gear.Gear].FullLoadStationaryTorque(avgEngineSpeed); var dynamicFullLoadPower = ComputeFullLoadPower(avgEngineSpeed, stationaryFullLoadTorque, dt, dryRun); @@ -236,12 +225,56 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var deltaFull = totalTorqueDemand - dynamicFullLoadTorque; //ComputeDelta(torqueOut, totalTorqueDemand, dynamicFullLoadTorque, gearboxFullLoad, true); var deltaDrag = totalTorqueDemand - fullDragTorque; //ComputeDelta(torqueOut, totalTorqueDemand, fullDragTorque, - //gearboxFullLoad != null ? -gearboxFullLoad : null, false); + //gearboxFullLoad != null ? -gearboxFullLoad : null, false); + + if (!dryRun && !angularVelocity.IsSmallerOrEqual(engineSpeedLimit)) { + if (DataBus.HybridControllerInfo?.ICESpeed != null && DataBus.HybridControllerInfo.ICESpeed != angularVelocity) { + return new ResponseInvalidOperatingPoint(this); + } + return new ResponseEngineSpeedTooHigh(this) { + DeltaEngineSpeed = avgEngineSpeed - engineSpeedLimit, + Engine = { + EngineSpeed = angularVelocity, + PowerRequest = torqueOut * avgEngineSpeed, + TorqueOutDemand = torqueOut, + TotalTorqueDemand = totalTorqueDemand, + DynamicFullLoadPower = dynamicFullLoadPower, + DynamicFullLoadTorque = dynamicFullLoadTorque, + StationaryFullLoadTorque = stationaryFullLoadTorque, + DragPower = fullDragTorque * avgEngineSpeed, + DragTorque = fullDragTorque, + AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, + } + }; + } + + if (!dryRun && !angularVelocity.IsSmallerOrEqual(engineSpeedLimit)) { + if (DataBus.HybridControllerInfo?.ICESpeed != null && DataBus.HybridControllerInfo.ICESpeed != angularVelocity) { + return new ResponseInvalidOperatingPoint(this); + } + return new ResponseEngineSpeedTooHigh(this) { + DeltaEngineSpeed = avgEngineSpeed - engineSpeedLimit, + Engine = { + EngineSpeed = angularVelocity, + PowerRequest = torqueOut * avgEngineSpeed, + TorqueOutDemand = torqueOut, + TotalTorqueDemand = totalTorqueDemand, + DynamicFullLoadPower = dynamicFullLoadPower, + DynamicFullLoadTorque = dynamicFullLoadTorque, + StationaryFullLoadTorque = stationaryFullLoadTorque, + DragPower = fullDragTorque * avgEngineSpeed, + DragTorque = fullDragTorque, + AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, + } + }; + } if (dryRun) { return new ResponseDryRun(this) { DeltaFullLoad = deltaFull * avgEngineSpeed, DeltaDragLoad = deltaDrag * avgEngineSpeed, + DeltaFullLoadTorque = deltaFull, + DeltaDragLoadTorque = deltaDrag, DeltaEngineSpeed = angularVelocity - engineSpeedLimit, Engine = { EngineSpeed = angularVelocity, diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs index 1611ec956f6d40ecd020d020f0e96ccc71be6645..e184f90af05ff405a783a10f4121143ea163f9d3 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs @@ -320,6 +320,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl }, DeltaDragLoad = outTorque * avgOutAngularVelocity, DeltaFullLoad = outTorque * avgOutAngularVelocity, + DeltaFullLoadTorque = outTorque, + DeltaDragLoadTorque = outTorque, + }; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs index 2452ba4e73033ce2f11c1d0b702e0ca6be6163fa..02d0ed555b320581b21e1faa1e4129c43ec2a1df 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs @@ -865,6 +865,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } var response = HandleRequestDisengaged(absTime, ds, gradient, velocityWithOverspeed, debug); + if (response is ResponseDrivingCycleDistanceExceeded) { + return response; + } if (!(response is ResponseSuccess) && DataBus.ClutchInfo.ClutchClosed(absTime)) { response = HandleRequestEngaged( absTime, ds, targetVelocity, gradient, prohibitOverspeed, velocityWithOverspeed, debug); @@ -925,7 +928,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl debug.Add(new { action = "first:(Underload & Overspeed)-> Coast", second }); second = HandleCoastAfterUnderloadWithOverspeed(absTime, ds, gradient, velocityWithOverspeed, debug, second); } else { - second = Driver.DrivingActionBrake(absTime, ds, velocityWithOverspeed, gradient); + second = Driver.DrivingActionBrake(absTime, ds, velocityWithOverspeed, gradient, + overrideAction: DataBus.GearboxInfo.GearboxType.AutomaticTransmission() + ? DrivingAction.Accelerate + : (DrivingAction?)null); debug.Add(new { action = "first:(Underload & !Overspeed) -> Brake", second }); } }) @@ -1097,7 +1103,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient, bool prohibitOverspeed = false) { - if (DataBus.VehicleInfo.VehicleSpeed <= DriverStrategy.BrakeTrigger.NextTargetSpeed && !DataBus.VehicleInfo.VehicleStopped) { + if (DataBus.VehicleInfo.VehicleSpeed.IsSmallerOrEqual(DriverStrategy.BrakeTrigger.NextTargetSpeed) && !DataBus.VehicleInfo.VehicleStopped) { var retVal = HandleTargetspeedReached(absTime, ds, targetVelocity, gradient); for (var i = 0; i < 3 && retVal == null; i++) { retVal = HandleTargetspeedReached(absTime, ds, targetVelocity, gradient); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs index 6ff1f6bc7971fc6ede31e8f5ceb9ce7c173c3db8..905ffc56dfb3bc908843b01e38886cf7f3e3ab74 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -440,6 +440,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl searchedOperatingPoint = SetTCOperatingPointATGbxCoastOrRoll(absTime, gradient, requestedOperatingPoint, initialResponse as ResponseDryRun); } + if (searchedOperatingPoint == null) { + searchedOperatingPoint = SearchOperatingPoint( + absTime, requestedOperatingPoint.SimulationDistance, + gradient, + requestedOperatingPoint.Acceleration, initialResponse, coastingOrRoll: true, allowDistanceDecrease: true); + if (searchedOperatingPoint == null) { + throw new NotImplementedException(); + } + + if (searchedOperatingPoint.SimulationDistance.IsSmaller(ds)) { + return new ResponseDrivingCycleDistanceExceeded(this) { + MaxDistance = searchedOperatingPoint.SimulationDistance + }; + } + } + if (!ds.IsEqual(searchedOperatingPoint.SimulationDistance)) { // vehicle is at low speed, coasting would lead to stop before ds is reached: reduce simulated distance to stop distance. Log.Debug( @@ -508,6 +524,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private OperatingPoint SetTCOperatingPointATGbxCoastOrRoll(Second absTime, Radian gradient, OperatingPoint operatingPoint, ResponseDryRun dryRunResp) { var tc = DataBus.TorqueConverterCtl; + var tcInfo = DataBus.TorqueConverterInfo; if (tc == null) { throw new VectoException("NO TorqueConverter Available!"); } @@ -522,7 +539,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // if ICE torque is within valid range, search an acceleration that results in the required // out-torque at the torque converter var engineSpeed = DataBus.EngineInfo.EngineIdleSpeed * 1.01; - var tcOp = EstimateTCOpPoint(operatingPoint, dryRunResp, engineSpeed, tc); + var tcOp = EstimateTCOpPoint(operatingPoint, dryRunResp, engineSpeed, tcInfo); if (tcOp.Item1.Item2.IsBetween(tcOp.Item2, tcOp.Item3)) { if (!dryRunResp.TorqueConverter.TorqueConverterOperatingPoint.OutTorque.IsEqual(tcOp.Item1.Item1.OutTorque)) { @@ -539,7 +556,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // try again without changing the engine speed to 'spare' inertia torque engineSpeed = DataBus.EngineInfo.EngineSpeed; - tcOp = EstimateTCOpPoint(operatingPoint, dryRunResp, engineSpeed, tc); + tcOp = EstimateTCOpPoint(operatingPoint, dryRunResp, engineSpeed, tcInfo); if (tcOp.Item1.Item2.IsBetween(tcOp.Item2, tcOp.Item3)) { if (!dryRunResp.TorqueConverter.TorqueConverterOperatingPoint.OutTorque.IsEqual(tcOp.Item1.Item1.OutTorque)) { @@ -565,7 +582,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var t = (Tuple<Tuple<TorqueConverterOperatingPoint, NewtonMeter>, NewtonMeter, NewtonMeter>)tOp; return GetTCDelta(t.Item1, t.Item2, t.Item3); }, - evaluateFunction: engSpeed => { return EstimateTCOpPoint(operatingPoint, dryRunResp, engSpeed, tc); }, + evaluateFunction: engSpeed => { return EstimateTCOpPoint(operatingPoint, dryRunResp, engSpeed, tcInfo); }, criterion: tOp => { var t = (Tuple<Tuple<TorqueConverterOperatingPoint, NewtonMeter>, NewtonMeter, NewtonMeter>)tOp; return GetTCDelta(t.Item1, t.Item2, t.Item3).Value(); @@ -587,7 +604,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // a suitable engine sped was found - search acceleration to match TC out-torque try { - tcOp = EstimateTCOpPoint(operatingPoint, dryRunResp, nextICESpeed, tc); + tcOp = EstimateTCOpPoint(operatingPoint, dryRunResp, nextICESpeed, tcInfo); tc.SetOperatingPoint = tcOp.Item1.Item1; var acceleration = SearchAccelerationFixedTC(absTime, gradient, operatingPoint, tcOp.Item1, dryRunResp); @@ -604,7 +621,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // estimate a torque converter operating point via forward calculation for a certain engine speed. // furthermore, estimates the max/min torque at ICE out-shaft including estimates for ICE inertia & aux torque private Tuple<Tuple<TorqueConverterOperatingPoint, NewtonMeter>, NewtonMeter, NewtonMeter> EstimateTCOpPoint( - OperatingPoint operatingPoint, IResponse response, PerSecond engSpeed, ITorqueConverterControl tc) + OperatingPoint operatingPoint, IResponse response, PerSecond engSpeed, ITorqueConverterInfo tc) { var avgICDSpeed = (DataBus.EngineInfo.EngineSpeed + engSpeed) / 2.0; var drTq = (DataBus.EngineInfo.EngineDragPower(avgICDSpeed)) / avgICDSpeed; @@ -872,7 +889,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl operatingPoint.SimulationInterval) / avgEngineSpeed; var auxTqDemand = DataBus.EngineInfo.EngineAuxDemand(avgEngineSpeed, operatingPoint.SimulationInterval) / avgEngineSpeed; //var maxTorque = DataBus.e - var tcOp = tc.CalculateOperatingPoint(DataBus.EngineInfo.EngineIdleSpeed * 1.01, response.Gearbox.InputSpeed); + var tcOp = DataBus.TorqueConverterInfo.CalculateOperatingPoint(DataBus.EngineInfo.EngineIdleSpeed * 1.01, response.Gearbox.InputSpeed); if (!tcOp.Item2.IsBetween(dragTorque - inertiaTq - auxTqDemand, maxTorque - inertiaTq - auxTqDemand)) { @@ -1051,7 +1068,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } protected OperatingPoint SearchOperatingPoint(Second absTime, Meter ds, Radian gradient, - MeterPerSquareSecond acceleration, IResponse initialResponse, bool coastingOrRoll = false) + MeterPerSquareSecond acceleration, IResponse initialResponse, bool coastingOrRoll = false, bool allowDistanceDecrease = false) { IterationStatistics.Increment(this, "SearchOperatingPoint", 0); @@ -1123,7 +1140,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (nanCount > 10) { return true; } - return r != null && !actionRoll && !ds.IsEqual(r.Driver.OperatingPoint.SimulationDistance); + return r != null && !actionRoll && !allowDistanceDecrease && !ds.IsEqual(r.Driver.OperatingPoint.SimulationDistance); }); return ComputeTimeInterval(retVal.Acceleration, retVal.SimulationDistance); } catch (VectoSearchAbortedException) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs index 2cebd5bfbd536e5e2359e0524e3ec2e39d7c9287..3a8eaced7dff66cab21239a53d29636f512670b5 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs @@ -28,7 +28,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected internal Joule ThermalBuffer = 0.SI<Joule>(); protected internal bool DeRatingActive = false; - + public Joule OverloadBuffer { get; } public NewtonMeter ContinuousTorque { get; } @@ -51,6 +51,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl .ElectricalPower; var peakPwrLoss = -peakElPwr + ModelData.ContinuousPowerSpeed * maxTqDrive; // losses need to be positive OverloadBuffer = (peakPwrLoss - ContinuousPowerLoss) * ModelData.OverloadTime; + if (OverloadBuffer.IsSmallerOrEqual(0) && !(container is SimplePowertrainContainer)) { + Log.Error("Overload buffer for thermal de-rating is negative! Please check electric motor data!"); + } } public PowertrainPosition Position { get; } @@ -154,10 +157,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var emTorque = emTorqueDt == null ? null : ConvertDrivetrainTorqueToEm(emTorqueDt); var emOff = emTorqueDt == null; - if (!dryRun && emTorqueDt != null && ((emTorque).IsSmaller(maxDriveTorqueEm ?? 0.SI<NewtonMeter>(), 1e-3) || - (emTorque).IsGreater(maxRecuperationTorqueEm ?? 0.SI<NewtonMeter>(), 1e-3))) { + if (!dryRun && !DataBus.IsTestPowertrain && emTorqueDt != null && ((emTorque).IsSmaller(maxDriveTorqueEm ?? 0.SI<NewtonMeter>(), 1e-3) || + (emTorque).IsGreater(maxRecuperationTorqueEm ?? 0.SI<NewtonMeter>(), 1e-3))) { // check if provided EM torque (drivetrain) is valid) - if (DataBus.HybridControllerInfo != null && (!avgDtSpeed.IsEqual(DataBus.HybridControllerInfo.ElectricMotorSpeed(Position)) || + if ((!avgDtSpeed.IsEqual(DataBus.HybridControllerInfo.ElectricMotorSpeed(Position) / ModelData.Ratio) || !dt.IsEqual(DataBus.HybridControllerInfo.SimulationInterval))) { return new ResponseInvalidOperatingPoint(this); } @@ -222,7 +225,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl emTorqueMap = null; } - var electricPower = emOff || (ModelData.DragCurve.Lookup(avgEmSpeed) + inertiaTorqueEm).IsEqual(emTorque) + var electricPower = emOff || (ModelData.DragCurve.Lookup(avgEmSpeed) + inertiaTorqueEm).IsEqual(emTorque, 1e-3.SI<NewtonMeter>()) ? 0.SI<Watt>() : ModelData.EfficiencyMap .LookupElectricPower(avgEmSpeed, emTorqueMap, DataBus.ExecutionMode != ExecutionMode.Declaration) @@ -230,8 +233,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var electricSupplyResponse = ElectricPower.Request(absTime, dt, electricPower, dryRun); - if (!dryRun && !emOff && !(electricSupplyResponse is ElectricSystemResponseSuccess)) { - if (DataBus.HybridControllerInfo != null && !avgEmSpeed.IsEqual(DataBus.HybridControllerInfo.ElectricMotorSpeed(Position))) { + if (!dryRun && !DataBus.IsTestPowertrain && !emOff && !(electricSupplyResponse is ElectricSystemResponseSuccess)) { + if ( !avgEmSpeed.IsEqual(DataBus.HybridControllerInfo.ElectricMotorSpeed(Position) / ModelData.Ratio)) { return new ResponseInvalidOperatingPoint(this); } throw new VectoException( @@ -255,6 +258,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl }, DeltaFullLoad = remainingPower, DeltaDragLoad = remainingPower, + DeltaFullLoadTorque = inTorqueDt, + DeltaDragLoadTorque = inTorqueDt, + }; } else { @@ -292,6 +298,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl retVal.ElectricMotor.MaxDriveTorque = maxDriveTorqueDt; retVal.ElectricMotor.MaxRecuperationTorque = maxRecuperationTorqueDt; retVal.ElectricMotor.AngularVelocity = avgEmSpeed; + + retVal.ElectricMotor.TorqueRequest = outTorque; + retVal.ElectricMotor.InertiaTorque = + avgDtSpeed.IsEqual(0) ? 0.SI<NewtonMeter>() : inertiaTorqueEm * avgEmSpeed / avgDtSpeed; retVal.ElectricMotor.PowerRequest = outTorque * outAngularVelocity; retVal.ElectricMotor.InertiaPowerDemand = inertiaTorqueEm * avgEmSpeed; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineOnlyCombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineOnlyCombustionEngine.cs index dc18cdd9741e03004297eafc8a577fba865430b3..25f5b7ed33373cddf8734457a43ed4125d82724a 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineOnlyCombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineOnlyCombustionEngine.cs @@ -80,7 +80,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (dryRun) { return new ResponseDryRun(this) { DeltaFullLoad = CurrentState.EnginePower - CurrentState.DynamicFullLoadTorque * avgEngineSpeed, - DeltaDragLoad = CurrentState.EnginePower - CurrentState.FullDragTorque * avgEngineSpeed + DeltaDragLoad = CurrentState.EnginePower - CurrentState.FullDragTorque * avgEngineSpeed, + DeltaFullLoadTorque = CurrentState.EngineTorque - CurrentState.DynamicFullLoadTorque, + DeltaDragLoadTorque = CurrentState.EngineTorque - CurrentState.FullDragTorque, }; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index c23d505cf20067b4f93eec3409feaa3428d8bc35..9ab95d269e87a1b4cfe7610a7516028063d10115 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -321,7 +321,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Gear = new GearshiftPosition(0), }, DeltaDragLoad = delta, - DeltaFullLoad = delta + DeltaFullLoad = delta, + DeltaDragLoadTorque = inTorque, + DeltaFullLoadTorque = inTorque, }; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs index 2cfc50a66951661addb73f6ffcc1db2e32d1b3d1..5d2900901b3294d6d68548c6eb5271914ced1191 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs @@ -142,6 +142,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return new ResponseDryRun(this) { DeltaDragLoad = ovl.Delta, DeltaFullLoad = ovl.Delta, + // TODO! delta full/drag torque DeltaEngineSpeed = ovl.DeltaEngineSpeed }; } @@ -163,7 +164,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DataBus.GearboxCtl.TriggerGearshift(absTime, dt); _shiftStrategy.SetNextGear(strategySettings.NextGear); SelectedGear = strategySettings.NextGear; - return new ResponseGearShift(this); + if (!DataBus.GearboxInfo.GearboxType.AutomaticTransmission()) { + return new ResponseGearShift(this); + } } if (!dryRun /*&& DataBus.VehicleInfo.VehicleStopped*/) { @@ -289,9 +292,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } + public void RepeatDrivingAction(Second absTime) + { + Strategy.RepeatDrivingAction(absTime); + } ///======================================================================================= - + public class HybridCtlShiftStrategy : ShiftStrategy { protected HybridController _controller; @@ -496,11 +503,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } - public void RepeatDrivingAction(Second absTime) - { - Strategy.RepeatDrivingAction(absTime); - } - ///======================================================================================= @@ -525,6 +527,57 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _gearbox = myGearbox; } } + + public override GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) + { + if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) { + // AT always starts in first gear and TC active! + _gearbox.Disengaged = true; + return Gears.First(); + } + + foreach (var gear in Gears.Reverse()) { + var response = _gearbox.Initialize(gear, torque, outAngularVelocity); + + if (response.Engine.EngineSpeed > DataBus.EngineInfo.EngineRatedSpeed || response.Engine.EngineSpeed < DataBus.EngineInfo.EngineIdleSpeed) { + continue; + } + + if (!IsBelowDownShiftCurve(gear, response.Engine.PowerRequest / response.Engine.EngineSpeed, response.Engine.EngineSpeed)) { + _gearbox.Disengaged = false; + return gear; + } + } + + // fallback: start with first gear; + _gearbox.Disengaged = false; + return Gears.First(); + } + + protected override bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, + IResponse response) + { + return false; + } + + //public override GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + //{ + // if (_nextGear.AbsTime != null && _nextGear.AbsTime.IsEqual(absTime)) { + // //_gearbox.Gear = _nextGear.Gear; + // _gearbox.Disengaged = _nextGear.Disengaged; + // _nextGear.AbsTime = null; + // return _nextGear.Gear; + // } + + // _nextGear.AbsTime = null; + // return _gearbox.Gear; + //} + + public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + throw new System.NotImplementedException("AT Shift Strategy does not support disengaging."); + } } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs index da3e53ba337d5a57b6cc75f1e0e499e7295edd9b..d1efc09b8f88f172c0a0ffbb21f16ea3c0bff8e1 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs @@ -322,7 +322,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var minFc = results.MinBy(x => x.Item2); - if (minFc.Item2.IsGreater(fcCurrent * shiftStrategyParameters.RatingFactorCurrentGear)) { + var ratingFactor = outTorque < 0 + ? 1 / shiftStrategyParameters.RatingFactorCurrentGear + : shiftStrategyParameters.RatingFactorCurrentGear; + + if (minFc.Item2.IsGreater(fcCurrent * ratingFactor)) { return minFc.Item1; } @@ -511,8 +515,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var fcCurrent = GetFCRating(responseCurrent); var minFc = results.MinBy(x => x.Item2); - - if (minFc.Item2.IsGreater(fcCurrent * shiftStrategyParameters.RatingFactorCurrentGear)) { + + var ratingFactor = outTorque < 0 + ? 1 / shiftStrategyParameters.RatingFactorCurrentGear + : shiftStrategyParameters.RatingFactorCurrentGear; + + + if (minFc.Item2.IsGreater(fcCurrent * ratingFactor)) { return minFc.Item1; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimplePowertrainContainer.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimplePowertrainContainer.cs index c7b1285f75d07a12b70f7f9f8661bed1cca9b50a..ca523806819f30ff811089970def1f36f500c9dd 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimplePowertrainContainer.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimplePowertrainContainer.cs @@ -32,6 +32,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { public override IDriverInfo DriverInfo { get { return base.DriverInfo ?? this; } } + public override bool IsTestPowertrain + { + get { return true; } + } + #region Implementation of IDriverInfo public DrivingBehavior DriverBehavior diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs index 18b79341db5b5f73f02efeff430a5ca5ebed5166..23902397c7ad211cc486f96dc65ac00eabd9e782 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs @@ -46,17 +46,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { protected virtual IResponse HandleEngineOffRequest(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) { - if (!outTorque.IsEqual(0, 1e-3)) { + if (!outTorque.IsEqual(0, 1e-2)) { if (dryRun) { return new ResponseDryRun(this) { DeltaFullLoad = outTorque * ModelData.IdleSpeed, DeltaDragLoad = outTorque * ModelData.IdleSpeed, + DeltaDragLoadTorque = outTorque, + DeltaFullLoadTorque = outTorque, Engine = { TorqueOutDemand = outTorque, TotalTorqueDemand = outTorque, PowerRequest = outTorque * outAngularVelocity, DynamicFullLoadPower = 0.SI<Watt>(), DragPower = 0.SI<Watt>(), + DragTorque = 0.SI<NewtonMeter>(), EngineSpeed = outAngularVelocity, // 0.RPMtoRad(), AuxiliariesPowerDemand = 0.SI<Watt>(), }, @@ -73,6 +76,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { retVal.Engine.PowerRequest = outTorque * outAngularVelocity; retVal.Engine.DynamicFullLoadPower = 0.SI<Watt>(); retVal.Engine.DragPower = 0.SI<Watt>(); + retVal.Engine.DragTorque = 0.SI<NewtonMeter>(); retVal.Engine.EngineSpeed = 0.RPMtoRad(); retVal.Engine.AuxiliariesPowerDemand = 0.SI<Watt>(); return retVal; @@ -93,6 +97,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { return new ResponseDryRun(this) { DeltaFullLoad = 0.SI<Watt>(), DeltaDragLoad = 0.SI<Watt>(), + DeltaDragLoadTorque = 0.SI<NewtonMeter>(), + DeltaFullLoadTorque = 0.SI<NewtonMeter>(), Engine = { TorqueOutDemand = outTorque, PowerRequest = outTorque * outAngularVelocity, diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs index e839aec156019109d5e5cf0ee43e9d0e7e90b9b7..79f867702f8f33a5a1296551cb422323a6339d66 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs @@ -52,12 +52,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public Watt MaxDischargePower(Second dt) { + var maxPower = -InternalVoltage / (4 * ModelData.InternalResistance) * InternalVoltage; + var maxPowerCurrent = maxPower / InternalVoltage; var maxDischargeCurrent = VectoMath.Max((ModelData.Capacity * ModelData.MinVoltage - PreviousState.Charge) / dt, ModelData.MaxCurrentDischarge); + maxDischargeCurrent = VectoMath.Max(maxDischargeCurrent, maxPowerCurrent); var maxDischargePower = InternalVoltage * maxDischargeCurrent + maxDischargeCurrent * ModelData.InternalResistance * maxDischargeCurrent; - var maxPower = -InternalVoltage / (4 * ModelData.InternalResistance) * InternalVoltage; return VectoMath.Max(maxDischargePower, maxPower); } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs index 63eaadaad42708513fab116dfcd08dc07df57f7d..dd112987a45197921d7d47be89f0030c18ded683 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs @@ -33,6 +33,7 @@ using System; using System.Collections.Generic; using System.Linq; using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Configuration; @@ -47,7 +48,7 @@ using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { public class TorqueConverter : StatefulVectoSimulationComponent<TorqueConverter.TorqueConverterComponentState>, - ITnInPort, ITnOutPort, ITorqueConverterControl + ITnInPort, ITnOutPort, ITorqueConverter { protected readonly IGearboxInfo Gearbox; protected readonly IShiftStrategy ShiftStrategy; @@ -174,6 +175,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return new ResponseDryRun(this) { DeltaFullLoad = delta, DeltaDragLoad = delta, + DeltaDragLoadTorque = outTorque - operatingPoint.OutTorque, + DeltaFullLoadTorque = outTorque - operatingPoint.OutTorque, + DeltaEngineSpeed = operatingPoint.InAngularVelocity - maxEngineSpeed, TorqueConverter = { TorqueConverterOperatingPoint = operatingPoint}, Engine = { @@ -205,6 +209,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return new ResponseDryRun(this) { DeltaFullLoad = 10 * deltaMax, DeltaDragLoad = 10 * deltaMin, + // TODO! delta full/drag torque DeltaEngineSpeed = dryOperatingPointMax.InAngularVelocity - maxEngineSpeed, TorqueConverter = { TorqueConverterOperatingPoint = dryOperatingPointMax}, Engine = { @@ -221,8 +226,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ResponseDryRun engineResponse, Watt previousPower) { try { + var emPower = DataBus.ElectricMotorInfo(PowertrainPosition.HybridP1) == null + ? 0.SI<Watt>() + : engineResponse.ElectricMotor.ElectricMotorPowerMech; var operatingPoint = ModelData.FindOperatingPointForPowerDemand( - engineResponse.Engine.DragPower - engineResponse.Engine.AuxiliariesPowerDemand, + engineResponse.Engine.DragPower - engineResponse.Engine.AuxiliariesPowerDemand - emPower, DataBus.EngineInfo.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower); var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineInfo.EngineN95hSpeed); var lowerInputSpeed = DataBus.EngineInfo.EngineIdleSpeed * 1.001; // VectoMath.Max(DataBus.EngineIdleSpeed * 1.001, 0.8 * DataBus.EngineSpeed); @@ -255,10 +263,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl absTime, dt, outAngularVelocity, engineSpeed, x => x.DeltaDragLoad.IsGreater(0), x => VectoMath.Abs(DataBus.EngineInfo.EngineSpeed - x.Engine.EngineSpeed).Value()); - if (retVal != null) - retVal.Creeping = true; + if (retVal != null) { + retVal.Creeping = true; + } + return retVal; - } + } } @@ -268,8 +278,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ResponseDryRun engineResponse, Watt previousPower) { try { + var emPower = DataBus.ElectricMotorInfo(PowertrainPosition.HybridP1) == null + ? 0.SI<Watt>() + : engineResponse.ElectricMotor.ElectricMotorPowerMech; var operatingPoint = ModelData.FindOperatingPointForPowerDemand( - (engineResponse.Engine.DynamicFullLoadPower - engineResponse.Engine.AuxiliariesPowerDemand), + (engineResponse.Engine.DynamicFullLoadPower - engineResponse.Engine.AuxiliariesPowerDemand - emPower), DataBus.EngineInfo.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower); var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineInfo.EngineN95hSpeed); if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/VTPCombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VTPCombustionEngine.cs index da5a665e21d9a1621d6e858fc5171089cc670adc..a239827b159be0170b9b080fe2cf3f0cd9cf4536 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/VTPCombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VTPCombustionEngine.cs @@ -112,6 +112,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return new ResponseDryRun(this) { DeltaFullLoad = deltaFull * avgEngineSpeed, DeltaDragLoad = deltaDrag * avgEngineSpeed, + DeltaDragLoadTorque = deltaDrag, + DeltaFullLoadTorque = deltaFull, DeltaEngineSpeed = 0.RPMtoRad(), Engine = { PowerRequest = torqueOut * avgEngineSpeed, diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs index e05f8ef8b7a2d3645c1967944dfb1ed8b79df0d6..0686ff64a4b3aefbf2ed5f0b2b7432b8de6949dd 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs @@ -45,7 +45,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies testContainer, -grad, grad, 2); } - protected override ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition nextGear, HybridStrategyResponse cfg) + protected override IResponse RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition nextGear, HybridStrategyResponse cfg) { TestPowertrain.Gearbox.Gear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear; TestPowertrain.Gearbox.Disengaged = !nextGear.Engaged; @@ -57,6 +57,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies TestPowertrain.Battery?.Initialize(DataBus.BatteryInfo.StateOfCharge); TestPowertrain.SuperCap?.Initialize(DataBus.BatteryInfo.StateOfCharge); + TestPowertrain.Brakes.BrakePower = DataBus.Brakes.BrakePower; + var currentGear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear; if (nextGear.Engaged && !nextGear.Equals(currentGear)) { @@ -114,6 +116,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies TestPowertrain.Clutch.PreviousState.InAngularVelocity = (DataBus.ClutchInfo as SwitchableClutch).PreviousState.InAngularVelocity; + TestPowertrain.Clutch.PreviousState.OutAngularVelocity = + (DataBus.ClutchInfo as SwitchableClutch).PreviousState.OutAngularVelocity; //} @@ -123,18 +127,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies TestPowertrain.ElectricMotor.DeRatingActive = (DataBus.ElectricMotorInfo(pos) as ElectricMotor).DeRatingActive; - if (/*nextGear != DataBus.GearboxInfo.Gear && */TestPowertrain.ElectricMotorP2 != null) { - TestPowertrain.ElectricMotorP2.PreviousState.EMSpeed = - DataBus.ElectricMotorInfo(PowertrainPosition.HybridP2).ElectricMotorSpeed; - } - if (/*nextGear != DataBus.GearboxInfo.Gear && */TestPowertrain.ElectricMotorP3 != null) { - TestPowertrain.ElectricMotorP3.PreviousState.EMSpeed = - DataBus.ElectricMotorInfo(PowertrainPosition.HybridP3).ElectricMotorSpeed; + foreach (var emPos in TestPowertrain.ElectricMotorsUpstreamTransmission.Keys) { + TestPowertrain.ElectricMotorsUpstreamTransmission[pos].PreviousState.EMSpeed = + DataBus.ElectricMotorInfo(emPos).ElectricMotorSpeed; } var retVal = TestPowertrain.HybridController.NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, true); - return retVal as ResponseDryRun; + return retVal; } } @@ -153,7 +153,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies } - protected override ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + protected override IResponse RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition nextGear, HybridStrategyResponse cfg) { TestPowertrain.Gearbox.Gear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear; @@ -162,13 +162,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies TestPowertrain.Container.VehiclePort.Initialize(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); TestPowertrain.HybridController.ApplyStrategySettings(cfg); TestPowertrain.HybridController.Initialize(Controller.PreviousState.OutTorque, Controller.PreviousState.OutAngularVelocity); - TestPowertrain.Clutch.Initialize(DataBus.ClutchInfo.ClutchLosses); + // TestPowertrain.Clutch.Initialize(DataBus.ClutchInfo.ClutchLosses); + TestPowertrain.Battery?.Initialize(DataBus.BatteryInfo.StateOfCharge); TestPowertrain.SuperCap?.Initialize(DataBus.BatteryInfo.StateOfCharge); + TestPowertrain.Brakes.BrakePower = DataBus.Brakes.BrakePower; + var currentGear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear; - if (nextGear.Engaged && nextGear.Equals(currentGear)) { + if (nextGear.Engaged && !nextGear.Equals(currentGear)) { if (!AllowEmergencyShift && ModelData.GearboxData.Gears[nextGear.Gear].Ratio > ModelData.GearshiftParameters.RatioEarlyUpshiftFC) { return null; } @@ -177,21 +180,39 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return null; } - var estimatedVelocityPostShift = VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); - if (!AllowEmergencyShift && !estimatedVelocityPostShift.IsGreater(DeclarationData.GearboxTCU.MIN_SPEED_AFTER_TRACTION_INTERRUPTION)) { + var vDrop = DataBus.DriverInfo.DriverAcceleration * ModelData.GearshiftParameters.ATLookAheadTime; + var vehicleSpeedPostShift = (DataBus.VehicleInfo.VehicleSpeed + vDrop * ModelData.GearshiftParameters.VelocityDropFactor).LimitTo( + 0.KMPHtoMeterPerSecond(), DataBus.DrivingCycleInfo.CycleData.LeftSample.VehicleTargetSpeed); + + //var estimatedVelocityPostShift = VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); + //if (!AllowEmergencyShift && !estimatedVelocityPostShift.IsGreater(DeclarationData.GearboxTCU.MIN_SPEED_AFTER_TRACTION_INTERRUPTION)) { + // return null; + //} + var inAngularVelocity = ModelData.GearboxData.Gears[nextGear.Gear].Ratio * outAngularVelocity; + + if (inAngularVelocity.IsEqual(0)) { return null; } + var totalTransmissionRatio = inAngularVelocity / (DataBus.VehicleInfo.VehicleSpeed + DataBus.DriverInfo.DriverAcceleration * dt); + var estimatedEngineSpeed = (vehicleSpeedPostShift * totalTransmissionRatio).Cast<PerSecond>(); + if (estimatedEngineSpeed.IsSmaller(ModelData.GearshiftParameters.MinEngineSpeedPostUpshift)) { + return null; + } - var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift; - var vehicleSpeedPostShift = estimatedVelocityPostShift; // DataBus.VehicleInfo.VehicleSpeed - vDrop * ModelData.GearshiftParameters.VelocityDropFactor; + //var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift; + //var vehicleSpeedPostShift = estimatedVelocityPostShift; // DataBus.VehicleInfo.VehicleSpeed - vDrop * ModelData.GearshiftParameters.VelocityDropFactor; TestPowertrain.Gearbox.Gear = nextGear; + TestPowertrain.Gearbox.RequestAfterGearshift = true; var init = TestPowertrain.Container.VehiclePort.Initialize( vehicleSpeedPostShift, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); if (!AllowEmergencyShift && init.Engine.EngineSpeed.IsSmaller(ModelData.EngineData.IdleSpeed)) { return null; } + } else { + TestPowertrain.Gearbox.RequestAfterGearshift = (DataBus.GearboxInfo as ATGearbox).RequestAfterGearshift; } + //TestPowertrain.Gearbox.ShiftToLocked = (DataBus.GearboxInfo as ATGearbox).ShiftToLocked; if (!nextGear.Engaged) { //TestPowertrain.Gearbox._nextGear = Controller.ShiftStrategy.NextGear; @@ -218,11 +239,32 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies (TestPowertrain.CombustionEngine.EngineAux as EngineAuxiliary).PreviousState.AngularSpeed = ((DataBus.EngineInfo as CombustionEngine).EngineAux as EngineAuxiliary).PreviousState.AngularSpeed; + TestPowertrain.Gearbox.PreviousState.OutAngularVelocity = + (DataBus.GearboxInfo as ATGearbox).PreviousState.OutAngularVelocity; TestPowertrain.Gearbox.PreviousState.InAngularVelocity = - (DataBus.GearboxInfo as Gearbox).PreviousState.InAngularVelocity; - - TestPowertrain.Clutch.PreviousState.InAngularVelocity = - (DataBus.ClutchInfo as SwitchableClutch).PreviousState.InAngularVelocity; + (DataBus.GearboxInfo as ATGearbox).PreviousState.InAngularVelocity; + TestPowertrain.Gearbox._powershiftLossEnergy = + (DataBus.GearboxInfo as ATGearbox)._powershiftLossEnergy; + TestPowertrain.Gearbox.PreviousState.PowershiftLossEnergy = + (DataBus.GearboxInfo as ATGearbox).PreviousState.PowershiftLossEnergy; + TestPowertrain.Gearbox.LastShift = + (DataBus.GearboxInfo as ATGearbox).LastShift; + TestPowertrain.Gearbox.PreviousState.Gear = + (DataBus.GearboxInfo as ATGearbox).PreviousState.Gear; + + if (nextGear.TorqueConverterLocked.HasValue && !nextGear.TorqueConverterLocked.Value) { + TestPowertrain.TorqueConverter.PreviousState.InAngularVelocity = + (DataBus.TorqueConverterInfo as TorqueConverter).PreviousState.InAngularVelocity; + TestPowertrain.TorqueConverter.PreviousState.InTorque = + (DataBus.TorqueConverterInfo as TorqueConverter).PreviousState.InTorque; + TestPowertrain.TorqueConverter.PreviousState.OutAngularVelocity = + (DataBus.TorqueConverterInfo as TorqueConverter).PreviousState.OutAngularVelocity; + TestPowertrain.TorqueConverter.PreviousState.IgnitionOn = + (DataBus.TorqueConverterInfo as TorqueConverter).PreviousState.IgnitionOn; + } + + //TestPowertrain.Clutch.PreviousState.InAngularVelocity = + // (DataBus.ClutchInfo as SwitchableClutch).PreviousState.InAngularVelocity; //} @@ -232,24 +274,30 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies TestPowertrain.ElectricMotor.DeRatingActive = (DataBus.ElectricMotorInfo(pos) as ElectricMotor).DeRatingActive; - if (/*nextGear != DataBus.GearboxInfo.Gear && */TestPowertrain.ElectricMotorP2 != null) { - TestPowertrain.ElectricMotorP2.PreviousState.EMSpeed = - DataBus.ElectricMotorInfo(PowertrainPosition.HybridP2).ElectricMotorSpeed; - } - if (/*nextGear != DataBus.GearboxInfo.Gear && */TestPowertrain.ElectricMotorP3 != null) { - TestPowertrain.ElectricMotorP3.PreviousState.EMSpeed = - DataBus.ElectricMotorInfo(PowertrainPosition.HybridP3).ElectricMotorSpeed; + foreach (var emPos in TestPowertrain.ElectricMotorsUpstreamTransmission.Keys) { + TestPowertrain.ElectricMotorsUpstreamTransmission[pos].PreviousState.EMSpeed = + DataBus.ElectricMotorInfo(emPos).ElectricMotorSpeed; } - var retVal = TestPowertrain.HybridController.NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, true); + try { + var retVal = TestPowertrain.HybridController.NextComponent.Request(absTime, dt, outTorque, + outAngularVelocity, false); + + if (retVal.Source is TorqueConverter) { + return null; + } - return retVal as ResponseDryRun; + return retVal; + } catch (Exception e) { + Log.Debug(e); + return null; + } } } // ===================================================== - public abstract class AbstractHybridStrategy<T> : LoggingObject, IHybridControlStrategy where T: class, IHybridControlledGearbox + public abstract class AbstractHybridStrategy<T> : LoggingObject, IHybridControlStrategy where T: class, IHybridControlledGearbox, IGearbox { public class StrategyState @@ -259,7 +307,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies public List<HybridResultEntry> Evaluations; public HybridResultEntry Solution { get; set; } - public bool GearboxEngaged; + public bool GearboxEngaged { get; set; } public Second ICEStartTStmp { get; set; } @@ -268,15 +316,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies public class DryRunSolutionState { - public DryRunSolutionState(DrivingAction drivingAction, HybridResultEntry setting) + public DryRunSolutionState(DrivingAction drivingAction, HybridResultEntry setting, + List<HybridResultEntry> hybridResultEntries) { DrivingAction = drivingAction; Solution = setting; + EvaluatedConfigs = hybridResultEntries; } - public DrivingAction DrivingAction { get; set; } - public HybridResultEntry Solution { get; set; } + public DrivingAction DrivingAction { get; } + + public HybridResultEntry Solution { get; } + + public List<HybridResultEntry> EvaluatedConfigs { get; } } protected VectoRunData ModelData; @@ -303,7 +356,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies protected DebugData DebugData = new DebugData(); protected WattSecond BatteryDischargeEnergyThreshold; - protected DryRunSolutionState DryRunSolution; + protected DryRunSolutionState DryRunSolution { get; set; } protected readonly GearList GearList; @@ -396,7 +449,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies DryRunSolution = null; } - if (DryRunSolution != null && DryRunSolution.DrivingAction == DataBus.DriverInfo.DrivingAction) { + var oldDryRunSolution = DryRunSolution; + if (!dryRun && DryRunSolution != null && !DryRunSolution.Solution.IgnoreReason.AllOK()) { + DryRunSolution = null; + } + + if (dryRun && DryRunSolution != null && DryRunSolution.DrivingAction == DataBus.DriverInfo.DrivingAction) { var tmp = CreateResponse(DryRunSolution.Solution, currentGear); return tmp; } @@ -428,14 +486,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies eval.Add(MaxRecuperationSetting(absTime, dt, outTorque, outAngularVelocity, dryRun)); } - //var origBest = SelectBestOption_ORIG(eval, absTime, dt, outTorque, outAngularVelocity, dryRun, currentGear); var best = SelectBestOption(eval, absTime, dt, outTorque, outAngularVelocity, dryRun, currentGear); - - //if (!best.IsEqual(origBest)) { - // Log.Debug("best: {0}, origBest: {1}", best.ToString(), origBest.ToString()); - //} - //best.SimulationInterval = dt; + if (best == null && oldDryRunSolution != null) { + best = oldDryRunSolution.Solution; + } + + if (oldDryRunSolution != null && best != null && best.IgnoreReason.Evaluated() && !best.IgnoreReason.AllOK()) { + //throw new NotImplementedException("hmmm"); + Log.Info("found better solution..."); + best = oldDryRunSolution.Solution; + } + + if (best == null) { + best = ResponseEmOff; + best.ICEOff = false; + } + var retVal = CreateResponse(best, currentGear); retVal.GearboxEngaged = DataBus.GearboxInfo.GearEngaged(absTime); @@ -449,15 +516,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies CurrentState.Solution = best; CurrentState.AngularVelocity = outAngularVelocity; CurrentState.Evaluations = eval; - CurrentState.GearboxEngaged = DataBus.GearboxInfo.GearEngaged(absTime); + CurrentState.GearboxEngaged = DataBus.GearboxInfo.GearEngaged(absTime) || DataBus.GearboxInfo.GearboxType.AutomaticTransmission(); if (!DataBus.EngineCtl.CombustionEngineOn && !best.ICEOff && !retVal.ShiftRequired) { CurrentState.ICEStartTStmp = absTime; } else { CurrentState.ICEStartTStmp = PreviousState.ICEStartTStmp; } - DryRunSolution = new DryRunSolutionState(DataBus.DriverInfo.DrivingAction, best); } - + + DryRunSolution = new DryRunSolutionState(DataBus.DriverInfo.DrivingAction, best, eval); + if (retVal.ShiftRequired) { DryRunSolution = null; CurrentState.GearshiftTriggerTstmp = absTime; @@ -500,7 +568,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies DryRunSolution = null; } - protected abstract ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, + protected abstract IResponse RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition nextGear, HybridStrategyResponse cfg); private IHybridStrategyResponse HandleRequestExceedsMaxPower(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) @@ -530,32 +598,47 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies }; var maxEmDriveResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, currentGear, maxEmDriveSetting); - if (maxEmDriveResponse.DeltaFullLoad.IsSmallerOrEqual(0)) { + var deltaFullLoadTq = (maxEmDriveResponse.Engine.TotalTorqueDemand - + maxEmDriveResponse.Engine.DynamicFullLoadTorque); + var maxEngineSpeed = + maxEmDriveResponse.Gearbox.Gear.Gear == 0 || !DataBus.ClutchInfo.ClutchClosed(absTime) || + !DataBus.GearboxInfo.TCLocked + ? ModelData.EngineData.FullLoadCurves[0].N95hSpeed : + VectoMath.Min(DataBus.GearboxInfo.GetGearData(DataBus.GearboxInfo.Gear.Gear).MaxSpeed, ModelData.EngineData.FullLoadCurves[0].N95hSpeed); + + if (deltaFullLoadTq.IsSmallerOrEqual(0)) { + return new HybridStrategyLimitedResponse() { Delta = outTorque * outAngularVelocity - StrategyParameters.MaxDrivetrainPower, - DeltaEngineSpeed = maxEmDriveResponse.DeltaEngineSpeed + DeltaEngineSpeed = maxEmDriveResponse.Engine.EngineSpeed - maxEngineSpeed, // .DeltaEngineSpeed }; } - var maxTorque = SearchAlgorithm.Search(outTorque, maxEmDriveResponse.DeltaFullLoad, -outTorque * 0.1, + var avgEngineSpeed = (maxEmDriveResponse.Engine.EngineSpeed + DataBus.EngineInfo.EngineSpeed) / 2; + var maxTorque = SearchAlgorithm.Search(outTorque, deltaFullLoadTq * avgEngineSpeed, -outTorque * 0.1, getYValue: resp => { - var r = resp as ResponseDryRun; - return r.DeltaFullLoad; + var r = resp as IResponse; + var deltaMaxTq = (r.Engine.TotalTorqueDemand - + r.Engine.DynamicFullLoadTorque); + return deltaMaxTq * avgEngineSpeed; }, evaluateFunction: x => { return RequestDryRun(absTime, dt, x, outAngularVelocity, currentGear, maxEmDriveSetting); }, criterion: resp => { - var r = resp as ResponseDryRun; - return r.DeltaFullLoad.Value(); + var r = resp as IResponse; + var deltaMaxTq = (r.Engine.TotalTorqueDemand - + r.Engine.DynamicFullLoadTorque); + return (deltaMaxTq * avgEngineSpeed).Value(); }); var delta = outTorque * outAngularVelocity - StrategyParameters.MaxDrivetrainPower; if ((maxTorque * outAngularVelocity).IsSmaller(StrategyParameters.MaxDrivetrainPower)) { delta = (outTorque - maxTorque) * outAngularVelocity; } + return new HybridStrategyLimitedResponse() { Delta = delta, - DeltaEngineSpeed = maxEmDriveResponse.DeltaEngineSpeed + DeltaEngineSpeed = maxEmDriveResponse.Engine.EngineSpeed - maxEngineSpeed }; } @@ -588,11 +671,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies protected virtual void HandleBrakeAction(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun, List<HybridResultEntry> eval) { + if (DataBus.GearboxInfo.GearboxType.AutomaticTransmission() && + DataBus.GearboxInfo.Gear.Equals(GearList.First())) { + eval.Add(ResponseEmOff); + return; + } if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime)) { var emPos = ModelData.ElectricMachinesData.First().Item1; - var vehiclespeedBelowThreshold = - DataBus.VehicleInfo.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ClutchDisengageWhenHaltingSpeed); + var disengageSpeedThreshold = DataBus.GearboxInfo.GearboxType.AutomaticTransmission() + ? Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed + : Constants.SimulationSettings.ClutchDisengageWhenHaltingSpeed; + var vehiclespeedBelowThreshold = DataBus.VehicleInfo.VehicleSpeed.IsSmaller(disengageSpeedThreshold); if ((vehiclespeedBelowThreshold) && emPos == PowertrainPosition.HybridP2) { eval.Add(ResponseEmOff); return; @@ -603,6 +693,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies : (PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear); + var disengaged = nextGear.Gear == 0; var currentGear = nextGear; var tmp = new HybridStrategyResponse() { CombustionEngineOn = DataBus.EngineInfo.EngineOn, // AllowICEOff(absTime), @@ -611,11 +702,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies MechanicalAssistPower = ElectricMotorsOff }; var firstResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, tmp); - - if (GearList.HasPredecessor(nextGear) && firstResponse.Clutch.OutputSpeed.IsSmaller(ModelData.EngineData.IdleSpeed) && !vehiclespeedBelowThreshold) { + + var engineSpeedTooLow = !DataBus.GearboxInfo.GearboxType.AutomaticTransmission() + ? firstResponse.Clutch.OutputSpeed.IsSmaller(ModelData.EngineData.IdleSpeed) + : firstResponse.Engine.EngineSpeed.IsSmaller(ModelData.EngineData.IdleSpeed); + + if (GearList.HasPredecessor(nextGear) && engineSpeedTooLow && !vehiclespeedBelowThreshold) { // engine speed would fall below idling speed - consider downshift - var estimatedVelocityPostShift = VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); - var postShiftBelowThreshold = estimatedVelocityPostShift.IsSmaller(Constants.SimulationSettings.ClutchDisengageWhenHaltingSpeed); + var estimatedVelocityPostShift = VelocityDropData.Valid + ? VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, + DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()) + : DataBus.VehicleInfo.VehicleSpeed; + var postShiftBelowThreshold = estimatedVelocityPostShift.IsSmaller(disengageSpeedThreshold); if (postShiftBelowThreshold) { var downshift = ResponseEmOff; downshift.Gear = GearList.Predecessor(nextGear); @@ -628,12 +726,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies } while (GearList.HasPredecessor(nextGear) && firstResponse == null); } + if (DataBus.GearboxInfo.GearboxType.AutomaticTransmission() && firstResponse == null && nextGear.Equals(GearList.First())) { + var downshift = ResponseEmOff; + downshift.Gear = nextGear; + eval.Add(downshift); + return; + } + if (tmp.CombustionEngineOn) { var firstEntry = new HybridResultEntry(); CalcualteCosts(firstResponse, dt, firstEntry, AllowICEOff(absTime), dryRun); var minimumShiftTimePassed = (DataBus.GearboxInfo.LastShift + ModelData.GearshiftParameters.TimeBetweenGearshifts).IsSmallerOrEqual(absTime); if (DataBus.GearboxInfo.GearEngaged(absTime) && !vehiclespeedBelowThreshold) { - if ((minimumShiftTimePassed && firstEntry.IgnoreReason.EngineSpeedBelowDownshift()) || + if (firstEntry.IgnoreReason.EngineSpeedBelowDownshift() || firstEntry.IgnoreReason.EngineSpeedTooLow()) { // downshift required! var downshift = ResponseEmOff; @@ -644,7 +749,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies } } - if (firstResponse.DeltaDragLoad.IsGreater(0)) { + var deltaDragTqFirst = disengaged ? + (firstResponse as ResponseDryRun).DeltaDragLoadTorque + : firstResponse.Engine.TotalTorqueDemand - firstResponse.Engine.DragTorque; + + if (deltaDragTqFirst.IsGreater(0)) { // braking requested but engine operating point is not below drag curve. if (ElectricMotorCanPropellDuringTractionInterruption) { if (DataBus.GearboxInfo.GearEngaged(absTime)) { @@ -683,7 +792,29 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies var maxRecuperationResponse = RequestDryRun( absTime, dt, outTorque, outAngularVelocity, nextGear, maxRecuperation); - if (maxRecuperationResponse.DeltaDragLoad.IsSmaller(0) && + var deltaDragTqMaxRecuperation = disengaged + ? (maxRecuperationResponse as ResponseDryRun).DeltaDragLoadTorque + : maxRecuperationResponse.Engine.TotalTorqueDemand - maxRecuperationResponse.Engine.DragTorque; + + if (deltaDragTqMaxRecuperation.IsEqual(0)) { + // with max recuperation we are already at the drag curve (e.g. because search braking power was invoked before + eval.Add( + new HybridResultEntry() { + ICEOff = !DataBus.EngineInfo.EngineOn, + Gear = nextGear, + Setting = new HybridStrategyResponse() { + CombustionEngineOn = DataBus.EngineInfo.EngineOn, + GearboxInNeutral = false, + NextGear = nextGear, + MechanicalAssistPower = new Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>>() { + { emPos, Tuple.Create(firstResponse.ElectricMotor.AngularVelocity, firstResponse.ElectricMotor.MaxRecuperationTorque) } + } + } + }); + return; + } + + if (deltaDragTqMaxRecuperation.IsSmaller(0) && maxRecuperationResponse.ElectricSystem.RESSPowerDemand.IsBetween(maxRecuperationResponse.ElectricSystem.MaxPowerDrag, maxRecuperationResponse.ElectricSystem.MaxPowerDrive)) { // even with full recuperation (and no braking) the operating point is below the drag curve (and the battery can handle it) - use full recuperation eval.Add( @@ -708,8 +839,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies maxRecuperationResponse.ElectricMotor.AngularVelocity, maxRecuperationResponse.Engine.TorqueOutDemand, maxRecuperationResponse.ElectricMotor.MaxRecuperationTorque * 0.1, getYValue: r => { - var response = r as ResponseDryRun; - return response.DeltaDragLoad; + var response = r as IResponse; + var deltaDragLoad = disengaged + ? (response as ResponseDryRun).DeltaDragLoadTorque + : response.Engine.TotalTorqueDemand - response.Engine.DragTorque; + return deltaDragLoad; }, evaluateFunction: emTq => { var cfg = new HybridStrategyResponse() { @@ -723,8 +857,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return RequestDryRun(absTime, dt, outTorque, outAngularVelocity, DataBus.GearboxInfo.GearEngaged(absTime) ? nextGear : new GearshiftPosition(0), cfg); }, criterion: r => { - var response = r as ResponseDryRun; - return response.DeltaDragLoad.Value(); + var response = r as IResponse; + var deltaDragLoad = disengaged + ? (response as ResponseDryRun).DeltaDragLoadTorque + : response.Engine.TotalTorqueDemand - response.Engine.DragTorque; + return deltaDragLoad.Value(); } ); if (emRecuperationTq.IsBetween( @@ -782,7 +919,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies MechanicalAssistPower = ElectricMotorsOff }; var resp = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, tmp); - if (!dryRun) { + if (!dryRun && resp != null) { // resp.Engine.EngineSpeed != null && resp.Gearbox.Gear > 1 && ModelData.GearboxData //.Gears[resp.Gearbox.Gear].ShiftPolygon //.IsBelowDownshiftCurve(resp.Engine.TorqueOutDemand, resp.Engine.EngineSpeed)) { @@ -828,7 +965,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies protected virtual void HandleAccelerateAction(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun, List<HybridResultEntry> eval) { - if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime)) { + if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime) || DataBus.GearboxInfo.GearboxType.AutomaticTransmission()) { eval.AddRange(FindSolution(absTime, dt, outTorque, outAngularVelocity, dryRun)); } else { eval.Add(ResponseEmOff); @@ -840,7 +977,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies bool dryRun, GearshiftPosition currentGear) { var best = DoSelectBestOption(eval, absTime, dt, outTorque, outAngularVelocity, dryRun, currentGear); - if (best == null || !best.IgnoreReason.InvalidEngineSpeed() || best.ICEOff || + if (best == null) { + return null; + } + if (!best.IgnoreReason.InvalidEngineSpeed() || best.ICEOff || eval.Select(x => x.Gear).Distinct().Count() <= 1) { best.SimulationInterval = dt; return best; @@ -876,6 +1016,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies List<HybridResultEntry> eval, Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun, GearshiftPosition currentGear) { + if (eval.Count == 0) { + return null; + } HybridResultEntry best = null; if (DataBus.VehicleInfo.VehicleSpeed.IsSmallerOrEqual(ModelData.GearshiftParameters.StartSpeed)) { @@ -900,10 +1043,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return best; } - - var allOverload = eval.Where(x => !(x.IgnoreReason.BatteryDemandExceeded() || x.IgnoreReason.BatterySoCTooLow())) + var validResponses = eval.Where(x => x.Response != null).ToArray(); + var allOverload = validResponses.Where(x => !(x.IgnoreReason.BatteryDemandExceeded() || x.IgnoreReason.BatterySoCTooLow())) .All(x => x.IgnoreReason.EngineTorqueDemandTooHigh()); - var allUnderload = eval.All(x => x.IgnoreReason.EngineTorqueDemandTooLow()); + var allUnderload = validResponses.All(x => x.IgnoreReason.EngineTorqueDemandTooLow()); if (DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate && allOverload) { if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime)) { // overload, EM can support - use solution with max EM power @@ -961,6 +1104,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies if (filtered3.Length == 0) { filtered3 = filtered2; } + + var filteredCurrentGear = filtered3.Where(x => x.Gear.Equals(currentGear)).ToArray(); + if (filteredCurrentGear.Length > 0) { + best = filteredCurrentGear.MinBy(x => x.Setting.MechanicalAssistPower.Sum(e => e.Value?.Item2 ?? 0.SI<NewtonMeter>())); + return best; + } best = filtered3.MinBy(x => x.Setting.MechanicalAssistPower.Sum(e => e.Value?.Item2 ?? 0.SI<NewtonMeter>())); if (best != null) { return best; @@ -1054,10 +1203,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies var allowEmergencyDownshift = false; foreach (var nextGear in GearList.IterateGears(GearList.Predecessor(gear, (uint)gearRangeDownshift), GearList.Successor(gear, (uint)gearRangeUpshift))) { - //for (uint nextGear = (uint)Math.Max(1, gear - gearRangeDownshift); - //nextGear <= Math.Min(numGears, gear + gearRangeUpshift); - //nextGear++) { - var emOffEntry = EvaluateConfigsForGear(absTime, dt, outTorque, outAngularVelocity, nextGear, allowICEOff, responses, emPos, dryRun); if (emOffEntry == null) { @@ -1076,39 +1221,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies var nextGear = GearList.Successor(gear); var emOffEntry = EvaluateConfigsForGear( absTime, dt, outTorque, outAngularVelocity, nextGear, allowICEOff, responses, emPos, dryRun); - - // GetEmOffResultEntry(absTime, dt, outTorque, outAngularVelocity, nextGear); - //if (emOffEntry != null) { - // CalcualteCosts(emOffEntry.Response, dt, emOffEntry, allowICEOff); - - // responses.Add(emOffEntry); - - // var emTqReq = - // (emOffEntry.Response.ElectricMotor.PowerRequest + emOffEntry.Response.ElectricMotor.InertiaPowerDemand) / - // emOffEntry.Response.ElectricMotor.AngularVelocity; - // IterateEMTorque( - // absTime, dt, outTorque, outAngularVelocity, nextGear, allowICEOff, emOffEntry.Response, emTqReq, emPos, - // responses); - //} } if (allowEmergencyDownshift && tmpBest != null && !tmpBest.ICEOff) { var nextGear = GearList.Predecessor(gear); var emOffEntry = EvaluateConfigsForGear( absTime, dt, outTorque, outAngularVelocity, nextGear, allowICEOff, responses, emPos, dryRun); - - // GetEmOffResultEntry(absTime, dt, outTorque, outAngularVelocity, nextGear); - //if (emOffEntry != null) { - // CalcualteCosts(emOffEntry.Response, dt, emOffEntry, allowICEOff); - - // responses.Add(emOffEntry); - - // var emTqReq = - // (emOffEntry.Response.ElectricMotor.PowerRequest + emOffEntry.Response.ElectricMotor.InertiaPowerDemand) / - // emOffEntry.Response.ElectricMotor.AngularVelocity; - // IterateEMTorque( - // absTime, dt, outTorque, outAngularVelocity, nextGear, allowICEOff, emOffEntry.Response, emTqReq, emPos, - // responses); - //} } return responses; @@ -1127,8 +1244,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies responses.Add(emOffEntry); - var emTqReq = (emOffEntry.Response.ElectricMotor.PowerRequest + emOffEntry.Response.ElectricMotor.InertiaPowerDemand) / - emOffEntry.Response.ElectricMotor.AngularVelocity; + var emTqReq = emOffEntry.Response.ElectricMotor.TorqueRequest + + emOffEntry.Response.ElectricMotor.InertiaTorque; + IterateEMTorque( absTime, dt, outTorque, outAngularVelocity, nextGear, allowICEOff, emOffEntry.Response, emTqReq, emPos, responses, dryRun); return emOffEntry; @@ -1228,7 +1346,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies firstResponse.ElectricMotor.ElectricMotorPowerMech / firstResponse.ElectricMotor.AngularVelocity, firstResponse.Engine.TorqueOutDemand, firstResponse.ElectricMotor.MaxDriveTorque * 0.1, getYValue: r => { - var response = r as ResponseDryRun; + var response = r as IResponse; return response.Engine.TorqueOutDemand; }, evaluateFunction: emTq => { @@ -1242,7 +1360,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, cfg); }, criterion: r => { - var response = r as ResponseDryRun; + var response = r as IResponse; return response.Engine.TorqueOutDemand.Value(); } ); @@ -1283,7 +1401,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies firstResponse.ElectricMotor.ElectricMotorPowerMech / firstResponse.ElectricMotor.AngularVelocity, firstResponse.Engine.TorqueOutDemand, firstResponse.ElectricMotor.MaxRecuperationTorque * 0.1, getYValue: r => { - var response = r as ResponseDryRun; + var response = r as IResponse; return response.Engine.TorqueOutDemand; }, evaluateFunction: emTq => { @@ -1297,7 +1415,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, cfg); }, criterion: r => { - var response = r as ResponseDryRun; + var response = r as IResponse; return response.Engine.TorqueOutDemand.Value(); } ); @@ -1444,7 +1562,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies tmp.SoCPenalty += extraSoCPenalty; } - tmp.EqualityFactor = StrategyParameters.EquivalenceFactor; + tmp.EquivalenceFactor = resp.ElectricSystem.RESSPowerDemand.IsSmaller(0) + ? StrategyParameters.EquivalenceFactorDischarge + : StrategyParameters.EquivalenceFactorCharge; tmp.GearshiftPenalty = resp.Gearbox.Gear.Engaged && !resp.Gearbox.Gear.Equals(DataBus.GearboxInfo.Gear) ? ModelData.GearshiftParameters.RatingFactorCurrentGear : 1; @@ -1542,7 +1662,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies // $"{x.Response.Engine.TorqueOutDemand}, {x.Response.Engine.TotalTorqueDemand}, {x.Response.Engine.DynamicFullLoadTorque}"; // } // return - // $"{x.U:F2}: {x.Score:F2}; G{x.Gear}; ({x.FuelCosts:F2} + {x.EqualityFactor:F2} * ({x.BatCosts:F2} + {x.ICEStartPenalty1:F2}) * {x.SoCPenalty:F2} + {x.ICEStartPenalty2:F2}) / {x.GearshiftPenalty:F2} = {x.Score:F2} ({foo} ICE: {ice}); {x.IgnoreReason.HumanReadable()}"; + // $"{x.U:F2}: {x.Score:F2}; G{x.Gear}; ({x.FuelCosts:F2} + {x.EquivalenceFactor:F2} * ({x.BatCosts:F2} + {x.ICEStartPenalty1:F2}) * {x.SoCPenalty:F2} + {x.ICEStartPenalty2:F2}) / {x.GearshiftPenalty:F2} = {x.Score:F2} ({foo} ICE: {ice}); {x.IgnoreReason.HumanReadable()}"; // }) // ) // ); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs index 4e220c12d49afdb774da7c8810e412b18723b60a..154a5277f742dfb41de6ba9ef44171d2536d882c 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs @@ -2,6 +2,7 @@ using System.Linq; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.Simulation.DataBus; @@ -11,7 +12,7 @@ using TUGraz.VectoCore.Models.SimulationComponent.Impl; using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies { - public class TestPowertrain<T> where T: class, IHybridControlledGearbox + public class TestPowertrain<T> where T: class, IHybridControlledGearbox, IGearbox { public SimplePowertrainContainer Container; public T Gearbox; @@ -27,8 +28,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies { public StopStartCombustionEngine CombustionEngine; public ElectricMotor ElectricMotor; - public ElectricMotor ElectricMotorP2; - public ElectricMotor ElectricMotorP3; + public Dictionary<PowertrainPosition, ElectricMotor> ElectricMotorsUpstreamTransmission = new Dictionary<PowertrainPosition, ElectricMotor>(); + public TorqueConverter TorqueConverter; public TestPowertrain(SimplePowertrainContainer container, IDataBus realContainer) { @@ -41,23 +42,33 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies { Clutch = Container.ClutchInfo as Clutch; CombustionEngine = Container.EngineInfo as StopStartCombustionEngine; ElectricMotor = container.ElectricMotors.FirstOrDefault().Value as ElectricMotor; - ElectricMotorP2 = container.ElectricMotors.ContainsKey(PowertrainPosition.HybridP2) - ? container.ElectricMotors[PowertrainPosition.HybridP2] as ElectricMotor - : null; - ElectricMotorP3 = container.ElectricMotors.ContainsKey(PowertrainPosition.HybridP3) - ? container.ElectricMotors[PowertrainPosition.HybridP3] as ElectricMotor - : null; + foreach (var pos in container.ElectricMotorPositions) { + if (pos == PowertrainPosition.HybridP1 || pos == PowertrainPosition.HybridP2 || + pos == PowertrainPosition.HybridP3) { + ElectricMotorsUpstreamTransmission[pos] = container.ElectricMotors[pos] as ElectricMotor; + } + } if (Gearbox == null) { - throw new VectoException("Unknown gearboxtype in TestContainer: {0}", Container.GearboxCtl.GetType().FullName); + } + + if (Gearbox.GearboxType.AutomaticTransmission()) { + TorqueConverter = Container.TorqueConverterInfo as TorqueConverter; + if (TorqueConverter == null) { + throw new VectoException("Torque converter missing for automatic transmission: {0}", Container.TorqueConverterInfo?.GetType().FullName); + } } if (HybridController == null) { - throw new VectoException("Unknown HybridController in TestContainer: {0}", Container.HybridController.GetType().FullName); + throw new VectoException("Unknown HybridController in TestContainer: {0}", Container.HybridController?.GetType().FullName); } Driver = new MockDriver(container, realContainer); DrivingCycle = new MockDrivingCycle(container, realContainer); - Brakes = new MockBrakes(container); + Brakes = container.Brakes as Brakes; + if (Brakes == null) { + throw new VectoException("Unknown or missing brakes in TestContainer: {0}", Container.Brakes?.GetType().FullName); + } + //Brakes = new MockBrakes(container); } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs index 25b5367bc43a0071176668d6a588581516dc1c45..bbba27d2824da33ce3c3b401ae2215bed2bbbde0 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs @@ -53,6 +53,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent { DeltaFullLoad = avgOutSpeed * outTorque, DeltaDragLoad = avgOutSpeed * outTorque, + DeltaFullLoadTorque = outTorque, + DeltaDragLoadTorque = outTorque, Clutch = { PowerRequest = avgOutSpeed * outTorque, OutputSpeed = outAngularVelocity diff --git a/VectoCore/VectoCore/OutputData/FileIO/JSONFileWriter.cs b/VectoCore/VectoCore/OutputData/FileIO/JSONFileWriter.cs index 7a3eaa8668be4577b34aa09c5df69f97f6c7bcf4..b3c0c8b786de4c27edcbde9e9e9cfd2553c794e6 100644 --- a/VectoCore/VectoCore/OutputData/FileIO/JSONFileWriter.cs +++ b/VectoCore/VectoCore/OutputData/FileIO/JSONFileWriter.cs @@ -1108,7 +1108,8 @@ public class JSONFileWriter : IOutputFileWriter { var header = GetHeader(HybridStrategyParamsVersion); var body = new Dictionary<string, object>() { - {"EquivalenceFactor", hp.EquivalenceFactor}, + {"EquivalenceFactorDischarge", hp.EquivalenceFactorDischarge}, + {"EquivalenceFactorCharge", hp.EquivalenceFactorCharge}, {"MinSoC", hp.MinSoC * 100}, {"MaxSoC", hp.MaxSoC * 100}, {"TargetSoC", hp.TargetSoC * 100}, diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs index 00c10f9ad55631c3a3b075481654b6889f39b135..8481931abf6b344a0986664b1a842f190dd3e55c 100644 --- a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs +++ b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs @@ -41,10 +41,16 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid public const string AccelerationFile = @"TestData\Components\Truck.vacc"; public const string MotorFile240kW = @"TestData\Hybrids\ElectricMotor\GenericEMotor240kW.vem"; + public const string P1HybridMotor = @"Testdata\Hybrids\GenericVehicle_P1-APT\GenericEMotor20kW.vem"; + public const string P1BatteryFile = @"Testdata\Hybrids\GenericVehicle_P1-APT\GenericBattery.vbat"; + public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm"; public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm"; + public const string TorqueConverterSerial = @"TestData\Hybrids\GenericVehicle_P1-APT\TorqueConverter.vtcc"; + public const string TorqueConverterPowerSplit = @"TestData\Hybrids\GenericVehicle_P1-APT\TorqueConverterPowerSplit.vtcc"; + public const bool PlotGraphs = true; [OneTimeSetUp] @@ -79,9 +85,162 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid return graphWriter; } + // -------------------------------------- + + [ + TestCase(30, 0.7, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 30km/h SoC: 0.7, level"), + TestCase(50, 0.7, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 50km/h SoC: 0.7, level"), + TestCase(70, 0.7, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 70km/h SoC: 0.7, level"), + + TestCase(30, 0.25, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 30km/h SoC: 0.25, level"), + TestCase(50, 0.25, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 50km/h SoC: 0.25, level"), + TestCase(70, 0.25, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 70km/h SoC: 0.25, level"), + + TestCase(30, 0.5, 5, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 30km/h SoC: 0.5, UH 5%"), + TestCase(50, 0.5, 5, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 50km/h SoC: 0.5, UH 5%"), + TestCase(70, 0.5, 5, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 70km/h SoC: 0.5, UH 5%"), + + TestCase(30, 0.5, -5, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 30km/h SoC: 0.5, DH 5%"), + TestCase(50, 0.5, -5, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 50km/h SoC: 0.5, DH 5%"), + TestCase(70, 0.5, -5, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S ConstantSpeed 70km/h SoC: 0.5, DH 5%"), + + //------ + + TestCase(30, 0.7, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 30km/h SoC: 0.7, level"), + TestCase(50, 0.7, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 50km/h SoC: 0.7, level"), + TestCase(70, 0.7, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 70km/h SoC: 0.7, level"), + + TestCase(30, 0.25, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 30km/h SoC: 0.25, level"), + TestCase(50, 0.25, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 50km/h SoC: 0.25, level"), + TestCase(70, 0.25, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 70km/h SoC: 0.25, level"), + + TestCase(30, 0.5, 5, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 30km/h SoC: 0.5, UH 5%"), + TestCase(50, 0.5, 5, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 50km/h SoC: 0.5, UH 5%"), + TestCase(70, 0.5, 5, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 70km/h SoC: 0.5, UH 5%"), + + TestCase(30, 0.5, -5, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 30km/h SoC: 0.5, DH 5%"), + TestCase(50, 0.5, -5, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 50km/h SoC: 0.5, DH 5%"), + TestCase(70, 0.5, -5, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P ConstantSpeed 70km/h SoC: 0.5, DH 5%"), + ] + public void P1HybridConstantSpeed(double vmax, double initialSoC, double slope, GearboxType gbxType) + { + var cycleData = string.Format( + @" 0, {0}, {1}, 0 + 7000, {0}, {1}, 0", vmax, slope); + var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); + + const bool largeMotor = true; + + var modFilename = string.Format("SimpleParallelHybrid-P1_constant_{0}-{1}_{2}_{3}.vmod", vmax, initialSoC, slope, gbxType.ToXMLFormat()); + const PowertrainPosition pos = PowertrainPosition.HybridP1; + var job = CreateEngineeringRun( + cycle, modFilename, initialSoC, pos, 1.0, largeMotor: false, gearboxType: gbxType); + var run = job.Runs.First().Run; + + var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController; + Assert.NotNull(hybridController); + + var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data; + + var data = run.GetContainer().RunData; + //File.WriteAllText( + // $"{modFilename}.json", + // JsonConvert.SerializeObject(data, Formatting.Indented)); + + run.Run(); + Assert.IsTrue(run.FinishedWithoutErrors); + + Assert.IsTrue(modData.Rows.Count > 0); + var graphWriter = GetGraphWriter(new[] { ModalResultField.P_electricMotor_mech_P1 }); + graphWriter.Write(modFilename); + } + + [ + TestCase(30, 0.7, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S DriveOff 30km/h SoC: 0.7, level"), + TestCase(80, 0.7, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S DriveOff 80km/h SoC: 0.7, level"), + TestCase(80, 0.7, 5, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S DriveOff 80km/h SoC: 0.7, UH 5"), + TestCase(30, 0.22, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S DriveOff 30km/h SoC: 0.22, level"), + + TestCase(30, 0.7, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P DriveOff 30km/h SoC: 0.7, level"), + TestCase(80, 0.7, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P DriveOff 80km/h SoC: 0.7, level"), + TestCase(80, 0.7, 5, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P DriveOff 80km/h SoC: 0.7, UH 5"), + TestCase(30, 0.22, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P DriveOff 30km/h SoC: 0.22, level"), + + ] + public void P1HybridDriveOff(double vmax, double initialSoC, double slope, GearboxType gbxType) + { + var graphWriter = GetGraphWriter(new[] { ModalResultField.P_electricMotor_mech_P1 }); + var cycleData = string.Format( + @" 0, 0, {1}, 3 + 700, {0}, {1}, 0", vmax, slope); + var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); + + const bool largeMotor = true; + + var modFilename = string.Format("SimpleParallelHybrid-P1_acc_{0}-{1}_{2}_{3}.vmod", vmax, initialSoC, slope, gbxType.ToXMLFormat()); + const PowertrainPosition pos = PowertrainPosition.HybridP1; + var job = CreateEngineeringRun( + cycle, modFilename, initialSoC, pos, 1.0, largeMotor: false, gearboxType: gbxType); + var run = job.Runs.First().Run; + + var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController; + Assert.NotNull(hybridController); + + var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data; + + //run.Run(); + job.Execute(); + job.WaitFinished(); + Assert.IsTrue(run.FinishedWithoutErrors); + + Assert.IsTrue(modData.Rows.Count > 0); + graphWriter.Write(modFilename); + } + + [ + TestCase(50, 0.79, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S Brake Standstill 50km/h SoC: 0.79, level"), + TestCase(50, 0.25, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S Brake Standstill 50km/h SoC: 0.25, level"), + TestCase(50, 0.65, 0, GearboxType.ATSerial, TestName = "P1 Hybrid APT-S Brake Standstill 50km/h SoC: 0.65, level"), + + TestCase(50, 0.79, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P Brake Standstill 50km/h SoC: 0.79, level"), + TestCase(50, 0.25, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P Brake Standstill 50km/h SoC: 0.25, level"), + TestCase(50, 0.65, 0, GearboxType.ATPowerSplit, TestName = "P1 Hybrid APT-P Brake Standstill 50km/h SoC: 0.65, level") + ] + public void P1HybridBrakeStandstill(double vmax, double initialSoC, double slope, GearboxType gbxType) + { + var cycleData = string.Format( + @" 0, {0}, {1}, 0 + 200, 0, {1}, 3", vmax, slope); + var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); + + const bool largeMotor = true; + + var modFilename = string.Format("SimpleParallelHybrid-P1_stop_{0}-{1}_{2}_{3}.vmod", vmax, initialSoC, slope, gbxType.ToXMLFormat()); + const PowertrainPosition pos = PowertrainPosition.HybridP1; + var job = CreateEngineeringRun( + cycle, modFilename, initialSoC, pos, 1.0, largeMotor: false, gearboxType: gbxType); + var run = job.Runs.First().Run; + + var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController; + Assert.NotNull(hybridController); + //var strategy = (DelegateParallelHybridStrategy)hybridController.Strategy; + //Assert.NotNull(strategy); + + var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data; + + run.Run(); + Assert.IsTrue(run.FinishedWithoutErrors); + + Assert.IsTrue(modData.Rows.Count > 0); + var graphWriter = GetGraphWriter(new[] { ModalResultField.P_electricMotor_mech_P1 }); + graphWriter.Write(modFilename); + } + const string TestJobP1_APTS = @"TestData\Hybrids\GenericVehicle_P1-APT\CityBus_AT_Ser.vecto"; const string TestJobP1_APTP = @"TestData\Hybrids\GenericVehicle_P1-APT\CityBus_AT_PS.vecto"; + private const string TestJobCityBusP1_APTP = @"TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\CityBus_AT-P.vecto"; + [ TestCase(TestJobP1_APTS, 0, TestName = "P1 Hybrid APT-S, DriveCycle LongHaul"), TestCase(TestJobP1_APTS, 1, TestName = "P1 Hybrid APT-S, DriveCycle Coach"), @@ -104,7 +263,18 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid TestCase(TestJobP1_APTP, 7, TestName = "P1 Hybrid APT-P, DriveCycle Suburban"), TestCase(TestJobP1_APTP, 8, TestName = "P1 Hybrid APT-P, DriveCycle Urban"), TestCase(TestJobP1_APTP, 9, TestName = "P1 Hybrid APT-P, DriveCycle UrbanDelivery"), - ] + + TestCase(TestJobCityBusP1_APTP, 0, TestName = "P1 CityBus Hybrid APT-P, DriveCycle LongHaul"), + TestCase(TestJobCityBusP1_APTP, 1, TestName = "P1 CityBus Hybrid APT-P, DriveCycle Coach"), + TestCase(TestJobCityBusP1_APTP, 2, TestName = "P1 CityBus Hybrid APT-P, DriveCycle Construction"), + TestCase(TestJobCityBusP1_APTP, 3, TestName = "P1 CityBus Hybrid APT-P, DriveCycle HeavyUrban"), + TestCase(TestJobCityBusP1_APTP, 4, TestName = "P1 CityBus Hybrid APT-P, DriveCycle Interurban"), + TestCase(TestJobCityBusP1_APTP, 5, TestName = "P1 CityBus Hybrid APT-P, DriveCycle MunicipalUtility"), + TestCase(TestJobCityBusP1_APTP, 6, TestName = "P1 CityBus Hybrid APT-P, DriveCycle RegionalDelivery"), + TestCase(TestJobCityBusP1_APTP, 7, TestName = "P1 CityBus Hybrid APT-P, DriveCycle Suburban"), + TestCase(TestJobCityBusP1_APTP, 8, TestName = "P1 CityBus Hybrid APT-P, DriveCycle Urban"), + TestCase(TestJobCityBusP1_APTP, 9, TestName = "P1 CityBus Hybrid APT-P, DriveCycle UrbanDelivery"), + ] public void P1APTHybridDriveCycle(string jobFile, int cycleIdx) { var inputProvider = JSONInputDataFactory.ReadJsonJob(jobFile); @@ -137,6 +307,8 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid //Assert.IsTrue(jobContainer.GetProgress().All(x => x.Value.Success)); } + // ======================================================================================= + [ TestCase(30, 0.7, 0, TestName = "P2 Hybrid DriveOff 30km/h SoC: 0.7, level"), TestCase(80, 0.7, 0, TestName = "P2 Hybrid DriveOff 80km/h SoC: 0.7, level"), @@ -923,13 +1095,16 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid // ================================================= - public static JobContainer CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, double initialSoc, PowertrainPosition pos, double ratio, bool largeMotor = false, double pAuxEl = 0, Kilogram payload = null, Watt maxDriveTrainPower = null) + public static JobContainer CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, + double initialSoc, PowertrainPosition pos, double ratio, bool largeMotor = false, double pAuxEl = 0, + Kilogram payload = null, Watt maxDriveTrainPower = null, GearboxType gearboxType = GearboxType.NoGeabox) { var fileWriter = new FileOutputWriter(Path.GetFileNameWithoutExtension(modFileName)); var sumData = new SummaryDataContainer(fileWriter); var jobContainer = new JobContainer(sumData); var container = CreateParallelHybridPowerTrain( - cycleData,modFileName, initialSoc, largeMotor, sumData, pAuxEl, pos, ratio, payload, maxDriveTrainPower); + cycleData, modFileName, initialSoc, largeMotor, sumData, pAuxEl, pos, ratio, payload, + maxDriveTrainPower, gearboxType); var run = new DistanceRun(container); jobContainer.AddRun(run); return jobContainer; @@ -945,19 +1120,20 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid public static VehicleContainer CreateParallelHybridPowerTrain(DrivingCycleData cycleData, string modFileName, double initialBatCharge, bool largeMotor, SummaryDataContainer sumData, double pAuxEl, - PowertrainPosition pos, double ratio, Kilogram payload = null, Watt maxDriveTrainPower = null) + PowertrainPosition pos, double ratio, Kilogram payload = null, Watt maxDriveTrainPower = null, GearboxType gearboxType = GearboxType.NoGeabox) { - var gearboxData = CreateGearboxData(); - var axleGearData = CreateAxleGearData(); + var gearboxData = CreateGearboxData(gearboxType); + var axleGearData = CreateAxleGearData(gearboxType); var vehicleData = CreateVehicleData(payload ??3300.SI<Kilogram>()); var airdragData = CreateAirdragData(); var driverData = CreateDriverData(AccelerationFile, true); - var electricMotorData = - MockSimulationDataFactory.CreateElectricMotorData(largeMotor ? MotorFile240kW : MotorFile, 1, pos, ratio, 1); + var emFile = pos == PowertrainPosition.HybridP1 ? P1HybridMotor : (largeMotor ? MotorFile240kW : MotorFile); + var electricMotorData = MockSimulationDataFactory.CreateElectricMotorData(emFile, 1, pos, ratio, 1); - var batteryData = MockSimulationDataFactory.CreateBatteryData(BatFile, initialBatCharge); + var batFile = pos == PowertrainPosition.HybridP1 ? P1BatteryFile : BatFile; + var batteryData = MockSimulationDataFactory.CreateBatteryData(batFile, initialBatCharge); //batteryData.TargetSoC = 0.5; var engineData = MockSimulationDataFactory.CreateEngineDataFromFile( @@ -999,18 +1175,22 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid ExecutionMode.Engineering, modData, x => { sumData?.Write(x, 1, 1, runData); }); container.RunData = runData; - var strategy = new HybridStrategy(runData, container); + var strategy = gearboxType.AutomaticTransmission() + ? (IHybridControlStrategy) new HybridStrategyAT(runData, container) + : new HybridStrategy(runData, container); var es = new ElectricSystem(container); var battery = new Battery(container, batteryData); battery.Initialize(initialBatCharge); - var clutch = new SwitchableClutch(container, runData.EngineData); + var clutch = gearboxType.AutomaticTransmission() ? null : new SwitchableClutch(container, runData.EngineData); var ctl = new HybridController(container, strategy, es); es.Connect(battery); var engine = new StopStartCombustionEngine(container, runData.EngineData); - var gearbox = new Gearbox(container, ctl.ShiftStrategy); + var gearbox = gearboxType.AutomaticTransmission() + ? (IHybridControlledGearbox)new ATGearbox(container, ctl.ShiftStrategy) + : new Gearbox(container, ctl.ShiftStrategy); //var hybridStrategy = new DelegateParallelHybridStrategy(); ctl.Gearbox = gearbox; @@ -1036,7 +1216,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid .AddComponent(GetElectricMachine(PowertrainPosition.HybridP3, runData.ElectricMachinesData, container, es, ctl)) .AddComponent(runData.AngledriveData != null ? new Angledrive(container, runData.AngledriveData) : null) - .AddComponent(gearbox, runData.Retarder, container) + .AddComponent((IGearbox)gearbox, runData.Retarder, container) .AddComponent(GetElectricMachine(PowertrainPosition.HybridP2, runData.ElectricMachinesData, container, es, ctl)) .AddComponent(clutch) @@ -1045,13 +1225,21 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid .AddComponent(engine, idleController) .AddAuxiliaries(container, runData); + if (runData.ElectricMachinesData.Any(x => x.Item1 == PowertrainPosition.HybridP1)) { + if (gearbox is ATGearbox atGbx) { + atGbx.IdleController = idleController; + new ATClutchInfo(container); + } + } + return container; } private static HybridStrategyParameters CreateHybridStrategyData(Watt maxDriveTrainPower) { return new HybridStrategyParameters() { - EquivalenceFactor = 2.5, + EquivalenceFactorDischarge = 2.5, + EquivalenceFactorCharge = 2.5, MinSoC = 0.22, MaxSoC = 0.8, TargetSoC = 0.5, @@ -1071,7 +1259,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid //strategySettings.StrategyName = "SimpleParallelHybridStrategy"; var gearboxData = CreateGearboxData(); - var axleGearData = CreateAxleGearData(); + var axleGearData = CreateAxleGearData(GearboxType.AMT); var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); var airdragData = CreateAirdragData(); @@ -1169,8 +1357,8 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid GearResidenceTime = DeclarationData.GearboxTCU.GearResidenceTime, DnT99L_highMin1 = DeclarationData.GearboxTCU.DnT99L_highMin1, DnT99L_highMin2 = DeclarationData.GearboxTCU.DnT99L_highMin2, - AllowedGearRangeUp = DeclarationData.GearboxTCU.AllowedGearRangeUp, - AllowedGearRangeDown = DeclarationData.GearboxTCU.AllowedGearRangeDown, + AllowedGearRangeUp = gbx.Type.AutomaticTransmission() ? 1 : DeclarationData.GearboxTCU.AllowedGearRangeUp, + AllowedGearRangeDown = gbx.Type.AutomaticTransmission() ? 1: DeclarationData.GearboxTCU.AllowedGearRangeDown, LookBackInterval = DeclarationData.GearboxTCU.LookBackInterval, DriverAccelerationLookBackInterval = DeclarationData.GearboxTCU.DriverAccelerationLookBackInterval, DriverAccelerationThresholdLow = DeclarationData.GearboxTCU.DriverAccelerationThresholdLow, @@ -1220,7 +1408,23 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid return motor; } - private static GearboxData CreateGearboxData() + private static GearboxData CreateGearboxData(GearboxType gearboxType = GearboxType.NoGeabox) + { + switch (gearboxType) { + + case GearboxType.NoGeabox: + case GearboxType.AMT: + return CreateAMTGearbox(); + case GearboxType.ATSerial: + return CreateATSerial(); + case GearboxType.ATPowerSplit: + return CreateATPowerSplit(); + default: + throw new ArgumentOutOfRangeException(nameof(gearboxType), gearboxType, null); + } + } + + private static GearboxData CreateAMTGearbox() { var ratios = new[] { 14.93, 11.64, 9.02, 7.04, 5.64, 4.4, 3.39, 2.65, 2.05, 1.6, 1.28, 1.0 }; @@ -1241,10 +1445,82 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid }; } - - private static AxleGearData CreateAxleGearData() + private static GearboxData CreateATSerial() + { + //var shiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon( + // gearbox.Type, (int)i, engine.FullLoadCurves[i + 1], + // gearsInput, engine, + // axlegearRatio, dynamicTyreRadius, null); + + var ratios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 }; + return new GearboxData { + Type = GearboxType.ATSerial, + Gears = ratios.Select( + (ratio, i) => Tuple.Create( + (uint)i, new GearData { + //MaxTorque = 2300.SI<NewtonMeter>(), + LossMap = + TransmissionLossMapReader.ReadFromFile( + ratio.IsEqual(1) ? GearboxIndirectLoss : GearboxDirectLoss, ratio, + string.Format("Gear {0}", i)), + Ratio = ratio, + //ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile), + TorqueConverterRatio = i == 0 ? ratio : double.NaN, + TorqueConverterGearLossMap = i == 0 + ? TransmissionLossMapReader.Create( 0.98, ratio, string.Format("Gear {0}", i)) + : null, + //TorqueConverterShiftPolygon = i == 0 ? ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile) : null + })).ToDictionary(k => k.Item1 + 1, v => v.Item2), + Inertia = 0.SI<KilogramSquareMeter>(), + TractionInterruption = 1.SI<Second>(), + TorqueConverterData = TorqueConverterDataReader.ReadFromFile(TorqueConverterSerial, 1000.RPMtoRad(), + 5000.RPMtoRad(), ExecutionMode.Engineering, 1.0, DeclarationData.Gearbox.UpshiftMinAcceleration, + DeclarationData.Gearbox.UpshiftMinAcceleration), + PowershiftShiftTime = DeclarationData.Gearbox.PowershiftShiftTime + }; + } + + private static GearboxData CreateATPowerSplit() + { + var ratios = new[] { 1.35, 1.0, 0.73 }; + return new GearboxData { + Type = GearboxType.ATPowerSplit, + Gears = ratios.Select( + (ratio, i) => Tuple.Create( + (uint)i, new GearData { + //MaxTorque = 2300.SI<NewtonMeter>(), + LossMap = + TransmissionLossMapReader.ReadFromFile( + ratio.IsEqual(1) ? GearboxIndirectLoss : GearboxDirectLoss, ratio, + string.Format("Gear {0}", i)), + Ratio = ratio, + //ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile), + TorqueConverterRatio = i == 0 ? 1.0 : double.NaN, + TorqueConverterGearLossMap = i == 0 + ? TransmissionLossMapReader.Create(1.0, ratio, string.Format("Gear {0}", i)) + : null, + //TorqueConverterShiftPolygon = i == 0 ? ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile) : null + })).ToDictionary(k => k.Item1 + 1, v => v.Item2), + Inertia = 0.SI<KilogramSquareMeter>(), + TractionInterruption = 1.SI<Second>(), + TorqueConverterData = TorqueConverterDataReader.ReadFromFile(TorqueConverterSerial, 1000.RPMtoRad(), + 5000.RPMtoRad(), ExecutionMode.Engineering, 1.0 / ratios[0], DeclarationData.Gearbox.UpshiftMinAcceleration, + DeclarationData.Gearbox.UpshiftMinAcceleration), + PowershiftShiftTime = DeclarationData.Gearbox.PowershiftShiftTime + }; + } + + private static AxleGearData CreateAxleGearData(GearboxType gearboxType) { var ratio = 2.59; + switch (gearboxType) { + case GearboxType.ATSerial: + ratio = 6.2; + break; + case GearboxType.ATPowerSplit: + ratio = 5.8; + break; + } return new AxleGearData { AxleGear = new GearData { Ratio = ratio, diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Bus.vacc b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Bus.vacc new file mode 100644 index 0000000000000000000000000000000000000000..8ae1ce269631975dc3cda4923cdbe8b7a5377490 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Bus.vacc @@ -0,0 +1,15 @@ +v [km/h] , acc [m/s²] , dec [m/s²] +0 , 0.88 , -0.94 +10 , 1.00 , -0.94 +13 , 1.00 , -0.94 +20 , 1.00 , -0.88 +30 , 0.97 , -0.81 +40 , 0.80 , -0.73 +50 , 0.63 , -0.66 +58 , 0.50 , -0.52 +60 , 0.46 , -0.50 +70 , 0.39 , -0.50 +80 , 0.39 , -0.50 +90 , 0.39 , -0.50 +100 , 0.39 , -0.50 +120 , 0.39 , -0.50 \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/CityBus_AT-P.vecto b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/CityBus_AT-P.vecto new file mode 100644 index 0000000000000000000000000000000000000000..ee92960bc2d0fc10983c453c15a98d5d78573dbd --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/CityBus_AT-P.vecto @@ -0,0 +1,64 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2021-01-18T16:23:23.1599991Z", + "AppVersion": "3", + "FileVersion": 8 + }, + "Body": { + "SavedInDeclMode": false, + "EngineOnlyMode": false, + "VehicleFile": "CityBus_AT-P.vveh", + "EngineFile": "GenericICE_220kW_7.7l.veng", + "GearboxFile": "GearboxAT-P.vgbx", + "TCU": "ShiftPArameters.vtcu", + "ShiftStrategy": "TUGraz.VectoCore.Models.SimulationComponent.Impl.ATShiftStrategyOptimized", + "HybridStrategyParams": "HybridStrategyParams.vhctl", + "AuxiliaryAssembly": "Classic", + "AuxiliaryVersion": "CLASSIC", + "AdvancedAuxiliaryFilePath": "", + "Aux": [], + "Padd": 5000.0, + "Padd_electric": 0.0, + "VACC": "Bus.vacc", + "EngineStopStartAtVehicleStopThreshold": 2.0, + "EngineStopStartMaxOffTimespan": 30.0, + "EngineStopStartUtilityFactor": 1.0, + "EcoRollMinSpeed": 0.0, + "EcoRollActivationDelay": 0.0, + "EcoRollUnderspeedThreshold": 0.0, + "EcoRollMaxAcceleration": 0.0, + "PCCEnableSpeed": 0.0, + "PCCMinSpeed": 0.0, + "PCCUnderspeed": 0.0, + "PCCOverSpeed": 5.0, + "PCCPreviewDistanceUC1": 0.0, + "PCCPreviewDistanceUC2": 0.0, + "LAC": { + "Enabled": true, + "PreviewDistanceFactor": 10.0, + "DF_offset": 2.5, + "DF_scaling": 1.5, + "DF_targetSpeedLookup": "", + "Df_velocityDropLookup": "", + "MinSpeed": 50.0 + }, + "OverSpeedEcoRoll": { + "Mode": "Off", + "MinSpeed": 50.0, + "OverSpeed": 2.5 + }, + "Cycles": [ + "LongHaul", + "Coach", + "Construction", + "HeavyUrban", + "Interurban", + "MunicipalUtility", + "RegionalDelivery", + "Suburban", + "Urban", + "UrbanDelivery" + ] + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/CityBus_AT-P.vveh b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/CityBus_AT-P.vveh new file mode 100644 index 0000000000000000000000000000000000000000..e12de617e79273066fad24ac500379cb1160744f --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/CityBus_AT-P.vveh @@ -0,0 +1,82 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2021-02-01T12:49:19.2221328Z", + "AppVersion": "3", + "FileVersion": 10 + }, + "Body": { + "SavedInDeclMode": false, + "VehCat": "CityBus", + "LegislativeClass": "Unknown", + "CurbWeight": 12000.0, + "CurbWeightExtra": 0.0, + "MassMax": 18.0, + "Loading": 1000.0, + "rdyn": 421.0, + "CdCorrMode": "CdofVdecl", + "CdCorrFile": "", + "AxleConfig": { + "Type": "4x2", + "Axles": [ + { + "Inertia": 6.5, + "Wheels": "265/70 R19.5", + "AxleWeightShare": 0.4, + "TwinTyres": false, + "RRCISO": 0.0065, + "FzISO": 20850.0, + "Type": "VehicleNonDriven" + }, + { + "Inertia": 6.5, + "Wheels": "265/70 R19.5", + "AxleWeightShare": 0.6, + "TwinTyres": true, + "RRCISO": 0.0075, + "FzISO": 20850.0, + "Type": "VehicleDriven" + } + ] + }, + "EngineStopStart": false, + "EcoRoll": "None", + "PredictiveCruiseControl": "None", + "ATEcoRollReleaseLockupClutch": false, + "CdA": 4.25, + "VehicleHeight": 3.3, + "IdlingSpeed": 600.0, + "Retarder": { + "Type": "None", + "Ratio": 0.0, + "File": "" + }, + "Angledrive": { + "Type": "None", + "Ratio": 0.0, + "LossMap": "" + }, + "PTO": { + "Type": "None", + "LossMap": "", + "Cycle": "" + }, + "TorqueLimits": {}, + "MaxDrivetrainPower": 10000.0, + "InitialSoC": 90.0, + "PowertrainConfiguration": "ParallelHybrid", + "ElectricMotors": [ + { + "Count": 1, + "Ratio": 2.0, + "MechanicalEfficiency": 0.98, + "Position": "P1", + "MotorFile": "GenericEM_15KW_220Nm.vem" + } + ], + "Battery": { + "NumPacks": 1, + "BatteryFile": "Generic Supercap 48V.vreess" + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Engine map_7.7l.vmap b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Engine map_7.7l.vmap new file mode 100644 index 0000000000000000000000000000000000000000..0dcbccd5228fc1a5a663a157d584ed14c43533a8 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Engine map_7.7l.vmap @@ -0,0 +1,183 @@ +engine speed [rpm],torque [Nm],fuel consumption [g/h] +600,-156.5714286,0 +600,-56.57142857,0 +600,0,638 +600,216.9,3553.94 +600,433.8,6644.06 +600,650.7,11050.13 +600,867.6,15456.14 +600,1084.5,19862.14 +600,1301.4,24268.15 +600,1518.3,28674.15 +600,1735.2,33080.15 +600,1952.1,37486.16 +600,2169,41892.16 +748.9,-166.0198746,0 +748.9,-66.01987455,0 +748.9,0,843.67 +748.9,216.9,4100.1 +748.9,433.8,7706.21 +748.9,650.7,12298.69 +748.9,867.6,16731.15 +748.9,1084.5,21128.17 +748.9,1301.4,25525.18 +748.9,1518.3,29922.2 +748.9,1735.2,34319.22 +748.9,1952.1,38716.24 +748.9,2169,43113.26 +897.8,-174.5509889,0 +897.8,-74.55098889,0 +897.8,0,1049.35 +897.8,216.9,4646.25 +897.8,433.8,8768.36 +897.8,650.7,13541.46 +897.8,867.6,18156.42 +897.8,1084.5,22760.37 +897.8,1301.4,27362.81 +897.8,1518.3,31965.25 +897.8,1735.2,36567.69 +897.8,1952.1,41170.14 +897.8,2169,45772.58 +1046.7,-183.6305194,0 +1046.7,-83.63051942,0 +1046.7,0,1255.02 +1046.7,216.9,5192.4 +1046.7,433.8,9830.52 +1046.7,650.7,14781.21 +1046.7,867.6,19659.22 +1046.7,1084.5,24580.08 +1046.7,1301.4,29611.62 +1046.7,1518.3,34620.74 +1046.7,1735.2,39629.86 +1046.7,1952.1,44638.98 +1046.7,2169,49648.11 +1195.57,-193.9794114,0 +1195.57,-93.97941143,0 +1195.57,0,1460.65 +1195.57,216.9,5738.45 +1195.57,433.8,10892.45 +1195.57,650.7,16020.7 +1195.57,867.6,21159.59 +1195.57,1084.5,26391.05 +1195.57,1301.4,32095.87 +1195.57,1518.3,37706.84 +1195.57,1735.2,43317.81 +1195.57,1952.1,48928.77 +1195.57,2169,54539.74 +1359.19,-205.6210761,0 +1359.19,-105.6210761,0 +1359.19,0,1846.01 +1359.19,216.9,6560.14 +1359.19,433.8,12332.07 +1359.19,650.7,18097.95 +1359.19,867.6,23937.72 +1359.19,1084.5,29597.59 +1359.19,1301.4,35520.27 +1359.19,1518.3,41402.13 +1359.19,1735.2,47284 +1359.19,1952.1,53165.86 +1359.19,2169,59047.73 +1484,-215.5394502,0 +1484,-115.5394502,0 +1484,0,2131.16 +1484,216.9,7194.66 +1484,433.8,13496.22 +1484,650.7,19795.45 +1484,867.6,26122.03 +1484,1084.5,32222.77 +1484,1301.4,38588.45 +1484,1518.3,44936.74 +1484,1735.2,51285.03 +1484,1952.1,57633.32 +1484,2169,63981.62 +1608.9,-223.6490478,0 +1608.9,-123.6490478,0 +1608.9,0,2412.92 +1608.9,216.9,7832.39 +1608.9,433.8,14689.88 +1608.9,650.7,21533.67 +1608.9,867.6,28332.13 +1608.9,1084.5,34956.02 +1608.9,1301.4,41921.53 +1608.9,1518.3,48882.7 +1608.9,1735.2,55843.86 +1608.9,1952.1,62805.03 +1608.9,2169,69766.19 +1733.8,-228.2687944,0 +1733.8,-128.2687944,0 +1733.8,0,2725.03 +1733.8,216.9,8486.62 +1733.8,433.8,15875.76 +1733.8,650.7,23166.99 +1733.8,867.6,30597.07 +1733.8,1084.5,38101 +1733.8,1301.4,45882.06 +1733.8,1518.3,53661.69 +1733.8,1735.2,61441.31 +1733.8,1952.1,69220.94 +1733.8,2169,77000.57 +1858.61,-233.2770119,0 +1858.61,-133.2770119,0 +1858.61,0,3067.94 +1858.61,216.9,9180.54 +1858.61,433.8,17097.03 +1858.61,650.7,24909.82 +1858.61,867.6,32982.42 +1858.61,1084.5,41176.53 +1858.61,1301.4,49526.09 +1858.61,1518.3,57875.73 +1858.61,1735.2,66225.36 +1858.61,1952.1,74575 +1858.61,2169,82924.64 +1983.51,-239.7011553,0 +1983.51,-139.7011553,0 +1983.51,0,3446.165969 +1983.51,216.9,9920.378324 +1983.51,433.8,18360.13899 +1983.51,650.7,26779.01758 +1983.51,867.6,35507.453 +1983.51,1084.5,44178.34965 +1983.51,1301.4,52818.23622 +1983.51,1518.3,61458.13164 +1983.51,1735.2,70098.02705 +1983.51,1952.1,78737.92246 +1983.51,2169,87377.81788 +2108.41,-250.3624289,0 +2108.41,-150.3624289,0 +2108.41,0,3903.220883 +2108.41,216.9,10693.19834 +2108.41,433.8,19641.08191 +2108.41,650.7,28745.17923 +2108.41,867.6,38180.93551 +2108.41,1084.5,47433.46318 +2108.41,1301.4,56664.44413 +2108.41,1518.3,65895.42508 +2108.41,1735.2,75126.40604 +2108.41,1952.1,84357.38699 +2108.41,2169,93588.36794 +2233.31,-260.6179336,0 +2233.31,-160.6179336,0 +2233.31,0,4363.413897 +2233.31,216.9,11487.86565 +2233.31,433.8,20985.72948 +2233.31,650.7,30841.62288 +2233.31,867.6,41079.19748 +2233.31,1084.5,51089.00489 +2233.31,1301.4,61104.85222 +2233.31,1518.3,71120.69954 +2233.31,1735.2,81136.54686 +2233.31,1952.1,91152.39418 +2233.31,2169,101168.2415 +2358.21,-268.3446286,0 +2358.21,-168.3446286,0 +2358.21,0,4799.266043 +2358.21,216.9,12328.80853 +2358.21,433.8,22498.08244 +2358.21,650.7,33255.73916 +2358.21,867.6,44533.43058 +2358.21,1084.5,55739.63684 +2358.21,1301.4,66947.35734 +2358.21,1518.3,78155.07784 +2358.21,1735.2,89362.79834 +2358.21,1952.1,100570.5188 +2358.21,2169,111778.2393 diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Full-load curve 220kW.vfld b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Full-load curve 220kW.vfld new file mode 100644 index 0000000000000000000000000000000000000000..c886b973fd4999cf55bbd97d57565d78e161fa07 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Full-load curve 220kW.vfld @@ -0,0 +1,14 @@ +engine speed [1/min],full load torque [Nm],motoring torque [Nm] +500,628.5714286,-50.28571429 +600,779.4285714,-56.57142857 +800,942.8571429,-69.14285714 +1000,1131.428571,-80.45714286 +1100,1294.857143,-87.37142857 +1200,1294.857143,-94.28571429 +1300,1294.857143,-101.2 +1600,1294.857143,-123.2 +1800,1150.285714,-130.7428571 +2000,1043.428571,-140.8 +2200,955.4285714,-158.4 +2300,867.4285714,-164.6857143 +2400,779.4285714,-170.9714286 diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GearboxAT-P.vgbx b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GearboxAT-P.vgbx new file mode 100644 index 0000000000000000000000000000000000000000..7f3a3f92be54c5d11b0e7f14921ab7959c884f2e --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GearboxAT-P.vgbx @@ -0,0 +1,61 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2021-01-18T16:15:44.9706996Z", + "AppVersion": "3", + "FileVersion": 6 + }, + "Body": { + "SavedInDeclMode": false, + "ModelName": "AT PowerSplit", + "Inertia": 0.0, + "TracInt": 0.0, + "Gears": [ + { + "Ratio": 5.8, + "Efficiency": 0.97 + }, + { + "Ratio": 1.43, + "Efficiency": 0.93, + "ShiftPolygon": "", + "MaxTorque": "", + "MaxSpeed": "" + }, + { + "Ratio": 1.0, + "Efficiency": 0.93, + "ShiftPolygon": "", + "MaxTorque": "", + "MaxSpeed": "" + }, + { + "Ratio": 0.7, + "Efficiency": 0.93, + "ShiftPolygon": "", + "MaxTorque": "", + "MaxSpeed": "" + } + ], + "TqReserve": 0.0, + "ShiftTime": 0.5, + "StartTqReserve": 0.0, + "StartSpeed": 2.0, + "StartAcc": 0.6, + "GearboxType": "ATPowerSplit", + "TorqueConverter": { + "Enabled": true, + "File": "TC Parallel.vtcc", + "RefRPM": 999.99999999999989, + "Inertia": 0.0, + "MaxTCSpeed": 5000.0, + "ShiftPolygon": "", + "CLUpshiftMinAcceleration": 0.0, + "CCUpshiftMinAcceleration": 0.0 + }, + "DownshiftAfterUpshiftDelay": 6.0, + "UpshiftAfterDownshiftDelay": 0.0, + "UpshiftMinAcceleration": 0.0, + "PowershiftShiftTime": 0.8 + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Generic Supercap 48V.vreess b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Generic Supercap 48V.vreess new file mode 100644 index 0000000000000000000000000000000000000000..5cf5a9b538063f4c171bd6dbbb9007a00c01cacf --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/Generic Supercap 48V.vreess @@ -0,0 +1,19 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2021-01-18T15:17:57.4852109Z", + "AppVersion": "3", + "FileVersion": 1 + }, + "Body": { + "SavedInDeclMode": false, + "REESSType": "SuperCap", + "Model": "Generic Supercap 48V", + "Capacity": 166.0, + "InternalResistance": 0.005, + "U_min": 5.0, + "U_max": 48.6, + "I_maxCharge": 2200.0, + "I_maxDischarge": 2200.0 + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM.vemd b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM.vemd new file mode 100644 index 0000000000000000000000000000000000000000..41157c01c87a2201fb1af0f5aacd5983d7e8e786 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM.vemd @@ -0,0 +1,3 @@ +n [rpm] , T_drag [Nm] +0 , -5.6 +5000 , -28.1 \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM_15KW_220Nm.vem b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM_15KW_220Nm.vem new file mode 100644 index 0000000000000000000000000000000000000000..a960e797c1258cc5ef401dad878f891c26a526c6 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM_15KW_220Nm.vem @@ -0,0 +1,20 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2021-01-18T16:23:20.3712200Z", + "AppVersion": "3", + "FileVersion": 1 + }, + "Body": { + "SavedInDeclMode": false, + "Model": "Generic 15kW_220Nm", + "FullLoadCurve": "GenericEM_15kW_220Nm.vemp", + "DragCurve": "GenericEM.vemd", + "EfficiencyMap": "GenericEM_32kW_450Nm.vemo", + "Inertia": 0.198, + "ContinuousPower": 15000.0, + "ContinuousPowerSpeed": 651.0, + "OverloadTime": 15.0, + "ThermalOverloadRecoveryFactor": 0.9 + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM_15kW_220Nm.vemp b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM_15kW_220Nm.vemp new file mode 100644 index 0000000000000000000000000000000000000000..249f3bb3b67d87cdb259a4d730d3d116946d8a03 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM_15kW_220Nm.vemp @@ -0,0 +1,75 @@ +n [rpm], T_drive [Nm], T_recuperation [Nm] +0,220,-440 +651.0884036,220,-440 +648.7012987,220,-440 +652.5974026,219.494,-438.988 +656.4935065,218.1905,-436.381 +660.3896104,216.9035,-433.807 +662.3376623,216.2655,-432.531 +681.8181818,210.0835,-420.167 +701.2987013,204.248,-408.496 +720.7792208,198.726,-397.452 +740.2597403,193.501,-387.002 +759.7402597,188.54,-377.08 +779.2207792,183.8265,-367.653 +798.7012987,179.3385,-358.677 +818.1818182,175.0705,-350.141 +837.6623377,171.0005,-342.001 +857.1428571,167.112,-334.224 +876.6233766,163.3995,-326.799 +896.1038961,159.8465,-319.693 +915.5844156,156.4475,-312.895 +935.0649351,153.186,-306.372 +954.5454545,150.062,-300.124 +974.025974,147.059,-294.118 +993.5064935,144.177,-288.354 +1012.987013,141.405,-282.81 +1032.467532,138.7375,-277.475 +1051.948052,136.1635,-272.327 +1071.428571,133.6885,-267.377 +1090.909091,131.3015,-262.603 +1110.38961,128.997,-257.994 +1129.87013,126.775,-253.55 +1149.350649,124.6245,-249.249 +1168.831169,122.551,-245.102 +1188.311688,120.538,-241.076 +1207.792208,118.5965,-237.193 +1227.272727,116.7155,-233.431 +1246.753247,114.8895,-229.779 +1266.233766,113.124,-226.248 +1285.714286,111.408,-222.816 +1305.194805,109.747,-219.494 +1324.675325,108.13,-216.26 +1344.155844,106.5625,-213.125 +1363.636364,105.0445,-210.089 +1383.116883,103.565,-207.13 +1402.597403,102.124,-204.248 +1422.077922,100.727,-201.454 +1441.558442,99.363,-198.726 +1461.038961,98.0375,-196.075 +1480.519481,96.7505,-193.501 +1500,95.491,-190.982 +1519.480519,94.27,-188.54 +1538.961039,93.0765,-186.153 +1558.441558,91.9105,-183.821 +1577.922078,90.7775,-181.555 +1597.402597,89.672,-179.344 +1616.883117,88.5885,-177.177 +1636.363636,87.5325,-175.065 +1655.844156,86.504,-173.008 +1675.324675,85.4975,-170.995 +1694.805195,84.5185,-169.037 +1714.285714,83.556,-167.112 +1733.766234,82.6155,-165.231 +1753.246753,81.697,-163.394 +1772.727273,80.8005,-161.601 +1792.207792,79.926,-159.852 +1811.688312,79.0625,-158.125 +1831.168831,78.221,-156.442 +1850.649351,77.4015,-154.803 +1870.12987,76.593,-153.186 +1889.61039,75.801,-151.602 +1909.090909,75.031,-150.062 +1928.571429,74.272,-148.544 +1948.051948,73.5295,-147.059 +4864.577923,29.44539927,-58.89079854 diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM_32kW_450Nm.vemo b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM_32kW_450Nm.vemo new file mode 100644 index 0000000000000000000000000000000000000000..d83549939cce849ba212493c65671b81017e72f8 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericEM_32kW_450Nm.vemo @@ -0,0 +1,2016 @@ +n [rpm] , T [Nm] , P_el [kW] +0,-450,5.625657143 +0,-435.9375,5.298228573 +0,-421.875,4.980628573 +0,-407.8125,4.672742858 +0,-393.75,4.374742858 +0,-379.6875,4.086514285 +0,-365.625,3.808057143 +0,-351.5625,3.539428573 +0,-337.5,3.280571428 +0,-323.4375,3.031542858 +0,-309.375,2.792342858 +0,-295.3125,2.562914285 +0,-281.25,2.343257143 +0,-267.1875,2.133428573 +0,-253.125,1.933371428 +0,-239.0625,1.743142858 +0,-225,1.562742858 +0,-210.9375,1.392114285 +0,-196.875,1.231257143 +0,-182.8125,1.080228573 +0,-168.75,0.939028573 +0,-154.6875,0.8076 +0,-140.625,0.685942858 +0,-126.5625,0.574114285 +0,-112.5,0.472097143 +0,-98.4375,0.379874285 +0,-84.375,0.297445715 +0,-70.3125,0.224822858 +0,-56.25,0.161994285 +0,-42.1875,0.108971428 +0,-28.125,0.065748573 +0,-14.0625,0.032323428 +0,0,0.020628573 +0,14.0625,0.049702285 +0,28.125,0.088577143 +0,42.1875,0.137251428 +0,56.25,0.195725715 +0,70.3125,0.264 +0,84.375,0.34208 +0,98.4375,0.429954285 +0,112.5,0.527628573 +0,126.5625,0.635085715 +0,140.625,0.7524 +0,154.6875,0.879485715 +0,168.75,1.016342858 +0,182.8125,1.163028573 +0,196.875,1.319485715 +0,210.9375,1.485771428 +0,225,1.661885715 +0,239.0625,1.847771428 +0,253.125,2.043428573 +0,267.1875,2.248914285 +0,281.25,2.464171428 +0,295.3125,2.689257143 +0,309.375,2.924171428 +0,323.4375,3.168857143 +0,337.5,3.423314285 +0,351.5625,3.6876 +0,365.625,3.961714285 +0,379.6875,4.2456 +0,393.75,4.539257143 +0,407.8125,4.842742858 +0,421.875,5.156057143 +0,435.9375,5.479142858 +0,450,5.812 +46.50584415,-450,3.335257143 +46.50584415,-435.9375,3.080057143 +46.50584415,-421.875,2.834628573 +46.50584415,-407.8125,2.598971428 +46.50584415,-393.75,2.373142858 +46.50584415,-379.6875,2.157142858 +46.50584415,-365.625,1.950914285 +46.50584415,-351.5625,1.754514285 +46.50584415,-337.5,1.567885715 +46.50584415,-323.4375,1.391085715 +46.50584415,-309.375,1.224057143 +46.50584415,-295.3125,1.0668 +46.50584415,-281.25,0.919428573 +46.50584415,-267.1875,0.781771428 +46.50584415,-253.125,0.654 +46.50584415,-239.0625,0.53596 +46.50584415,-225,0.427742858 +46.50584415,-210.9375,0.32988 +46.50584415,-196.875,0.242057143 +46.50584415,-182.8125,0.164377143 +46.50584415,-168.75,0.096302858 +46.50584415,-154.6875,0.037838285 +46.50584415,-140.625,-0.011020573 +46.50584415,-126.5625,-0.050273715 +46.50584415,-112.5,-0.07992 +46.50584415,-98.4375,-0.09996 +46.50584415,-84.375,-0.110394285 +46.50584415,-70.3125,-0.111222858 +46.50584415,-56.25,-0.10244 +46.50584415,-42.1875,-0.084057143 +46.50584415,-28.125,-0.056062858 +46.50584415,-14.0625,-0.018464573 +46.50584415,0,0.0414 +46.50584415,14.0625,0.142691428 +46.50584415,28.125,0.253777143 +46.50584415,42.1875,0.374668573 +46.50584415,56.25,0.505354285 +46.50584415,70.3125,0.645828573 +46.50584415,84.375,0.796114285 +46.50584415,98.4375,0.956228573 +46.50584415,112.5,1.126114285 +46.50584415,126.5625,1.305828573 +46.50584415,140.625,1.495314285 +46.50584415,154.6875,1.694571428 +46.50584415,168.75,1.903714285 +46.50584415,182.8125,2.122571428 +46.50584415,196.875,2.351257143 +46.50584415,210.9375,2.589771428 +46.50584415,225,2.838057143 +46.50584415,239.0625,3.096171428 +46.50584415,253.125,3.364057143 +46.50584415,267.1875,3.641771428 +46.50584415,281.25,3.929257143 +46.50584415,295.3125,4.226571428 +46.50584415,309.375,4.533657143 +46.50584415,323.4375,4.850571428 +46.50584415,337.5,5.177257143 +46.50584415,351.5625,5.513771428 +46.50584415,365.625,5.86 +46.50584415,379.6875,6.216 +46.50584415,393.75,6.582285715 +46.50584415,407.8125,6.957714285 +46.50584415,421.875,7.343428573 +46.50584415,435.9375,7.738285715 +46.50584415,450,8.143428573 +93.01266235,-450,1.045885715 +93.01266235,-435.9375,0.862914285 +93.01266235,-421.875,0.69 +93.01266235,-407.8125,0.528325715 +93.01266235,-393.75,0.377337143 +93.01266235,-379.6875,0.235954285 +93.01266235,-365.625,0.104177143 +93.01266235,-351.5625,-0.017996 +93.01266235,-337.5,-0.13056 +93.01266235,-323.4375,-0.23352 +93.01266235,-309.375,-0.326868573 +93.01266235,-295.3125,-0.410617143 +93.01266235,-281.25,-0.484754285 +93.01266235,-267.1875,-0.549285715 +93.01266235,-253.125,-0.604228573 +93.01266235,-239.0625,-0.649542858 +93.01266235,-225,-0.685257143 +93.01266235,-210.9375,-0.711371428 +93.01266235,-196.875,-0.727828573 +93.01266235,-182.8125,-0.734742858 +93.01266235,-168.75,-0.732057143 +93.01266235,-154.6875,-0.719714285 +93.01266235,-140.625,-0.697771428 +93.01266235,-126.5625,-0.666228573 +93.01266235,-112.5,-0.625085715 +93.01266235,-98.4375,-0.574342858 +93.01266235,-84.375,-0.514017143 +93.01266235,-70.3125,-0.444057143 +93.01266235,-56.25,-0.364497143 +93.01266235,-42.1875,-0.275325715 +93.01266235,-28.125,-0.176548573 +93.01266235,-14.0625,-0.068165715 +93.01266235,0,0.063228573 +93.01266235,14.0625,0.236731428 +93.01266235,28.125,0.42004 +93.01266235,42.1875,0.613142858 +93.01266235,56.25,0.816057143 +93.01266235,70.3125,1.028742858 +93.01266235,84.375,1.251257143 +93.01266235,98.4375,1.483542858 +93.01266235,112.5,1.725657143 +93.01266235,126.5625,1.9776 +93.01266235,140.625,2.239314285 +93.01266235,154.6875,2.5108 +93.01266235,168.75,2.792114285 +93.01266235,182.8125,3.0832 +93.01266235,196.875,3.384114285 +93.01266235,210.9375,3.694857143 +93.01266235,225,4.015371428 +93.01266235,239.0625,4.345657143 +93.01266235,253.125,4.685771428 +93.01266235,267.1875,5.035657143 +93.01266235,281.25,5.395371428 +93.01266235,295.3125,5.765142858 +93.01266235,309.375,6.144 +93.01266235,323.4375,6.533142858 +93.01266235,337.5,6.932 +93.01266235,351.5625,7.341142858 +93.01266235,365.625,7.759428573 +93.01266235,379.6875,8.188 +93.01266235,393.75,8.625714285 +93.01266235,407.8125,9.073714285 +93.01266235,421.875,9.531428573 +93.01266235,435.9375,9.998857143 +93.01266235,450,10.47657143 +139.5194805,-450,-1.204057143 +139.5194805,-435.9375,-1.313085715 +139.5194805,-421.875,-1.412514285 +139.5194805,-407.8125,-1.502285715 +139.5194805,-393.75,-1.582514285 +139.5194805,-379.6875,-1.653085715 +139.5194805,-365.625,-1.714114285 +139.5194805,-351.5625,-1.765485715 +139.5194805,-337.5,-1.807257143 +139.5194805,-323.4375,-1.839428573 +139.5194805,-309.375,-1.862 +139.5194805,-295.3125,-1.874971428 +139.5194805,-281.25,-1.878342858 +139.5194805,-267.1875,-1.872057143 +139.5194805,-253.125,-1.856228573 +139.5194805,-239.0625,-1.830742858 +139.5194805,-225,-1.795657143 +139.5194805,-210.9375,-1.750971428 +139.5194805,-196.875,-1.696685715 +139.5194805,-182.8125,-1.6328 +139.5194805,-168.75,-1.559314285 +139.5194805,-154.6875,-1.476228573 +139.5194805,-140.625,-1.383485715 +139.5194805,-126.5625,-1.2812 +139.5194805,-112.5,-1.169257143 +139.5194805,-98.4375,-1.047714285 +139.5194805,-84.375,-0.916571428 +139.5194805,-70.3125,-0.775828573 +139.5194805,-56.25,-0.625485715 +139.5194805,-42.1875,-0.465548573 +139.5194805,-28.125,-0.295988573 +139.5194805,-14.0625,-0.116822858 +139.5194805,0,0.086125715 +139.5194805,14.0625,0.33184 +139.5194805,28.125,0.587371428 +139.5194805,42.1875,0.852685715 +139.5194805,56.25,1.127828573 +139.5194805,70.3125,1.412742858 +139.5194805,84.375,1.707428573 +139.5194805,98.4375,2.011942858 +139.5194805,112.5,2.326285715 +139.5194805,126.5625,2.6504 +139.5194805,140.625,2.984342858 +139.5194805,154.6875,3.328057143 +139.5194805,168.75,3.6816 +139.5194805,182.8125,4.044914285 +139.5194805,196.875,4.418 +139.5194805,210.9375,4.800971428 +139.5194805,225,5.193657143 +139.5194805,239.0625,5.596228573 +139.5194805,253.125,6.008571428 +139.5194805,267.1875,6.430857143 +139.5194805,281.25,6.862857143 +139.5194805,295.3125,7.304571428 +139.5194805,309.375,7.756 +139.5194805,323.4375,8.217142858 +139.5194805,337.5,8.688571428 +139.5194805,351.5625,9.169142858 +139.5194805,365.625,9.66 +139.5194805,379.6875,10.16057143 +139.5194805,393.75,10.67085714 +139.5194805,407.8125,11.19085714 +139.5194805,421.875,11.72114286 +139.5194805,435.9375,12.26057143 +139.5194805,450,12.81028572 +186.0292208,-450,-3.446 +186.0292208,-435.9375,-3.484228573 +186.0292208,-421.875,-3.512857143 +186.0292208,-407.8125,-3.531885715 +186.0292208,-393.75,-3.541314285 +186.0292208,-379.6875,-3.541142858 +186.0292208,-365.625,-3.531371428 +186.0292208,-351.5625,-3.511942858 +186.0292208,-337.5,-3.482914285 +186.0292208,-323.4375,-3.444342858 +186.0292208,-309.375,-3.396114285 +186.0292208,-295.3125,-3.338285715 +186.0292208,-281.25,-3.270857143 +186.0292208,-267.1875,-3.193828573 +186.0292208,-253.125,-3.1072 +186.0292208,-239.0625,-3.010914285 +186.0292208,-225,-2.905085715 +186.0292208,-210.9375,-2.7896 +186.0292208,-196.875,-2.664514285 +186.0292208,-182.8125,-2.529828573 +186.0292208,-168.75,-2.3856 +186.0292208,-154.6875,-2.231657143 +186.0292208,-140.625,-2.068171428 +186.0292208,-126.5625,-1.895085715 +186.0292208,-112.5,-1.7124 +186.0292208,-98.4375,-1.520057143 +186.0292208,-84.375,-1.318114285 +186.0292208,-70.3125,-1.106628573 +186.0292208,-56.25,-0.885485715 +186.0292208,-42.1875,-0.654742858 +186.0292208,-28.125,-0.414394285 +186.0292208,-14.0625,-0.16444 +186.0292208,0,0.11008 +186.0292208,14.0625,0.428011428 +186.0292208,28.125,0.755771428 +186.0292208,42.1875,1.093257143 +186.0292208,56.25,1.440628573 +186.0292208,70.3125,1.797771428 +186.0292208,84.375,2.164685715 +186.0292208,98.4375,2.541428573 +186.0292208,112.5,2.927942858 +186.0292208,126.5625,3.324285715 +186.0292208,140.625,3.730457143 +186.0292208,154.6875,4.146342858 +186.0292208,168.75,4.572114285 +186.0292208,182.8125,5.007657143 +186.0292208,196.875,5.452971428 +186.0292208,210.9375,5.908 +186.0292208,225,6.373142858 +186.0292208,239.0625,6.848 +186.0292208,253.125,7.332571428 +186.0292208,267.1875,7.826857143 +186.0292208,281.25,8.330857143 +186.0292208,295.3125,8.844571428 +186.0292208,309.375,9.368571428 +186.0292208,323.4375,9.902285715 +186.0292208,337.5,10.44514286 +186.0292208,351.5625,10.99828572 +186.0292208,365.625,11.56171429 +186.0292208,379.6875,12.13428572 +186.0292208,393.75,12.71657143 +186.0292208,407.8125,13.30914286 +186.0292208,421.875,13.91142857 +186.0292208,435.9375,14.52342857 +186.0292208,450,15.14514286 +232.5292208,-450,-5.686914285 +232.5292208,-435.9375,-5.654342858 +232.5292208,-421.875,-5.612228573 +232.5292208,-407.8125,-5.560457143 +232.5292208,-393.75,-5.499085715 +232.5292208,-379.6875,-5.428114285 +232.5292208,-365.625,-5.347542858 +232.5292208,-351.5625,-5.257371428 +232.5292208,-337.5,-5.1576 +232.5292208,-323.4375,-5.048171428 +232.5292208,-309.375,-4.929142858 +232.5292208,-295.3125,-4.800571428 +232.5292208,-281.25,-4.662342858 +232.5292208,-267.1875,-4.514514285 +232.5292208,-253.125,-4.357085715 +232.5292208,-239.0625,-4.190057143 +232.5292208,-225,-4.013428573 +232.5292208,-210.9375,-3.827142858 +232.5292208,-196.875,-3.631314285 +232.5292208,-182.8125,-3.425828573 +232.5292208,-168.75,-3.2108 +232.5292208,-154.6875,-2.986114285 +232.5292208,-140.625,-2.751828573 +232.5292208,-126.5625,-2.507942858 +232.5292208,-112.5,-2.254457143 +232.5292208,-98.4375,-1.991371428 +232.5292208,-84.375,-1.718628573 +232.5292208,-70.3125,-1.436342858 +232.5292208,-56.25,-1.1444 +232.5292208,-42.1875,-0.842857143 +232.5292208,-28.125,-0.531754285 +232.5292208,-14.0625,-0.211017143 +232.5292208,0,0.135091428 +232.5292208,14.0625,0.52524 +232.5292208,28.125,0.9252 +232.5292208,42.1875,1.334914285 +232.5292208,56.25,1.754514285 +232.5292208,70.3125,2.183828573 +232.5292208,84.375,2.622971428 +232.5292208,98.4375,3.071942858 +232.5292208,112.5,3.530685715 +232.5292208,126.5625,3.999257143 +232.5292208,140.625,4.4776 +232.5292208,154.6875,4.965771428 +232.5292208,168.75,5.463714285 +232.5292208,182.8125,5.971428573 +232.5292208,196.875,6.489142858 +232.5292208,210.9375,7.016571428 +232.5292208,225,7.553714285 +232.5292208,239.0625,8.100571428 +232.5292208,253.125,8.657142858 +232.5292208,267.1875,9.224 +232.5292208,281.25,9.8 +232.5292208,295.3125,10.38628572 +232.5292208,309.375,10.98228572 +232.5292208,323.4375,11.588 +232.5292208,337.5,12.20342857 +232.5292208,351.5625,12.82914286 +232.5292208,365.625,13.464 +232.5292208,379.6875,14.10914286 +232.5292208,393.75,14.764 +232.5292208,407.8125,15.42857143 +232.5292208,421.875,16.10285714 +232.5292208,435.9375,16.78685714 +232.5292208,450,17.48114286 +279.038961,-450,-7.926857143 +279.038961,-435.9375,-7.823428573 +279.038961,-421.875,-7.710285715 +279.038961,-407.8125,-7.588 +279.038961,-393.75,-7.456 +279.038961,-379.6875,-7.314285715 +279.038961,-365.625,-7.162857143 +279.038961,-351.5625,-7.001714285 +279.038961,-337.5,-6.831428573 +279.038961,-323.4375,-6.650857143 +279.038961,-309.375,-6.461142858 +279.038961,-295.3125,-6.261714285 +279.038961,-281.25,-6.052571428 +279.038961,-267.1875,-5.834285715 +279.038961,-253.125,-5.606 +279.038961,-239.0625,-5.368171428 +279.038961,-225,-5.120742858 +279.038961,-210.9375,-4.863714285 +279.038961,-196.875,-4.597028573 +279.038961,-182.8125,-4.3208 +279.038961,-168.75,-4.034971428 +279.038961,-154.6875,-3.739485715 +279.038961,-140.625,-3.434457143 +279.038961,-126.5625,-3.119771428 +279.038961,-112.5,-2.795485715 +279.038961,-98.4375,-2.4616 +279.038961,-84.375,-2.118114285 +279.038961,-70.3125,-1.765028573 +279.038961,-56.25,-1.402285715 +279.038961,-42.1875,-1.03 +279.038961,-28.125,-0.648057143 +279.038961,-14.0625,-0.256548573 +279.038961,0,0.161171428 +279.038961,14.0625,0.623542858 +279.038961,28.125,1.095714285 +279.038961,42.1875,1.577657143 +279.038961,56.25,2.069428573 +279.038961,70.3125,2.570971428 +279.038961,84.375,3.082342858 +279.038961,98.4375,3.603542858 +279.038961,112.5,4.134514285 +279.038961,126.5625,4.675257143 +279.038961,140.625,5.225828573 +279.038961,154.6875,5.786285715 +279.038961,168.75,6.356571428 +279.038961,182.8125,6.936571428 +279.038961,196.875,7.526285715 +279.038961,210.9375,8.125714285 +279.038961,225,8.734857143 +279.038961,239.0625,9.354285715 +279.038961,253.125,9.983428573 +279.038961,267.1875,10.62171429 +279.038961,281.25,11.27028572 +279.038961,295.3125,11.92914286 +279.038961,309.375,12.59714286 +279.038961,323.4375,13.27485714 +279.038961,337.5,13.96285714 +279.038961,351.5625,14.66057143 +279.038961,365.625,15.368 +279.038961,379.6875,16.08514286 +279.038961,393.75,16.812 +279.038961,407.8125,17.54857143 +279.038961,421.875,18.29542857 +279.038961,435.9375,19.05142857 +279.038961,450,19.81771429 +325.5487013,-450,-10.16571429 +325.5487013,-435.9375,-9.991428573 +325.5487013,-421.875,-9.808 +325.5487013,-407.8125,-9.614285715 +325.5487013,-393.75,-9.411428573 +325.5487013,-379.6875,-9.198857143 +325.5487013,-365.625,-8.976571428 +325.5487013,-351.5625,-8.745142858 +325.5487013,-337.5,-8.503428573 +325.5487013,-323.4375,-8.252571428 +325.5487013,-309.375,-7.992 +325.5487013,-295.3125,-7.721714285 +325.5487013,-281.25,-7.442285715 +325.5487013,-267.1875,-7.152571428 +325.5487013,-253.125,-6.853714285 +325.5487013,-239.0625,-6.545142858 +325.5487013,-225,-6.226857143 +325.5487013,-210.9375,-5.899428573 +325.5487013,-196.875,-5.561771428 +325.5487013,-182.8125,-5.214742858 +325.5487013,-168.75,-4.858057143 +325.5487013,-154.6875,-4.491828573 +325.5487013,-140.625,-4.116 +325.5487013,-126.5625,-3.730514285 +325.5487013,-112.5,-3.335485715 +325.5487013,-98.4375,-2.9308 +325.5487013,-84.375,-2.516514285 +325.5487013,-70.3125,-2.092628573 +325.5487013,-56.25,-1.659142858 +325.5487013,-42.1875,-1.216057143 +325.5487013,-28.125,-0.763371428 +325.5487013,-14.0625,-0.301045715 +325.5487013,0,0.188308573 +325.5487013,14.0625,0.722914285 +325.5487013,28.125,1.267257143 +325.5487013,42.1875,1.821428573 +325.5487013,56.25,2.385428573 +325.5487013,70.3125,2.9592 +325.5487013,84.375,3.5428 +325.5487013,98.4375,4.136171428 +325.5487013,112.5,4.739371428 +325.5487013,126.5625,5.352342858 +325.5487013,140.625,5.974857143 +325.5487013,154.6875,6.607428573 +325.5487013,168.75,7.250285715 +325.5487013,182.8125,7.902285715 +325.5487013,196.875,8.564 +325.5487013,210.9375,9.236 +325.5487013,225,9.917714285 +325.5487013,239.0625,10.60914286 +325.5487013,253.125,11.31028572 +325.5487013,267.1875,12.02114286 +325.5487013,281.25,12.74171429 +325.5487013,295.3125,13.47257143 +325.5487013,309.375,14.21314286 +325.5487013,323.4375,14.96285714 +325.5487013,337.5,15.72285714 +325.5487013,351.5625,16.49314286 +325.5487013,365.625,17.27257143 +325.5487013,379.6875,18.06171429 +325.5487013,393.75,18.86114286 +325.5487013,407.8125,19.67028572 +325.5487013,421.875,20.48914286 +325.5487013,435.9375,21.31771429 +325.5487013,450,22.156 +372.0487013,-450,-12.40342857 +372.0487013,-435.9375,-12.15828572 +372.0487013,-421.875,-11.904 +372.0487013,-407.8125,-11.64 +372.0487013,-393.75,-11.36628572 +372.0487013,-379.6875,-11.08285714 +372.0487013,-365.625,-10.78971429 +372.0487013,-351.5625,-10.48742857 +372.0487013,-337.5,-10.17542857 +372.0487013,-323.4375,-9.853714285 +372.0487013,-309.375,-9.522285715 +372.0487013,-295.3125,-9.181142858 +372.0487013,-281.25,-8.830857143 +372.0487013,-267.1875,-8.470285715 +372.0487013,-253.125,-8.100571428 +372.0487013,-239.0625,-7.721142858 +372.0487013,-225,-7.332 +372.0487013,-210.9375,-6.933714285 +372.0487013,-196.875,-6.525142858 +372.0487013,-182.8125,-6.107428573 +372.0487013,-168.75,-5.680171428 +372.0487013,-154.6875,-5.243142858 +372.0487013,-140.625,-4.796514285 +372.0487013,-126.5625,-4.340285715 +372.0487013,-112.5,-3.8744 +372.0487013,-98.4375,-3.398971428 +372.0487013,-84.375,-2.913885715 +372.0487013,-70.3125,-2.419257143 +372.0487013,-56.25,-1.914971428 +372.0487013,-42.1875,-1.401085715 +372.0487013,-28.125,-0.8776 +372.0487013,-14.0625,-0.344502858 +372.0487013,0,0.216508573 +372.0487013,14.0625,0.823314285 +372.0487013,28.125,1.439885715 +372.0487013,42.1875,2.066285715 +372.0487013,56.25,2.702457143 +372.0487013,70.3125,3.348457143 +372.0487013,84.375,4.004285715 +372.0487013,98.4375,4.669885715 +372.0487013,112.5,5.345257143 +372.0487013,126.5625,6.030285715 +372.0487013,140.625,6.725714285 +372.0487013,154.6875,7.430285715 +372.0487013,168.75,8.145142858 +372.0487013,182.8125,8.869142858 +372.0487013,196.875,9.603428573 +372.0487013,210.9375,10.34742857 +372.0487013,225,11.10114286 +372.0487013,239.0625,11.86514286 +372.0487013,253.125,12.63828572 +372.0487013,267.1875,13.42171429 +372.0487013,281.25,14.21428572 +372.0487013,295.3125,15.01714286 +372.0487013,309.375,15.82971429 +372.0487013,323.4375,16.652 +372.0487013,337.5,17.48457143 +372.0487013,351.5625,18.32628572 +372.0487013,365.625,19.17828572 +372.0487013,379.6875,20.04 +372.0487013,393.75,20.91142857 +372.0487013,407.8125,21.79257143 +372.0487013,421.875,22.68342857 +372.0487013,435.9375,23.58457143 +372.0487013,450,24.49485714 +418.5584415,-450,-14.64 +418.5584415,-435.9375,-14.32457143 +418.5584415,-421.875,-13.99942857 +418.5584415,-407.8125,-13.664 +418.5584415,-393.75,-13.32 +418.5584415,-379.6875,-12.96571429 +418.5584415,-365.625,-12.60171429 +418.5584415,-351.5625,-12.22857143 +418.5584415,-337.5,-11.84571429 +418.5584415,-323.4375,-11.45314286 +418.5584415,-309.375,-11.05085714 +418.5584415,-295.3125,-10.63942857 +418.5584415,-281.25,-10.21771429 +418.5584415,-267.1875,-9.786857143 +418.5584415,-253.125,-9.346285715 +418.5584415,-239.0625,-8.896 +418.5584415,-225,-8.436571428 +418.5584415,-210.9375,-7.966857143 +418.5584415,-196.875,-7.488 +418.5584415,-182.8125,-6.999428573 +418.5584415,-168.75,-6.501142858 +418.5584415,-154.6875,-5.993142858 +418.5584415,-140.625,-5.476 +418.5584415,-126.5625,-4.948971428 +418.5584415,-112.5,-4.412342858 +418.5584415,-98.4375,-3.866114285 +418.5584415,-84.375,-3.310228573 +418.5584415,-70.3125,-2.7448 +418.5584415,-56.25,-2.169714285 +418.5584415,-42.1875,-1.585085715 +418.5584415,-28.125,-0.9908 +418.5584415,-14.0625,-0.38692 +418.5584415,0,0.245771428 +418.5584415,14.0625,0.9248 +418.5584415,28.125,1.6136 +418.5584415,42.1875,2.312171428 +418.5584415,56.25,3.020628573 +418.5584415,70.3125,3.7388 +418.5584415,84.375,4.4668 +418.5584415,98.4375,5.204628573 +418.5584415,112.5,5.952 +418.5584415,126.5625,6.709714285 +418.5584415,140.625,7.477142858 +418.5584415,154.6875,8.253714285 +418.5584415,168.75,9.040571428 +418.5584415,182.8125,9.837142858 +418.5584415,196.875,10.644 +418.5584415,210.9375,11.46 +418.5584415,225,12.28571429 +418.5584415,239.0625,13.12171429 +418.5584415,253.125,13.96742857 +418.5584415,267.1875,14.82285714 +418.5584415,281.25,15.688 +418.5584415,295.3125,16.56285714 +418.5584415,309.375,17.448 +418.5584415,323.4375,18.34228572 +418.5584415,337.5,19.24685714 +418.5584415,351.5625,20.16114286 +418.5584415,365.625,21.08514286 +418.5584415,379.6875,22.01885714 +418.5584415,393.75,22.96285714 +418.5584415,407.8125,23.916 +418.5584415,421.875,24.87942857 +418.5584415,435.9375,25.852 +418.5584415,450,26.83485715 +465.0584415,-450,-16.876 +465.0584415,-435.9375,-16.48914286 +465.0584415,-421.875,-16.09314286 +465.0584415,-407.8125,-15.68742857 +465.0584415,-393.75,-15.27257143 +465.0584415,-379.6875,-14.84742857 +465.0584415,-365.625,-14.41314286 +465.0584415,-351.5625,-13.96857143 +465.0584415,-337.5,-13.51485714 +465.0584415,-323.4375,-13.052 +465.0584415,-309.375,-12.57885714 +465.0584415,-295.3125,-12.09657143 +465.0584415,-281.25,-11.604 +465.0584415,-267.1875,-11.10228572 +465.0584415,-253.125,-10.59085714 +465.0584415,-239.0625,-10.07028572 +465.0584415,-225,-9.539428573 +465.0584415,-210.9375,-8.999428573 +465.0584415,-196.875,-8.449714285 +465.0584415,-182.8125,-7.890285715 +465.0584415,-168.75,-7.321142858 +465.0584415,-154.6875,-6.742857143 +465.0584415,-140.625,-6.154285715 +465.0584415,-126.5625,-5.556628573 +465.0584415,-112.5,-4.9492 +465.0584415,-98.4375,-4.332171428 +465.0584415,-84.375,-3.705542858 +465.0584415,-70.3125,-3.069314285 +465.0584415,-56.25,-2.423485715 +465.0584415,-42.1875,-1.768 +465.0584415,-28.125,-1.102971428 +465.0584415,-14.0625,-0.428291428 +465.0584415,0,0.276097143 +465.0584415,14.0625,1.027314285 +465.0584415,28.125,1.788342858 +465.0584415,42.1875,2.559142858 +465.0584415,56.25,3.339771428 +465.0584415,70.3125,4.130228573 +465.0584415,84.375,4.930457143 +465.0584415,98.4375,5.740571428 +465.0584415,112.5,6.560571428 +465.0584415,126.5625,7.389714285 +465.0584415,140.625,8.229142858 +465.0584415,154.6875,9.078857143 +465.0584415,168.75,9.937714285 +465.0584415,182.8125,10.80628572 +465.0584415,196.875,11.68514286 +465.0584415,210.9375,12.57371429 +465.0584415,225,13.472 +465.0584415,239.0625,14.38 +465.0584415,253.125,15.29771429 +465.0584415,267.1875,16.22514286 +465.0584415,281.25,17.16285714 +465.0584415,295.3125,18.10971429 +465.0584415,309.375,19.06685714 +465.0584415,323.4375,20.03371429 +465.0584415,337.5,21.01028572 +465.0584415,351.5625,21.99657143 +465.0584415,365.625,22.99314286 +465.0584415,379.6875,23.99885714 +465.0584415,393.75,25.01485715 +465.0584415,407.8125,26.04057143 +465.0584415,421.875,27.076 +465.0584415,435.9375,28.12114285 +465.0584415,450,29.176 +511.5681818,-450,-19.11028572 +511.5681818,-435.9375,-18.65314286 +511.5681818,-421.875,-18.18628572 +511.5681818,-407.8125,-17.70971429 +511.5681818,-393.75,-17.224 +511.5681818,-379.6875,-16.728 +511.5681818,-365.625,-16.22285714 +511.5681818,-351.5625,-15.708 +511.5681818,-337.5,-15.18342857 +511.5681818,-323.4375,-14.64914286 +511.5681818,-309.375,-14.10571429 +511.5681818,-295.3125,-13.55257143 +511.5681818,-281.25,-12.98971429 +511.5681818,-267.1875,-12.41714286 +511.5681818,-253.125,-11.83485714 +511.5681818,-239.0625,-11.24285714 +511.5681818,-225,-10.64171429 +511.5681818,-210.9375,-10.03085714 +511.5681818,-196.875,-9.410285715 +511.5681818,-182.8125,-8.78 +511.5681818,-168.75,-8.14 +511.5681818,-154.6875,-7.490857143 +511.5681818,-140.625,-6.832 +511.5681818,-126.5625,-6.163428573 +511.5681818,-112.5,-5.485028573 +511.5681818,-98.4375,-4.7972 +511.5681818,-84.375,-4.099828573 +511.5681818,-70.3125,-3.3928 +511.5681818,-56.25,-2.676171428 +511.5681818,-42.1875,-1.949942858 +511.5681818,-28.125,-1.214057143 +511.5681818,-14.0625,-0.468622858 +511.5681818,0,0.30748 +511.5681818,14.0625,1.130914285 +511.5681818,28.125,1.964171428 +511.5681818,42.1875,2.8072 +511.5681818,56.25,3.660057143 +511.5681818,70.3125,4.522685715 +511.5681818,84.375,5.395085715 +511.5681818,98.4375,6.277142858 +511.5681818,112.5,7.169142858 +511.5681818,126.5625,8.071428573 +511.5681818,140.625,8.982857143 +511.5681818,154.6875,9.904571428 +511.5681818,168.75,10.83542857 +511.5681818,182.8125,11.77657143 +511.5681818,196.875,12.72742857 +511.5681818,210.9375,13.688 +511.5681818,225,14.65828572 +511.5681818,239.0625,15.63885714 +511.5681818,253.125,16.62857143 +511.5681818,267.1875,17.62857143 +511.5681818,281.25,18.63828572 +511.5681818,295.3125,19.65771429 +511.5681818,309.375,20.68685714 +511.5681818,323.4375,21.72628572 +511.5681818,337.5,22.77485714 +511.5681818,351.5625,23.83371429 +511.5681818,365.625,24.90228572 +511.5681818,379.6875,25.98 +511.5681818,393.75,27.06857143 +511.5681818,407.8125,28.16628573 +511.5681818,421.875,29.27371428 +511.5681818,435.9375,30.39142858 +511.5681818,450,31.51828573 +558.077922,-450,-21.344 +558.077922,-435.9375,-20.816 +558.077922,-421.875,-20.27828572 +558.077922,-407.8125,-19.73142857 +558.077922,-393.75,-19.17428572 +558.077922,-379.6875,-18.608 +558.077922,-365.625,-18.032 +558.077922,-351.5625,-17.44628572 +558.077922,-337.5,-16.85085714 +558.077922,-323.4375,-16.24571429 +558.077922,-309.375,-15.63142857 +558.077922,-295.3125,-15.00742857 +558.077922,-281.25,-14.37371429 +558.077922,-267.1875,-13.73028572 +558.077922,-253.125,-13.07714286 +558.077922,-239.0625,-12.41485714 +558.077922,-225,-11.74285714 +558.077922,-210.9375,-11.06114286 +558.077922,-196.875,-10.36971429 +558.077922,-182.8125,-9.668571428 +558.077922,-168.75,-8.958285715 +558.077922,-154.6875,-8.237714285 +558.077922,-140.625,-7.508 +558.077922,-126.5625,-6.768571428 +558.077922,-112.5,-6.02 +558.077922,-98.4375,-5.2612 +558.077922,-84.375,-4.493028573 +558.077922,-70.3125,-3.7152 +558.077922,-56.25,-2.927771428 +558.077922,-42.1875,-2.1308 +558.077922,-28.125,-1.324171428 +558.077922,-14.0625,-0.50792 +558.077922,0,0.339925715 +558.077922,14.0625,1.2356 +558.077922,28.125,2.141028573 +558.077922,42.1875,3.056285715 +558.077922,56.25,3.981314285 +558.077922,70.3125,4.916171428 +558.077922,84.375,5.860571428 +558.077922,98.4375,6.815428573 +558.077922,112.5,7.779428573 +558.077922,126.5625,8.753714285 +558.077922,140.625,9.737714285 +558.077922,154.6875,10.73085714 +558.077922,168.75,11.73485714 +558.077922,182.8125,12.748 +558.077922,196.875,13.77085714 +558.077922,210.9375,14.804 +558.077922,225,15.84628572 +558.077922,239.0625,16.89885714 +558.077922,253.125,17.96114286 +558.077922,267.1875,19.03314286 +558.077922,281.25,20.11485714 +558.077922,295.3125,21.20685714 +558.077922,309.375,22.308 +558.077922,323.4375,23.41942857 +558.077922,337.5,24.54057143 +558.077922,351.5625,25.67142858 +558.077922,365.625,26.812 +558.077922,379.6875,27.96228573 +558.077922,393.75,29.12285715 +558.077922,407.8125,30.29257143 +558.077922,421.875,31.47257143 +558.077922,435.9375,32.66228573 +558.077922,450,33.86171428 +930.1266235,-450,-39.17542858 +930.1266235,-435.9375,-38.08114285 +930.1266235,-421.875,-36.97771428 +930.1266235,-407.8125,-35.864 +930.1266235,-393.75,-34.74057143 +930.1266235,-379.6875,-33.608 +930.1266235,-365.625,-32.46571428 +930.1266235,-351.5625,-31.31371428 +930.1266235,-337.5,-30.152 +930.1266235,-323.4375,-28.98114285 +930.1266235,-309.375,-27.8 +930.1266235,-295.3125,-26.60971428 +930.1266235,-281.25,-25.40971428 +930.1266235,-267.1875,-24.2 +930.1266235,-253.125,-22.98114286 +930.1266235,-239.0625,-21.752 +930.1266235,-225,-20.51371429 +930.1266235,-210.9375,-19.26571429 +930.1266235,-196.875,-18.008 +930.1266235,-182.8125,-16.74114286 +930.1266235,-168.75,-15.464 +930.1266235,-154.6875,-14.17771429 +930.1266235,-140.625,-12.88171429 +930.1266235,-126.5625,-11.576 +930.1266235,-112.5,-10.26057143 +930.1266235,-98.4375,-8.936 +930.1266235,-84.375,-7.601142858 +930.1266235,-70.3125,-6.257142858 +930.1266235,-56.25,-4.903542858 +930.1266235,-42.1875,-3.540228573 +930.1266235,-28.125,-2.167314285 +930.1266235,-14.0625,-0.7848 +930.1266235,0,0.637714285 +930.1266235,14.0625,2.111085715 +930.1266235,28.125,3.594285715 +930.1266235,42.1875,5.087257143 +930.1266235,56.25,6.590285715 +930.1266235,70.3125,8.102857143 +930.1266235,84.375,9.625142858 +930.1266235,98.4375,11.15714286 +930.1266235,112.5,12.69885714 +930.1266235,126.5625,14.25085714 +930.1266235,140.625,15.81257143 +930.1266235,154.6875,17.384 +930.1266235,168.75,18.96514286 +930.1266235,182.8125,20.556 +930.1266235,196.875,22.15657143 +930.1266235,210.9375,23.76742857 +930.1266235,225,25.388 +930.1266235,239.0625,27.01771428 +930.1266235,253.125,28.65771428 +930.1266235,267.1875,30.30742858 +930.1266235,281.25,31.96742858 +930.1266235,295.3125,33.63657143 +930.1266235,309.375,35.316 +930.1266235,323.4375,37.00457143 +930.1266235,337.5,38.70342858 +930.1266235,351.5625,40.412 +930.1266235,365.625,42.13028573 +930.1266235,379.6875,43.85885715 +930.1266235,393.75,45.59657143 +930.1266235,407.8125,47.34457143 +930.1266235,421.875,49.10228573 +930.1266235,435.9375,50.86971428 +930.1266235,450,52.64685715 +1162.694805,-450,-50.28685715 +1162.694805,-435.9375,-48.83828573 +1162.694805,-421.875,-47.38057143 +1162.694805,-407.8125,-45.91314285 +1162.694805,-393.75,-44.436 +1162.694805,-379.6875,-42.94914285 +1162.694805,-365.625,-41.45314285 +1162.694805,-351.5625,-39.94742858 +1162.694805,-337.5,-38.43142858 +1162.694805,-323.4375,-36.90628573 +1162.694805,-309.375,-35.372 +1162.694805,-295.3125,-33.82742858 +1162.694805,-281.25,-32.27371428 +1162.694805,-267.1875,-30.71028573 +1162.694805,-253.125,-29.13714285 +1162.694805,-239.0625,-27.55428573 +1162.694805,-225,-25.96171428 +1162.694805,-210.9375,-24.36 +1162.694805,-196.875,-22.74857143 +1162.694805,-182.8125,-21.12742857 +1162.694805,-168.75,-19.49657143 +1162.694805,-154.6875,-17.856 +1162.694805,-140.625,-16.20628572 +1162.694805,-126.5625,-14.54628572 +1162.694805,-112.5,-12.87714286 +1162.694805,-98.4375,-11.19828572 +1162.694805,-84.375,-9.510285715 +1162.694805,-70.3125,-7.812 +1162.694805,-56.25,-6.104571428 +1162.694805,-42.1875,-4.387314285 +1162.694805,-28.125,-2.660457143 +1162.694805,-14.0625,-0.924057143 +1162.694805,0,0.858342858 +1162.694805,14.0625,2.6928 +1162.694805,28.125,4.537028573 +1162.694805,42.1875,6.390857143 +1162.694805,56.25,8.254857143 +1162.694805,70.3125,10.12857143 +1162.694805,84.375,12.012 +1162.694805,98.4375,13.90514286 +1162.694805,112.5,15.80857143 +1162.694805,126.5625,17.72114286 +1162.694805,140.625,19.644 +1162.694805,154.6875,21.576 +1162.694805,168.75,23.51828572 +1162.694805,182.8125,25.47085715 +1162.694805,196.875,27.43257143 +1162.694805,210.9375,29.404 +1162.694805,225,31.38571428 +1162.694805,239.0625,33.37657143 +1162.694805,253.125,35.37771428 +1162.694805,267.1875,37.38857143 +1162.694805,281.25,39.40914285 +1162.694805,295.3125,41.44 +1162.694805,309.375,43.48 +1162.694805,323.4375,45.53028573 +1162.694805,337.5,47.58971428 +1162.694805,351.5625,49.65942858 +1162.694805,365.625,51.73885715 +1162.694805,379.6875,53.82857143 +1162.694805,393.75,55.92742858 +1162.694805,407.8125,58.03428573 +1162.694805,421.875,60.15428573 +1162.694805,435.9375,62.28571428 +1162.694805,450,64.42285715 +1395.194805,-450,-61.37142858 +1395.194805,-435.9375,-59.57142858 +1395.194805,-421.875,-57.76 +1395.194805,-407.8125,-55.936 +1395.194805,-393.75,-54.10514285 +1395.194805,-379.6875,-52.26457143 +1395.194805,-365.625,-50.41428573 +1395.194805,-351.5625,-48.55428573 +1395.194805,-337.5,-46.68514285 +1395.194805,-323.4375,-44.80628573 +1395.194805,-309.375,-42.91771428 +1395.194805,-295.3125,-41.01942858 +1395.194805,-281.25,-39.11142858 +1395.194805,-267.1875,-37.19371428 +1395.194805,-253.125,-35.26685715 +1395.194805,-239.0625,-33.33028573 +1395.194805,-225,-31.384 +1395.194805,-210.9375,-29.428 +1395.194805,-196.875,-27.46285715 +1395.194805,-182.8125,-25.48742858 +1395.194805,-168.75,-23.50285714 +1395.194805,-154.6875,-21.50857143 +1395.194805,-140.625,-19.50457143 +1395.194805,-126.5625,-17.49142857 +1395.194805,-112.5,-15.468 +1395.194805,-98.4375,-13.43542857 +1395.194805,-84.375,-11.39314286 +1395.194805,-70.3125,-9.341142858 +1395.194805,-56.25,-7.279428573 +1395.194805,-42.1875,-5.2084 +1395.194805,-28.125,-3.127657143 +1395.194805,-14.0625,-1.037257143 +1395.194805,0,1.105485715 +1395.194805,14.0625,3.301028573 +1395.194805,28.125,5.506342858 +1395.194805,42.1875,7.721714285 +1395.194805,56.25,9.946285715 +1395.194805,70.3125,12.18114286 +1395.194805,84.375,14.42571429 +1395.194805,98.4375,16.68 +1395.194805,112.5,18.944 +1395.194805,126.5625,21.21771429 +1395.194805,140.625,23.50171429 +1395.194805,154.6875,25.79542858 +1395.194805,168.75,28.09885715 +1395.194805,182.8125,30.41142858 +1395.194805,196.875,32.73485715 +1395.194805,210.9375,35.06742858 +1395.194805,225,37.40971428 +1395.194805,239.0625,39.76228573 +1395.194805,253.125,42.12457143 +1395.194805,267.1875,44.496 +1395.194805,281.25,46.87828573 +1395.194805,295.3125,49.26971428 +1395.194805,309.375,51.67085715 +1395.194805,323.4375,54.08228573 +1395.194805,337.5,56.50285715 +1395.194805,351.5625,58.93142858 +1395.194805,365.625,61.37142858 +1395.194805,379.6875,63.82285715 +1395.194805,393.75,66.28571428 +1395.194805,407.8125,68.75428573 +1395.194805,421.875,71.23428573 +1395.194805,435.9375,73.72571428 +1395.194805,450,76.22285715 +1627.694805,-450,-72.42857143 +1627.694805,-435.9375,-70.27428573 +1627.694805,-421.875,-68.10857143 +1627.694805,-407.8125,-65.93142858 +1627.694805,-393.75,-63.74857143 +1627.694805,-379.6875,-61.55428573 +1627.694805,-365.625,-59.34857143 +1627.694805,-351.5625,-57.136 +1627.694805,-337.5,-54.91257143 +1627.694805,-323.4375,-52.67942858 +1627.694805,-309.375,-50.43714285 +1627.694805,-295.3125,-48.18514285 +1627.694805,-281.25,-45.92342858 +1627.694805,-267.1875,-43.652 +1627.694805,-253.125,-41.37085715 +1627.694805,-239.0625,-39.08057143 +1627.694805,-225,-36.78 +1627.694805,-210.9375,-34.47028573 +1627.694805,-196.875,-32.15085715 +1627.694805,-182.8125,-29.82171428 +1627.694805,-168.75,-27.48342858 +1627.694805,-154.6875,-25.13485715 +1627.694805,-140.625,-22.77714286 +1627.694805,-126.5625,-20.40971429 +1627.694805,-112.5,-18.03257143 +1627.694805,-98.4375,-15.64628572 +1627.694805,-84.375,-13.24971429 +1627.694805,-70.3125,-10.844 +1627.694805,-56.25,-8.428571428 +1627.694805,-42.1875,-6.003428573 +1627.694805,-28.125,-3.568742858 +1627.694805,-14.0625,-1.124457143 +1627.694805,0,1.3792 +1627.694805,14.0625,3.935771428 +1627.694805,28.125,6.502285715 +1627.694805,42.1875,9.078285715 +1627.694805,56.25,11.66457143 +1627.694805,70.3125,14.26 +1627.694805,84.375,16.86571429 +1627.694805,98.4375,19.48114286 +1627.694805,112.5,22.10628572 +1627.694805,126.5625,24.74114286 +1627.694805,140.625,27.38628573 +1627.694805,154.6875,30.04057143 +1627.694805,168.75,32.70514285 +1627.694805,182.8125,35.37942858 +1627.694805,196.875,38.06342858 +1627.694805,210.9375,40.75714285 +1627.694805,225,43.46057143 +1627.694805,239.0625,46.17428573 +1627.694805,253.125,48.89714285 +1627.694805,267.1875,51.63028573 +1627.694805,281.25,54.37314285 +1627.694805,295.3125,57.12571428 +1627.694805,309.375,59.88571428 +1627.694805,323.4375,62.66285715 +1627.694805,337.5,65.44 +1627.694805,351.5625,68.23428573 +1627.694805,365.625,71.03428573 +1627.694805,379.6875,73.84571428 +1627.694805,393.75,76.66857143 +1627.694805,407.8125,79.49714285 +1627.694805,421.875,82.34285715 +1627.694805,435.9375,85.18857143 +1627.694805,450,88.05142858 +1860.292208,-450,-83.46285715 +1860.292208,-435.9375,-80.95428573 +1860.292208,-421.875,-78.43428573 +1860.292208,-407.8125,-75.90285715 +1860.292208,-393.75,-73.36571428 +1860.292208,-379.6875,-70.81714285 +1860.292208,-365.625,-68.25714285 +1860.292208,-351.5625,-65.69142858 +1860.292208,-337.5,-63.11428573 +1860.292208,-323.4375,-60.52571428 +1860.292208,-309.375,-57.93142858 +1860.292208,-295.3125,-55.32457143 +1860.292208,-281.25,-52.70914285 +1860.292208,-267.1875,-50.08342858 +1860.292208,-253.125,-47.44857143 +1860.292208,-239.0625,-44.804 +1860.292208,-225,-42.15028573 +1860.292208,-210.9375,-39.48628573 +1860.292208,-196.875,-36.81314285 +1860.292208,-182.8125,-34.13028573 +1860.292208,-168.75,-31.43771428 +1860.292208,-154.6875,-28.73542858 +1860.292208,-140.625,-26.024 +1860.292208,-126.5625,-23.30228572 +1860.292208,-112.5,-20.57142857 +1860.292208,-98.4375,-17.83085714 +1860.292208,-84.375,-15.08057143 +1860.292208,-70.3125,-12.32114286 +1860.292208,-56.25,-9.551428573 +1860.292208,-42.1875,-6.772571428 +1860.292208,-28.125,-3.983885715 +1860.292208,-14.0625,-1.185657143 +1860.292208,0,1.679428573 +1860.292208,14.0625,4.597085715 +1860.292208,28.125,7.524571428 +1860.292208,42.1875,10.46171429 +1860.292208,56.25,13.40914286 +1860.292208,70.3125,16.36571429 +1860.292208,84.375,19.33257143 +1860.292208,98.4375,22.30914286 +1860.292208,112.5,25.29542858 +1860.292208,126.5625,28.29142858 +1860.292208,140.625,31.29714285 +1860.292208,154.6875,34.31257143 +1860.292208,168.75,37.33828573 +1860.292208,182.8125,40.37371428 +1860.292208,196.875,43.41885715 +1860.292208,210.9375,46.47371428 +1860.292208,225,49.53828573 +1860.292208,239.0625,52.61257143 +1860.292208,253.125,55.69714285 +1860.292208,267.1875,58.78857143 +1860.292208,281.25,61.89714285 +1860.292208,295.3125,65.01142858 +1860.292208,309.375,68.13142858 +1860.292208,323.4375,71.26285715 +1860.292208,337.5,74.40571428 +1860.292208,351.5625,77.56 +1860.292208,365.625,80.72571428 +1860.292208,379.6875,83.89714285 +1860.292208,393.75,87.08 +1860.292208,407.8125,90.26857143 +1860.292208,421.875,93.47428573 +1860.292208,435.9375,96.68571428 +1860.292208,450,99.90857143 +2092.792208,-450,-94.46857143 +2092.792208,-435.9375,-91.60571428 +2092.792208,-421.875,-88.73142858 +2092.792208,-407.8125,-85.85142858 +2092.792208,-393.75,-82.95428573 +2092.792208,-379.6875,-80.05714285 +2092.792208,-365.625,-77.14285715 +2092.792208,-351.5625,-74.22285715 +2092.792208,-337.5,-71.29142858 +2092.792208,-323.4375,-68.34857143 +2092.792208,-309.375,-65.4 +2092.792208,-295.3125,-62.44 +2092.792208,-281.25,-59.46857143 +2092.792208,-267.1875,-56.48971428 +2092.792208,-253.125,-53.50057143 +2092.792208,-239.0625,-50.50228573 +2092.792208,-225,-47.49428573 +2092.792208,-210.9375,-44.47657143 +2092.792208,-196.875,-41.44914285 +2092.792208,-182.8125,-38.41257143 +2092.792208,-168.75,-35.36628573 +2092.792208,-154.6875,-32.30971428 +2092.792208,-140.625,-29.244 +2092.792208,-126.5625,-26.16914285 +2092.792208,-112.5,-23.084 +2092.792208,-98.4375,-19.98971429 +2092.792208,-84.375,-16.88571429 +2092.792208,-70.3125,-13.772 +2092.792208,-56.25,-10.64857143 +2092.792208,-42.1875,-7.515428573 +2092.792208,-28.125,-4.373028573 +2092.792208,-14.0625,-1.220857143 +2092.792208,0,2.006171428 +2092.792208,14.0625,5.284914285 +2092.792208,28.125,8.573714285 +2092.792208,42.1875,11.872 +2092.792208,56.25,15.18 +2092.792208,70.3125,18.49771429 +2092.792208,84.375,21.82571429 +2092.792208,98.4375,25.16342858 +2092.792208,112.5,28.51028573 +2092.792208,126.5625,31.86742858 +2092.792208,140.625,35.23485715 +2092.792208,154.6875,38.61142858 +2092.792208,168.75,41.99771428 +2092.792208,182.8125,45.39428573 +2092.792208,196.875,48.80057143 +2092.792208,210.9375,52.21657143 +2092.792208,225,55.64228573 +2092.792208,239.0625,59.08 +2092.792208,253.125,62.52571428 +2092.792208,267.1875,65.97714285 +2092.792208,281.25,69.44571428 +2092.792208,295.3125,72.92 +2092.792208,309.375,76.4 +2092.792208,323.4375,79.89714285 +2092.792208,337.5,83.4 +2092.792208,351.5625,86.91428573 +2092.792208,365.625,90.44 +2092.792208,379.6875,93.97142858 +2092.792208,393.75,97.51428573 +2092.792208,407.8125,101.0685714 +2092.792208,421.875,104.6342857 +2092.792208,435.9375,108.2057143 +2092.792208,450,111.7885714 +2325.292208,-450,-105.4514286 +2325.292208,-435.9375,-102.2342857 +2325.292208,-421.875,-99.00571428 +2325.292208,-407.8125,-95.76571428 +2325.292208,-393.75,-92.52 +2325.292208,-379.6875,-89.26285715 +2325.292208,-365.625,-86 +2325.292208,-351.5625,-82.72571428 +2325.292208,-337.5,-79.44 +2325.292208,-323.4375,-76.14285715 +2325.292208,-309.375,-72.84 +2325.292208,-295.3125,-69.52571428 +2325.292208,-281.25,-66.2 +2325.292208,-267.1875,-62.86857143 +2325.292208,-253.125,-59.52571428 +2325.292208,-239.0625,-56.17428573 +2325.292208,-225,-52.812 +2325.292208,-210.9375,-49.44057143 +2325.292208,-196.875,-46.05942858 +2325.292208,-182.8125,-42.66857143 +2325.292208,-168.75,-39.26857143 +2325.292208,-154.6875,-35.85828573 +2325.292208,-140.625,-32.43885715 +2325.292208,-126.5625,-29.00971428 +2325.292208,-112.5,-25.57085715 +2325.292208,-98.4375,-22.12228572 +2325.292208,-84.375,-18.664 +2325.292208,-70.3125,-15.19657143 +2325.292208,-56.25,-11.71942857 +2325.292208,-42.1875,-8.232571428 +2325.292208,-28.125,-4.736114285 +2325.292208,-14.0625,-1.230057143 +2325.292208,0,2.359485715 +2325.292208,14.0625,5.999428573 +2325.292208,28.125,9.649142858 +2325.292208,42.1875,13.30857143 +2325.292208,56.25,16.97771429 +2325.292208,70.3125,20.65657143 +2325.292208,84.375,24.34514286 +2325.292208,98.4375,28.044 +2325.292208,112.5,31.75257143 +2325.292208,126.5625,35.47085715 +2325.292208,140.625,39.19885715 +2325.292208,154.6875,42.93657143 +2325.292208,168.75,46.684 +2325.292208,182.8125,50.44171428 +2325.292208,196.875,54.20857143 +2325.292208,210.9375,57.98857143 +2325.292208,225,61.77142858 +2325.292208,239.0625,65.57142858 +2325.292208,253.125,69.37714285 +2325.292208,267.1875,73.19428573 +2325.292208,281.25,77.01714285 +2325.292208,295.3125,80.85142858 +2325.292208,309.375,84.69714285 +2325.292208,323.4375,88.55428573 +2325.292208,337.5,92.42285715 +2325.292208,351.5625,96.29714285 +2325.292208,365.625,100.1771429 +2325.292208,379.6875,104.0742857 +2325.292208,393.75,107.9771429 +2325.292208,407.8125,111.8914286 +2325.292208,421.875,115.8171429 +2325.292208,435.9375,119.7485714 +2325.292208,450,123.6971429 +2557.88961,-450,-116.4057143 +2557.88961,-435.9375,-112.8342857 +2557.88961,-421.875,-109.2514286 +2557.88961,-407.8125,-105.6628572 +2557.88961,-393.75,-102.0628572 +2557.88961,-379.6875,-98.45142858 +2557.88961,-365.625,-94.82857143 +2557.88961,-351.5625,-91.2 +2557.88961,-337.5,-87.56 +2557.88961,-323.4375,-83.91428573 +2557.88961,-309.375,-80.25714285 +2557.88961,-295.3125,-76.58857143 +2557.88961,-281.25,-72.90857143 +2557.88961,-267.1875,-69.22285715 +2557.88961,-253.125,-65.52571428 +2557.88961,-239.0625,-61.82285715 +2557.88961,-225,-58.10285715 +2557.88961,-210.9375,-54.37885715 +2557.88961,-196.875,-50.64342858 +2557.88961,-182.8125,-46.89885715 +2557.88961,-168.75,-43.14457143 +2557.88961,-154.6875,-39.38057143 +2557.88961,-140.625,-35.60742858 +2557.88961,-126.5625,-31.824 +2557.88961,-112.5,-28.03142858 +2557.88961,-98.4375,-24.22914286 +2557.88961,-84.375,-20.41714286 +2557.88961,-70.3125,-16.59542857 +2557.88961,-56.25,-12.76457143 +2557.88961,-42.1875,-8.923428573 +2557.88961,-28.125,-5.0732 +2557.88961,-14.0625,-1.2132 +2557.88961,0,2.739314285 +2557.88961,14.0625,6.74 +2557.88961,28.125,10.75085714 +2557.88961,42.1875,14.77142857 +2557.88961,56.25,18.80171429 +2557.88961,70.3125,22.84171429 +2557.88961,84.375,26.89142858 +2557.88961,98.4375,30.95142858 +2557.88961,112.5,35.02114285 +2557.88961,126.5625,39.1 +2557.88961,140.625,43.18914285 +2557.88961,154.6875,47.288 +2557.88961,168.75,51.39714285 +2557.88961,182.8125,55.51542858 +2557.88961,196.875,59.64571428 +2557.88961,210.9375,63.78285715 +2557.88961,225,67.93142858 +2557.88961,239.0625,72.08571428 +2557.88961,253.125,76.25714285 +2557.88961,267.1875,80.43428573 +2557.88961,281.25,84.61714285 +2557.88961,295.3125,88.81714285 +2557.88961,309.375,93.02285715 +2557.88961,323.4375,97.24 +2557.88961,337.5,101.4685714 +2557.88961,351.5625,105.7028572 +2557.88961,365.625,109.9485714 +2557.88961,379.6875,114.2057143 +2557.88961,393.75,118.4685714 +2557.88961,407.8125,122.7428572 +2557.88961,421.875,127.0285714 +2557.88961,435.9375,131.3257143 +2557.88961,450,135.6285714 +2790.38961,-450,-127.3371429 +2790.38961,-435.9375,-123.4114286 +2790.38961,-421.875,-119.4742857 +2790.38961,-407.8125,-115.5314286 +2790.38961,-393.75,-111.5714286 +2790.38961,-379.6875,-107.6114286 +2790.38961,-365.625,-103.6342857 +2790.38961,-351.5625,-99.65142858 +2790.38961,-337.5,-95.65714285 +2790.38961,-323.4375,-91.65714285 +2790.38961,-309.375,-87.64571428 +2790.38961,-295.3125,-83.62285715 +2790.38961,-281.25,-79.59428573 +2790.38961,-267.1875,-75.54857143 +2790.38961,-253.125,-71.50285715 +2790.38961,-239.0625,-67.44 +2790.38961,-225,-63.37142858 +2790.38961,-210.9375,-59.29142858 +2790.38961,-196.875,-55.20171428 +2790.38961,-182.8125,-51.10342858 +2790.38961,-168.75,-46.99485715 +2790.38961,-154.6875,-42.87714285 +2790.38961,-140.625,-38.74971428 +2790.38961,-126.5625,-34.61257143 +2790.38961,-112.5,-30.46571428 +2790.38961,-98.4375,-26.30971428 +2790.38961,-84.375,-22.144 +2790.38961,-70.3125,-17.96857143 +2790.38961,-56.25,-13.78342857 +2790.38961,-42.1875,-9.588571428 +2790.38961,-28.125,-5.384285715 +2790.38961,-14.0625,-1.170342858 +2790.38961,0,3.145714285 +2790.38961,14.0625,7.507428573 +2790.38961,28.125,11.87942857 +2790.38961,42.1875,16.26114286 +2790.38961,56.25,20.65257143 +2790.38961,70.3125,25.05371428 +2790.38961,84.375,29.46457143 +2790.38961,98.4375,33.88514285 +2790.38961,112.5,38.316 +2790.38961,126.5625,42.756 +2790.38961,140.625,47.20628573 +2790.38961,154.6875,51.66628573 +2790.38961,168.75,56.136 +2790.38961,182.8125,60.61714285 +2790.38961,196.875,65.10285715 +2790.38961,210.9375,69.60571428 +2790.38961,225,74.11428573 +2790.38961,239.0625,78.63428573 +2790.38961,253.125,83.16 +2790.38961,267.1875,87.69714285 +2790.38961,281.25,92.24571428 +2790.38961,295.3125,96.80571428 +2790.38961,309.375,101.3714286 +2790.38961,323.4375,105.9485714 +2790.38961,337.5,110.5371429 +2790.38961,351.5625,115.1371429 +2790.38961,365.625,119.7428572 +2790.38961,379.6875,124.36 +2790.38961,393.75,128.9828572 +2790.38961,407.8125,133.6228572 +2790.38961,421.875,138.2685714 +2790.38961,435.9375,142.9257143 +2790.38961,450,147.5885714 +3022.88961,-450,-138.24 +3022.88961,-435.9375,-133.96 +3022.88961,-421.875,-129.6685714 +3022.88961,-407.8125,-125.3714286 +3022.88961,-393.75,-121.0628572 +3022.88961,-379.6875,-116.7428572 +3022.88961,-365.625,-112.4171429 +3022.88961,-351.5625,-108.08 +3022.88961,-337.5,-103.7314286 +3022.88961,-323.4375,-99.37714285 +3022.88961,-309.375,-95.01142858 +3022.88961,-295.3125,-90.63428573 +3022.88961,-281.25,-86.24571428 +3022.88961,-267.1875,-81.85142858 +3022.88961,-253.125,-77.44571428 +3022.88961,-239.0625,-73.03428573 +3022.88961,-225,-68.61142858 +3022.88961,-210.9375,-64.17714285 +3022.88961,-196.875,-59.73142858 +3022.88961,-182.8125,-55.28171428 +3022.88961,-168.75,-50.81942858 +3022.88961,-154.6875,-46.34742858 +3022.88961,-140.625,-41.86628573 +3022.88961,-126.5625,-37.37542858 +3022.88961,-112.5,-32.87485715 +3022.88961,-98.4375,-28.36457143 +3022.88961,-84.375,-23.84457143 +3022.88961,-70.3125,-19.31542857 +3022.88961,-56.25,-14.776 +3022.88961,-42.1875,-10.22742857 +3022.88961,-28.125,-5.669314285 +3022.88961,-14.0625,-1.101485715 +3022.88961,0,3.578628573 +3022.88961,14.0625,8.301714285 +3022.88961,28.125,13.03428572 +3022.88961,42.1875,17.77714286 +3022.88961,56.25,22.52971429 +3022.88961,70.3125,27.292 +3022.88961,84.375,32.064 +3022.88961,98.4375,36.84571428 +3022.88961,112.5,41.63714285 +3022.88961,126.5625,46.43885715 +3022.88961,140.625,51.25028573 +3022.88961,154.6875,56.07142858 +3022.88961,168.75,60.90285715 +3022.88961,182.8125,65.74285715 +3022.88961,196.875,70.59428573 +3022.88961,210.9375,75.45142858 +3022.88961,225,80.32571428 +3022.88961,239.0625,85.20571428 +3022.88961,253.125,90.09142858 +3022.88961,267.1875,94.99428573 +3022.88961,281.25,99.90285715 +3022.88961,295.3125,104.8228572 +3022.88961,309.375,109.7485714 +3022.88961,323.4375,114.6857143 +3022.88961,337.5,119.6342857 +3022.88961,351.5625,124.5942857 +3022.88961,365.625,129.5657143 +3022.88961,379.6875,134.5428572 +3022.88961,393.75,139.5257143 +3022.88961,407.8125,144.5257143 +3022.88961,421.875,149.5314286 +3022.88961,435.9375,154.5485714 +3022.88961,450,159.5771429 +3255.487013,-450,-149.1142857 +3255.487013,-435.9375,-144.48 +3255.487013,-421.875,-139.84 +3255.487013,-407.8125,-135.1828572 +3255.487013,-393.75,-130.52 +3255.487013,-379.6875,-125.8514286 +3255.487013,-365.625,-121.1714286 +3255.487013,-351.5625,-116.48 +3255.487013,-337.5,-111.7771429 +3255.487013,-323.4375,-107.0685714 +3255.487013,-309.375,-102.3485714 +3255.487013,-295.3125,-97.61714285 +3255.487013,-281.25,-92.88 +3255.487013,-267.1875,-88.12571428 +3255.487013,-253.125,-83.37142858 +3255.487013,-239.0625,-78.6 +3255.487013,-225,-73.82285715 +3255.487013,-210.9375,-69.03428573 +3255.487013,-196.875,-64.24 +3255.487013,-182.8125,-59.43428573 +3255.487013,-168.75,-54.61771428 +3255.487013,-154.6875,-49.792 +3255.487013,-140.625,-44.95657143 +3255.487013,-126.5625,-40.11142858 +3255.487013,-112.5,-35.25714285 +3255.487013,-98.4375,-30.39314285 +3255.487013,-84.375,-25.51942858 +3255.487013,-70.3125,-20.636 +3255.487013,-56.25,-15.74285714 +3255.487013,-42.1875,-10.84057143 +3255.487013,-28.125,-5.928571428 +3255.487013,-14.0625,-1.006628573 +3255.487013,0,4.038114285 +3255.487013,14.0625,9.122285715 +3255.487013,28.125,14.216 +3255.487013,42.1875,19.32 +3255.487013,56.25,24.43314286 +3255.487013,70.3125,29.55657143 +3255.487013,84.375,34.68971428 +3255.487013,98.4375,39.83257143 +3255.487013,112.5,44.98571428 +3255.487013,126.5625,50.148 +3255.487013,140.625,55.32057143 +3255.487013,154.6875,60.50285715 +3255.487013,168.75,65.69714285 +3255.487013,182.8125,70.89714285 +3255.487013,196.875,76.10857143 +3255.487013,210.9375,81.33142858 +3255.487013,225,86.56 +3255.487013,239.0625,91.8 +3255.487013,253.125,97.05142858 +3255.487013,267.1875,102.3142857 +3255.487013,281.25,107.5828572 +3255.487013,295.3125,112.8628572 +3255.487013,309.375,118.1542857 +3255.487013,323.4375,123.4514286 +3255.487013,337.5,128.76 +3255.487013,351.5625,134.08 +3255.487013,365.625,139.4114286 +3255.487013,379.6875,144.7485714 +3255.487013,393.75,150.0971429 +3255.487013,407.8125,155.4571429 +3255.487013,421.875,160.8228572 +3255.487013,435.9375,166.2057143 +3255.487013,450,171.5885714 +3487.987013,-450,-159.9657143 +3487.987013,-435.9375,-154.9771429 +3487.987013,-421.875,-149.9828572 +3487.987013,-407.8125,-144.9714286 +3487.987013,-393.75,-139.96 +3487.987013,-379.6875,-134.9314286 +3487.987013,-365.625,-129.8971429 +3487.987013,-351.5625,-124.8514286 +3487.987013,-337.5,-119.7942857 +3487.987013,-323.4375,-114.7314286 +3487.987013,-309.375,-109.6571429 +3487.987013,-295.3125,-104.5714286 +3487.987013,-281.25,-99.48 +3487.987013,-267.1875,-94.37714285 +3487.987013,-253.125,-89.26857143 +3487.987013,-239.0625,-84.14285715 +3487.987013,-225,-79.01142858 +3487.987013,-210.9375,-73.86857143 +3487.987013,-196.875,-68.72 +3487.987013,-182.8125,-63.56 +3487.987013,-168.75,-58.38857143 +3487.987013,-154.6875,-53.21028573 +3487.987013,-140.625,-48.02114285 +3487.987013,-126.5625,-42.82228573 +3487.987013,-112.5,-37.61371428 +3487.987013,-98.4375,-32.396 +3487.987013,-84.375,-27.168 +3487.987013,-70.3125,-21.93085714 +3487.987013,-56.25,-16.684 +3487.987013,-42.1875,-11.42742857 +3487.987013,-28.125,-6.161142858 +3487.987013,-14.0625,-0.885714285 +3487.987013,0,4.524114285 +3487.987013,14.0625,9.969142858 +3487.987013,28.125,15.42457143 +3487.987013,42.1875,20.88914286 +3487.987013,56.25,26.36342858 +3487.987013,70.3125,31.848 +3487.987013,84.375,37.34228573 +3487.987013,98.4375,42.84628573 +3487.987013,112.5,48.36 +3487.987013,126.5625,53.88342858 +3487.987013,140.625,59.41714285 +3487.987013,154.6875,64.96 +3487.987013,168.75,70.51428573 +3487.987013,182.8125,76.07428573 +3487.987013,196.875,81.65142858 +3487.987013,210.9375,87.22857143 +3487.987013,225,92.82285715 +3487.987013,239.0625,98.42285715 +3487.987013,253.125,104.0342857 +3487.987013,267.1875,109.6571429 +3487.987013,281.25,115.2914286 +3487.987013,295.3125,120.9314286 +3487.987013,309.375,126.5828572 +3487.987013,323.4375,132.2457143 +3487.987013,337.5,137.9142857 +3487.987013,351.5625,143.5942857 +3487.987013,365.625,149.2857143 +3487.987013,379.6875,154.9828572 +3487.987013,393.75,160.6914286 +3487.987013,407.8125,166.4114286 +3487.987013,421.875,172.1428572 +3487.987013,435.9375,177.88 +3487.987013,450,183.6285714 +3720.487013,-450,-170.7885714 +3720.487013,-435.9375,-165.4457143 +3720.487013,-421.875,-160.0971429 +3720.487013,-407.8125,-154.7371429 +3720.487013,-393.75,-149.3657143 +3720.487013,-379.6875,-143.9885714 +3720.487013,-365.625,-138.5942857 +3720.487013,-351.5625,-133.2 +3720.487013,-337.5,-127.7885714 +3720.487013,-323.4375,-122.3714286 +3720.487013,-309.375,-116.9428572 +3720.487013,-295.3125,-111.5085714 +3720.487013,-281.25,-106.0571429 +3720.487013,-267.1875,-100.6 +3720.487013,-253.125,-95.13714285 +3720.487013,-239.0625,-89.65714285 +3720.487013,-225,-84.17142858 +3720.487013,-210.9375,-78.68 +3720.487013,-196.875,-73.17714285 +3720.487013,-182.8125,-67.66285715 +3720.487013,-168.75,-62.13714285 +3720.487013,-154.6875,-56.60285715 +3720.487013,-140.625,-51.05942858 +3720.487013,-126.5625,-45.50685715 +3720.487013,-112.5,-39.94457143 +3720.487013,-98.4375,-34.37257143 +3720.487013,-84.375,-28.79085715 +3720.487013,-70.3125,-23.19942857 +3720.487013,-56.25,-17.59885714 +3720.487013,-42.1875,-11.98857143 +3720.487013,-28.125,-6.368571428 +3720.487013,-14.0625,-0.7388 +3720.487013,0,5.036628573 +3720.487013,14.0625,10.84285714 +3720.487013,28.125,16.65885714 +3720.487013,42.1875,22.48457143 +3720.487013,56.25,28.32057143 +3720.487013,70.3125,34.16571428 +3720.487013,84.375,40.02114285 +3720.487013,98.4375,45.88628573 +3720.487013,112.5,51.76114285 +3720.487013,126.5625,57.64571428 +3720.487013,140.625,63.54285715 +3720.487013,154.6875,69.44571428 +3720.487013,168.75,75.36 +3720.487013,182.8125,81.28 +3720.487013,196.875,87.21714285 +3720.487013,210.9375,93.16 +3720.487013,225,99.11428573 +3720.487013,239.0625,105.0742857 +3720.487013,253.125,111.0514286 +3720.487013,267.1875,117.0342857 +3720.487013,281.25,123.0228572 +3720.487013,295.3125,129.0285714 +3720.487013,309.375,135.04 +3720.487013,323.4375,141.0628572 +3720.487013,337.5,147.0914286 +3720.487013,351.5625,153.1314286 +3720.487013,365.625,159.1828572 +3720.487013,379.6875,165.2457143 +3720.487013,393.75,171.3142857 +3720.487013,407.8125,177.4 +3720.487013,421.875,183.4857143 +3720.487013,435.9375,189.5885714 +3720.487013,450,195.6971429 +3953.084415,-450,-181.5885714 +3953.084415,-435.9375,-175.8914286 +3953.084415,-421.875,-170.1885714 +3953.084415,-407.8125,-164.4742857 +3953.084415,-393.75,-158.7485714 +3953.084415,-379.6875,-153.0171429 +3953.084415,-365.625,-147.2742857 +3953.084415,-351.5625,-141.52 +3953.084415,-337.5,-135.7542857 +3953.084415,-323.4375,-129.9828572 +3953.084415,-309.375,-124.2 +3953.084415,-295.3125,-118.4114286 +3953.084415,-281.25,-112.6114286 +3953.084415,-267.1875,-106.8 +3953.084415,-253.125,-100.9771429 +3953.084415,-239.0625,-95.14857143 +3953.084415,-225,-89.30857143 +3953.084415,-210.9375,-83.46285715 +3953.084415,-196.875,-77.6 +3953.084415,-182.8125,-71.73142858 +3953.084415,-168.75,-65.85714285 +3953.084415,-154.6875,-59.97142858 +3953.084415,-140.625,-54.072 +3953.084415,-126.5625,-48.16514285 +3953.084415,-112.5,-42.24914285 +3953.084415,-98.4375,-36.32285715 +3953.084415,-84.375,-30.38742858 +3953.084415,-70.3125,-24.44228572 +3953.084415,-56.25,-18.48742857 +3953.084415,-42.1875,-12.52342857 +3953.084415,-28.125,-6.549714285 +3953.084415,-14.0625,-0.565897143 +3953.084415,0,5.575714285 +3953.084415,14.0625,11.74285714 +3953.084415,28.125,17.92 +3953.084415,42.1875,24.10742857 +3953.084415,56.25,30.304 +3953.084415,70.3125,36.51028573 +3953.084415,84.375,42.72685715 +3953.084415,98.4375,48.95314285 +3953.084415,112.5,55.18914285 +3953.084415,126.5625,61.43428573 +3953.084415,140.625,67.69142858 +3953.084415,154.6875,73.95428573 +3953.084415,168.75,80.22857143 +3953.084415,182.8125,86.51428573 +3953.084415,196.875,92.81142858 +3953.084415,210.9375,99.11428573 +3953.084415,225,105.4285714 +3953.084415,239.0625,111.7542857 +3953.084415,253.125,118.0857143 +3953.084415,267.1875,124.4285714 +3953.084415,281.25,130.7828572 +3953.084415,295.3125,137.1485714 +3953.084415,309.375,143.52 +3953.084415,323.4375,149.9028572 +3953.084415,337.5,156.2971429 +3953.084415,351.5625,162.6971429 +3953.084415,365.625,169.1142857 +3953.084415,379.6875,175.5314286 +3953.084415,393.75,181.9657143 +3953.084415,407.8125,188.4057143 +3953.084415,421.875,194.8571429 +3953.084415,435.9375,201.32 +3953.084415,450,207.7942857 +4185.584415,-450,-192.36 +4185.584415,-435.9375,-186.3142857 +4185.584415,-421.875,-180.2514286 +4185.584415,-407.8125,-174.1828572 +4185.584415,-393.75,-168.1085714 +4185.584415,-379.6875,-162.0171429 +4185.584415,-365.625,-155.92 +4185.584415,-351.5625,-149.8171429 +4185.584415,-337.5,-143.6971429 +4185.584415,-323.4375,-137.5714286 +4185.584415,-309.375,-131.4342857 +4185.584415,-295.3125,-125.2914286 +4185.584415,-281.25,-119.1371429 +4185.584415,-267.1875,-112.9714286 +4185.584415,-253.125,-106.8 +4185.584415,-239.0625,-100.6114286 +4185.584415,-225,-94.42285715 +4185.584415,-210.9375,-88.21714285 +4185.584415,-196.875,-82.00571428 +4185.584415,-182.8125,-75.78285715 +4185.584415,-168.75,-69.54857143 +4185.584415,-154.6875,-63.30857143 +4185.584415,-140.625,-57.05828573 +4185.584415,-126.5625,-50.79771428 +4185.584415,-112.5,-44.52742858 +4185.584415,-98.4375,-38.24742858 +4185.584415,-84.375,-31.95828573 +4185.584415,-70.3125,-25.65942858 +4185.584415,-56.25,-19.35028572 +4185.584415,-42.1875,-13.032 +4185.584415,-28.125,-6.704571428 +4185.584415,-14.0625,-0.366965715 +4185.584415,0,6.141142858 +4185.584415,14.0625,12.66971429 +4185.584415,28.125,19.208 +4185.584415,42.1875,25.756 +4185.584415,56.25,32.31371428 +4185.584415,70.3125,38.88171428 +4185.584415,84.375,45.45885715 +4185.584415,98.4375,52.04628573 +4185.584415,112.5,58.64571428 +4185.584415,126.5625,65.25142858 +4185.584415,140.625,71.86857143 +4185.584415,154.6875,78.49142858 +4185.584415,168.75,85.13142858 +4185.584415,182.8125,91.77714285 +4185.584415,196.875,98.42857143 +4185.584415,210.9375,105.0971429 +4185.584415,225,111.7714286 +4185.584415,239.0625,118.4571429 +4185.584415,253.125,125.1542857 +4185.584415,267.1875,131.8571429 +4185.584415,281.25,138.5714286 +4185.584415,295.3125,145.2971429 +4185.584415,309.375,152.0285714 +4185.584415,323.4375,158.7771429 +4185.584415,337.5,165.5257143 +4185.584415,351.5625,172.2914286 +4185.584415,365.625,179.0628572 +4185.584415,379.6875,185.8457143 +4185.584415,393.75,192.64 +4185.584415,407.8125,199.4457143 +4185.584415,421.875,206.2571429 +4185.584415,435.9375,213.08 +4185.584415,450,219.9142857 +4418.084415,-450,-203.1085714 +4418.084415,-435.9375,-196.7028572 +4418.084415,-421.875,-190.2914286 +4418.084415,-407.8125,-183.8685714 +4418.084415,-393.75,-177.44 +4418.084415,-379.6875,-170.9942857 +4418.084415,-365.625,-164.5428572 +4418.084415,-351.5625,-158.0857143 +4418.084415,-337.5,-151.6114286 +4418.084415,-323.4375,-145.1314286 +4418.084415,-309.375,-138.6457143 +4418.084415,-295.3125,-132.1428572 +4418.084415,-281.25,-125.6342857 +4418.084415,-267.1875,-119.1142857 +4418.084415,-253.125,-112.5885714 +4418.084415,-239.0625,-106.0514286 +4418.084415,-225,-99.50285715 +4418.084415,-210.9375,-92.94857143 +4418.084415,-196.875,-86.38285715 +4418.084415,-182.8125,-79.80571428 +4418.084415,-168.75,-73.21714285 +4418.084415,-154.6875,-66.62285715 +4418.084415,-140.625,-60.01714285 +4418.084415,-126.5625,-53.404 +4418.084415,-112.5,-46.78 +4418.084415,-98.4375,-40.14628573 +4418.084415,-84.375,-33.50285715 +4418.084415,-70.3125,-26.84971428 +4418.084415,-56.25,-20.18742857 +4418.084415,-42.1875,-13.51542857 +4418.084415,-28.125,-6.833142858 +4418.084415,-14.0625,-0.142028573 +4418.084415,0,6.733714285 +4418.084415,14.0625,13.62285714 +4418.084415,28.125,20.52228572 +4418.084415,42.1875,27.43142858 +4418.084415,56.25,34.35028573 +4418.084415,70.3125,41.27885715 +4418.084415,84.375,48.21771428 +4418.084415,98.4375,55.16571428 +4418.084415,112.5,62.12571428 +4418.084415,126.5625,69.09142858 +4418.084415,140.625,76.06857143 +4418.084415,154.6875,83.05714285 +4418.084415,168.75,90.05142858 +4418.084415,182.8125,97.06285715 +4418.084415,196.875,104.08 +4418.084415,210.9375,111.1028572 +4418.084415,225,118.1428572 +4418.084415,239.0625,125.1885714 +4418.084415,253.125,132.2457143 +4418.084415,267.1875,139.3085714 +4418.084415,281.25,146.3828572 +4418.084415,295.3125,153.4685714 +4418.084415,309.375,160.5657143 +4418.084415,323.4375,167.6685714 +4418.084415,337.5,174.7885714 +4418.084415,351.5625,181.9085714 +4418.084415,365.625,189.0457143 +4418.084415,379.6875,196.1885714 +4418.084415,393.75,203.3428572 +4418.084415,407.8125,210.5085714 +4418.084415,421.875,217.68 +4418.084415,435.9375,224.8628572 +4418.084415,450,232.0571429 +4650.584415,-450,-213.8285714 +4650.584415,-435.9375,-207.0742857 +4650.584415,-421.875,-200.3028572 +4650.584415,-407.8125,-193.5257143 +4650.584415,-393.75,-186.7428572 +4650.584415,-379.6875,-179.9485714 +4650.584415,-365.625,-173.1428572 +4650.584415,-351.5625,-166.3257143 +4650.584415,-337.5,-159.5028572 +4650.584415,-323.4375,-152.6685714 +4650.584415,-309.375,-145.8228572 +4650.584415,-295.3125,-138.9714286 +4650.584415,-281.25,-132.1085714 +4650.584415,-267.1875,-125.2342857 +4650.584415,-253.125,-118.3542857 +4650.584415,-239.0625,-111.4628572 +4650.584415,-225,-104.56 +4650.584415,-210.9375,-97.65142858 +4650.584415,-196.875,-90.73142858 +4650.584415,-182.8125,-83.8 +4650.584415,-168.75,-76.86285715 +4650.584415,-154.6875,-69.91428573 +4650.584415,-140.625,-62.95428573 +4650.584415,-126.5625,-55.98457143 +4650.584415,-112.5,-49.00628573 +4650.584415,-98.4375,-42.01885715 +4650.584415,-84.375,-35.02171428 +4650.584415,-70.3125,-28.01485715 +4650.584415,-56.25,-20.99828572 +4650.584415,-42.1875,-13.972 +4650.584415,-28.125,-6.936571428 +4650.584415,-14.0625,0.111422858 +4650.584415,0,7.352 +4650.584415,14.0625,14.60285714 +4650.584415,28.125,21.86285714 +4650.584415,42.1875,29.13314285 +4650.584415,56.25,36.41314285 +4650.584415,70.3125,43.70285715 +4650.584415,84.375,51.00285715 +4650.584415,98.4375,58.31428573 +4650.584415,112.5,65.62857143 +4650.584415,126.5625,72.96 +4650.584415,140.625,80.29714285 +4650.584415,154.6875,87.64571428 +4650.584415,168.75,95.00571428 +4650.584415,182.8125,102.3714286 +4650.584415,196.875,109.7542857 +4650.584415,210.9375,117.1371429 +4650.584415,225,124.5371429 +4650.584415,239.0625,131.9428572 +4650.584415,253.125,139.36 +4650.584415,267.1875,146.7885714 +4650.584415,281.25,154.2228572 +4650.584415,295.3125,161.6742857 +4650.584415,309.375,169.1257143 +4650.584415,323.4375,176.5942857 +4650.584415,337.5,184.0685714 +4650.584415,351.5625,191.5542857 +4650.584415,365.625,199.0514286 +4650.584415,379.6875,206.56 +4650.584415,393.75,214.0742857 +4650.584415,407.8125,221.6 +4650.584415,421.875,229.1314286 +4650.584415,435.9375,236.6742857 +4650.584415,450,244.2285714 +4864.577923,-450,-223.6685714 +4864.577923,-435.9375,-216.5885714 +4864.577923,-421.875,-209.4914286 +4864.577923,-407.8125,-202.3942857 +4864.577923,-393.75,-195.28 +4864.577923,-379.6875,-188.16 +4864.577923,-365.625,-181.0285714 +4864.577923,-351.5625,-173.8857143 +4864.577923,-337.5,-166.7371429 +4864.577923,-323.4375,-159.5771429 +4864.577923,-309.375,-152.4114286 +4864.577923,-295.3125,-145.2285714 +4864.577923,-281.25,-138.04 +4864.577923,-267.1875,-130.8457143 +4864.577923,-253.125,-123.6342857 +4864.577923,-239.0625,-116.4171429 +4864.577923,-225,-109.1942857 +4864.577923,-210.9375,-101.9542857 +4864.577923,-196.875,-94.70857143 +4864.577923,-182.8125,-87.45142858 +4864.577923,-168.75,-80.18857143 +4864.577923,-154.6875,-72.91428573 +4864.577923,-140.625,-65.62857143 +4864.577923,-126.5625,-58.33714285 +4864.577923,-112.5,-51.032 +4864.577923,-98.4375,-43.71885715 +4864.577923,-84.375,-36.396 +4864.577923,-70.3125,-29.06342858 +4864.577923,-56.25,-21.72114286 +4864.577923,-42.1875,-14.36971429 +4864.577923,-28.125,-7.008 +4864.577923,-14.0625,0.371868573 +4864.577923,0,7.944571428 +4864.577923,14.0625,15.52742857 +4864.577923,28.125,23.12 +4864.577923,42.1875,30.72228573 +4864.577923,56.25,38.33485715 +4864.577923,70.3125,45.95657143 +4864.577923,84.375,53.58857143 +4864.577923,98.4375,61.22857143 +4864.577923,112.5,68.88 +4864.577923,126.5625,76.54285715 +4864.577923,140.625,84.21142858 +4864.577923,154.6875,91.89142858 +4864.577923,168.75,99.58285715 +4864.577923,182.8125,107.2857143 +4864.577923,196.875,114.9942857 +4864.577923,210.9375,122.7142857 +4864.577923,225,130.4457143 +4864.577923,239.0625,138.1828572 +4864.577923,253.125,145.9314286 +4864.577923,267.1875,153.6914286 +4864.577923,281.25,161.4628572 +4864.577923,295.3125,169.24 +4864.577923,309.375,177.0285714 +4864.577923,323.4375,184.8285714 +4864.577923,337.5,192.6342857 +4864.577923,351.5625,200.4514286 +4864.577923,365.625,208.28 +4864.577923,379.6875,216.12 +4864.577923,393.75,223.9657143 +4864.577923,407.8125,231.8228572 +4864.577923,421.875,239.6914286 +4864.577923,435.9375,247.5657143 +4864.577923,450,255.4514285 diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericICE_220kW_7.7l.veng b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericICE_220kW_7.7l.veng new file mode 100644 index 0000000000000000000000000000000000000000..cca85ad4876bc8468233a5ea42647d710327f230 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/GenericICE_220kW_7.7l.veng @@ -0,0 +1,35 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2021-01-18T16:15:30.8161241Z", + "AppVersion": "3", + "FileVersion": 5 + }, + "Body": { + "SavedInDeclMode": false, + "ModelName": "Generic 220kW 7.7l", + "Displacement": "7700", + "IdlingSpeed": 600.0, + "Inertia": 3.789, + "Fuels": [ + { + "WHTC-Urban": 0.0, + "WHTC-Rural": 0.0, + "WHTC-Motorway": 0.0, + "WHTC-Engineering": 1.02, + "ColdHotBalancingFactor": 0.0, + "CFRegPer": 0.0, + "FuelMap": "Engine map_7.7l.vmap", + "FuelType": "DieselCI" + } + ], + "RatedPower": 220000.0, + "RatedSpeed": 2200.0, + "MaxTorque": 1295.0, + "FullLoadCurve": "Full-load curve 220kW.vfld", + "WHRType": [ + "None" + ], + "WHRCorrectionFactors": {} + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/HybridStrategyParams.vhctl b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/HybridStrategyParams.vhctl new file mode 100644 index 0000000000000000000000000000000000000000..7a28da155f1ad000e68fff3b98cc3c652d01a6c6 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/HybridStrategyParams.vhctl @@ -0,0 +1,18 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2020-08-04T07:11:24.0318977Z", + "AppVersion": "3", + "FileVersion": 1 + }, + "Body": { + "EquivalenceFactorDischarge": 2.5, + "EquivalenceFactorCharge": 1.5, + "MinSoC": 10.0, + "MaxSoC": 90.0, + "TargetSoC": 50.0, + "MinICEOnTime": 3, + "AuxBufferTime": 5, + "AuxBufferChgTime": 3 + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/MaxCurrent.vimax b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/MaxCurrent.vimax new file mode 100644 index 0000000000000000000000000000000000000000..d802d5d760daf410bca1fa2b9aa42c231188f3ad --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/MaxCurrent.vimax @@ -0,0 +1,4 @@ +SOC, I_charge, I_discharge +0, 375, 375 +50, 375, 375 +100, 375, 375 \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/ShiftParameters.vtcu b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/ShiftParameters.vtcu new file mode 100644 index 0000000000000000000000000000000000000000..623d9125b82cd7ca4c1760b3938de57a76ae8ea1 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/ShiftParameters.vtcu @@ -0,0 +1,13 @@ +{ + "Header": { + "CreatedBy": " ()", + "Date": "2016-10-13T15:52:04.0766564Z", + "AppVersion": "3", + "FileVersion": 1 + }, + "Body": { + + "GearRangeUp": 1, + "GearRangeDown": 1 + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/TC Parallel.vtcc b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/TC Parallel.vtcc new file mode 100644 index 0000000000000000000000000000000000000000..4860d3fa3c67c70269e124cd0116d1bdb6973d49 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/Citybus_P1-APT-P-220kW-7.7l/TC Parallel.vtcc @@ -0,0 +1,13 @@ +Speed Ratio, Torque Ratio,MP1000 +0,5.434,436.7877021 +0.06993007,3.984933333,400.388727 +0.13986014,3.384710267,363.9897518 +0.20979021,2.92414291,327.5907766 +0.27972028,2.535866667,291.1918014 +0.34965035,2.193788429,254.7928262 +0.41958042,1.884526063,218.3938511 +0.48951049,1.600129967,167.4352858 +0.559440559,1.335420534,116.4767206 +0.629370629,1.0868,65.51815532 +0.699300699,0.9295,0 +3.496503497,1.287,-1747.150809 diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_P1-APT/Acc_Citybus.vacc b/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_P1-APT/Acc_Citybus.vacc index 4e328c20140c086881471218705d901013dd919a..05d6190eb17de228488480dfbaf31b301c7e3b6a 100644 --- a/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_P1-APT/Acc_Citybus.vacc +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_P1-APT/Acc_Citybus.vacc @@ -1,5 +1,5 @@ v [km/h],acc [m/s²],dec [m/s²] -0,0.1,-1 +0,1,-1 7,1.1,-1 25,1.1,-1 50,0.6,-1 diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs index 2a6b492edb31d7135efd292c79e09794ec6f2cbf..5b0c38cf68cdd6b292b82be522b88c1365fd4348 100644 --- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs @@ -55,7 +55,7 @@ namespace TUGraz.VectoCore.Tests.Utils public List<VectoSimulationComponent> Components = new List<VectoSimulationComponent>(); private Watt _axlegearLoss = 0.SI<Watt>(); private bool _clutchClosed = true; - private ITorqueConverterControl _torqueConverter; + private ITorqueConverter _torqueConverter; private IGearboxInfo _gearboxInfoImplementation; public IAxlegearInfo AxlegearInfo @@ -149,6 +149,11 @@ namespace TUGraz.VectoCore.Tests.Utils get { throw new NotImplementedException(); } } + public ITorqueConverterInfo TorqueConverterInfo + { + get { return _torqueConverter; } + } + public ITorqueConverterControl TorqueConverterCtl { get { return _torqueConverter; } @@ -162,6 +167,10 @@ namespace TUGraz.VectoCore.Tests.Utils public IHybridControllerInfo HybridControllerInfo { get; } public IHybridControllerCtl HybridControllerCtl { get; } public IAngledriveInfo AngledriveInfo { get; } + public bool IsTestPowertrain + { + get { return false; } + } public Watt GearboxLoss() { diff --git a/VectoCore/VectoCoreTest/VectoCoreTest.csproj b/VectoCore/VectoCoreTest/VectoCoreTest.csproj index 644e72935f18339735376aa36b2c4a2be323073a..4880a3d9dcef25e75ee87f57d41a246e8a644c1d 100644 --- a/VectoCore/VectoCoreTest/VectoCoreTest.csproj +++ b/VectoCore/VectoCoreTest/VectoCoreTest.csproj @@ -502,6 +502,60 @@ <None Include="TestData\Hybrids\Battery\GenericBatteryLarge.vbat"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\Bus.vacc"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\CityBus_AT-P.vecto"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\CityBus_AT-P.vsum"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\CityBus_AT-P.vveh"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\Engine map_7.7l.vmap"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\Full-load curve 220kW.vfld"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\GearboxAT-P.vgbx"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\Generic Supercap 48V.vreess"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\GenericEM.vemd"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\GenericEM_15KW_220Nm.vem"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\GenericEM_15kW_220Nm.vemp"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\GenericEM_32kW_450Nm.vemo"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\GenericICE_220kW_7.7l.veng"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\HeavyUrban.vdri"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\HybridStrategyParams.vhctl"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\MaxCurrent.vimax"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\ShiftParameters.vtcu"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="TestData\Hybrids\Citybus_P1-APT-P-220kW-7.7l\TC Parallel.vtcc"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> <None Include="TestData\Hybrids\ElectricMotor\GenericDrag.vemd"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None>