Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit aa749d39 authored by Markus Quaritsch's avatar Markus Quaritsch
Browse files

implementing time-dependent internal resistance

parent 5b706429
No related branches found
No related tags found
No related merge requests found
Showing
with 843 additions and 226 deletions
......@@ -425,7 +425,7 @@ Public Class BatteryForm
Try
Dim riFile As String =
If(Not String.IsNullOrWhiteSpace(_batteryFile), Path.Combine(Path.GetDirectoryName(_batteryFile), tbRiCurve.Text), tbRiCurve.Text)
If File.Exists(riFile) Then riCurve = BatteryInternalResistanceReader.Create(VectoCSVFile.Read(riFile), 1)
If File.Exists(riFile) Then riCurve = BatteryInternalResistanceReader.Create(VectoCSVFile.Read(riFile))
Catch ex As Exception
End Try
......@@ -450,15 +450,24 @@ Public Class BatteryForm
End If
If Not riCurve Is Nothing Then
Dim series As Series = New Series
series.Points.DataBindXY(riCurve.Entries.Select(Function(x) x.SoC * 100).ToArray(),
riCurve.Entries.Select(Function(x) x.Resistance.Value()).ToArray())
series.ChartType = SeriesChartType.FastLine
series.MarkerSize = 3
series.Color = Color.Red
series.Name = "Internal Resistance"
series.YAxisType = AxisType.Secondary
chart.Series.Add(series)
Dim series1 As Series = New Series
series1.Points.DataBindXY(riCurve.Entries.Select(Function(x) x.SoC * 100).ToArray(),
riCurve.Entries.Select(Function(x) x.Resistance.First.Item2.Value()).ToArray())
series1.ChartType = SeriesChartType.FastLine
series1.MarkerSize = 3
series1.Color = Color.MediumVioletRed
series1.Name = "Internal Resistance t_min"
series1.YAxisType = AxisType.Secondary
chart.Series.Add(series1)
Dim series2 As Series = New Series
series2.Points.DataBindXY(riCurve.Entries.Select(Function(x) x.SoC * 100).ToArray(),
riCurve.Entries.Select(Function(x) x.Resistance.Last().Item2.Value()).ToArray())
series2.ChartType = SeriesChartType.FastLine
series2.MarkerSize = 3
series2.Color = Color.PaleVioletRed
series2.Name = "Internal Resistance t_max"
series2.YAxisType = AxisType.Secondary
chart.Series.Add(series2)
End If
......
......@@ -129,27 +129,26 @@ Partial Class MainForm
Me.OpenInGraphWindowToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.ShowInFolderToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.ToolTip1 = New System.Windows.Forms.ToolTip(Me.components)
Me.StatusBAR.SuspendLayout()
Me.Label2 = New System.Windows.Forms.Label()
Me.TabControl1.SuspendLayout()
Me.TabPageGEN.SuspendLayout()
CType(Me.PictureBox1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.TabPgOptions.SuspendLayout()
Me.PanelOptAllg.SuspendLayout()
Me.GroupBox5.SuspendLayout()
Me.GroupBox4.SuspendLayout()
Me.GroupBox3.SuspendLayout()
Me.GroupBox2.SuspendLayout()
Me.GroupBox1.SuspendLayout()
Me.TabPageDEV.SuspendLayout()
Me.ConMenFilelist.SuspendLayout()
CType(Me.SplitContainer1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SplitContainer1.Panel1.SuspendLayout()
Me.SplitContainer1.Panel2.SuspendLayout()
Me.SplitContainer1.SuspendLayout()
Me.ToolStrip1.SuspendLayout()
Me.CmOpenFile.SuspendLayout()
Me.SuspendLayout()
Me.StatusBAR.SuspendLayout
Me.TabControl1.SuspendLayout
Me.TabPageGEN.SuspendLayout
CType(Me.PictureBox1,System.ComponentModel.ISupportInitialize).BeginInit
Me.TabPgOptions.SuspendLayout
Me.PanelOptAllg.SuspendLayout
Me.GroupBox5.SuspendLayout
Me.GroupBox4.SuspendLayout
Me.GroupBox3.SuspendLayout
Me.GroupBox2.SuspendLayout
Me.GroupBox1.SuspendLayout
Me.TabPageDEV.SuspendLayout
Me.ConMenFilelist.SuspendLayout
CType(Me.SplitContainer1,System.ComponentModel.ISupportInitialize).BeginInit
Me.SplitContainer1.Panel1.SuspendLayout
Me.SplitContainer1.Panel2.SuspendLayout
Me.SplitContainer1.SuspendLayout
Me.ToolStrip1.SuspendLayout
Me.CmOpenFile.SuspendLayout
Me.SuspendLayout
'
'StatusBAR
'
......@@ -164,29 +163,29 @@ Partial Class MainForm
'
Me.ToolStripLbStatus.Name = "ToolStripLbStatus"
Me.ToolStripLbStatus.Size = New System.Drawing.Size(1030, 17)
Me.ToolStripLbStatus.Spring = True
Me.ToolStripLbStatus.Spring = true
Me.ToolStripLbStatus.Text = "Status Text"
Me.ToolStripLbStatus.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
'
'ToolStripProgBarJob
'
Me.ToolStripProgBarJob.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
Me.ToolStripProgBarJob.AutoSize = False
Me.ToolStripProgBarJob.AutoSize = false
Me.ToolStripProgBarJob.Name = "ToolStripProgBarJob"
Me.ToolStripProgBarJob.Size = New System.Drawing.Size(100, 16)
Me.ToolStripProgBarJob.Style = System.Windows.Forms.ProgressBarStyle.Continuous
Me.ToolStripProgBarJob.ToolTipText = "overall progress"
Me.ToolStripProgBarJob.Visible = False
Me.ToolStripProgBarJob.Visible = false
'
'ToolStripProgBarOverall
'
Me.ToolStripProgBarOverall.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
Me.ToolStripProgBarOverall.AutoSize = False
Me.ToolStripProgBarOverall.AutoSize = false
Me.ToolStripProgBarOverall.Name = "ToolStripProgBarOverall"
Me.ToolStripProgBarOverall.Size = New System.Drawing.Size(100, 16)
Me.ToolStripProgBarOverall.Style = System.Windows.Forms.ProgressBarStyle.Continuous
Me.ToolStripProgBarOverall.ToolTipText = "job progress"
Me.ToolStripProgBarOverall.Visible = False
Me.ToolStripProgBarOverall.Visible = false
'
'TabControl1
'
......@@ -222,34 +221,34 @@ Partial Class MainForm
Me.TabPageGEN.Size = New System.Drawing.Size(1034, 302)
Me.TabPageGEN.TabIndex = 0
Me.TabPageGEN.Text = "Job Files"
Me.TabPageGEN.UseVisualStyleBackColor = True
Me.TabPageGEN.UseVisualStyleBackColor = true
'
'btnImportXML
'
Me.btnImportXML.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.btnImportXML.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left),System.Windows.Forms.AnchorStyles)
Me.btnImportXML.Location = New System.Drawing.Point(460, 267)
Me.btnImportXML.Name = "btnImportXML"
Me.btnImportXML.Size = New System.Drawing.Size(115, 30)
Me.btnImportXML.TabIndex = 23
Me.btnImportXML.Text = "Import from XML"
Me.btnImportXML.UseVisualStyleBackColor = True
Me.btnImportXML.Visible = False
Me.btnImportXML.UseVisualStyleBackColor = true
Me.btnImportXML.Visible = false
'
'btnExportXML
'
Me.btnExportXML.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.btnExportXML.Enabled = False
Me.btnExportXML.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left),System.Windows.Forms.AnchorStyles)
Me.btnExportXML.Enabled = false
Me.btnExportXML.Location = New System.Drawing.Point(344, 267)
Me.btnExportXML.Name = "btnExportXML"
Me.btnExportXML.Size = New System.Drawing.Size(115, 30)
Me.btnExportXML.TabIndex = 22
Me.btnExportXML.Text = "Export as XML"
Me.btnExportXML.UseVisualStyleBackColor = True
Me.btnExportXML.UseVisualStyleBackColor = true
'
'Label6
'
Me.Label6.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.Label6.AutoSize = True
Me.Label6.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right),System.Windows.Forms.AnchorStyles)
Me.Label6.AutoSize = true
Me.Label6.Location = New System.Drawing.Point(814, 268)
Me.Label6.Name = "Label6"
Me.Label6.Size = New System.Drawing.Size(217, 13)
......@@ -258,7 +257,7 @@ Partial Class MainForm
'
'btStartV3
'
Me.btStartV3.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.btStartV3.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0,Byte))
Me.btStartV3.Image = Global.TUGraz.VECTO.My.Resources.Resources.Play_icon
Me.btStartV3.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft
Me.btStartV3.Location = New System.Drawing.Point(3, 56)
......@@ -268,80 +267,80 @@ Partial Class MainForm
Me.btStartV3.Text = "START"
Me.btStartV3.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText
Me.ToolTip1.SetToolTip(Me.btStartV3, "Start Simulation")
Me.btStartV3.UseVisualStyleBackColor = True
Me.btStartV3.UseVisualStyleBackColor = true
'
'LbDecl
'
Me.LbDecl.AutoSize = True
Me.LbDecl.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.LbDecl.AutoSize = true
Me.LbDecl.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0,Byte))
Me.LbDecl.Location = New System.Drawing.Point(5, 109)
Me.LbDecl.Name = "LbDecl"
Me.LbDecl.Size = New System.Drawing.Size(107, 13)
Me.LbDecl.TabIndex = 19
Me.LbDecl.Text = "Declaration Mode"
Me.LbDecl.Visible = False
Me.LbDecl.Visible = false
'
'PictureBox1
'
Me.PictureBox1.Image = CType(resources.GetObject("PictureBox1.Image"), System.Drawing.Image)
Me.PictureBox1.Image = CType(resources.GetObject("PictureBox1.Image"),System.Drawing.Image)
Me.PictureBox1.Location = New System.Drawing.Point(3, 3)
Me.PictureBox1.Name = "PictureBox1"
Me.PictureBox1.Size = New System.Drawing.Size(108, 47)
Me.PictureBox1.TabIndex = 18
Me.PictureBox1.TabStop = False
Me.PictureBox1.TabStop = false
'
'BtGENdown
'
Me.BtGENdown.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.BtGENdown.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left),System.Windows.Forms.AnchorStyles)
Me.BtGENdown.Image = Global.TUGraz.VECTO.My.Resources.Resources.Actions_arrow_down_icon
Me.BtGENdown.Location = New System.Drawing.Point(307, 267)
Me.BtGENdown.Name = "BtGENdown"
Me.BtGENdown.Size = New System.Drawing.Size(30, 30)
Me.BtGENdown.TabIndex = 6
Me.ToolTip1.SetToolTip(Me.BtGENdown, "Move job down one row")
Me.BtGENdown.UseVisualStyleBackColor = True
Me.BtGENdown.UseVisualStyleBackColor = true
'
'BtGENup
'
Me.BtGENup.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.BtGENup.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left),System.Windows.Forms.AnchorStyles)
Me.BtGENup.Image = Global.TUGraz.VECTO.My.Resources.Resources.Actions_arrow_up_icon
Me.BtGENup.Location = New System.Drawing.Point(276, 267)
Me.BtGENup.Name = "BtGENup"
Me.BtGENup.Size = New System.Drawing.Size(30, 30)
Me.BtGENup.TabIndex = 4
Me.ToolTip1.SetToolTip(Me.BtGENup, "Move job up one row")
Me.BtGENup.UseVisualStyleBackColor = True
Me.BtGENup.UseVisualStyleBackColor = true
'
'ChBoxAllGEN
'
Me.ChBoxAllGEN.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.ChBoxAllGEN.AutoSize = True
Me.ChBoxAllGEN.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left),System.Windows.Forms.AnchorStyles)
Me.ChBoxAllGEN.AutoSize = true
Me.ChBoxAllGEN.Location = New System.Drawing.Point(195, 274)
Me.ChBoxAllGEN.Name = "ChBoxAllGEN"
Me.ChBoxAllGEN.Size = New System.Drawing.Size(70, 17)
Me.ChBoxAllGEN.TabIndex = 16
Me.ChBoxAllGEN.Text = "Select All"
Me.ToolTip1.SetToolTip(Me.ChBoxAllGEN, "Select All / None")
Me.ChBoxAllGEN.UseVisualStyleBackColor = True
Me.ChBoxAllGEN.UseVisualStyleBackColor = true
'
'LvGEN
'
Me.LvGEN.AllowDrop = True
Me.LvGEN.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.LvGEN.CheckBoxes = True
Me.LvGEN.AllowDrop = true
Me.LvGEN.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right),System.Windows.Forms.AnchorStyles)
Me.LvGEN.CheckBoxes = true
Me.LvGEN.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.ColGENpath, Me.ColGENstatus})
Me.LvGEN.FullRowSelect = True
Me.LvGEN.GridLines = True
Me.LvGEN.FullRowSelect = true
Me.LvGEN.GridLines = true
Me.LvGEN.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable
Me.LvGEN.HideSelection = False
Me.LvGEN.LabelEdit = True
Me.LvGEN.HideSelection = false
Me.LvGEN.LabelEdit = true
Me.LvGEN.Location = New System.Drawing.Point(114, 3)
Me.LvGEN.Name = "LvGEN"
Me.LvGEN.Size = New System.Drawing.Size(917, 263)
Me.LvGEN.TabIndex = 14
Me.LvGEN.UseCompatibleStateImageBehavior = False
Me.LvGEN.UseCompatibleStateImageBehavior = false
Me.LvGEN.View = System.Windows.Forms.View.Details
'
'ColGENpath
......@@ -356,27 +355,27 @@ Partial Class MainForm
'
'ButtonGENremove
'
Me.ButtonGENremove.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.ButtonGENremove.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.ButtonGENremove.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left),System.Windows.Forms.AnchorStyles)
Me.ButtonGENremove.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0,Byte))
Me.ButtonGENremove.Image = Global.TUGraz.VECTO.My.Resources.Resources.minus_circle_icon
Me.ButtonGENremove.Location = New System.Drawing.Point(147, 267)
Me.ButtonGENremove.Name = "ButtonGENremove"
Me.ButtonGENremove.Size = New System.Drawing.Size(33, 30)
Me.ButtonGENremove.TabIndex = 2
Me.ToolTip1.SetToolTip(Me.ButtonGENremove, "Remove selected entries")
Me.ButtonGENremove.UseVisualStyleBackColor = True
Me.ButtonGENremove.UseVisualStyleBackColor = true
'
'ButtonGENadd
'
Me.ButtonGENadd.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.ButtonGENadd.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.ButtonGENadd.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left),System.Windows.Forms.AnchorStyles)
Me.ButtonGENadd.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0,Byte))
Me.ButtonGENadd.Image = Global.TUGraz.VECTO.My.Resources.Resources.plus_circle_icon
Me.ButtonGENadd.Location = New System.Drawing.Point(113, 267)
Me.ButtonGENadd.Name = "ButtonGENadd"
Me.ButtonGENadd.Size = New System.Drawing.Size(33, 30)
Me.ButtonGENadd.TabIndex = 1
Me.ToolTip1.SetToolTip(Me.ButtonGENadd, "Add Job File")
Me.ButtonGENadd.UseVisualStyleBackColor = True
Me.ButtonGENadd.UseVisualStyleBackColor = true
'
'TabPgOptions
'
......@@ -387,7 +386,7 @@ Partial Class MainForm
Me.TabPgOptions.Size = New System.Drawing.Size(1034, 302)
Me.TabPgOptions.TabIndex = 2
Me.TabPgOptions.Text = "Options"
Me.TabPgOptions.UseVisualStyleBackColor = True
Me.TabPgOptions.UseVisualStyleBackColor = true
'
'PanelOptAllg
'
......@@ -412,22 +411,22 @@ Partial Class MainForm
Me.GroupBox5.Name = "GroupBox5"
Me.GroupBox5.Size = New System.Drawing.Size(260, 100)
Me.GroupBox5.TabIndex = 20
Me.GroupBox5.TabStop = False
Me.GroupBox5.TabStop = false
Me.GroupBox5.Text = "Look-Ahead Coasting Override"
'
'Label5
'
Me.Label5.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label5.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, CType(0,Byte))
Me.Label5.Location = New System.Drawing.Point(7, 48)
Me.Label5.Name = "Label5"
Me.Label5.Size = New System.Drawing.Size(247, 36)
Me.Label5.TabIndex = 4
Me.Label5.Text = "Overrides Look-Ahead Coasting in declaration mode. Leave empty to use default beh" &
Me.Label5.Text = "Overrides Look-Ahead Coasting in declaration mode. Leave empty to use default beh"& _
"aviour."
'
'Label4
'
Me.Label4.AutoSize = True
Me.Label4.AutoSize = true
Me.Label4.Location = New System.Drawing.Point(10, 44)
Me.Label4.Name = "Label4"
Me.Label4.Size = New System.Drawing.Size(0, 13)
......@@ -442,7 +441,7 @@ Partial Class MainForm
'
'Label3
'
Me.Label3.AutoSize = True
Me.Label3.AutoSize = true
Me.Label3.Location = New System.Drawing.Point(158, 20)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(38, 13)
......@@ -451,12 +450,12 @@ Partial Class MainForm
'
'Label2
'
Me.Label2.AutoSize = True
Me.Label2.Location = New System.Drawing.Point(7, 20)
Me.Label2.AutoSize = true
Me.Label2.Location = New System.Drawing.Point(7, 19)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(64, 13)
Me.Label2.TabIndex = 0
Me.Label2.Text = "Min. Speed:"
Me.Label2.Size = New System.Drawing.Size(84, 13)
Me.Label2.TabIndex = 1
Me.Label2.Text = "Output Directory"
'
'GroupBox4
'
......@@ -466,7 +465,7 @@ Partial Class MainForm
Me.GroupBox4.Name = "GroupBox4"
Me.GroupBox4.Size = New System.Drawing.Size(260, 46)
Me.GroupBox4.TabIndex = 19
Me.GroupBox4.TabStop = False
Me.GroupBox4.TabStop = false
Me.GroupBox4.Text = "Output Directory"
'
'BtTCfileBrowse
......@@ -476,8 +475,8 @@ Partial Class MainForm
Me.BtTCfileBrowse.Name = "BtTCfileBrowse"
Me.BtTCfileBrowse.Size = New System.Drawing.Size(24, 24)
Me.BtTCfileBrowse.TabIndex = 27
Me.BtTCfileBrowse.TabStop = False
Me.BtTCfileBrowse.UseVisualStyleBackColor = True
Me.BtTCfileBrowse.TabStop = false
Me.BtTCfileBrowse.UseVisualStyleBackColor = true
'
'tbOutputFolder
'
......@@ -495,18 +494,18 @@ Partial Class MainForm
Me.GroupBox3.Name = "GroupBox3"
Me.GroupBox3.Size = New System.Drawing.Size(173, 110)
Me.GroupBox3.TabIndex = 18
Me.GroupBox3.TabStop = False
Me.GroupBox3.TabStop = false
Me.GroupBox3.Text = "Misc"
'
'cbSaveVectoRunData
'
Me.cbSaveVectoRunData.AutoSize = True
Me.cbSaveVectoRunData.AutoSize = true
Me.cbSaveVectoRunData.Location = New System.Drawing.Point(7, 86)
Me.cbSaveVectoRunData.Name = "cbSaveVectoRunData"
Me.cbSaveVectoRunData.Size = New System.Drawing.Size(166, 17)
Me.cbSaveVectoRunData.TabIndex = 19
Me.cbSaveVectoRunData.Text = "Export ModelData (EXPERT!)"
Me.cbSaveVectoRunData.UseVisualStyleBackColor = True
Me.cbSaveVectoRunData.UseVisualStyleBackColor = true
'
'cbActVmod
'
......@@ -515,19 +514,19 @@ Partial Class MainForm
Me.cbActVmod.Size = New System.Drawing.Size(167, 52)
Me.cbActVmod.TabIndex = 18
Me.cbActVmod.Text = "Output values in vmod at beginning and end of simulation interval (EXPERT!)"
Me.cbActVmod.UseVisualStyleBackColor = True
Me.cbActVmod.UseVisualStyleBackColor = true
'
'cbValidateRunData
'
Me.cbValidateRunData.AutoSize = True
Me.cbValidateRunData.Checked = True
Me.cbValidateRunData.AutoSize = true
Me.cbValidateRunData.Checked = true
Me.cbValidateRunData.CheckState = System.Windows.Forms.CheckState.Checked
Me.cbValidateRunData.Location = New System.Drawing.Point(6, 19)
Me.cbValidateRunData.Name = "cbValidateRunData"
Me.cbValidateRunData.Size = New System.Drawing.Size(90, 17)
Me.cbValidateRunData.TabIndex = 17
Me.cbValidateRunData.Text = "Validate Data"
Me.cbValidateRunData.UseVisualStyleBackColor = True
Me.cbValidateRunData.UseVisualStyleBackColor = true
'
'GroupBox2
'
......@@ -537,30 +536,30 @@ Partial Class MainForm
Me.GroupBox2.Name = "GroupBox2"
Me.GroupBox2.Size = New System.Drawing.Size(173, 89)
Me.GroupBox2.TabIndex = 16
Me.GroupBox2.TabStop = False
Me.GroupBox2.TabStop = false
Me.GroupBox2.Text = "Output"
'
'ChBoxModOut
'
Me.ChBoxModOut.AutoSize = True
Me.ChBoxModOut.Checked = True
Me.ChBoxModOut.AutoSize = true
Me.ChBoxModOut.Checked = true
Me.ChBoxModOut.CheckState = System.Windows.Forms.CheckState.Checked
Me.ChBoxModOut.Location = New System.Drawing.Point(6, 19)
Me.ChBoxModOut.Name = "ChBoxModOut"
Me.ChBoxModOut.Size = New System.Drawing.Size(115, 17)
Me.ChBoxModOut.TabIndex = 0
Me.ChBoxModOut.Text = "Write modal results"
Me.ChBoxModOut.UseVisualStyleBackColor = True
Me.ChBoxModOut.UseVisualStyleBackColor = true
'
'ChBoxMod1Hz
'
Me.ChBoxMod1Hz.AutoSize = True
Me.ChBoxMod1Hz.AutoSize = true
Me.ChBoxMod1Hz.Location = New System.Drawing.Point(6, 42)
Me.ChBoxMod1Hz.Name = "ChBoxMod1Hz"
Me.ChBoxMod1Hz.Size = New System.Drawing.Size(121, 17)
Me.ChBoxMod1Hz.TabIndex = 16
Me.ChBoxMod1Hz.Text = "Modal results in 1Hz"
Me.ChBoxMod1Hz.UseVisualStyleBackColor = True
Me.ChBoxMod1Hz.UseVisualStyleBackColor = true
'
'GroupBox1
'
......@@ -570,31 +569,31 @@ Partial Class MainForm
Me.GroupBox1.Name = "GroupBox1"
Me.GroupBox1.Size = New System.Drawing.Size(173, 72)
Me.GroupBox1.TabIndex = 15
Me.GroupBox1.TabStop = False
Me.GroupBox1.TabStop = false
Me.GroupBox1.Text = "Mode"
'
'RbDev
'
Me.RbDev.AutoSize = True
Me.RbDev.Checked = True
Me.RbDev.AutoSize = true
Me.RbDev.Checked = true
Me.RbDev.Location = New System.Drawing.Point(6, 42)
Me.RbDev.Name = "RbDev"
Me.RbDev.Size = New System.Drawing.Size(111, 17)
Me.RbDev.TabIndex = 1
Me.RbDev.TabStop = True
Me.RbDev.TabStop = true
Me.RbDev.Text = "Engineering Mode"
Me.RbDev.UseVisualStyleBackColor = True
Me.RbDev.UseVisualStyleBackColor = true
'
'RbDecl
'
Me.RbDecl.AutoSize = True
Me.RbDecl.AutoSize = true
Me.RbDecl.Location = New System.Drawing.Point(6, 19)
Me.RbDecl.Name = "RbDecl"
Me.RbDecl.Size = New System.Drawing.Size(109, 17)
Me.RbDecl.TabIndex = 0
Me.RbDecl.TabStop = True
Me.RbDecl.TabStop = true
Me.RbDecl.Text = "Declaration Mode"
Me.RbDecl.UseVisualStyleBackColor = True
Me.RbDecl.UseVisualStyleBackColor = true
'
'TabPageDEV
'
......@@ -606,12 +605,12 @@ Partial Class MainForm
Me.TabPageDEV.Size = New System.Drawing.Size(1034, 302)
Me.TabPageDEV.TabIndex = 3
Me.TabPageDEV.Text = "Test"
Me.TabPageDEV.UseVisualStyleBackColor = True
Me.TabPageDEV.UseVisualStyleBackColor = true
'
'Label1
'
Me.Label1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.Label1.AutoSize = True
Me.Label1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left),System.Windows.Forms.AnchorStyles)
Me.Label1.AutoSize = true
Me.Label1.Location = New System.Drawing.Point(1012, 283)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(106, 13)
......@@ -620,18 +619,19 @@ Partial Class MainForm
'
'LvDEVoptions
'
Me.LvDEVoptions.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.LvDEVoptions.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right),System.Windows.Forms.AnchorStyles)
Me.LvDEVoptions.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.ColumnHeader4, Me.ColumnHeader7, Me.ColumnHeader5, Me.ColumnHeader6, Me.ColumnHeader8, Me.ColumnHeader9})
Me.LvDEVoptions.FullRowSelect = True
Me.LvDEVoptions.GridLines = True
Me.LvDEVoptions.FullRowSelect = true
Me.LvDEVoptions.GridLines = true
Me.LvDEVoptions.HideSelection = false
Me.LvDEVoptions.Location = New System.Drawing.Point(6, 6)
Me.LvDEVoptions.MultiSelect = False
Me.LvDEVoptions.MultiSelect = false
Me.LvDEVoptions.Name = "LvDEVoptions"
Me.LvDEVoptions.Size = New System.Drawing.Size(1022, 277)
Me.LvDEVoptions.TabIndex = 0
Me.LvDEVoptions.UseCompatibleStateImageBehavior = False
Me.LvDEVoptions.UseCompatibleStateImageBehavior = false
Me.LvDEVoptions.View = System.Windows.Forms.View.Details
'
'ColumnHeader4
......@@ -668,7 +668,7 @@ Partial Class MainForm
'
Me.ConMenFilelist.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.ShowInFolderMenuItem, Me.SaveListToolStripMenuItem, Me.LoadListToolStripMenuItem, Me.LoadDefaultListToolStripMenuItem, Me.ClearListToolStripMenuItem})
Me.ConMenFilelist.Name = "ConMenFilelist"
Me.ConMenFilelist.ShowImageMargin = False
Me.ConMenFilelist.ShowImageMargin = false
Me.ConMenFilelist.Size = New System.Drawing.Size(151, 114)
'
'ShowInFolderMenuItem
......@@ -703,21 +703,22 @@ Partial Class MainForm
'
'LvMsg
'
Me.LvMsg.AllowColumnReorder = True
Me.LvMsg.AllowColumnReorder = true
Me.LvMsg.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
Me.LvMsg.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.ColumnHeader1, Me.ColumnHeader2, Me.ColumnHeader3})
Me.LvMsg.Dock = System.Windows.Forms.DockStyle.Fill
Me.LvMsg.Font = New System.Drawing.Font("Courier New", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.LvMsg.FullRowSelect = True
Me.LvMsg.GridLines = True
Me.LvMsg.Font = New System.Drawing.Font("Courier New", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0,Byte))
Me.LvMsg.FullRowSelect = true
Me.LvMsg.GridLines = true
Me.LvMsg.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable
Me.LvMsg.LabelWrap = False
Me.LvMsg.HideSelection = false
Me.LvMsg.LabelWrap = false
Me.LvMsg.Location = New System.Drawing.Point(0, 0)
Me.LvMsg.Margin = New System.Windows.Forms.Padding(0)
Me.LvMsg.Name = "LvMsg"
Me.LvMsg.Size = New System.Drawing.Size(1045, 281)
Me.LvMsg.TabIndex = 0
Me.LvMsg.UseCompatibleStateImageBehavior = False
Me.LvMsg.UseCompatibleStateImageBehavior = false
Me.LvMsg.View = System.Windows.Forms.View.Details
'
'ColumnHeader1
......@@ -737,9 +738,9 @@ Partial Class MainForm
'
'SplitContainer1
'
Me.SplitContainer1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.SplitContainer1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right),System.Windows.Forms.AnchorStyles)
Me.SplitContainer1.Location = New System.Drawing.Point(0, 27)
Me.SplitContainer1.Margin = New System.Windows.Forms.Padding(0)
Me.SplitContainer1.Name = "SplitContainer1"
......@@ -806,7 +807,7 @@ Partial Class MainForm
'
Me.GENEditorToolStripMenuItem1.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_VECTO
Me.GENEditorToolStripMenuItem1.Name = "GENEditorToolStripMenuItem1"
Me.GENEditorToolStripMenuItem1.Size = New System.Drawing.Size(152, 22)
Me.GENEditorToolStripMenuItem1.Size = New System.Drawing.Size(254, 22)
Me.GENEditorToolStripMenuItem1.Text = "Job Editor - Conventional Vehicle"
'
'JobEditorParallelHybridVehicleToolStripMenuItem
......@@ -834,52 +835,52 @@ Partial Class MainForm
'
Me.EPTPJobEditorToolStripMenuItem.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_VECTO
Me.EPTPJobEditorToolStripMenuItem.Name = "EPTPJobEditorToolStripMenuItem"
Me.EPTPJobEditorToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.EPTPJobEditorToolStripMenuItem.Size = New System.Drawing.Size(254, 22)
Me.EPTPJobEditorToolStripMenuItem.Text = "VTP Job Editor"
'
'VEHEditorToolStripMenuItem
'
Me.VEHEditorToolStripMenuItem.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_VEH
Me.VEHEditorToolStripMenuItem.Name = "VEHEditorToolStripMenuItem"
Me.VEHEditorToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.VEHEditorToolStripMenuItem.Size = New System.Drawing.Size(254, 22)
Me.VEHEditorToolStripMenuItem.Text = "Vehicle Editor"
'
'EngineEditorToolStripMenuItem
'
Me.EngineEditorToolStripMenuItem.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_ENG
Me.EngineEditorToolStripMenuItem.Name = "EngineEditorToolStripMenuItem"
Me.EngineEditorToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.EngineEditorToolStripMenuItem.Size = New System.Drawing.Size(254, 22)
Me.EngineEditorToolStripMenuItem.Text = "Engine Editor"
'
'GearboxEditorToolStripMenuItem
'
Me.GearboxEditorToolStripMenuItem.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_GBX
Me.GearboxEditorToolStripMenuItem.Name = "GearboxEditorToolStripMenuItem"
Me.GearboxEditorToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.GearboxEditorToolStripMenuItem.Size = New System.Drawing.Size(254, 22)
Me.GearboxEditorToolStripMenuItem.Text = "Gearbox Editor"
'
'GraphToolStripMenuItem
'
Me.GraphToolStripMenuItem.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_Graph
Me.GraphToolStripMenuItem.Name = "GraphToolStripMenuItem"
Me.GraphToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.GraphToolStripMenuItem.Size = New System.Drawing.Size(254, 22)
Me.GraphToolStripMenuItem.Text = "Graph"
'
'ToolStripSeparator6
'
Me.ToolStripSeparator6.Name = "ToolStripSeparator6"
Me.ToolStripSeparator6.Size = New System.Drawing.Size(149, 6)
Me.ToolStripSeparator6.Size = New System.Drawing.Size(251, 6)
'
'OpenLogToolStripMenuItem
'
Me.OpenLogToolStripMenuItem.Name = "OpenLogToolStripMenuItem"
Me.OpenLogToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.OpenLogToolStripMenuItem.Size = New System.Drawing.Size(254, 22)
Me.OpenLogToolStripMenuItem.Text = "Open Log"
'
'SettingsToolStripMenuItem
'
Me.SettingsToolStripMenuItem.Name = "SettingsToolStripMenuItem"
Me.SettingsToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.SettingsToolStripMenuItem.Size = New System.Drawing.Size(254, 22)
Me.SettingsToolStripMenuItem.Text = "Settings"
'
'ToolStripDrDnBtInfo
......@@ -923,7 +924,7 @@ Partial Class MainForm
'CmDEV
'
Me.CmDEV.Name = "CmDEV"
Me.CmDEV.ShowImageMargin = False
Me.CmDEV.ShowImageMargin = false
Me.CmDEV.Size = New System.Drawing.Size(36, 4)
'
'TmProgSec
......@@ -934,7 +935,7 @@ Partial Class MainForm
'
Me.CmOpenFile.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.OpenWithToolStripMenuItem, Me.OpenInGraphWindowToolStripMenuItem, Me.ShowInFolderToolStripMenuItem})
Me.CmOpenFile.Name = "CmOpenFile"
Me.CmOpenFile.ShowImageMargin = False
Me.CmOpenFile.ShowImageMargin = false
Me.CmOpenFile.Size = New System.Drawing.Size(174, 70)
'
'OpenWithToolStripMenuItem
......@@ -955,15 +956,6 @@ Partial Class MainForm
Me.ShowInFolderToolStripMenuItem.Size = New System.Drawing.Size(173, 22)
Me.ShowInFolderToolStripMenuItem.Text = "Show in Folder"
'
'Label2
'
Me.Label2.AutoSize = true
Me.Label2.Location = New System.Drawing.Point(7, 19)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(84, 13)
Me.Label2.TabIndex = 1
Me.Label2.Text = "Output Directory"
'
'MainForm
'
Me.AcceptButton = Me.btStartV3
......
......@@ -1239,6 +1239,7 @@ Public Class VehicleForm
If lvREESSPacks.SelectedItems.Count = 0 Then Exit Sub
Dim entry As ListViewItem = lvREESSPacks.SelectedItems(0)
_reessPackDlg._vehFile = _vehFile
_reessPackDlg.tbBattery.Text = entry.SubItems(REESPackTbl.ReessFile).Text
_reessPackDlg.tbBatteryPackCnt.Text = entry.SubItems(REESPackTbl.Count).Text
_reessPackDlg.tbStreamId.Text = entry.SubItems(REESPackTbl.StringId).Text
......@@ -1252,6 +1253,7 @@ Public Class VehicleForm
Private Sub btnAddReessPack_Click(sender As Object, e As EventArgs) Handles btnAddReessPack.Click
_reessPackDlg.Clear()
_reessPackDlg._vehFile = _vehFile
If _reessPackDlg.ShowDialog() = DialogResult.OK Then
lvREESSPacks.Items.Add(CreateREESSPackListViewItem(_reessPackDlg.tbBattery.Text, _reessPackDlg.tbBatteryPackCnt.Text.ToInt(0), _reessPackDlg.tbStreamId.Text.ToInt(0)))
......
using System.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using TUGraz.VectoCommon.Exceptions;
......@@ -11,27 +13,85 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
{
public static class BatteryInternalResistanceReader
{
public static InternalResistanceMap Create(DataTable data, int packCount)
public static InternalResistanceMap Create(DataTable data)
{
if (data.Columns.Count != 2) {
throw new VectoException("Internal Resistance Map data must contain exactly two columns: {0}, {1}",Fields.StateOfCharge, Fields.InternalResistance);
if (!(data.Columns.Count == 2 || data.Columns.Count == 4 || data.Columns.Count != 5)) {
throw new VectoException(
"Internal Resistance Map data must contain either two, four or five columns: {0}, {1}",
Fields.StateOfCharge, Fields.InternalResistance);
}
if (data.Rows.Count < 2) {
throw new VectoException("Internal Resistance Map data must contain at least 2 entries!");
}
if (!data.Columns.Contains(Fields.StateOfCharge) || !data.Columns.Contains(Fields.InternalResistance)) {
data.Columns[0].ColumnName = Fields.StateOfCharge;
data.Columns[1].ColumnName = Fields.InternalResistance;
LoggingObject.Logger<InternalResistanceMap>().Warn("Internal Resistance Map Header is invalid. Expected: '{0}, {1}', Got: '{2}'. Falling back to column index.",
Fields.StateOfCharge, Fields.InternalResistance, string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
if (data.Columns.Count == 2) {
if (!data.Columns.Contains(Fields.StateOfCharge) || !data.Columns.Contains(Fields.InternalResistance)) {
data.Columns[0].ColumnName = Fields.StateOfCharge;
data.Columns[1].ColumnName = Fields.InternalResistance;
LoggingObject.Logger<InternalResistanceMap>().Warn(
"Internal Resistance Map Header is invalid. Expected: '{0}, {1}', Got: '{2}'. Falling back to column index.",
Fields.StateOfCharge, Fields.InternalResistance,
string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
}
return new InternalResistanceMap(data.Rows.Cast<DataRow>().Select(row => {
var resistance = row.ParseDouble(Fields.InternalResistance).SI<Ohm>();
return new InternalResistanceMap.InternalResistanceMapEntry() {
SoC = row.ParseDouble(Fields.StateOfCharge) / 100,
Resistance = new List<Tuple<Second, Ohm>>() {
Tuple.Create(0.SI<Second>(), resistance),
Tuple.Create(1e9.SI<Second>(), resistance)
}
};
}).OrderBy(e => e.SoC).ToArray());
}
return new InternalResistanceMap(data.Rows.Cast<DataRow>().Select(row => new InternalResistanceMap.InternalResistanceMapEntry() {
SoC = row.ParseDouble(Fields.StateOfCharge) / 100,
Resistance = row.ParseDouble(Fields.InternalResistance).SI<Ohm>() / packCount
}).OrderBy(e => e.SoC).ToArray());
var col1 = new[] {
Tuple.Create(2.SI<Second>(), Fields.InternalResistance_2),
Tuple.Create(10.SI<Second>(), Fields.InternalResistance_10),
Tuple.Create(20.SI<Second>(), Fields.InternalResistance_20),
};
if (data.Columns.Count == col1.Length + 1) {
return ReadInternalResistanceMap(data, col1);
}
var col2 = new[] {
Tuple.Create(2.SI<Second>(), Fields.InternalResistance_2),
Tuple.Create(10.SI<Second>(), Fields.InternalResistance_10),
Tuple.Create(20.SI<Second>(), Fields.InternalResistance_20),
Tuple.Create(120.SI<Second>(), Fields.InternalResistance_120)
};
if (data.Columns.Count == col2.Length + 1) {
return ReadInternalResistanceMap(data, col2);
}
throw new VectoException("Failed to read InternalResistanceMap");
}
private static InternalResistanceMap ReadInternalResistanceMap(DataTable data, Tuple<Second, string>[] col1)
{
if ((!data.Columns.Contains(Fields.StateOfCharge) || !col1.All(x => data.Columns.Contains(x.Item2)))) {
for (var i = 0; i < col1.Length; i++) {
data.Columns[i].ColumnName = col1[i].Item2;
}
LoggingObject.Logger<InternalResistanceMap>().Warn(
"Internal Resistance Map Header is invalid. Expected: '{0}', Got: '{1}'. Falling back to column index.",
string.Join(", ", col1.Select(x => x.Item2)),
string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
}
return new InternalResistanceMap(data.Rows.Cast<DataRow>().Select(row => {
var values = col1.Select(x =>
row.Table.Columns.Contains(x.Item2) ? Tuple.Create(x.Item1, row.ParseDouble(x.Item2).SI<Ohm>()) : null)
.Where(x => x != null).ToList();
return new InternalResistanceMap.InternalResistanceMapEntry() {
SoC = row.ParseDouble(Fields.StateOfCharge) / 100,
Resistance = values
};
}).OrderBy(e => e.SoC).ToArray());
}
public static class Fields
......@@ -39,11 +99,20 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
public const string StateOfCharge = "SoC";
public const string InternalResistance = "Ri";
public const string InternalResistance_2 = "Ri-2";
public const string InternalResistance_10 = "Ri-10";
public const string InternalResistance_20 = "Ri-20";
public const string InternalResistance_120 = "Ri-120";
}
public static InternalResistanceMap Create(Stream data, int packCount)
public static InternalResistanceMap Create(Stream data)
{
return Create(VectoCSVFile.ReadStream(data), packCount);
return Create(VectoCSVFile.ReadStream(data));
}
}
}
\ No newline at end of file
......@@ -11,7 +11,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
{
public static class BatteryMaxCurrentReader
{
public static MaxCurrentMap Create(DataTable data, int packCount)
public static MaxCurrentMap Create(DataTable data)
{
if (data.Columns.Count != 3) {
throw new VectoException("Max Current Map data must contain exactly three columns: {0}, {1}, {2}", Fields.StateOfCharge, Fields.MaxChargeCurrent, Fields.MaxDischargeCurrent);
......@@ -30,8 +30,8 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
}
return new MaxCurrentMap(data.Rows.Cast<DataRow>().Select(row => new MaxCurrentMap.MaxCurrentEntry() {
SoC = row.ParseDouble(Fields.StateOfCharge) / 100,
MaxChargeCurrent = row.ParseDouble(Fields.MaxChargeCurrent).SI<Ampere>() * packCount,
MaxDischargeCurrent = -1 * row.ParseDouble(Fields.MaxDischargeCurrent).SI<Ampere>() * packCount
MaxChargeCurrent = row.ParseDouble(Fields.MaxChargeCurrent).SI<Ampere>(),
MaxDischargeCurrent = -1 * row.ParseDouble(Fields.MaxDischargeCurrent).SI<Ampere>()
}).OrderBy(e => e.SoC).ToArray());
}
......@@ -46,9 +46,9 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
}
public static MaxCurrentMap Create(Stream data, int packCount)
public static MaxCurrentMap Create(Stream data)
{
return Create(VectoCSVFile.ReadStream(data), packCount);
return Create(VectoCSVFile.ReadStream(data));
}
}
}
\ No newline at end of file
......@@ -713,10 +713,10 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
retVal.Batteries.Add(Tuple.Create(entry.StringId, new BatteryData() {
MinSOC = b.MinSOC,
MaxSOC = b.MaxSOC,
MaxCurrent = BatteryMaxCurrentReader.Create(b.MaxCurrentMap, entry.Count),
MaxCurrent = BatteryMaxCurrentReader.Create(b.MaxCurrentMap),
Capacity = b.Capacity,
InternalResistance =
BatteryInternalResistanceReader.Create(b.InternalResistanceCurve, 1),
BatteryInternalResistanceReader.Create(b.InternalResistanceCurve),
SOCMap = BatterySOCReader.Create(b.VoltageCurve),
}));
}
......
......@@ -116,12 +116,45 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Battery {
Entries = entries;
}
public Ohm Lookup(double SoC)
public Ohm Lookup(double SoC, Second tPulse)
{
var idx = FindIndex(SoC);
return VectoMath.Interpolate(Entries[idx - 1].SoC, Entries[idx].SoC, Entries[idx - 1].Resistance,
Entries[idx].Resistance, SoC);
}
var entry1 = Entries[idx - 1];
var entry2 = Entries[idx];
var resistance1 = InterpolateResistance(entry1.Resistance, tPulse);
var resistance2 = InterpolateResistance(entry2.Resistance, tPulse);
return VectoMath.Interpolate(entry1.SoC, entry2.SoC, resistance1, resistance2, SoC);
}
private Ohm InterpolateResistance(List<Tuple<Second, Ohm>> resistance, Second tPulse)
{
if (tPulse < resistance.First().Item1) {
return resistance.First().Item2;
}
if (tPulse > resistance.Last().Item1) {
return resistance.Last().Item2;
}
Tuple<Second, Ohm> entry1 = null;
Tuple<Second, Ohm> entry2 = null;
for (var index = 1; index < resistance.Count; index++) {
if (tPulse >= resistance[index - 1].Item1 && tPulse <= resistance[index].Item1) {
entry1 = resistance[index - 1];
entry2 = resistance[index];
}
}
if (entry1 == null || entry2 == null) {
throw new VectoSimulationException("Failed to lookup internal resistance!");
}
return VectoMath.Interpolate(entry1.Item1, entry2.Item1,
entry1.Item2, entry2.Item2, tPulse);
}
protected int FindIndex(double soc)
{
......@@ -147,7 +180,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Battery {
public class InternalResistanceMapEntry
{
[Required, Range(0, 1)] public double SoC;
[Required, SIRange(0, 1e6)] public Ohm Resistance;
[Required, SIRange(0, 1e6)] public List<Tuple<Second, Ohm>> Resistance;
}
}
......
......@@ -24,6 +24,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
if (idx >= 0) {
BatteryId = idx;
}
CurrentState.PulseDuration = 0.SI<Second>();
PreviousState.PulseDuration = 0.SI<Second>();
PreviousState.PowerDemand = 0.SI<Watt>();
}
#region Implementation of IBatteryProvider
......@@ -36,6 +39,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public void Initialize(double initialSoC)
{
CurrentState.PulseDuration = 0.SI<Second>();
PreviousState.PulseDuration = 0.SI<Second>();
PreviousState.PowerDemand = 0.SI<Watt>();
if (initialSoC.IsSmaller(ModelData.MinSOC) || initialSoC.IsGreater(ModelData.MaxSOC))
{
throw new VectoException("SoC must be between {0} and {1}", ModelData.MinSOC, ModelData.MaxSOC);
......@@ -45,16 +52,21 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public IRESSResponse Request(Second absTime, Second dt, Watt powerDemand, bool dryRun = false)
{
var tPulse = PreviousState.PowerDemand.Sign() == powerDemand.Sign()
? PreviousState.PulseDuration
: 0.SI<Second>();
var maxChargePower = MaxChargePower(dt);
var maxDischargePower = MaxDischargePower(dt);
if (powerDemand.IsGreater(maxChargePower, Constants.SimulationSettings.InterpolateSearchTolerance) ||
powerDemand.IsSmaller(maxDischargePower, Constants.SimulationSettings.InterpolateSearchTolerance))
{
return PowerDemandExceeded(absTime, dt, powerDemand, maxDischargePower, maxChargePower, dryRun);
return PowerDemandExceeded(absTime, dt, powerDemand, maxDischargePower, maxChargePower, tPulse, dryRun);
}
var internalResistance = ModelData.InternalResistance.Lookup(PreviousState.StateOfCharge);
var internalResistance = ModelData.InternalResistance.Lookup(PreviousState.StateOfCharge, tPulse);
var current = 0.SI<Ampere>();
if (!powerDemand.IsEqual(0))
{
......@@ -106,7 +118,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
private IRESSResponse PowerDemandExceeded(Second absTime, Second dt, Watt powerDemand, Watt maxDischargePower,
Watt maxChargePower, bool dryRun)
Watt maxChargePower, Second tPulse, bool dryRun)
{
var maxPower = powerDemand < 0 ? maxDischargePower : maxChargePower;
......@@ -116,7 +128,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
ModelData.MaxCurrent.LookupMaxDischargeCurrent(PreviousState.StateOfCharge));
var current = powerDemand < 0 ? maxDischargeCurrent : maxChargeCurrent;
var batteryLoss = current * ModelData.InternalResistance.Lookup(PreviousState.StateOfCharge) * current;
var batteryLoss = current * ModelData.InternalResistance.Lookup(PreviousState.StateOfCharge, tPulse) * current;
AbstractRESSResponse response;
if (dryRun) {
......@@ -146,11 +158,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
protected override void DoWriteModalResults(Second absTime, Second dt, IModalDataContainer container)
{
var cellVoltage = ModelData.SOCMap.Lookup(PreviousState.StateOfCharge);
var tPulse = PreviousState.PowerDemand.Sign() == CurrentState.PowerDemand.Sign()
? PreviousState.PulseDuration
: 0.SI<Second>();
container[ModalResultField.U0_reess, BatteryId] = cellVoltage;
container[ModalResultField.U_reess_terminal, BatteryId] =
cellVoltage +
CurrentState.TotalCurrent *
ModelData.InternalResistance.Lookup(PreviousState.StateOfCharge); // adding both terms because pos. current charges the battery!
ModelData.InternalResistance.Lookup(PreviousState.StateOfCharge, tPulse); // adding both terms because pos. current charges the battery!
container[ModalResultField.I_reess, BatteryId] = CurrentState.TotalCurrent;
container[ModalResultField.REESSStateOfCharge, BatteryId] = CurrentState.StateOfCharge.SI();
container[ModalResultField.P_reess_terminal, BatteryId] = CurrentState.PowerDemand;
......@@ -164,6 +179,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
protected override void DoCommitSimulationStep(Second time, Second simulationInterval)
{
var tPulse = PreviousState.PowerDemand.Sign() == CurrentState.PowerDemand.Sign()
? PreviousState.PulseDuration
: 0.SI<Second>();
CurrentState.PulseDuration = tPulse + simulationInterval;
AdvanceState();
}
......@@ -181,25 +200,27 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Watt MaxChargePower(Second dt)
{
//var maxChargeCurrent = VectoMath.Min((ModelData.MaxSOC - PreviousState.StateOfCharge) * ModelData.Capacity / dt,
// ModelData.MaxCurrent.LookupMaxChargeCurrent(PreviousState.StateOfCharge));
var maxChargeCurrent = MaxChargeCurrent(dt);
var tPulse = PreviousState.PowerDemand.Sign() > 0 // keep on charging?
? PreviousState.PulseDuration
: 0.SI<Second>();
return InternalVoltage * maxChargeCurrent +
maxChargeCurrent * InternalResistance * maxChargeCurrent;
maxChargeCurrent * InternalResistance(tPulse) * maxChargeCurrent;
}
public Watt MaxDischargePower(Second dt)
{
//var maxDischargeCurrent = VectoMath.Max(
// ((ModelData.MinSOC - PreviousState.StateOfCharge) * ModelData.Capacity / dt).LimitTo(ModelData.MaxCurrent.LookupMaxDischargeCurrent(PreviousState.StateOfCharge),
// 0.SI<Ampere>()), ModelData.MaxCurrent.LookupMaxDischargeCurrent(PreviousState.StateOfCharge));
var maxDischargeCurrent = MaxDischargeCurrent(dt);
var cellVoltage = InternalVoltage;
var tPulse = PreviousState.PowerDemand.Sign() < 0 // keep on discharging?
? PreviousState.PulseDuration
: 0.SI<Second>();
var internalResistance = InternalResistance(tPulse);
var maxDischargePower = InternalVoltage * maxDischargeCurrent +
maxDischargeCurrent * InternalResistance * maxDischargeCurrent;
var maxPower = -cellVoltage / (4 * InternalResistance) * cellVoltage;
maxDischargeCurrent * internalResistance * maxDischargeCurrent;
var maxPower = -cellVoltage / (4 * internalResistance) * cellVoltage;
return VectoMath.Max(maxDischargePower, maxPower);
}
......@@ -207,7 +228,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public double MaxSoC => ModelData.MaxSOC;
public Ohm InternalResistance => ModelData.InternalResistance.Lookup(PreviousState.StateOfCharge);
public Ohm InternalResistance(Second tPulse)
{
return ModelData.InternalResistance.Lookup(PreviousState.StateOfCharge, tPulse);
}
public AmpereSecond Capacity => ModelData.Capacity;
public Ampere MaxChargeCurrent(Second dt)
......@@ -246,6 +271,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Watt MaxChargePower;
public Watt MaxDischargePower;
public Watt BatteryLoss;
public Second PulseDuration;
}
......
......@@ -38,21 +38,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Volt OpenCircuitVoltage => _batteries.Sum(x => x.InternalVoltage);
public Ohm InternalResistance => _batteries.Sum(x => x.InternalResistance);
public Ohm InternalResistance(Second tPulse) => _batteries.Sum(x => x.InternalResistance(tPulse));
public AmpereSecond Capacity => _capacity ?? (_capacity = _batteries.Min(x => x.Capacity));
public double SoC => _batteries.Min(x => x.StateOfCharge * x.Capacity) / Capacity;
public WattSecond StoredEnergy => _batteries.Min(x => x.StateOfCharge * x.Capacity) * OpenCircuitVoltage;
public Watt MaxDischargePower(Second dt)
public Watt MaxDischargePower(Second dt, Second tPulse)
{
var maxDischargeCurrent = MaxDischargeCurrent(dt);
var maxDischargePower = OpenCircuitVoltage * maxDischargeCurrent +
maxDischargeCurrent * InternalResistance * maxDischargeCurrent;
var maxPower = -OpenCircuitVoltage / (4 * InternalResistance) * OpenCircuitVoltage;
return VectoMath.Max(maxDischargePower, maxPower);
var internalResistance = InternalResistance(tPulse);
var maxDischargePower = OpenCircuitVoltage * maxDischargeCurrent +
maxDischargeCurrent * internalResistance* maxDischargeCurrent;
var maxPower = -OpenCircuitVoltage / (4 * internalResistance) * OpenCircuitVoltage;
return VectoMath.Max(maxDischargePower, maxPower);
}
public Ampere MaxChargeCurrent(Second dt)
......@@ -65,18 +66,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return _batteries.Max(x => x.MaxDischargeCurrent(dt));
}
public Watt MaxChargePower(Second dt)
public Watt MaxChargePower(Second dt, Second tPulse)
{
var maxCurrent = MaxChargeCurrent(dt);
return OpenCircuitVoltage * maxCurrent +
maxCurrent * InternalResistance * maxCurrent;
maxCurrent * InternalResistance(tPulse) * maxCurrent;
}
public IList<IRESSResponse> Request(Second absTime, Second dt, Watt powerDemand, bool dryRun)
public IList<IRESSResponse> Request(Second absTime, Second dt, Watt powerDemand, Second tPulse, bool dryRun)
{
var current = 0.SI<Ampere>();
if (!powerDemand.IsEqual(0)) {
var solutions = VectoMath.QuadraticEquationSolver(InternalResistance.Value(), OpenCircuitVoltage.Value(),
var solutions = VectoMath.QuadraticEquationSolver(InternalResistance(tPulse).Value(), OpenCircuitVoltage.Value(),
-powerDemand.Value());
current = SelectSolution(solutions, powerDemand.Value(), dt);
}
......@@ -86,7 +87,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
return _batteries.Select(x => {
var demand = (x.InternalVoltage + x.InternalResistance * current) * current;
var demand = (x.InternalVoltage + x.InternalResistance(tPulse) * current) * current;
return x.Request(absTime, dt, demand, dryRun);
}).ToList();
}
......@@ -116,6 +117,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
Batteries[entry.Item1].AddBattery(bat);
}
PreviousState.PowerDemand = 0.SI<Watt>();
}
#region Overrides of VectoSimulationComponent
......@@ -138,11 +141,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container)
{
var cellVoltage = InternalVoltage;
var tPulse = PreviousState.PowerDemand.Sign() == CurrentState.PowerDemand.Sign()
? PreviousState.PulseDuration
: 0.SI<Second>();
container[ModalResultField.U0_reess] = cellVoltage;
container[ModalResultField.U_reess_terminal] =
cellVoltage +
CurrentState.TotalCurrent *
InternalResistance; // adding both terms because pos. current charges the battery!
InternalResistance(tPulse); // adding both terms because pos. current charges the battery!
container[ModalResultField.I_reess] = CurrentState.TotalCurrent;
//container[ModalResultField.REESSStateOfCharge] = CurrentState.StateOfCharge.SI();
container[ModalResultField.P_reess_terminal] = CurrentState.PowerDemand;
......@@ -152,11 +158,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
container[ModalResultField.P_reess_discharge_max] = CurrentState.MaxDischargePower;
}
public Ohm InternalResistance => (1 / Batteries.Sum(bs => 1 / bs.Value.InternalResistance.Value())).SI<Ohm>();
public Ohm InternalResistance(Second tPulse) => (1 / Batteries.Sum(bs => 1 / bs.Value.InternalResistance(tPulse).Value())).SI<Ohm>();
protected override void DoCommitSimulationStep(Second time, Second simulationInterval)
{
var tPulse = PreviousState.PowerDemand.Sign() == CurrentState.PowerDemand.Sign()
? PreviousState.PulseDuration
: 0.SI<Second>();
CurrentState.PulseDuration = tPulse + simulationInterval;
AdvanceState();
}
......@@ -181,13 +191,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Watt MaxChargePower(Second dt)
{
return Batteries.Values.Sum(bs => bs.MaxChargePower(dt));
var tPulse = PreviousState.PowerDemand.Sign() > 0 // keep on charging?
? PreviousState.PulseDuration
: 0.SI<Second>();
return Batteries.Values.Sum(bs => bs.MaxChargePower(dt, tPulse));
}
public Watt MaxDischargePower(Second dt)
{
return Batteries.Values.Sum(bs => bs.MaxDischargePower(dt));
var tPulse = PreviousState.PowerDemand.Sign() < 0 // keep on discharging?
? PreviousState.PulseDuration
: 0.SI<Second>();
return Batteries.Values.Sum(bs => bs.MaxDischargePower(dt, tPulse));
}
public double MinSoC { get; }
......@@ -199,6 +215,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public void Initialize(double initialSoC)
{
CurrentState.PulseDuration = 0.SI<Second>();
PreviousState.PulseDuration = 0.SI<Second>();
PreviousState.PowerDemand = 0.SI<Watt>();
foreach (var b in Batteries.Values.SelectMany(bs => bs.Batteries)) {
b.Initialize(initialSoC);
}
......@@ -209,12 +228,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var maxChargePower = MaxChargePower(dt);
var maxDischargePower = MaxDischargePower(dt);
var tPulse = PreviousState.PowerDemand.Sign() == powerDemand.Sign()
? PreviousState.PulseDuration
: 0.SI<Second>();
if (powerDemand.IsGreater(maxChargePower, Constants.SimulationSettings.InterpolateSearchTolerance) ||
powerDemand.IsSmaller(maxDischargePower, Constants.SimulationSettings.InterpolateSearchTolerance)) {
return PowerDemandExceeded(absTime, dt, powerDemand, maxDischargePower, maxChargePower, dryRun);
return PowerDemandExceeded(absTime, dt, powerDemand, maxDischargePower, maxChargePower, tPulse, dryRun);
}
var tPulseChg = PreviousState.PowerDemand.Sign() > 0 // keep on charging?
? PreviousState.PulseDuration
: 0.SI<Second>();
var tPulseDischg = PreviousState.PowerDemand.Sign() < 0 // keep on discharging?
? PreviousState.PulseDuration
: 0.SI<Second>();
var powerDemands = new Dictionary<int, Watt>();
var limitBB = new Dictionary<int, Watt>();
var distributedPower = 0.SI<Watt>();
......@@ -230,8 +259,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
var delta = 1 - Math.Sign(remainingPower.Value()) * (bs.Value.SoC - averageSoC) / averageSoC;
var power = bs.Value.Capacity / totalCapacity * delta * remainingPower;
if (!power.IsBetween(bs.Value.MaxDischargePower(dt), bs.Value.MaxChargePower(dt))) {
limitBB[bs.Key] = power.LimitTo(bs.Value.MaxDischargePower(dt), bs.Value.MaxChargePower(dt));
if (!power.IsBetween(bs.Value.MaxDischargePower(dt, tPulseDischg), bs.Value.MaxChargePower(dt, tPulseChg))) {
limitBB[bs.Key] = power.LimitTo(bs.Value.MaxDischargePower(dt, tPulseDischg), bs.Value.MaxChargePower(dt, tPulseChg));
} else {
powerDemands[bs.Key] = power;
distributedPower += power;
......@@ -247,7 +277,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var responses = new Dictionary<int, IList<IRESSResponse>>();
foreach (var entry in powerDemands) {
responses[entry.Key] = Batteries[entry.Key].Request(absTime, dt, entry.Value, dryRun);
responses[entry.Key] = Batteries[entry.Key].Request(absTime, dt, entry.Value, tPulse, dryRun);
}
if (dryRun) {
......@@ -269,7 +299,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
CurrentState.MaxChargePower = maxChargePower;
CurrentState.MaxDischargePower = maxDischargePower;
CurrentState.TotalCurrent = current;
CurrentState.BatteryLoss = current * InternalResistance * current;
CurrentState.BatteryLoss = current * InternalResistance(tPulse) * current;
if (responses.All(bb => bb.Value.All(b => b is RESSResponseSuccess))) {
return new RESSResponseSuccess(this) {
......@@ -287,14 +317,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
private IRESSResponse PowerDemandExceeded(Second absTime, Second dt, Watt powerDemand, Watt maxDischargePower,
Watt maxChargePower, bool dryRun)
Watt maxChargePower, Second tPulse, bool dryRun)
{
var maxPower = powerDemand < 0 ? maxDischargePower : maxChargePower;
var maxChargeCurrent = Batteries.Values.Sum(bs => bs.MaxChargeCurrent(dt));
var maxDischargeCurrent = Batteries.Values.Sum(bs => bs.MaxDischargeCurrent(dt));
var current = powerDemand < 0 ? maxDischargeCurrent : maxChargeCurrent;
var internalResistance = (1 / Batteries.Values.Sum(bs => 1 / bs.InternalResistance.Value())).SI<Ohm>();
var internalResistance = (1 / Batteries.Values.Sum(bs => 1 / bs.InternalResistance(tPulse).Value())).SI<Ohm>();
var batteryLoss = current * internalResistance * current;
......@@ -332,6 +362,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Watt MaxChargePower;
public Watt MaxDischargePower;
public Watt BatteryLoss;
public Second PulseDuration;
}
}
}
\ No newline at end of file
......@@ -44,10 +44,25 @@ namespace TUGraz.VectoCore.Utils
#endif
#endif
public static string VersionNumber => "0.7.3.2247" + SUFFIX;
public static string VersionNumber
{
get {
return "0.7.5.2380" + SUFFIX;
}
}
public static string BranchSuffix => "-DEV";
public static string BranchSuffix
{
get {
return "-DEV";
}
}
public static string FullVersion => string.Format("VectoCore{1} {0}", VersionNumber, BranchSuffix);
public static string FullVersion
{
get {
return string.Format("VectoCore{1} {0}", VersionNumber, BranchSuffix);
}
}
}
}
\ No newline at end of file
......@@ -211,8 +211,8 @@ namespace TUGraz.VectoCore.Tests.FileIO
Assert.AreEqual(0.8, engineering.JobInputData.Vehicle.InitialSOC);
var bat = engineering.JobInputData.Vehicle.Components.ElectricStorage.ElectricStorageElements.First().REESSPack as IBatteryPackEngineeringInputData;
var ri = BatteryInternalResistanceReader.Create(bat.InternalResistanceCurve, 1);
var imax = BatteryMaxCurrentReader.Create(bat.MaxCurrentMap, 1);
var ri = BatteryInternalResistanceReader.Create(bat.InternalResistanceCurve);
var imax = BatteryMaxCurrentReader.Create(bat.MaxCurrentMap);
Assert.NotNull(bat);
Assert.AreEqual(2, engineering.JobInputData.Vehicle.Components.ElectricStorage.ElectricStorageElements.First().Count);
......@@ -221,7 +221,7 @@ namespace TUGraz.VectoCore.Tests.FileIO
Assert.AreEqual("375", bat.MaxCurrentMap.Rows[1][BatteryMaxCurrentReader.Fields.MaxDischargeCurrent]);
Assert.AreEqual(375, imax.LookupMaxChargeCurrent(0.5).Value());
Assert.AreEqual(-375, imax.LookupMaxDischargeCurrent(0.5).Value());
Assert.AreEqual(0.04, ri.Lookup(0.5).Value());
Assert.AreEqual(0.04, ri.Lookup(0.5, 0.SI<Second>()).Value());
var em = engineering.JobInputData.Vehicle.Components.ElectricMachines;
......
......@@ -900,10 +900,9 @@ namespace TUGraz.VectoCore.Tests.Models.EngineeringMode
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create("SoC, Ri\n0,0.02\n100,0.02".ToStream(),
packCount),
BatteryInternalResistanceReader.Create("SoC, Ri\n0,0.02\n100,0.02".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream(), packCount),
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
})
}
};
......
using System.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NUnit.Framework;
using TUGraz.VECTO;
using TUGraz.VectoCommon.InputData;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.InputData.FileIO.JSON;
using TUGraz.VectoCore.InputData.Reader.ComponentData;
using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.SimulationComponent;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Battery;
using TUGraz.VectoCore.Models.SimulationComponent.Impl;
using TUGraz.VectoCore.Tests.Utils;
using Battery = TUGraz.VectoCore.Models.SimulationComponent.Impl.Battery;
......@@ -197,5 +203,440 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
Assert.AreEqual(auxPower, response.AuxPower.Value(), 1e-2);
Assert.AreEqual(powerDemand - auxPower, response.RESSResponse.PowerDemand.Value(), 1e-2);
}
public const double REESS_Capacity = 4.5;
public const double REESS_MinSoC = 0.2;
public const double REESS_MaxSoC = 0.8;
[TestCase(0.5, 0.5, 5000),
TestCase(0.5, 0.5, -5000)]
public void BatteryTimeDependentInternalResistanceTest_ConstantLoad(double initialSoC, double dt, double powerDemand)
{
var r1 = 0.02;
var r2 = 0.04;
var r3 = 0.1;
var batteryData = new BatterySystemData() {
Batteries = new List<Tuple<int, BatteryData>>() {
Tuple.Create(0, new BatteryData() {
Capacity = REESS_Capacity.SI(Unit.SI.Ampere.Hour).Cast<AmpereSecond>(),
MinSOC = REESS_MinSoC,
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create($"SoC, Ri-2, Ri-10, Ri-20\n0, {r1}, {r2}, {r3}\n100, {r1}, {r2}, {r3}".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
})
}
};
var container = new MockVehicleContainer();
var bat = new Battery(container, batteryData.Batteries.First().Item2);
var es = new ElectricSystem(container);
es.Connect(bat);
es.Connect(new MockElectricConsumer(0.SI<Watt>()));
bat.Initialize(initialSoC);
var modData = new MockModalDataContainer();
var absTime = 0.SI<Second>();
var i = 0;
for (; i < 5; i++) { // constant for the first 2 sec
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
Assert.AreEqual(r1, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 21; i++) { // linear increase for the next 8s to 0.04
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
var slope = (r2 - r1) / (10 - 2);
var r = slope * absTime.Value() + r1 - slope * 2;
Assert.AreEqual(r, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 41; i++) { // linear increase for the next 10s to 0.1
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
var slope = (r3 - r2) / (20 - 10);
var r = slope * absTime.Value() + r2 - slope * 10;
Assert.AreEqual(r, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 100; i++) { // constant after 20 sec
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
Assert.AreEqual(r3, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
}
[TestCase(0.5, 0.5, 5000),
TestCase(0.5, 0.5, -5000)]
public void BatteryTimeDependentInternalResistanceTest_LoadChanges(double initialSoC, double dt, double powerDemand)
{
var r1 = 0.02;
var r2 = 0.04;
var r3 = 0.1;
var batteryData = new BatterySystemData() {
Batteries = new List<Tuple<int, BatteryData>>() {
Tuple.Create(0, new BatteryData() {
Capacity = REESS_Capacity.SI(Unit.SI.Ampere.Hour).Cast<AmpereSecond>(),
MinSOC = REESS_MinSoC,
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create($"SoC, Ri-2, Ri-10, Ri-20\n0, {r1}, {r2}, {r3}\n100, {r1}, {r2}, {r3}".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
})
}
};
var container = new MockVehicleContainer();
var bat = new Battery(container, batteryData.Batteries.First().Item2);
var es = new ElectricSystem(container);
es.Connect(bat);
es.Connect(new MockElectricConsumer(0.SI<Watt>()));
bat.Initialize(initialSoC);
var modData = new MockModalDataContainer();
var absTime = 0.SI<Second>();
var i = 0;
for (; i < 11; i++) { // constant for the first 5 sec
var response = es.Request(absTime, dt.SI<Second>(), -Math.Sign(powerDemand) * Math.Abs(powerDemand).SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
absTime += dt.SI<Second>();
}
for (; i < 11 + 5; i++) { // constant for the first 2 sec
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
Assert.AreEqual(r1, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 10 + 21; i++) { // linear increase for the next 8s to 0.04
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
var slope = (r2 - r1) / (10 - 2);
var r = slope * (absTime.Value() - 5.5) + r1 - slope * 2;
Assert.AreEqual(r, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 10 + 41; i++) { // linear increase for the next 10s to 0.1
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
var slope = (r3 - r2) / (20 - 10);
var r = slope * (absTime.Value() - 5.5) + r2 - slope * 10;
Assert.AreEqual(r, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 100; i++) { // constant after 20 sec
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
Assert.AreEqual(r3, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
}
[TestCase(0.5, 0.5, 5000),
TestCase(0.5, 0.5, -5000)]
public void BatterySystemTimeDependentInternalResistanceTest_ConstantLoad(double initialSoC, double dt, double powerDemand)
{
var r1 = 0.02;
var r2 = 0.04;
var r3 = 0.1;
var batteryData = new BatterySystemData() {
Batteries = new List<Tuple<int, BatteryData>>() {
Tuple.Create(0, new BatteryData() {
Capacity = REESS_Capacity.SI(Unit.SI.Ampere.Hour).Cast<AmpereSecond>(),
MinSOC = REESS_MinSoC,
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create($"SoC, Ri-2, Ri-10, Ri-20\n0, {r1}, {r2}, {r3}\n100, {r1}, {r2}, {r3}".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
}),
Tuple.Create(0, new BatteryData() {
Capacity = REESS_Capacity.SI(Unit.SI.Ampere.Hour).Cast<AmpereSecond>(),
MinSOC = REESS_MinSoC,
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create($"SoC, Ri-2, Ri-10, Ri-20\n0, {r1}, {r2}, {r3}\n100, {r1}, {r2}, {r3}".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
}),
Tuple.Create(1, new BatteryData() {
Capacity = REESS_Capacity.SI(Unit.SI.Ampere.Hour).Cast<AmpereSecond>(),
MinSOC = REESS_MinSoC,
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create($"SoC, Ri-2, Ri-10, Ri-20\n0, {r1}, {r2}, {r3}\n100, {r1}, {r2}, {r3}".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
}),
Tuple.Create(1, new BatteryData() {
Capacity = REESS_Capacity.SI(Unit.SI.Ampere.Hour).Cast<AmpereSecond>(),
MinSOC = REESS_MinSoC,
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create($"SoC, Ri-2, Ri-10, Ri-20\n0, {r1}, {r2}, {r3}\n100, {r1}, {r2}, {r3}".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
})
}
};
var container = new MockVehicleContainer();
var bat = new BatterySystem(container, batteryData);
var es = new ElectricSystem(container);
es.Connect(bat);
es.Connect(new MockElectricConsumer(0.SI<Watt>()));
bat.Initialize(initialSoC);
var modData = new MockModalDataContainer();
var absTime = 0.SI<Second>();
var i = 0;
for (; i < 5; i++) { // constant for the first 2 sec
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
Assert.AreEqual(r1, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 21; i++) { // linear increase for the next 8s to 0.04
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
var slope = (r2 - r1) / (10 - 2);
var r = slope * absTime.Value() + r1 - slope * 2;
Assert.AreEqual(r, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 41; i++) { // linear increase for the next 10s to 0.1
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
var slope = (r3 - r2) / (20 - 10);
var r = slope * absTime.Value() + r2 - slope * 10;
Assert.AreEqual(r, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 100; i++) { // constant after 20 sec
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
Assert.AreEqual(r3, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
}
[TestCase(0.5, 0.5, 5000),
TestCase(0.5, 0.5, -5000)]
public void BatterySystemTimeDependentInternalResistanceTest_LoadChanges(double initialSoC, double dt, double powerDemand)
{
var r1 = 0.02;
var r2 = 0.04;
var r3 = 0.1;
var batteryData = new BatterySystemData() {
Batteries = new List<Tuple<int, BatteryData>>() {
Tuple.Create(0, new BatteryData() {
Capacity = REESS_Capacity.SI(Unit.SI.Ampere.Hour).Cast<AmpereSecond>(),
MinSOC = REESS_MinSoC,
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create($"SoC, Ri-2, Ri-10, Ri-20\n0, {r1}, {r2}, {r3}\n100, {r1}, {r2}, {r3}".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
}),
Tuple.Create(0, new BatteryData() {
Capacity = REESS_Capacity.SI(Unit.SI.Ampere.Hour).Cast<AmpereSecond>(),
MinSOC = REESS_MinSoC,
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create($"SoC, Ri-2, Ri-10, Ri-20\n0, {r1}, {r2}, {r3}\n100, {r1}, {r2}, {r3}".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
}),
Tuple.Create(1, new BatteryData() {
Capacity = REESS_Capacity.SI(Unit.SI.Ampere.Hour).Cast<AmpereSecond>(),
MinSOC = REESS_MinSoC,
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create($"SoC, Ri-2, Ri-10, Ri-20\n0, {r1}, {r2}, {r3}\n100, {r1}, {r2}, {r3}".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
}),
Tuple.Create(1, new BatteryData() {
Capacity = REESS_Capacity.SI(Unit.SI.Ampere.Hour).Cast<AmpereSecond>(),
MinSOC = REESS_MinSoC,
MaxSOC = REESS_MaxSoC,
SOCMap = BatterySOCReader.Create("SOC,V\n0,590\n100,658".ToStream()),
InternalResistance =
BatteryInternalResistanceReader.Create($"SoC, Ri-2, Ri-10, Ri-20\n0, {r1}, {r2}, {r3}\n100, {r1}, {r2}, {r3}".ToStream()),
MaxCurrent = BatteryMaxCurrentReader.Create(
"SOC, I_charge, I_discharge\n0, 375, 573\n100, 375, 375".ToStream()),
})
}
};
var container = new MockVehicleContainer();
var bat = new BatterySystem(container, batteryData);
var es = new ElectricSystem(container);
es.Connect(bat);
es.Connect(new MockElectricConsumer(0.SI<Watt>()));
bat.Initialize(initialSoC);
var modData = new MockModalDataContainer();
var absTime = 0.SI<Second>();
var i = 0;
for (; i < 11; i++) { // constant for the first 2 sec
var response = es.Request(absTime, dt.SI<Second>(), -Math.Sign(powerDemand) * Math.Abs(powerDemand).SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
absTime += dt.SI<Second>();
}
for (; i < 11 + 5; i++) { // constant for the first 2 sec
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
Assert.AreEqual(r1, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 11 + 21; i++) { // linear increase for the next 8s to 0.04
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
var slope = (r2 - r1) / (10 - 2);
var r = slope * (absTime.Value() - 5.5) + r1 - slope * 2;
Assert.AreEqual(r, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 11 + 41; i++) { // linear increase for the next 10s to 0.1
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
var slope = (r3 - r2) / (20 - 10);
var r = slope * (absTime.Value() - 5.5) + r2 - slope * 10;
Assert.AreEqual(r, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
for (; i < 11 + 100; i++) { // constant after 20 sec
var response = es.Request(absTime, dt.SI<Second>(), powerDemand.SI<Watt>());
Assert.IsInstanceOf<ElectricSystemResponseSuccess>(response);
bat.CommitSimulationStep(absTime, dt.SI<Second>(), modData);
var current = (Ampere)modData[ModalResultField.I_reess];
var rREESS = (Watt)modData[ModalResultField.P_reess_loss] / current / current;
Assert.AreEqual(r3, rREESS.Value(), 1e-9, $"{i} / {absTime}");
absTime += dt.SI<Second>();
}
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment