Skip to content

Commit

Permalink
Merge pull request #3 from Virtual-FCS/dev
Browse files Browse the repository at this point in the history
Pull dev to main
  • Loading branch information
jsimonclark authored Jul 1, 2021
2 parents 3c8363a + 6d91a89 commit 36ab989
Show file tree
Hide file tree
Showing 212 changed files with 5,427 additions and 244 deletions.
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ The model is rather dedicated to transport applications. However, it should rema

![picture](img/VirtualFCS_Model_Scope.png)

Documentation for the VirtualFCS library is maintained regularly and available online at the URL: https://virtual-fcs.github.io/VirtualFCS/

## System Requirements and Installation
The VirtualFCS library is designed to work with OpenModelica and supports up through version 1.14. To install OpenModelica, please visit their website:

[Information about OpenModelica](https://www.openmodelica.org/)<br/>
[Download OpenModelica v1.14 for Windows](https://build.openmodelica.org/omc/builds/windows/releases/1.14/final/)<br/>
[OpenModelica on GitHub](https://github.com/OpenModelica)<br/>

To use the VirtualFCS library, follow these steps:
1. Clone this repository to your computer
2. Open the OpenModelica Connection Editor
3. Open the file VirtualFCS\package.mo
4. The VirtualFCS library will load in the library browser on the left of the Connection Editor

Development and conventions
------------------------

Expand All @@ -22,11 +37,11 @@ Issues can be reported using the [«Issues](https://github.com/Virtual-FCS/Virtu
### Naming conventions
Naming conventions are laid out below:

Classes. Classes should be nouns in UpperCamelCase (e.g. FuelCellStack).
Instance. Instance names should be nouns in lowerCamelCase. An underscore at the end of the name may be used to characterize an upper or lower index (e.g. automotiveStack, pin_a).
Method. Methods should be verbs in lowerCamelCase (e.g. updateFuelCellStack).
Variables. Local variables, instance variables, and class variables are also written either as single letters or in lowerCamelCase (e.g. U, cellVoltage).
Constants. Constants should be written in uppercase characters separated by underscores (e.g. T_REF).
Classes. Classes should be nouns in UpperCamelCase (e.g. FuelCellStack).<br/>
Instance. Instance names should be nouns in lowerCamelCase. An underscore at the end of the name may be used to characterize an upper or lower index (e.g. automotiveStack, pin_a).<br/>
Method. Methods should be verbs in lowerCamelCase (e.g. updateFuelCellStack).<br/>
Variables. Local variables, instance variables, and class variables are also written either as single letters or in lowerCamelCase (e.g. U, cellVoltage).<br/>
Constants. Constants should be written in uppercase characters separated by underscores (e.g. T_REF).<br/>

License
-------
Expand Down
5 changes: 3 additions & 2 deletions VirtualFCS/Control/BatteryManagementSystem.mo
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
within VirtualFCS.Control;

model BatteryManagementSystem
model BatteryManagementSystem "Implement algorithms for the control of battery systems."

parameter Integer s "Number of Cells in Series";
parameter Integer p "Number of Cells in Parallel";
Expand Down Expand Up @@ -47,5 +47,6 @@ equation
Line(points = {{-64, -74}, {-64, -96}, {-44, -96}}, color = {0, 0, 255}));
annotation(
Icon(graphics = {Rectangle(fillColor = {50, 50, 50}, fillPattern = FillPattern.Solid, extent = {{-100, 100}, {100, -100}}), Text(origin = {2, 72}, lineColor = {255, 255, 255}, extent = {{-26, 22}, {26, -22}}, textString = "Load"), Text(origin = {0, -52}, lineColor = {255, 255, 255}, extent = {{-44, 34}, {48, -36}}, textString = "Battery"), Text(origin = {104, 146}, lineColor = {0, 0, 255}, extent = {{-26, 22}, {84, -80}}, textString = "%name"), Text(origin = {62, 24}, lineColor = {255, 255, 255}, extent = {{-44, 34}, {26, -24}}, textString = "SOC_init"), Text(origin = {106, -52}, lineColor = {255, 255, 255}, extent = {{-44, 34}, {-8, 10}}, textString = "Q")}, coordinateSystem(extent = {{-150, -100}, {150, 100}}, initialScale = 0.1)),
Diagram(coordinateSystem(extent = {{-150, -100}, {150, 100}})));
Diagram(coordinateSystem(extent = {{-150, -100}, {150, 100}})),
Documentation(info = "<html><head></head><body>The BatteryManagementSystem component is responsible for protecting the battery pack. It ensures that the pack is not overcharged or overdischarged to dangerous state-of-charge levels. It also limits the maximum charging and discharging current the battery pack can support.</body></html>"));
end BatteryManagementSystem;
19 changes: 13 additions & 6 deletions VirtualFCS/Control/ChargeCounter.mo
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
within VirtualFCS.Control;

model ChargeCounter
Modelica.Blocks.Interfaces.RealInput SOC_init annotation(
block ChargeCounter "Determine the state-of-charge of a battery using a charge counting algorithm"
input Modelica.Blocks.Interfaces.RealInput SOC_init "Initial state of charge of the battery." annotation(
Placement(visible = true, transformation(origin = {-120, 80}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, 80}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealInput chargeCapacity annotation(
input Modelica.Blocks.Interfaces.RealInput chargeCapacity "Nominal capacity of the battery." annotation(
Placement(visible = true, transformation(origin = {-120, -80}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, -80}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealInput electricCurrent annotation(
input Modelica.Blocks.Interfaces.RealInput electricCurrent "Measured electric current to/from the battery." annotation(
Placement(visible = true, transformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealOutput SOC annotation(
output Modelica.Blocks.Interfaces.RealOutput SOC "Battery state of charge at the current time step." annotation(
Placement(visible = true, transformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Math.Add add(k2 = -1) annotation(
Placement(visible = true, transformation(origin = {39, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Expand All @@ -34,5 +34,12 @@ equation
Line(points = {{88, 0}, {102, 0}, {102, 0}, {110, 0}}, color = {0, 0, 127}));
annotation(
Diagram,
Icon(graphics = {Rectangle(fillColor = {50, 50, 50}, fillPattern = FillPattern.Solid, extent = {{-100, 100}, {100, -100}}), Text(origin = {-38, 149}, lineColor = {0, 0, 255}, extent = {{-34, 19}, {106, -71}}, textString = "%name"), Text(origin = {-56, 85}, lineColor = {255, 255, 255}, extent = {{-34, 19}, {30, -25}}, textString = "SOC_init"), Text(origin = {-58, 5}, lineColor = {255, 255, 255}, extent = {{-34, 19}, {30, -25}}, textString = "Current"), Text(origin = {-60, -73}, lineColor = {255, 255, 255}, extent = {{-34, 19}, {38, -31}}, textString = "Capacity"), Text(origin = {88, -7}, lineColor = {255, 255, 255}, extent = {{-34, 19}, {2, -5}}, textString = "SOC")}, coordinateSystem(initialScale = 0.1)));
Icon(graphics = {Rectangle(fillColor = {50, 50, 50}, fillPattern = FillPattern.Solid, extent = {{-100, 100}, {100, -100}}), Text(origin = {-38, 149}, lineColor = {0, 0, 255}, extent = {{-34, 19}, {106, -71}}, textString = "%name"), Text(origin = {-56, 85}, lineColor = {255, 255, 255}, extent = {{-34, 19}, {30, -25}}, textString = "SOC_init"), Text(origin = {-58, 5}, lineColor = {255, 255, 255}, extent = {{-34, 19}, {30, -25}}, textString = "Current"), Text(origin = {-60, -73}, lineColor = {255, 255, 255}, extent = {{-34, 19}, {38, -31}}, textString = "Capacity"), Text(origin = {88, -7}, lineColor = {255, 255, 255}, extent = {{-34, 19}, {2, -5}}, textString = "SOC")}, coordinateSystem(initialScale = 0.1)),
Documentation(info = "<html><head></head><body><!--StartFragment--><div class=\"SCXW49888958 BCX0\" style=\"margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent; orphans: 2; widows: 2; background-color: rgb(255, 255, 255);\"><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><b>What it does</b></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\">The ChargeCounter model is designed to calculate the state-of-charge of a battery using a simple charge counting algorithm.&nbsp;</div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><br></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><b>Description</b></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\">The ChargeCounter model can be used together with a battery model (e.g. VirtualFCS.Electrochemical.Battery.LiIonBatteryPack_Lumped). It may be implement either on its own or as a component in a larger battery management system (BMS) block (e.g. VirtualFCS.Control.BatteryManagementSystem). ChargeCounter builds on components from the Modelica Standard Library.</div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><br></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><b>Assumptions</b></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\">The inital version assumes a faradaic efficiency of 100%.</div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><br></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><b>Formula</b></div>
<div><br></div></div>
<div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\">SOC = SOC_init - int_0^t{i/C dt}</div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><br></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><b>Operation</b></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><br></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><br></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\">
<b>Main Authors</b></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><a href=\"https://scholar.google.no/citations?user=YyXXh8UAAAAJ&amp;hl=en\">Dr. Simon Clark</a></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><br></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\"><b>List of Updates</b></div><div class=\"SCXW49888958 BCX0\" style=\"orphans: auto; widows: auto; margin: 0px; padding: 0px; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent;\">30.06.2021 <span class=\"Apple-tab-span\" style=\"white-space:pre\"> </span>Initial Version</div><!--EndFragment--></body></html>", __OpenModelica_infoHeader = "<html><head></head><body><br></body></html>"));
end ChargeCounter;
11 changes: 5 additions & 6 deletions VirtualFCS/Control/DCMotorControl.mo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
within VirtualFCS.Control;
model DCMotorControl
model DCMotorControl "Control the speed of a DC motor"
//*** DEFINE REPLACEABLE PACKAGES ***//
replaceable parameter VirtualFCS.Utilities.ParameterRecords.DriveDataDcPm driveData annotation(
Placement(visible = true, transformation(extent = {{-152, -68}, {-132, -48}}, rotation = 0))) constrainedby
Expand Down Expand Up @@ -94,19 +94,18 @@ equation
connect(currentController.feedForward, measuredSpeedInput) annotation(
Line(points = {{-12, -12}, {-12, -36}, {-88, -36}, {-88, -64}}, color = {0, 0, 127}));
annotation(
Documentation(info = "<html>
<p>This is a partial model of a controlled DC PM drive.</p>
Documentation(info = "<html><head></head><body><p>This is a partial model of a controlled DC PM drive.</p>
<p>
Electrical power is taken from a battery (constant voltage with inner resistance) and fed to the motor via a DC-DC inverter.
Electrical power is fed to the motor via a DC-DC inverter.
The level of detail of the DC-DC inverter may be chosen from ideal averaging or switching.
The DC-DC inverter is commanded by the current controller.
The current controller is parameterized according to the absolute optimum.
</p>
<p>
Further reading:
<a href=\"modelica://Modelica/Resources/Documentation/Electrical/Machines/DriveControl.pdf\">Tutorial at the Modelica Conference 2017</a>
</p>
</html>"),
</p><p>This model is adapted from the DC PM drive control model used in the Modelica Standard Library.</p>
</body></html>"),
Diagram(coordinateSystem(extent = {{-200, -100}, {100, 100}})),
Icon(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(fillColor = {50, 50, 50}, fillPattern = FillPattern.Solid, extent = {{-100, 100}, {100, -100}}), Text(origin = {-87, 9}, lineColor = {255, 255, 255}, extent = {{-19, 11}, {27, -21}}, textString = "s"), Text(origin = {-3, 73}, lineColor = {255, 255, 255}, extent = {{-19, 11}, {27, -17}}, textString = "pwr"), Text(origin = {73, 9}, lineColor = {255, 255, 255}, extent = {{-19, 11}, {35, -23}}, textString = "m"), Text(origin = {-5, -57}, lineColor = {255, 255, 255}, extent = {{-19, 11}, {27, -19}}, textString = "out"), Text(origin = {161, 84}, lineColor = {0, 0, 255}, extent = {{-55, 18}, {55, -18}}, textString = "%name")}),
uses(Modelica(version = "3.2.3")));
Expand Down
4 changes: 2 additions & 2 deletions VirtualFCS/Control/EnergyManagementSystem.mo
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
within VirtualFCS.Control;

model EnergyManagementSystem
block EnergyManagementSystem "Implement algorithms to control the energy and power distribution in a hybrid system."

Modelica.Blocks.Sources.Constant shut_down(k = 0) annotation(
Placement(visible = true, transformation(origin = {-70, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Expand Down Expand Up @@ -35,5 +35,5 @@ equation
Line(points = {{-120, 0}, {-82, 0}, {-82, 0}, {-82, 0}}, color = {0, 0, 127}));
annotation(
Icon(graphics = {Rectangle(fillColor = {50, 50, 50}, fillPattern = FillPattern.Solid, extent = {{-100, 100}, {100, -100}}), Text(origin = {-8, 121}, lineColor = {0, 0, 255}, extent = {{-54, 17}, {54, -17}}, textString = "%name")}, coordinateSystem(initialScale = 0.1)),
Documentation(info = "<html><head></head><body>This model implements a simple energy management algorithm for a hybrid fuel cell &amp; battery system. The model reads the state-of-charge (SOC) of the battery. If it is less than a lower threshold value, then a signal is sent to activate the fuel cell with a given electric current. The rate at which current can be demanded from the fuel cell is limited by a slew rate.&nbsp;</body></html>"));
Documentation(info = "<html><head></head><body><div>The EnergyManagementSystem component is designed to manage the flow of power between the fuel cell stack, battery, vehicle load, and balance-of-plant load. It splits the load according to pre-defined energy management rules, which are implemented within the bounds of the battery management system and the fuel cell control unit.</div><div><br></div>This model implements a simple energy management algorithm for a hybrid fuel cell &amp; battery system. The model reads the state-of-charge (SOC) of the battery. If it is less than a lower threshold value, then a signal is sent to activate the fuel cell with a given electric current. The rate at which current can be demanded from the fuel cell is limited by a slew rate.&nbsp;</body></html>"));
end EnergyManagementSystem;
Loading

0 comments on commit 36ab989

Please sign in to comment.