AIDA is a study case for model based system engineering, made by MOISE project. This project contains the simulation model of AIDA (made with SimulationX in Modelica)
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.

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