Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation and demo of IntervalTest #3913

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions Modelica/Blocks/Logical.mo
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,84 @@ Real input u2, otherwise the output is <strong>false</strong>.
</html>"));
end LessEqual;

block IntervalTest
"Tests if input u is within the specified interval"
extends Modelica.Blocks.Interfaces.partialBooleanSO;
parameter Boolean useConstantLimits=true "Use constant limits, if true; otherwise signal input limits are used" annotation(Evaluate=true);
parameter Real constantLowerLimit "Lower limit of interval" annotation(Dialog(enable=useConstantLimits));
parameter Boolean ClosedOnLeft=false "Include lower limit point, if true" annotation(Evaluate=true);
parameter Real constantUpperLimit "Upper limit of interval" annotation(Dialog(enable=useConstantLimits));
parameter Boolean ClosedOnRight=false "Include upper limit point, if true" annotation(Evaluate=true);
parameter Boolean InsideInterval=true "Output u is equal to true, if u is inside interval; otherwise output is inverted" annotation(Evaluate=true);
Modelica.Blocks.Interfaces.RealInput u annotation (Placement(transformation(
extent={{-140,-20},{-100,20}}), iconTransformation(extent={{-140,-20},{
-100,20}})));
Modelica.Blocks.Interfaces.RealInput lowerLimit if not useConstantLimits
annotation (Placement(transformation(extent={{-140,-100},{-100,-60}})));
Modelica.Blocks.Interfaces.RealInput upperLimit if not useConstantLimits
annotation (Placement(transformation(extent={{-140,60},{-100,100}})));

protected
Modelica.Blocks.Interfaces.RealInput lowerLimitInternal annotation (Placement(
transformation(extent={{-94,-84},{-86,-76}}), iconTransformation(extent={
{-94,56},{-86,64}})));
Modelica.Blocks.Interfaces.RealInput upperLimitInternal annotation (Placement(
transformation(extent={{-94,76},{-86,84}}), iconTransformation(extent={{-94,76},
{-86,84}})));
Comment on lines +379 to +384
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it could be considered good style to at least not have an iconTransformation on a protected component? Maybe remove the entire Placement annotation?

equation
if useConstantLimits then
upperLimitInternal = constantUpperLimit;
lowerLimitInternal = constantLowerLimit;
else
connect(upperLimitInternal, upperLimit);
connect(lowerLimitInternal, lowerLimit);
end if;
assert(upperLimitInternal>lowerLimitInternal, "Erroneous interval limits");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this assertion is really needed, I would set this as a warning only - insted of hard termination of the simulation. Optionally, a parameter of type "AssertionLevel" could be add to give the user an opportunity to decide - but this approach is not used elsewhere in MSL so maybe not that good idea.

if ClosedOnLeft then
if ClosedOnRight then
if InsideInterval then
y = u>=lowerLimitInternal and u<=upperLimitInternal;
else
y = u< lowerLimitInternal or u> upperLimitInternal;
end if;
else
if InsideInterval then
y = u>=lowerLimitInternal and u< upperLimitInternal;
else
y = u< lowerLimitInternal or u>=upperLimitInternal;
end if;
end if;
else
if ClosedOnRight then
if InsideInterval then
y = u> lowerLimitInternal and u<=upperLimitInternal;
else
y = u<=lowerLimitInternal or u> upperLimitInternal;
end if;
else
if InsideInterval then
y = u> lowerLimitInternal and u< upperLimitInternal;
else
y = u<=lowerLimitInternal or u>=upperLimitInternal;
end if;
end if;
end if;
annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},
{100,100}}), graphics={Text(
extent={{-60,50},{60,-30}},
textColor={0,0,0},
textString="[ ? ]"),
Line(visible=not useConstantLimits, points={{-100,-80},{-50,-80},{-50,-26}}, color={0,0,0}),
Line(visible=not useConstantLimits, points={{-100,80},{50,80},{50,34}}, color={0,0,0})}),
Documentation(info="<html>
<p>
The output is <strong>true</strong> if the Real input is within the interval specified by the lower and the upper limit.
The Boolean parameters ClosedOnLeft and ClosedOnRight indicate whether the lower and upper limit point, respectively, are included in the interval.
If the Boolean parameter InsideInterval = false, the output is inverted, i.e. y is <strong>true</strong> if u is outside the interval.
</p>
</html>"));
end IntervalTest;

block ZeroCrossing "Trigger zero crossing of input u"
extends Blocks.Interfaces.partialBooleanSO;
Blocks.Interfaces.RealInput u annotation (Placement(transformation(extent={
Expand Down
33 changes: 33 additions & 0 deletions Modelica/Blocks/package.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,39 @@ The output is constant from the beginning.
</html>"));
end DemoSignalCharacteristic;

model DemoIntervalTest "Demonstrate usage of interval test"
extends Modelica.Icons.Example;
Modelica.Blocks.Sources.Sine sine(f=2)
annotation (Placement(transformation(extent={{-50,-20},{-30,0}})));
Modelica.Blocks.Logical.IntervalTest intervalTest(constantLowerLimit=-0.5,
constantUpperLimit=0.5)
annotation (Placement(transformation(extent={{30,-20},{50,0}})));
Modelica.Blocks.Logical.GreaterThreshold greaterThreshold(threshold=-0.5)
annotation (Placement(transformation(extent={{-10,50},{10,70}})));
Modelica.Blocks.Logical.LessThreshold lessThreshold(threshold=0.5)
annotation (Placement(transformation(extent={{-10,10},{10,30}})));
Modelica.Blocks.Logical.And and1
annotation (Placement(transformation(extent={{30,30},{50,50}})));
equation
connect(sine.y, lessThreshold.u) annotation (Line(points={{-29,-10},{-20,-10},
{-20,20},{-12,20}}, color={0,0,127}));
connect(sine.y, intervalTest.u)
annotation (Line(points={{-29,-10},{28,-10}}, color={0,0,127}));
connect(sine.y, greaterThreshold.u) annotation (Line(points={{-29,-10},{-20,-10},
{-20,60},{-12,60}}, color={0,0,127}));
connect(lessThreshold.y, and1.u2) annotation (Line(points={{11,20},{20,20},{20,
32},{28,32}}, color={255,0,255}));
connect(greaterThreshold.y, and1.u1) annotation (Line(points={{11,60},{20,60},
{20,40},{28,40}}, color={255,0,255}));
annotation (experiment(
StopTime=1.0,
Interval=0.001), Documentation(info="<html>
<p>
Compare and1.y and intervalTest.y
</p>
</html>"));
end DemoIntervalTest;

package Noise "Library of examples to demonstrate the usage of package Blocks.Noise"
extends Modelica.Icons.ExamplesPackage;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
time
and1.y
intervallTest.y
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
intervallTest.y
intervalTest.y