|
|
|
|
// CP: 65001
|
|
|
|
|
// SimulationX Version: 3.8.2.45319 x64
|
|
|
|
|
within AIDAModelica;
|
|
|
|
|
model Step_analysis "Step_analysis.mo"
|
|
|
|
|
Modelica.Blocks.Interfaces.RealInput Consign "'input Real' as connector" annotation(Placement(
|
|
|
|
|
transformation(extent={{-105,40},{-65,80}}),
|
|
|
|
|
iconTransformation(extent={{-120,30},{-80,70}})));
|
|
|
|
|
Modelica.Blocks.Interfaces.RealInput State "'input Real' as connector" annotation(Placement(
|
|
|
|
|
transformation(extent={{-105,-15},{-65,25}}),
|
|
|
|
|
iconTransformation(extent={{-120,-70},{-80,-30}})));
|
|
|
|
|
Modelica.Blocks.Interfaces.RealOutput Stabilized(start=0) "'output Real' as connector" annotation(Placement(
|
|
|
|
|
transformation(extent={{65,35},{85,55}}),
|
|
|
|
|
iconTransformation(extent={{80,30},{120,70}})));
|
|
|
|
|
Modelica.Blocks.Interfaces.BooleanOutput Success(start=false) "'output Boolean' as connector" annotation(Placement(
|
|
|
|
|
transformation(extent={{64.7,2.3},{84.7,22.3}}),
|
|
|
|
|
iconTransformation(extent={{80,-70},{120,-30}})));
|
|
|
|
|
parameter Boolean Desactivate(start=false);
|
|
|
|
|
parameter Real Precision(start=0.05);
|
|
|
|
|
parameter Real Trigger(start=0.1);
|
|
|
|
|
parameter Real Nb_Osc(start=3.0)=1.5;
|
|
|
|
|
Boolean Step_Activ(fixed=false);
|
|
|
|
|
Real Step_Size(start=0);
|
|
|
|
|
Real Step_Start(start=0);
|
|
|
|
|
Real Maximum_Overshot(start=0);
|
|
|
|
|
Real Semi_Period(start=0);
|
|
|
|
|
Real Last_Osc(start=0);
|
|
|
|
|
parameter Real period_cst(start=0.2);
|
|
|
|
|
Real Prev_Consign(start=0);
|
|
|
|
|
Boolean Inside(start=false);
|
|
|
|
|
Real Top[2](start={0,0});
|
|
|
|
|
Real Prev_Top[2](start={0,0});
|
|
|
|
|
Real First(start=0);
|
|
|
|
|
Real x(start=0);
|
|
|
|
|
Real DerS;
|
|
|
|
|
parameter Real T(start=100*Modelica.Constants.eps) "time constant for input State derivation";
|
|
|
|
|
algorithm
|
|
|
|
|
if Desactivate then
|
|
|
|
|
|
|
|
|
|
Step_Start:=0;
|
|
|
|
|
Step_Size:=0;
|
|
|
|
|
First:=0;
|
|
|
|
|
Inside:=false;
|
|
|
|
|
Success:=false;
|
|
|
|
|
Maximum_Overshot:=0;
|
|
|
|
|
Semi_Period:=0;
|
|
|
|
|
Prev_Top:={0,0};
|
|
|
|
|
Top:={0,0};
|
|
|
|
|
Stabilized:=0;
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//détection d'un step de consign
|
|
|
|
|
if not Step_Activ then
|
|
|
|
|
|
|
|
|
|
when abs(Consign-Prev_Consign) > Trigger then
|
|
|
|
|
|
|
|
|
|
Step_Activ:=true;
|
|
|
|
|
Step_Start:=time;
|
|
|
|
|
Step_Size:=Consign-Prev_Consign;
|
|
|
|
|
|
|
|
|
|
end when;
|
|
|
|
|
|
|
|
|
|
Prev_Consign:=Consign;
|
|
|
|
|
|
|
|
|
|
elseif Step_Activ then
|
|
|
|
|
|
|
|
|
|
//il faut surveiller que la consign ne varie plus
|
|
|
|
|
/*if abs(Consign-Prev_Consign) > Trigger then
|
|
|
|
|
|
|
|
|
|
Step_Start:=time;
|
|
|
|
|
Step_Size:=Consign-Prev_Consign;
|
|
|
|
|
First:=0;
|
|
|
|
|
Inside:=false;
|
|
|
|
|
Success:=false;
|
|
|
|
|
Maximum_Overshot:=0;
|
|
|
|
|
Semi_Period:=0;
|
|
|
|
|
Prev_Top:={0,0};
|
|
|
|
|
Top:={0,0};
|
|
|
|
|
Stabilized:=0;
|
|
|
|
|
|
|
|
|
|
end if ;*/
|
|
|
|
|
|
|
|
|
|
//Détermination du temps de réponse pour un réponse non oscillatoire
|
|
|
|
|
when abs(State-Consign) < Precision*abs(Step_Size) then
|
|
|
|
|
First:=time-Step_Start;
|
|
|
|
|
Stabilized:=First;
|
|
|
|
|
Inside:=true;
|
|
|
|
|
elsewhen abs(State-Consign) >= Precision*abs(Step_Size) then
|
|
|
|
|
Inside:=false;
|
|
|
|
|
Success:=false;
|
|
|
|
|
end when;
|
|
|
|
|
|
|
|
|
|
//si on est à la consigne au bout de N période, la réponse est Inside
|
|
|
|
|
when time-(First+Step_Start)>Semi_Period*Nb_Osc and Inside and Semi_Period>0 then
|
|
|
|
|
Success:=true;
|
|
|
|
|
end when;
|
|
|
|
|
|
|
|
|
|
//calcul de la semi-période d'oscillation, si on est passé une fois autour de la consign (First>0)
|
|
|
|
|
when not Success and abs(DerS)<abs(Step_Size)/1000 and First>0 then //si success, la réponse est stabilisée : on ne calcule plus la période
|
|
|
|
|
//premier passage
|
|
|
|
|
if Last_Osc==0 then
|
|
|
|
|
Maximum_Overshot:= (State - Consign)/Step_Size;
|
|
|
|
|
|
|
|
|
|
//deuxième passage
|
|
|
|
|
elseif Last_Osc<>0 and Semi_Period==0 then
|
|
|
|
|
Semi_Period:=2*(time-Last_Osc);
|
|
|
|
|
|
|
|
|
|
//troisième passage et plus
|
|
|
|
|
elseif Last_Osc<>0 then
|
|
|
|
|
Semi_Period:=(1-period_cst)*Semi_Period+2*period_cst*(time-Last_Osc);
|
|
|
|
|
end if;
|
|
|
|
|
Last_Osc:=time;
|
|
|
|
|
//enregistrement des sommets successifs
|
|
|
|
|
if (State-Consign)*sign(Step_Size)>0 then
|
|
|
|
|
Prev_Top:=Top;
|
|
|
|
|
Top[1]:=time-Step_Start;
|
|
|
|
|
Top[2]:=State-Consign;
|
|
|
|
|
end if;
|
|
|
|
|
// estimation par interpolation du temps de réponse : en prenant le dernier instant ou on passe sous le seuil, le résultat est discontinu car dépend de la localisation extact de la dernière oscillation
|
|
|
|
|
if Stabilized==First and Inside and Prev_Top[1]>0 and State-Consign>0 then
|
|
|
|
|
Stabilized:=Top[1]+(Precision*Step_Size-Top[2])*(Top[1]-Prev_Top[1])/(Top[2]-Prev_Top[2]);
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
end when;
|
|
|
|
|
|
|
|
|
|
end if;
|
|
|
|
|
end if;
|
|
|
|
|
initial equation
|
|
|
|
|
x=0;
|
|
|
|
|
equation
|
|
|
|
|
//calcul de la dérivée de l'entrée State (sinon ne fonctionne pas en FMU, car on ne peux avoir un bloc dérivé directement sur une entrée : Error type DerOfInput)
|
|
|
|
|
if Desactivate then
|
|
|
|
|
DerS=0;
|
|
|
|
|
else
|
|
|
|
|
der(x)=(State-x)/T;
|
|
|
|
|
DerS=(State-x)/T;
|
|
|
|
|
end if;
|
|
|
|
|
annotation(
|
|
|
|
|
Diagram(graphics={
|
|
|
|
|
Line(
|
|
|
|
|
points={{-50,5},{-35,5},{-25,70},{-20,45},{-15,55},{-10,
|
|
|
|
|
50},{-5,50},{40,50}},
|
|
|
|
|
smooth=Smooth.Bezier),
|
|
|
|
|
Line(points={{40,55},{-60,55}}),
|
|
|
|
|
Line(points={{40,45},{-60,45}}),
|
|
|
|
|
Text(
|
|
|
|
|
textString="x % of target",
|
|
|
|
|
fillPattern=FillPattern.Solid,
|
|
|
|
|
extent={{-5,30},{35,20}}),
|
|
|
|
|
Line(points={{-20,55},{-20,5}}),
|
|
|
|
|
Line(points={{-40,15},{-40,5}}),
|
|
|
|
|
Text(
|
|
|
|
|
textString="Time to reach",
|
|
|
|
|
fillPattern=FillPattern.Solid,
|
|
|
|
|
extent={{-15,35},{35,25}}),
|
|
|
|
|
Line(
|
|
|
|
|
points={{-50,5},{-35,5},{-25,70},{-20,45},{-15,55},{-10,
|
|
|
|
|
50},{-5,50},{40,50}},
|
|
|
|
|
smooth=Smooth.Bezier),
|
|
|
|
|
Line(points={{40,55},{-60,55}}),
|
|
|
|
|
Line(points={{40,45},{-60,45}}),
|
|
|
|
|
Text(
|
|
|
|
|
textString="x % of target",
|
|
|
|
|
fillPattern=FillPattern.Solid,
|
|
|
|
|
extent={{-5,30},{35,20}}),
|
|
|
|
|
Line(points={{-20,55},{-20,5}}),
|
|
|
|
|
Line(points={{-40,15},{-40,5}}),
|
|
|
|
|
Text(
|
|
|
|
|
textString="Time to reach",
|
|
|
|
|
fillPattern=FillPattern.Solid,
|
|
|
|
|
extent={{-15,35},{35,25}})}),
|
|
|
|
|
experiment(
|
|
|
|
|
StopTime=1,
|
|
|
|
|
StartTime=0,
|
|
|
|
|
Interval=0.001));
|
|
|
|
|
end Step_analysis;
|