Skip to content

Commit

Permalink
move fuzzy logic to separate model, make preOnOff name clear and hope…
Browse files Browse the repository at this point in the history
…fully fix optimica error.
  • Loading branch information
FWuellhorst committed Dec 6, 2023
1 parent 9c60776 commit c6c73a3
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
within IBPSA.Fluid.HeatPumps.ModularReversible.Controls.Safety.BaseClasses;
model OnOffFuzzyLogic
"Fuzzy logic approach for on-off control"
parameter Real ySetRed
"Reduced relative compressor speed to allow longer on-time";
Modelica.Blocks.Interfaces.BooleanInput turOn(start=false, fixed=true)
"Indicates if device should turn on" annotation (Placement(transformation(
extent={{-132,-76},{-100,-44}})));
Modelica.Blocks.Interfaces.BooleanInput isAblToTurOn
"Indicates if the device can turn on" annotation (Placement(transformation(
extent={{-132,-106},{-100,-74}})));
Modelica.Blocks.Interfaces.BooleanInput turOff(start=false, fixed=true)
"Indicates if the device should turn off" annotation (Placement(
transformation(extent={{-132,14},{-100,46}})));
Modelica.Blocks.Interfaces.BooleanInput isAblToTurOff
"Indicates if the device can turn off"
annotation (Placement(transformation(extent={{-132,74},{-100,106}})));
Modelica.Blocks.Interfaces.BooleanInput staOff
"Indicates if the device has to stay off" annotation (Placement(
transformation(extent={{-132,-46},{-100,-14}})));
Modelica.Blocks.Interfaces.BooleanInput staOn
"Indicates if the device has to stay on" annotation (Placement(transformation(
extent={{-132,44},{-100,76}})));
Modelica.Blocks.Interfaces.RealOutput yOut
"Output for relative compressor speed from 0 to 1"
annotation (Placement(transformation(extent={{100,-10},{120,10}})));
Modelica.Blocks.Interfaces.RealInput ySet
"Input for relative compressor speed from 0 to 1"
annotation (Placement(transformation(extent={{-132,-16},{-100,16}})));
protected
Integer devRunMin(start=0, fixed=true)
"Indicates if device needs to run at minimal limit";
Integer devTurOff(start=0, fixed=true)
"Indicates if device needs to turn off";
Integer devNorOpe(start=1, fixed=true)
"Indicates if device is at normal operation";
equation
yOut = ySet * devNorOpe + 0 * devTurOff + ySetRed * devRunMin;
when edge(turOn) then
if isAblToTurOn then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
else
devTurOff = 1;
devRunMin = 0;
devNorOpe = 0;
end if;
elsewhen edge(turOff) then
if isAblToTurOff then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
else
devTurOff = 0;
devRunMin = 1;
devNorOpe = 0;
end if;
elsewhen isAblToTurOn and turOn then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
elsewhen isAblToTurOff and turOff then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
elsewhen staOff then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
elsewhen staOn then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
end when;

