You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
5.6 KiB
177 lines
5.6 KiB
// 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;
|
|
|