67 eng_est: EngineEstimate,
68 cfg: ControllerConfig,
71 Compute constraint violation margins and soft constraint distances.
73 Positive values indicate constraint violations (unsafe).
74 Negative values indicate constraint satisfaction with margin.
78 x : np.ndarray, shape (N_STATE,)
79 State vector: [P_copv, P_reg, P_u_F, P_u_O, P_d_F, P_d_O, V_u_F, V_u_O]
80 eng_est : EngineEstimate
81 Engine performance estimate
82 cfg : ControllerConfig
83 Controller configuration
88 Dictionary with constraint values:
90 Hard constraints (positive = violation):
91 - "copv_min": P_copv_min - P_copv [Pa]
92 - "ullage_max_F": P_u_F - P_u_max [Pa]
93 - "ullage_max_O": P_u_O - P_u_max [Pa]
94 - "MR_min": MR_min - MR [dimensionless]
95 - "MR_max": MR - MR_max [dimensionless]
96 - "injector_stiffness_F": eps_i * P_ch - (P_d_F - P_ch) [Pa]
97 - "injector_stiffness_O": eps_i * P_ch - (P_d_O - P_ch) [Pa]
99 Soft constraints (margins, negative = safe with margin):
100 - "copv_margin": P_copv - P_copv_min [Pa] (distance above minimum)
101 - "ullage_margin_F": P_u_max - P_u_F [Pa] (distance below maximum)
102 - "ullage_margin_O": P_u_max - P_u_O [Pa] (distance below maximum)
103 - "MR_margin_low": MR - MR_min [dimensionless] (distance above minimum)
104 - "MR_margin_high": MR_max - MR [dimensionless] (distance below maximum)
105 - "injector_stiffness_margin_F": (P_d_F - P_ch) - eps_i * P_ch [Pa]
106 - "injector_stiffness_margin_O": (P_d_O - P_ch) - eps_i * P_ch [Pa]
108 Headroom flags (boolean-like, 1.0 = insufficient, 0.0 = sufficient):
109 - "headroom_insufficient_F": 1.0 if (P_reg - P_u_F) < dp_min, else 0.0
110 - "headroom_insufficient_O": 1.0 if (P_reg - P_u_O) < dp_min, else 0.0
111 - "headroom_margin_F": (P_reg - P_u_F) - dp_min [Pa]
112 - "headroom_margin_O": (P_reg - P_u_O) - dp_min [Pa]
115 P_copv = x[IDX_P_COPV]
131 copv_violation = cfg.P_copv_min - P_copv
132 constraints[
"copv_min"] = copv_violation
135 constraints[
"copv_margin"] = P_copv - cfg.P_copv_min
140 ullage_violation_F = P_u_F - cfg.P_u_max
141 ullage_violation_O = P_u_O - cfg.P_u_max
142 constraints[
"ullage_max_F"] = ullage_violation_F
143 constraints[
"ullage_max_O"] = ullage_violation_O
146 constraints[
"ullage_margin_F"] = cfg.P_u_max - P_u_F
147 constraints[
"ullage_margin_O"] = cfg.P_u_max - P_u_O
153 MR_violation_low = cfg.MR_min - MR
154 constraints[
"MR_min"] = MR_violation_low
157 MR_violation_high = MR - cfg.MR_max
158 constraints[
"MR_max"] = MR_violation_high
161 constraints[
"MR_margin_low"] = MR - cfg.MR_min
162 constraints[
"MR_margin_high"] = cfg.MR_max - MR
165 constraints[
"MR_min"] = np.inf
166 constraints[
"MR_max"] = np.inf
167 constraints[
"MR_margin_low"] = -np.inf
168 constraints[
"MR_margin_high"] = -np.inf
174 if np.isfinite(P_ch)
and P_ch > 0:
176 injector_dp_F = eng_est.injector_dp_F
177 if np.isfinite(injector_dp_F):
178 required_dp_F = cfg.eps_i * P_ch
179 stiffness_violation_F = required_dp_F - injector_dp_F
180 constraints[
"injector_stiffness_F"] = stiffness_violation_F
181 constraints[
"injector_stiffness_margin_F"] = injector_dp_F - required_dp_F
183 constraints[
"injector_stiffness_F"] = np.inf
184 constraints[
"injector_stiffness_margin_F"] = -np.inf
187 injector_dp_O = eng_est.injector_dp_O
188 if np.isfinite(injector_dp_O):
189 required_dp_O = cfg.eps_i * P_ch
190 stiffness_violation_O = required_dp_O - injector_dp_O
191 constraints[
"injector_stiffness_O"] = stiffness_violation_O
192 constraints[
"injector_stiffness_margin_O"] = injector_dp_O - required_dp_O
194 constraints[
"injector_stiffness_O"] = np.inf
195 constraints[
"injector_stiffness_margin_O"] = -np.inf
198 constraints[
"injector_stiffness_F"] = np.inf
199 constraints[
"injector_stiffness_O"] = np.inf
200 constraints[
"injector_stiffness_margin_F"] = -np.inf
201 constraints[
"injector_stiffness_margin_O"] = -np.inf
206 headroom_F = P_reg - P_u_F
207 headroom_O = P_reg - P_u_O
209 constraints[
"headroom_insufficient_F"] = 1.0
if headroom_F < cfg.headroom_dp_min
else 0.0
210 constraints[
"headroom_insufficient_O"] = 1.0
if headroom_O < cfg.headroom_dp_min
else 0.0
213 constraints[
"headroom_margin_F"] = headroom_F - cfg.headroom_dp_min
214 constraints[
"headroom_margin_O"] = headroom_O - cfg.headroom_dp_min