annotation (Documentation(info="<html>
<p>
The model uses a fuzzy logic approach to avoid the need for a state-machine.
The device either has to turn off, run at the desired operating speed, or run
at the minimal speed.
</p>
</html>", revisions="<html><ul>
<li>
<i>December 06, 2023</i> by Fabian Wuellhorst:<br/>
First implementation (see issue <a href=
\"https://github.com/RWTH-EBC/IBPSA/issues/1576\">IBPSA #1576</a>)
</li>
</ul>
</html>"), Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end OnOffFuzzyLogic;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
within IBPSA.Fluid.HeatPumps.ModularReversible.Controls.Safety.BaseClasses;
within IBPSA.Fluid.HeatPumps.ModularReversible.Controls.Safety.BaseClasses;
partial model PartialOperationalEnvelope
"Indicates if the device operation is within a defined envelope"
extends BaseClasses.PartialSafetyWithCounter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ OnPastThreshold
PartialOperationalEnvelope
PartialSafety
PartialSafetyWithCounter
OnOffFuzzyLogic
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ record Generic "Generic record definition for safety control blocks"
annotation (
Dialog(group="On/Off Control",
enable=use_minOnTime));
parameter Boolean preYSet_start "Start value of pre(n) at initial time"
parameter Boolean onOffMea_start=true
"Start value for the on-off signal of the device, true for on"
annotation (
Dialog(group="On/Off Control"),
choices(checkBox=true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ record Wuellhorst2021
extends Generic(
tabLowCoo=[263.15,283.15; 333.15,283.15],
dTHysAntFre=2,
preYSet_start=false,
onOffMea_start=false,
ySetRed=0.3,
r_mConMinPer_flow=0.1,
r_mEvaMinPer_flow=0.1,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
within IBPSA.Fluid.HeatPumps.ModularReversible.Controls.Safety.Examples;
model OnOff "Example for on off controller"
extends BaseClasses.PartialSafety( hys(pre_y_start=true));
extends BaseClasses.PartialSafety;
extends Modelica.Icons.Example;

IBPSA.Fluid.HeatPumps.ModularReversible.Controls.Safety.OnOff onOffCtr(
maxCycRat=2,
minOffTime(displayUnit="s") = 200,
minOnTime(displayUnit="s") = 300,
preYSet_start=false,
onOffMea_start=false,
use_minOffTime=true,
use_minOnTime=true,
use_maxCycRat=true,
Expand All @@ -25,7 +25,7 @@ equation
11.6667},{42,-50},{22,-50}},
color={0,0,127}));
connect(onOffCtr.sigBus, sigBus) annotation (Line(
points={{0.0833333,3.91667},{-50,3.91667},{-50,-52}},
points={{0.0833333,3.91667},{-50,3.91667},{-50,-50}},
color={255,204,51},
thickness=0.5), Text(
string="%second",
Expand Down
115 changes: 39 additions & 76 deletions IBPSA/Fluid/HeatPumps/ModularReversible/Controls/Safety/OnOff.mo
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,32 @@ model OnOff
annotation(choices(checkBox=true));
parameter Integer maxCycRat "Maximum cycle rate"
annotation (Dialog(enable=use_maxCycRat));
parameter Boolean preYSet_start=true
"Start value of pre(ySet) at initial time";
parameter Boolean onOffMea_start=true
"Start value for the on-off signal of the device, true for on";
parameter Real ySet_small
"Threshold for relative speed for the device to be considered on";
parameter Real ySetRed=ySet_small
"Reduced relative compressor speed to allow longer on-time";
Modelica.Blocks.Logical.Hysteresis ySetOn(
final pre_y_start=preYSet_start,
final pre_y_start=onOffMea_start,
final uHigh=ySet_small,
final uLow=ySet_small/2) "=true if device is set on"
annotation (Placement(transformation(extent={{-100,60},{-80,80}})));
Modelica.Blocks.Routing.BooleanPassThrough isAblToTurOff(
y(start=true, fixed=true))
"=true if the device is allowed to turn off, else false"
annotation (Placement(transformation(extent={{40,80},{60,100}})));
Modelica.Blocks.Logical.Pre preOnOff(final pre_u_start=preYSet_start)
Modelica.Blocks.Logical.Pre preOnOff(final pre_u_start=onOffMea_start)
"On off signal of previous time step"
annotation (Placement(transformation(extent={{-100,-100},{-80,-80}})));
IBPSA.Fluid.HeatPumps.ModularReversible.Controls.Safety.BaseClasses.CycleRateBoundary
cycRatBou(final maxCycRat=maxCycRat, final delTim=3600) if use_maxCycRat
"Check cycle rate violations"
annotation (Placement(transformation(extent={{20,-60},{40,-40}})));
annotation (Placement(transformation(extent={{0,-60},{20,-40}})));
IBPSA.Fluid.HeatPumps.ModularReversible.Controls.Safety.BaseClasses.OnPastThreshold locTimCtr(
final minOnTime=minOffTime) if use_minOffTime
"Check if device should be locked"
annotation (Placement(transformation(extent={{20,10},{40,30}})));
annotation (Placement(transformation(extent={{0,10},{20,30}})));
Modelica.Blocks.Logical.Not notIsOn "=true if device is off"
annotation (Placement(transformation(extent={{-100,-60},{-80,-40}})));
IBPSA.Fluid.HeatPumps.ModularReversible.Controls.Safety.BaseClasses.OnPastThreshold runTimCtr(
Expand All @@ -53,26 +53,24 @@ model OnOff
Modelica.Blocks.Logical.And andIsAblToTurOn(
y(start=true, fixed=true))
"=false to lock the device off"
annotation (Placement(transformation(extent={{60,-70},{80,-50}})));
annotation (Placement(transformation(extent={{50,-70},{70,-50}})));

Modelica.Blocks.Sources.BooleanConstant booConstCycRat(final k=true)
if not use_maxCycRat "Constant value for disabled option"
annotation (Placement(transformation(extent={{20,-100},{40,-80}})));
annotation (Placement(transformation(extent={{0,-100},{20,-80}})));
Modelica.Blocks.Sources.BooleanConstant booConstLocTim(final k=true)
if not use_minOffTime "Constant value for disabled option"
annotation (Placement(transformation(extent={{20,-20},{40,0}})));
annotation (Placement(transformation(extent={{0,-20},{20,0}})));
Modelica.Blocks.Sources.BooleanConstant booConstRunTim(final k=true)
if not use_minOnTime "Constant value for disabled option"
annotation (Placement(transformation(extent={{0,60},{20,80}})));
Modelica.Blocks.Logical.Not notSetOn "Device is not set to turn on"
annotation (Placement(transformation(extent={{-100,18},{-80,38}})));
Modelica.Blocks.Logical.And andTurOff(
y(start=not preYSet_start, fixed=true))
Modelica.Blocks.Logical.And andTurOff
"Check if device is on and is set to be turned off"
annotation (Placement(transformation(extent={{-40,0},{-20,20}})));
Modelica.Blocks.Logical.And andTurOn(
y(start=preYSet_start, fixed=true))
"Check if device is Off and is set to be turned on"
Modelica.Blocks.Logical.And andTurOn
"Check if device is off and is set to be turned on"
annotation (Placement(transformation(extent={{-40,-100},{-20,-80}})));

Modelica.Blocks.Logical.And andStaOn
Expand All @@ -87,71 +85,29 @@ model OnOff
rotation=0,
origin={-90,110})));

protected
Integer devRunMin(start=0, fixed=true)
"Indicates if device needs to run at minimal limit";
Integer devTurOff(start=0, fixed=true)
"Indicates if device needs to turn off";
Integer devNorOpe(start=1, fixed=true)
"Indicates if device is at normal operation";
BaseClasses.OnOffFuzzyLogic onOffFuzLog(ySetRed=ySetRed)
"Fuzzy logic to device for output"
annotation (Placement(transformation(extent={{74,0},{114,40}})));
equation
yOut = ySet * devNorOpe + 0 * devTurOff +ySetRed * devRunMin;
when edge(andTurOn.y) then
if andIsAblToTurOn.y then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
else
devTurOff = 1;
devRunMin = 0;
devNorOpe = 0;
end if;
elsewhen edge(andTurOff.y) then
if isAblToTurOff.y then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
else
devTurOff = 0;
devRunMin = 1;
devNorOpe = 0;
end if;
elsewhen andIsAblToTurOn.y and andTurOn.y then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
elsewhen isAblToTurOff.y and andTurOff.y then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
elsewhen andStaOff.y then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
elsewhen andStaOn.y then
devTurOff = 0;
devRunMin = 0;
devNorOpe = 1;
end when;
connect(preOnOff.y, cycRatBou.u) annotation (Line(points={{-79,-90},{-66,-90},{-66,
-66},{-24,-66},{-24,-50},{18,-50}}, color={255,0,255}));
-50},{-2,-50}}, color={255,0,255}));
connect(preOnOff.y, notIsOn.u) annotation (Line(points={{-79,-90},{-66,-90},{-66,
-66},{-108,-66},{-108,-50},{-102,-50}}, color={255,0,255}));
connect(notIsOn.y, locTimCtr.u) annotation (Line(points={{-79,-50},{-52,-50},{
-52,-10},{0,-10},{0,20},{18,20}},
connect(notIsOn.y, locTimCtr.u) annotation (Line(points={{-79,-50},{-52,-50},{-52,
-30},{-48,-30},{-48,-4},{-8,-4},{-8,20},{-2,20}},
color={255,0,255}));
connect(runTimCtr.u, preOnOff.y) annotation (Line(points={{-2,100},{-66,100},{
-66,-90},{-79,-90}}, color={255,0,255}));
connect(locTimCtr.y, andIsAblToTurOn.u1) annotation (Line(
points={{41,20},{52,20},{52,-60},{58,-60}},
points={{21,20},{26,20},{26,-10},{36,-10},{36,-60},{48,-60}},
color={255,0,255},
pattern=LinePattern.Dash));
connect(cycRatBou.y, andIsAblToTurOn.u2) annotation (Line(
points={{41,-50},{50,-50},{50,-68},{58,-68}},
points={{21,-50},{30,-50},{30,-68},{48,-68}},
color={255,0,255},
pattern=LinePattern.Dash));
connect(booConstCycRat.y, andIsAblToTurOn.u2) annotation (Line(
points={{41,-90},{50,-90},{50,-68},{58,-68}},
points={{21,-90},{32,-90},{32,-68},{48,-68}},
color={255,0,255},
pattern=LinePattern.Dash));

Expand All @@ -167,7 +123,7 @@ equation
connect(notIsOn.y, andTurOn.u1) annotation (Line(points={{-79,-50},{-52,-50},{
-52,-90},{-42,-90}}, color={255,0,255}));
connect(booConstLocTim.y, andIsAblToTurOn.u1) annotation (Line(
points={{41,-10},{52,-10},{52,-60},{58,-60}},
points={{21,-10},{36,-10},{36,-60},{48,-60}},
color={255,0,255},
pattern=LinePattern.Dash));

Expand Down Expand Up @@ -195,6 +151,22 @@ equation
{28,100},{21,100}}, color={255,0,255}));
connect(booConstRunTim.y, isAblToTurOff.u) annotation (Line(points={{21,70},{28,
70},{28,90},{38,90}}, color={255,0,255}));
connect(onOffFuzLog.yOut, yOut)
annotation (Line(points={{116,20},{130,20}}, color={0,0,127}));
connect(onOffFuzLog.ySet, ySet) annotation (Line(points={{70.8,20},{56,20},{56,36},
{-76,36},{-76,20},{-136,20}}, color={0,0,127}));
connect(onOffFuzLog.staOff, andStaOff.y) annotation (Line(points={{70.8,14},{36,
14},{36,-30},{-19,-30}}, color={255,0,255}));
connect(onOffFuzLog.staOn, andStaOn.y) annotation (Line(points={{70.8,32},{42,32},
{42,50},{-19,50}}, color={255,0,255}));
connect(onOffFuzLog.isAblToTurOff, isAblToTurOff.y) annotation (Line(points={{70.8,
38},{64,38},{64,90},{61,90}}, color={255,0,255}));
connect(andIsAblToTurOn.y, onOffFuzLog.isAblToTurOn) annotation (Line(points={{71,
-60},{80,-60},{80,-40},{54,-40},{54,2},{70.8,2}}, color={255,0,255}));
connect(onOffFuzLog.turOff, andTurOff.y) annotation (Line(points={{70.8,26},{32,
26},{32,40},{-12,40},{-12,10},{-19,10}}, color={255,0,255}));
connect(onOffFuzLog.turOn, andTurOn.y) annotation (Line(points={{70.8,8},{28,8},
{28,-70},{-12,-70},{-12,-90},{-19,-90}}, color={255,0,255}));
annotation (Documentation(info="<html>
<p>
Checks if the <code>ySet</code> value is legal by checking if
Expand Down Expand Up @@ -240,14 +212,5 @@ equation
</li>
</ul>
</html>"),
Diagram(coordinateSystem(extent={{-120,-120},{120,120}}), graphics={
Rectangle(
extent={{120,60},{60,-10}},
lineColor={0,0,127},
fillColor={255,255,255},
fillPattern=FillPattern.Solid), Text(
extent={{60,60},{120,-6}},
textColor={0,0,127},
textString="See
equations")}));
Diagram(coordinateSystem(extent={{-120,-120},{120,120}})));
end OnOff;
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ model Safety "Model including all safety levels"
final use_minOffTime=safCtrPar.use_minOffTime,
final use_maxCycRat=safCtrPar.use_maxCycRat,
final maxCycRat=safCtrPar.maxCycRat,
final preYSet_start=safCtrPar.preYSet_start,
final onOffMea_start=safCtrPar.onOffMea_start,
final ySet_small=ySet_small,
final ySetRed=safCtrPar.ySetRed) if safCtrPar.use_minOnTime or safCtrPar.use_minOffTime
or safCtrPar.use_maxCycRat "On off control block"
Expand Down

0 comments on commit c6c73a3

Please sign in to comment.