Skip to content

Commit

Permalink
Implement continuous version of SignalExtrema
Browse files Browse the repository at this point in the history
  • Loading branch information
AHaumer committed Jul 29, 2022
1 parent 7cb98d4 commit 4e76364
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 1 deletion.
97 changes: 96 additions & 1 deletion Modelica/Blocks/Math.mo
Expand Up @@ -2530,6 +2530,101 @@ This means that:</p>
</html>"));
end SignalExtrema;

block ContinuousSignalExtrema "Peak of input signal"
extends Modelica.Blocks.Icons.Block;
parameter Modelica.Units.SI.Time T(min=Modelica.Constants.small)=1e-6 "Derivative time constant";
Modelica.Blocks.Interfaces.RealInput u
annotation (Placement(transformation(extent={{-140,-20},{-100,20}})));
Modelica.Blocks.Interfaces.RealOutput y_min
annotation (Placement(transformation(extent={{100,-70},{120,-50}})));
Modelica.Blocks.Interfaces.RealOutput y_max
annotation (Placement(transformation(extent={{100,50},{120,70}})));
output Modelica.Units.SI.Time t_min "Time instant of last found minimum";
output Modelica.Units.SI.Time t_max "Time instant of last found maximum";
protected
Real x "Aux.state";
initial equation
x = u;
y_min = u;
y_max = u;
t_min = time;
t_max = time;
equation
//first order approximation of input
der(x) = (u - x)/T;
//first order approximation of derivative of input
when {u<=x, u>=x, terminal()} then
//detect local extrema at zero derivative, just before and after a step, and at the end of the simulation
y_min = min({pre(y_min), u, pre(u)});
y_max = max({pre(y_max), u, pre(u)});
if y_min<pre(y_min) then
t_min=time;
t_max=pre(t_max);
elseif y_max>pre(y_max) then
t_min=pre(t_min);
t_max=time;
else
t_min=pre(t_min);
t_max=pre(t_max);
end if;
end when;
annotation (defaultComponentName="signalExtrema",
Documentation(info="<html>
<p>
This block detects positive and negative peaks of differentiable and non-differentiable input signals without sampling.
</p>
<p>
For differentiable input singals, an extremum is detected if the derivative of the input signal is zero.
</p>
<p>
To handle non-differentiable input signals, the input signal <code>u</code> is conditioned by a first order wth time constant <code>T</code>.
Like in the <a href=\"modelica://Modelica.Blocks.Continuous.Derivative\">derivative block</a>,
the derivative of the input signal is approximated by <code>(u - x)/T</code>.
This way even steps with local extrema just before and after the step are taken into account.
</p>
<p>
Additionally, when the simulation terminates, <code>y_max</code>y_min and <code>y_max</code> are updated.
</p>
</html>"),
Icon(graphics={
Polygon(
points={{-80,90},{-88,68},{-72,68},{-80,90}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(
points={{-80,0},{-75.2,32.3},{-72,50.3},{-68.7,64.5},{-65.5,74.2},{
-62.3,79.3},{-59.1,79.6},{-55.9,75.3},{-52.7,67.1},{-48.6,52.2},
{-43,25.8},{-35,-13.9},{-30.2,-33.7},{-26.1,-45.9},{-22.1,-53.2},
{-18,-56},{-14.1,-52.5},{-10.1,-45.3},{-5.23,-32.1},{8.44,13.7},
{13.3,26.4},{18.1,34.8},{22.1,38},{26.9,37.2},{31.8,31.8},{38.2,
19.4},{51.1,-10.5},{57.5,-21.2},{63.1,-25.9},{68.7,-25.9},{75.2,
-20.5},{80,-13.8}},
smooth=Smooth.Bezier,
color={192,192,192}),
Line(points={{-90,0},{68,0}}, color={192,192,192}),
Line(points={{-80,68},{-80,-80}}, color={192,192,192}),
Polygon(
points={{90,0},{68,8},{68,-8},{90,0}},
lineColor={192,192,192},
fillColor={192,192,192},
fillPattern=FillPattern.Solid),
Line(
points={{-60,80},{52,80}},
color={0,0,0},
pattern=LinePattern.Dash),
Line(
points={{-18,-56},{50,-56}},
color={0,0,0},
pattern=LinePattern.Dash),
Text(extent={{60,-50},{92,-70}},
textColor={0,0,0},
textString="min"),
Text(extent={{60,70},{92,50}},
textColor={0,0,0},
textString="max")}));
end ContinuousSignalExtrema;

block Variance "Calculates the empirical variance of its input signal"
extends Modelica.Blocks.Icons.Block;
parameter SI.Time t_eps(min=100*Modelica.Constants.eps)=1e-7
Expand Down Expand Up @@ -3230,4 +3325,4 @@ connected with continuous blocks or with sampled-data blocks.
57.5,-63.9},{63.9,-49.2},{72,-26.8},{80,-2}},
color={95,95,95},
smooth=Smooth.Bezier)}));
end Math;
end Math;
52 changes: 52 additions & 0 deletions Modelica/Blocks/package.mo
Expand Up @@ -1490,6 +1490,58 @@ whereas signalExtrema2 catches the extrema rather good due to the fact that samp
</html>"));
end DemonstrateSignalExtrema;

