From 5d0738ddeacee6dd3aa9dcb0226c7265ab0a444f Mon Sep 17 00:00:00 2001 From: KV Date: Thu, 8 Sep 2022 18:30:54 +0200 Subject: [PATCH] Add LoadProfile example for Site1 --- XInTheLoop/Examples/Site1.mo | 75 ++++++++++++++++++++- XInTheLoop/Resources/Data/DriveProfile.mat | Bin 0 -> 10068 bytes 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 XInTheLoop/Resources/Data/DriveProfile.mat diff --git a/XInTheLoop/Examples/Site1.mo b/XInTheLoop/Examples/Site1.mo index ab1db63..f64446d 100644 --- a/XInTheLoop/Examples/Site1.mo +++ b/XInTheLoop/Examples/Site1.mo @@ -45,6 +45,79 @@ package Site1 "Example Site 1 for Hardware-in-the-loop (HIL) simulation" experiment(StartTime = 0, StopTime = 60, Tolerance = 1e-06, Interval = 0.1)); end Test; + model LoadProfile "Example model demonstrating exchanging values with this site for half an hour using a load profile from a data file" + extends Modelica.Icons.Example; + XInTheLoop.Examples.Site1.Blocks.Sync sync annotation( + Placement(visible = true, transformation(origin = {10, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Sources.CombiTimeTable loadSP(fileName = Modelica.Utilities.Files.loadResource("modelica://XInTheLoop/Resources/Data/DriveProfile.mat"), tableName = "X", tableOnFile = true) annotation( + Placement(visible = true, transformation(origin = {-30, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Sources.RealExpression dcdcSP annotation( + Placement(visible = true, transformation(origin = {-30, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + XInTheLoop.Examples.Site1.Blocks.PackControlBits packControlBits annotation( + Placement(visible = true, transformation(origin = {-30, 36}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + XInTheLoop.Examples.Site1.Blocks.UnpackStatusBits unpackStatusBits annotation( + Placement(visible = true, transformation(origin = {50, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + XInTheLoop.Blocks.Customized.IntegerTable keyOn(table = [0, 0; 100, 1; 1700, 0]) annotation( + Placement(visible = true, transformation(origin = {-80, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Sources.IntegerExpression loadSequence annotation( + Placement(visible = true, transformation(origin = {-80, -40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Sources.IntegerExpression remoteControl(y = 1) annotation( + Placement(visible = true, transformation(origin = {-80, 80}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + XInTheLoop.Blocks.Customized.IntegerTable start(table = [0, 0; 200, 1; 1695, 0]) annotation( + Placement(visible = true, transformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Math.MultiProduct powerStack(nu = 2) annotation( + Placement(visible = true, transformation(origin = {50, 36}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Math.MultiProduct powerBatt(nu = 2) annotation( + Placement(visible = true, transformation(origin = {50, 6}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Math.MultiProduct powerDcDcIn(nu = 2) annotation( + Placement(visible = true, transformation(origin = {50, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Math.MultiProduct powerDcDcOut(nu = 2) annotation( + Placement(visible = true, transformation(origin = {50, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Math.MultiProduct powerLoad(nu = 2) annotation( + Placement(visible = true, transformation(origin = {50, -80}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + equation + connect(keyOn.y, packControlBits.uKeyOn) annotation( + Line(points = {{-69, 40}, {-42, 40}, {-42, 39}}, color = {255, 127, 0})); + connect(loadSequence.y, packControlBits.uLoadSequence) annotation( + Line(points = {{-68, -40}, {-52, -40}, {-52, 27}, {-42, 27}}, color = {255, 127, 0})); + connect(dcdcSP.y, sync.uDcDc_SP_req) annotation( + Line(points = {{-19, 0}, {-2, 0}}, color = {0, 0, 127})); + connect(sync.yStatusBits, unpackStatusBits.u) annotation( + Line(points = {{14, 11}, {14, 70}, {38, 70}}, color = {255, 127, 0})); + connect(packControlBits.y, sync.uControlBits) annotation( + Line(points = {{-19, 36}, {-10, 36}, {-10, 6}, {-2, 6}}, color = {255, 127, 0})); + connect(start.y, packControlBits.uStartButton) annotation( + Line(points = {{-68, 0}, {-60, 0}, {-60, 32}, {-42, 32}, {-42, 33}}, color = {255, 127, 0})); + connect(remoteControl.y, packControlBits.uRemoteControl) annotation( + Line(points = {{-69, 80}, {-60, 80}, {-60, 44}, {-42, 44}, {-42, 45}}, color = {255, 127, 0})); + connect(loadSP.y[1], sync.uLoad_SP_req) annotation( + Line(points = {{-18, -30}, {-10, -30}, {-10, -6}, {-2, -6}}, color = {0, 0, 127})); + connect(sync.yV_Stack, powerStack.u[1]) annotation( + Line(points = {{22, 10}, {28, 10}, {28, 36}, {40, 36}}, color = {0, 0, 127})); + connect(sync.yI_Stack, powerStack.u[2]) annotation( + Line(points = {{22, 8}, {30, 8}, {30, 34}, {40, 34}, {40, 36}}, color = {0, 0, 127})); + connect(sync.yI_Batt, powerBatt.u[1]) annotation( + Line(points = {{22, 2}, {40, 2}, {40, 6}}, color = {0, 0, 127})); + connect(sync.yV_Batt, powerBatt.u[2]) annotation( + Line(points = {{22, 4}, {40, 4}, {40, 6}, {40, 6}}, color = {0, 0, 127})); + connect(sync.yV_In_DcDc, powerDcDcIn.u[1]) annotation( + Line(points = {{22, -2}, {34, -2}, {34, -18}, {40, -18}, {40, -20}}, color = {0, 0, 127})); + connect(sync.yI_In_DcDc, powerDcDcIn.u[2]) annotation( + Line(points = {{22, -4}, {32, -4}, {32, -20}, {40, -20}}, color = {0, 0, 127})); + connect(sync.yV_Out_DcDc, powerDcDcOut.u[1]) annotation( + Line(points = {{22, -4}, {30, -4}, {30, -48}, {40, -48}, {40, -50}}, color = {0, 0, 127})); + connect(sync.yI_Out_DcDc, powerDcDcOut.u[2]) annotation( + Line(points = {{22, -6}, {28, -6}, {28, -50}, {40, -50}, {40, -50}}, color = {0, 0, 127})); + connect(sync.yV_Load, powerLoad.u[1]) annotation( + Line(points = {{22, -8}, {26, -8}, {26, -78}, {40, -78}, {40, -80}}, color = {0, 0, 127})); + connect(sync.yI_Load, powerLoad.u[2]) annotation( + Line(points = {{22, -10}, {24, -10}, {24, -80}, {40, -80}, {40, -80}}, color = {0, 0, 127})); + annotation( + experiment(StartTime = 0, StopTime = 1750, Tolerance = 1e-06, Interval = 1), + __OpenModelica_commandLineOptions = "--matchingAlgorithm=PFPlusExt --indexReductionMethod=dynamicStateSelection -d=initialization,NLSanalyticJacobian,newInst", + __OpenModelica_simulationFlags(lv = "LOG_STATS", outputFormat = "mat", s = "dassl")); + end LoadProfile; + package Blocks "Site1-Specific Blocks" extends Icons.BlocksPackage; @@ -257,9 +330,7 @@ package Site1 "Example Site 1 for Hardware-in-the-loop (HIL) simulation" connect(unpackInt2Bools.y[13], yModelicaHeartbeat) annotation( Line(points = {{62, 0}, {80, 0}, {80, -94}, {110, -94}}, color = {255, 0, 255})); end UnpackStatusBits; - end Blocks; - annotation( Documentation(info = " This example implements a protocol to exchange values with an external system running a fuel cell, DC-DC-converter, battery, and a variable load - to enable Hardware-in-the-loop (HIL) simulations. diff --git a/XInTheLoop/Resources/Data/DriveProfile.mat b/XInTheLoop/Resources/Data/DriveProfile.mat new file mode 100644 index 0000000000000000000000000000000000000000..4ef4ff17d842b543cb58b06c5f69aaed3c1e7493 GIT binary patch literal 10068 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 UGXM6)Z;oj|>Rn?1$b^rhX literal 0 HcmV?d00001