FLUX_OBS #
Brief #
flux_obs is a hybrid rotor flux observer for an induction motor on an encoder (review item B5). It measures the rotor flux angle and magnitude from voltage and current, without tr, and can trim the current model’s slip so that the field orientation follows the measured flux at speed. Below its crossover it falls back to the current model (acim_flux), so at low speed nothing changes.
Status (14 Oct): shadow (pos_err, psi) and the slip trim are bench-checked on the spindle, cold and warm, without load; untested under a cutting load.
conf/template/flux_obs.txt loads it after acim_foc (link flux_obs) in shadow mode, at rt_prio 9.4, with en = fault0.en_out, r = conf0.r, l = conf0.l, adv = hv0.adv, id/iq/ud/uq = hv0.*_fb, pos_ref = angle0.pos, vel_ref = angle0.vel, psi_cm = acim_flux0.psi, slip_in = acim_flux0.slip and slip_max = acim_flux0.slip_max. flux_obs0.pos_err then shows how far the current model’s orientation is off at speed (tr). To trim the slip with it: flux_obs0.kp_s = 20, flux_obs0.ki_s = 2 and angle0.slip = flux_obs0.slip; flux_obs0.k is then true / modelled slip.
Component Explanation #
All work is done in rt; rt_start clears the observer and sets k to 1.
- Model (Jansen / Lorenz, stationary frame):
- With
l = sigma*Lsandpsi = lmr * i_mr(the rotor flux seen from the stator, asacim_flux0.psi): - Voltage model:
d(psi_s)/dt = u - r i. - Current model:
psi_s_cm = psi_cm e^(j pos_ref) + l i. - Hybrid:
d(psi_s)/dt = u - r i + kp (psi_s_cm - psi_s) + ki int(psi_s_cm - psi_s), withkp = 1.4 wc,ki = wc^2. - Rotor flux:
psi_r = psi_s - l i;psiis its magnitude,posits angle. - The estimate follows the current model below about
wcand the voltage model above it, where onlyrandlmatter and r’s share falls with speed. The current model term holds the voltage integrator’s drift (offsets, r error). - The resistance used is
r + r_w * abs(vel_ref). - While
en <= 0the stator flux is set to the current model’s and the integral cleared.
- Frames:
- Like
obs: the feedback (hv0.id_fb…) is in the framepos_ref + vel_ref * adv(angle0.pos,hv0.adv). Runflux_obsbeforeangle0(lowerrt_prio), sopos_refis the angle the feedback was taken with. - The voltages are the mean over the rt period before the sample, which the frame turned through, so they sit
u_advoff the current’s frame: half an rt period (u_adv0 =-period / 2, -100 us at 5 kHz). - Do not calibrate
u_advon idle holds: on the spindle (13 Oct) -30 us zeroedpos_errthere, but that hid the current model’s slip error and left 0.17 rad while braking. At -100 us the rotor resistance seen by the observer (slip * psi / iq) is 0.121 to 0.128 in run-up, hold and both brakes, at -30 us 0.09 to 0.15. pos_err = posminus that frame: how far the current model’s orientation is off, 0 below the crossover (and 0 whilepsiis below 1e-4).
- Slip trim (off by default, shadow):
slip = slip_in * k + kp_s * pos_err.kp_spulls the frame onto the measured flux. The pull is bounded to0.5 * abs(slip_in) + slip_min, so a wrong angle (voltage limit, sensor fault, transient) cannot drive the frame off by more (it was open: +-63 rad/s atkp_s20).ki_smovesk, the ratio of true to modelled slip (tr / true tr), sopos_errgoes to 0 in steady state and a load step finds the right slip at once. Flux ahead of the frame (pos_err > 0) means the true slip is larger.kstays within 0.5 to 2.- Both act only while the gate is open (
trim= 1):en > 0,abs(vel_ref) > vel_min,abs(psi_cm) > 1e-3andpsi > psi_min * abs(psi_cm).kmoves only while alsoki_s > 0andabs(slip_in) > slip_min. - With
acc_max > 0,kalso holds whileabs(acc)(thevel_refderivative, 5 Hz low pass) is above it. Withu_advrightkis the same in run-up, hold and brake (spindle 13 Oct: within 0.01 in field weakening), so the gate is only for a doubtfulu_adv. kstarts at 1 when the drive starts (rt_start) and otherwise keeps its value while the gates are shut orenis 0, soslip = slip_in * kstill applies there:ktracks the rotor temperature, which changes slowly, so a new enable starts from the last learnt ratio.- The trimmed slip is clamped to
+-slip_maxwhenslip_max > 0, asacim_fluxclamps its own. kp_s0 andki_s0:slip = slip_in(withkat 1), the observer only reports. Wireangle0.slip = flux_obs0.slipto use it.
- Results:
- Spindle bench (13 Oct, unloaded): shadow (
pos_err,psi) checked. - Spindle bench (14 Oct, no load, template): shadow within 0.03 rad cold. Trim
kp_s20,ki_s2 follows the rotor temperature (k1.0 cold, 1.07 to 1.11 after 20 min at 2352 rpm) and holdspos_errwithin 0.02 rad.
The slip trim is not tested under a cutting load yet.
Pins #
| Name | Description |
|---|---|
| r | parameter, Stator resistance (ohm, default 0.2), conf0.r |
| r_w | parameter, Resistance growing with speed, d loss (ohm per rad/s electrical, default 0), as obs0.r_w |
| l | parameter, Leakage inductance sigma*Ls (H, default 0.001), conf0.l |
| wc | parameter, Crossover from the current to the voltage model (rad/s electrical, default 20) |
| adv | parameter, Feedback frame lead over pos_ref (s), hv0.adv |
| u_adv | parameter, Voltage frame lead over the current’s (s, default 0 = -half the rt period) |
| kp_s | parameter, Frame pull onto the measured flux (1/s, default 0 = off) |
| ki_s | parameter, Rate of the slip ratio k (1/(rad s), default 0 = off) |
| vel_min | parameter, Trim only above this abs(vel_ref) (rad/s electrical, default 150) |
| psi_min | parameter, Trim only while psi > psi_min * abs(psi_cm) (default 0.5) |
| slip_min | parameter, k moves only above this abs(slip_in), also widens the kp_s bound (rad/s electrical, default 2) |
| acc_max | parameter, k moves only below this abs(acc) (rad/s^2 electrical, default 0 = no gate) |
| slip_max | input, Clamp on the trimmed slip (rad/s electrical, 0 = none), acim_flux0.slip_max |
| en | input, Enable, 0 = flux estimate follows the current model and trim off (k is kept), fault0.en_out |
| id | input, d current feedback (A), hv0.id_fb |
| iq | input, q current feedback (A), hv0.iq_fb |
| ud | input, d voltage feedback (V), hv0.ud_fb |
| uq | input, q voltage feedback (V), hv0.uq_fb |
| pos_ref | input, Angle the feedback frame was at (rad electrical), angle0.pos |
| vel_ref | input, Frame velocity (rad/s electrical), angle0.vel |
| psi_cm | input, Current model rotor flux (V s), acim_flux0.psi |
| slip_in | input, Current model slip (rad/s electrical), acim_flux0.slip |
| psi | output, Measured rotor flux magnitude (V s) |
| pos | output, Measured rotor flux angle (rad electrical) |
| pos_err | output, pos minus the feedback frame (rad) |
| k | output, True / modelled slip, the trim’s integral (1 at start, 0.5 to 2) |
| slip | output, Trimmed slip (rad/s electrical), to angle0.slip |
| trim | output, 1 = trim gates open |
| acc | output, vel_ref derivative, 5 Hz low pass (rad/s^2 electrical) |
References #
Source: .c File