Files
AIDASimulation/SimulationModels/OpenModelica 1.25/Requirements/StabilityRequirement.mo

121 lines
6.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
within Requirements;
model StabilityRequirement "SR-WIND-02: The UAS shall maintain lateral and yaw stability under wind disturbance and recover within limits"
// ---- System-level parameters (traceable to SR-WIND-02) ----
parameter Real hoverTolerance = 1.5 "Maximum allowed lateral deviation during hover [m]";
parameter Real yawTolerance = 5 "Maximum allowed yaw error [deg]";
parameter Real recoveryBand = 0.5 "Position error band for recovery after disturbance [m]";
parameter Real recoveryTime = 3 "Time to remain within recovery band [s]";
parameter Real eps = 1e-6 "Numerical regularization term to avoid division by zero when normalizing the trajectory direction.";
// ---- Inputs from the system ----
Modelica.Blocks.Interfaces.RealInput posX "Measured X position [m]" annotation(
Placement(transformation(origin = {22, 0}, extent = {{120, 40}, {80, 80}}), iconTransformation(origin = {20, 0}, extent = {{120, 40}, {80, 80}})));
Modelica.Blocks.Interfaces.RealInput posY "Measured Y position [m]" annotation(
Placement(transformation(origin = {20, 60}, extent = {{120, -80}, {80, -40}}), iconTransformation(origin = {20, 0}, extent = {{120, -80}, {80, -40}})));
Modelica.Blocks.Interfaces.RealInput yaw "Measured yaw angle [deg]" annotation(
Placement(transformation(origin = {20, -70}, extent = {{120, -10}, {80, 30}}), iconTransformation(origin = {20, -10}, extent = {{120, -10}, {80, 30}})));
Modelica.Blocks.Interfaces.RealInput DronePositionConsign[3] "Commanded reference position [m]" annotation(
Placement(transformation(origin = {-158, 120}, extent = {{-20, 120}, {20, 80}}, rotation = -90), iconTransformation(origin = {-40, 120},extent = {{-20, 120}, {20, 80}}, rotation = -90)));
Modelica.Blocks.Interfaces.RealInput yawConsign "Commanded yaw angle [deg]" annotation(
Placement(transformation(origin = {-40, 80}, extent = {{-60, 120}, {-20, 80}}, rotation = -90), iconTransformation(origin = {-158, 78},extent = {{-60, 120}, {-20, 80}}, rotation = -90)));
// ---- Outputs for monitoring ----
Modelica.Blocks.Interfaces.RealOutput lateralError "2D lateral position error magnitude [m]" annotation(
Placement(transformation(origin = {-10, 20}, extent = {{-90, 50}, {-110, 70}}), iconTransformation(origin = {-10, 16}, extent = {{-90, 50}, {-110, 70}})));
Modelica.Blocks.Interfaces.RealOutput yawError "Yaw error magnitude [deg]" annotation(
Placement(transformation(origin = {-10, 20}, extent = {{-90, 20}, {-110, 40}}), iconTransformation(origin = {-10, 16}, extent = {{-90, 20}, {-110, 40}})));
Modelica.Blocks.Interfaces.BooleanOutput withinHoverLimit "true if lateralError < hoverTolerance" annotation(
Placement(transformation(origin = {-210, -34}, extent = {{-110, -10}, {-90, 10}}, rotation = 180), iconTransformation(origin = {-110, 16}, extent = {{10, -10}, {-10, 10}})));
Modelica.Blocks.Interfaces.BooleanOutput withinYawLimit "true if yawError < yawTolerance" annotation(
Placement(transformation(origin = {-210, -34}, extent = {{-110, -40}, {-90, -20}}, rotation = 180), iconTransformation(origin = {-110, -14}, extent = {{10, -10}, {-10, 10}})));
Modelica.Blocks.Interfaces.BooleanOutput recovered "true if position remains within recoveryBand for recoveryTime" annotation(
Placement(transformation(origin = {-210, -34}, extent = {{-110, -70}, {-90, -50}}, rotation = 180), iconTransformation(origin = {-110, -44}, extent = {{10, -10}, {-10, 10}})));
Modelica.Blocks.Interfaces.BooleanOutput pass "true if all criteria are satisfied" annotation(
Placement(transformation(origin = {-210, 22},extent = {{110, -100}, {90, -80}}, rotation = -0), iconTransformation(origin = {-110, -74}, extent = {{10, -10}, {-10, 10}})));
Modelica.Blocks.Interfaces.RealOutput envUpperX;
Modelica.Blocks.Interfaces.RealOutput envUpperY;
Modelica.Blocks.Interfaces.RealOutput envLowerX;
Modelica.Blocks.Interfaces.RealOutput envLowerY;
Modelica.Blocks.Continuous.Derivative dRefX annotation(
Placement(transformation(origin = {20, 30}, extent = {{-10, -10}, {10, 10}})));
Modelica.Blocks.Continuous.Derivative dRefY annotation(
Placement(transformation(origin = {18, -10}, extent = {{-10, -10}, {10, 10}})));
protected
Real t_since_exit(start = 0) "Elapsed time since last exit from recovery band";
Boolean insideBand(start = true);
Real vx;
Real vy;
Real norm;
Real nx;
Real ny;
Boolean outsideBand(start=false);
Boolean timeout;
equation
connect(DronePositionConsign[1], dRefX.u);
connect(DronePositionConsign[2], dRefY.u);
vx = dRefX.y;
vy = dRefY.y;
norm = sqrt(vx*vx + vy*vy + eps);
nx = -vy / norm;
ny = vx / norm;
lateralError =
abs((posX - DronePositionConsign[1]) * nx +
(posY - DronePositionConsign[2]) * ny);
yawError = abs(Modelica.Math.wrapAngle(yaw - yawConsign));
withinHoverLimit = noEvent(lateralError < hoverTolerance);
withinYawLimit = noEvent(yawError < yawTolerance);
insideBand = noEvent(lateralError <= recoveryBand);
outsideBand = not insideBand;
der(t_since_exit) =
if noEvent(lateralError > recoveryBand)
then 1
else -t_since_exit;
timeout = noEvent(t_since_exit > recoveryTime);
recovered = not timeout;
pass = withinHoverLimit and withinYawLimit and recovered;
envUpperX = DronePositionConsign[1] + recoveryBand * nx;
envUpperY = DronePositionConsign[2] + recoveryBand * ny;
envLowerX = DronePositionConsign[1] - recoveryBand * nx;
envLowerY = DronePositionConsign[2] - recoveryBand * ny;
annotation(
Documentation(info = "
<html>
<h4>SR-WIND-02 Performance in Wind</h4>
<p>
Source: EASA Means of Compliance Light-UAS.2512,
ISO 21384-3 (Clause 10 Operational limitations).
</p>
<p>
<b>Requirement:</b><br>
Under a steady 8 m/s wind with 12 m/s gusts, the UAS shall:
<ul>
<li>Maintain lateral position error ≤ 1.5 m (95th percentile) during hover.</li>
<li>Maintain yaw pointing error ≤ 5° (95th percentile).</li>
<li>Recover to within 0.5 m acceptance enveloppe position error within 3 s after gust disturbance.</li>
</ul>
</p>
<p>
<b>Simulation Inputs:</b> Connect to AIDA_System position, yaw, and
reference signals.
</p>
</html>"),
Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "SR-WIND-02"), Rectangle(extent = {{-104, -2}, {-104, -2}}), Rectangle(origin = {0, -1}, extent = {{-100, 101}, {100, -99}})}, coordinateSystem(initialScale = 0.1)));
end StabilityRequirement;