Files
AIDASimulation/SimulationModels/AIDAModelica/Step_analysis.mo

178 lines
5.6 KiB
Plaintext
Raw Normal View History

// 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;