model DemonstrateContinuousSignalExtrema
"Test the ContinuousSignalExtrema block"
extends Modelica.Icons.Example;
Modelica.Blocks.Sources.Sine sine(
amplitude=1,
f=9,
offset=-2)
annotation (Placement(transformation(extent={{-80,20},{-60,40}})));
Modelica.Blocks.Sources.SawTooth sawTooth(
amplitude=2,
period=1/9,
offset=1)
annotation (Placement(transformation(extent={{-80,-40},{-60,-20}})));
Modelica.Blocks.Sources.Sine amplitude(
amplitude=1,
f=0.75,
offset=0)
annotation (Placement(transformation(extent={{-60,-10},{-40,10}})));
Modelica.Blocks.Math.Product product1
annotation (Placement(transformation(extent={{-20,20},{0,40}})));
Modelica.Blocks.Math.Product product2
annotation (Placement(transformation(extent={{-20,-40},{0,-20}})));
Modelica.Blocks.Math.ContinuousSignalExtrema signalExtrema1
annotation (Placement(transformation(extent={{20,20},{40,40}})));
Modelica.Blocks.Math.ContinuousSignalExtrema signalExtrema2
annotation (Placement(transformation(extent={{20,-40},{40,-20}})));
equation
connect(amplitude.y, product1.u2) annotation (Line(points={{-39,0},{-30,0},{
-30,24},{-22,24}}, color={0,0,127}));
connect(amplitude.y, product2.u1) annotation (Line(points={{-39,0},{-30,0},{
-30,-24},{-22,-24}}, color={0,0,127}));
connect(sine.y, product1.u1) annotation (Line(points={{-59,30},{-40,30},{-40,
36},{-22,36}}, color={0,0,127}));
connect(sawTooth.y, product2.u2) annotation (Line(points={{-59,-30},{-40,-30},
{-40,-36},{-22,-36}}, color={0,0,127}));
connect(product1.y, signalExtrema1.u)
annotation (Line(points={{1,30},{18,30}}, color={0,0,127}));
connect(product2.y, signalExtrema2.u)
annotation (Line(points={{1,-30},{18,-30}}, color={0,0,127}));
annotation (experiment(
StopTime=1,
Interval=0.0001,
Tolerance=1e-06), Documentation(info="<html>
<p>
The amplitude of both a differentiable sinudoidal signal (frequency 9 Hz) and a non-differentiable sawtooth signal (period 1/9 s) is modulated sinusoidally /frequency 0.75 Hz).
</p>
<p>
Note that the ContinuousSignalExtremaBlock detects extrema of both signals without sampling.
</p>
</html>"));
end DemonstrateContinuousSignalExtrema;

model DemoSignalCharacteristic
"Demonstrate characteristic values of a signal"
extends Modelica.Icons.Example;
Expand Down

0 comments on commit 4e76364

Please sign in to comment.