This note maps the code to the method in the paper
(references.bib → glac2018optimal). For the full
derivation see the paper and its reference [6] (eldeeb2017unified).
For a synchronous machine in the rotor-oriented dq frame, find the stator
current setpoint (i_sd*, i_sq*) that produces a requested torque m_ref
while
- minimising stator Joule losses (maximum torque per current, MTPC/MTPA),
- respecting the current limit
|i_s| ≤ I_sfn, and - respecting the voltage limit
|u_s| ≤ Ûset by the DC link.
Each of these conditions is a quadric (conic) in the (i_sd, i_sd) plane.
The optimal setpoint always lies on the intersection of two of them; which two
depends on the operating regime (below/above base speed, current- or
voltage-limited, MTPV).
All quadrics use the form
Q(d,q) = x11·d² + 2·x12·d·q + x22·q² + 2·x1·d + 2·x2·q + x0 = 0
in per-unit currents (d = i_sd/I_sfn). They are assembled in
FFIS_matrixInit_Par (speed-independent) and
FFIS_matrixInit_M (speed/torque dependent):
| Quadric | Symbol in code | Meaning |
|---|---|---|
| MTPC / MTPA hyperbola | FFIS_MTpC |
max torque per current |
| maximum current circle | FFIS_MCurr |
` |
| torque hyperbola | FFIS_NTorq |
constant torque = m_ref |
| voltage ellipse | FFIS_NVolt |
` |
| MTPV hyperbola | FFIS_MTpV |
max torque per voltage (flux) |
The key contribution of the paper is that the regime is chosen online,
every control step, rather than from a precomputed speed schedule. This lets
the controller react immediately to changing parameters (saturation, thermal
drift). In FFIS_optimal_control:
- Re-normalise the (possibly time-varying) parameters and the operating point
(
Normalize_Par,Normalize_M) and rebuild the quadric coefficients. - Intersect the relevant quadric pairs with
FFIS_intersection, which reduces the problem to a single quartic and solves it with thepoly34fsolver. - Compare the requested torque against the torque available on the
voltage ellipse (
Mintersect) and the maximum feasible torque (Mmaxfeas) to pick the operating regime, then return the setpoint on the appropriate intersection.
The implementation targets a single-precision DSP, so it normalises everything to per-unit to keep magnitudes ≈ O(1), and:
- uses an experimentally tuned tolerance
ZERO_TOLwhen deciding how to scale the pencil of quadrics (paper'sε); - clamps the speed used in the voltage ellipse below a threshold
ω_min = 0.8·ω_Nto avoid an ill-conditioned ellipse at low speed; - (in this port) guards the cube-root helper against non-finite arguments and
falls back to a zero reference if a degenerate input would otherwise yield a
non-finite setpoint. See the source comments and
THIRD_PARTY_NOTICES.md.
This repository fixes a few issues so the code builds and runs correctly on a host PC; each is commented at the site in the source:
- Torque hyperbola scaling —
NTorq.x0is normalised byUsfn·Isfn(the per-unit current convention), notUsfn/Isfn. - Per-cycle re-normalisation —
optimal_controlnow callsNormalize_Par, so the controller reacts to the commanded speed each step (without itwk_Nkept its init-time value). - Low-speed clamp — a stray
;after the clamp condition (which made the clamp unconditional) was removed. - Robustness — the
root3infinite-loop guard and the non-finite fallback described above.