VF #
Brief #
vf runs an induction motor open loop, V/f, and replaces uf (uf2.c) for new configs. It is loaded by conf/template/vf.txt: its frequency vel_e goes to angle0.vel_cmd (angle0.src 3) and its voltage u_cmd to hv0.d_cmd in volt mode (hv0.cmd_mode 0, hv0.q_cmd 0). en and scale come from fault0, the currents and voltages from hv0, dc_hold from conf0.high_dc_volt. conf/template/vf_enc.txt links vf, adds fb_switch and vel and sets vf0.vel_fb = vel0.vel, vf0.enc = 1 for slip frequency control on an encoder, and vel0.torque = vf0.torque. The speed command is vf0.vel_cmd (rad/s mech).
Component Explanation #
All work is done in rt. The active current i_act = (ud * id + uq * iq) / abs(u) is the current along the voltage vector: it is torque producing, positive when motoring in either direction and negative when the motor brakes; the magnetizing current does not count. Its low pass at damp_hz drives stall prevention and slip compensation, so they follow the load but not the rotor swing.
- Ramp and stall prevention:
velramps towardvel_cmdataccanddec; vf is its own ramp, so no ramp0 is needed in front.en0 setsvelto 0 at once.- Accel stall prevention scales the ramp with the low passed active current: full
accup toi_stall, down to 0 at 1.1 * i_stall (stall1), then back toward zero, reachingstall_decat 1.3 * i_stall (stall2). Proportional, so the frequency never steps. As the magnetizing current does not count, i_stall is a load limit and works near base speed too. - Decel stall prevention:
velstops falling while the dc link is abovedc_hold, the motor regenerating into the link (stall-1). scale(fault0.scale) lowers i_stall, so a derate slows the motor instead of cutting its flux.
- Voltage:
u_cmd= u_n * abs(vel + slip) / vel_n plus a boost u_boost that fades linearly to 0 at boost_vel. Phase peak volts, like every volt mode d_cmd.- Capped at duty * pwm_volt (hv0.pwm_volt, live from the dc link): above that speed the flux falls as 1/f, field weakening, and
u_limis 1. - The vf template sets u_boost 12 V: it covers the dead time drop (no compensation in volt mode) plus r * the magnetizing current, so the encoder path starts from rest on the slip frequency alone (spindle IM06B50GC1, drop about 8.7 V).
- Stop at 0:
- A
vel_cmdbelow 0.5 rad/s (either sign) counts as 0, so noise on a 0 command does not keep the boost and the speed PI running. Once the command is 0 and the ramp has reachedvel0,u_cmdis 0 and, with the encoder, the slip and its integrator are 0 too, so the field stops and the rotor runs down. The damping states reset there as well, sodampandvel_eare exactly 0 and the next start begins clean. Without this the boost drove a dc current into the limit at standstill (21 A on the spindle), which only heats a cage motor, and the encoder path’s speed PI on 0 hunted with the field near 0 Hz (spindle, 12-13 Oct: +-17 rad/s, 29 A peaks). - A new command restarts the encoder path’s PI from the open loop slip.
- Slip compensation (open loop,
slip_n> 0):
slip= slip_n * i_act / cur_n from the low passed active current, clamped to 2 * slip_n, times the sign of vel: it adds in the direction of rotation when motoring and takes away when braking. Unfiltered, every current swing would move the field and feed the hunting.
- Encoder path (
enc1, needsvel_fb): slip frequency control.
- The field turns at vel_fb + slip, and slip comes from a PI on the speed error vel - vel_fb (
enc_kp,enc_ki), clamped toslip_max(2 * slip_n when 0). With slip_n and slip_max both 0 the clamp would be 0 and the field would sit on the rotor with no torque, so vf runs open loop instead. - The ramp, stall prevention and dc_hold still shape
vel, which becomes the speed reference. The slip clamp bounds the torque, so the rotor cannot pull out; the integrator holds while clamped, and vel stays within slip_max of vel_fb, so a ramp faster than the motor can follow just slows down. - It replaces the slip compensation and the damping (k_damp, k_vel): the field is tied to the rotor. Switched on while running, the integrator starts from the open loop slip.
- With the encoder the voltage (u_n * abs(vel_fb + slip) / vel_n) and the boost fade (on abs(vel_fb)) use the rotor speed vel_fb in place of vel, so the boost does not fade with the reference at standstill.
- Damping (optional, open loop only):
- Open loop V/f on a lightly loaded motor hunts, the rotor swinging against the field.
damp= k_damp * the active current band passed between damp_hz and damp_lp_hz moves the field frequency with the swing and damps it. The term is multiplied by the sign of vel, like the slip, so it damps the same in reverse. The high pass keeps steady slip and the ramp’s acceleration current out, the low pass the pwm and current loop ripple. Frequency only, the voltage stays on vel + slip. Clamped to 5 % of vel_n. Positive k_damp damps. - Speed damping (needs a speed feedback):
k_veltimes the rotor speed swing (vel_fb - vel, same band pass) adds todamp. With an encoder this measures the swing directly, to find the damping law that an estimate can then replace. vel_src1 uses an estimate instead, no encoder: the air gap torquetorque= 1.5 * (u * i_act - r * (id^2 + iq^2)) / signed synchronous speed (at least 5 rad/s) overjis the rotor acceleration; less the field’s own acceleration (the ramp, stall prevention, slip, damp), high passed at damp_hz and integrated (leaky at damp_hz), it gives the swing of the rotor against the field,w_est. Needsj> 0.
- Output:
vel_e= (vel + slip + damp) * polecount (vel_fb in place of vel with the encoder), the synchronous electrical speed for angle0.vel_cmd, so hv0.vel is right and the f3 extrapolates between packets.
- vf has no speed clamp and the vf template does not link conf0.max_vel, so limit vel_cmd at its source. Under load it is usable from about boost_vel (below it r and the dead time drop eat most of the small voltage) to about vel_n; above the voltage cap the flux falls as 1/f and the breakdown torque as 1/f^2.
- vel_fb must have the field’s sign and mechanical scale; a reversed encoder runs away against the slip clamp, so check vel_fb (vel0.vel against vf0.vel, conf0.mot_fb_rev) with enc 0 before the first run.
- Speed commands below 0.5 rad/s mech (about 5 rpm) are not possible: they count as 0 and stop the field.
Pins #
| Name | Description |
|---|---|
| en | input, Enable, 0 = frequency back to 0 at once (fault0.en_out) |
| vel_cmd | input, Speed command (rad/s mech) |
| polecount | parameter, Pole pairs (conf0.polecount, default 2) |
| u_n | parameter, Phase peak voltage at vel_n (V, default 90) |
| vel_n | parameter, Base speed (rad/s mech, default 246.3) |
| u_boost | parameter, Low speed voltage boost at standstill (V, default 0, vf template 12) |
| boost_vel | parameter, Speed where the boost has faded out (rad/s mech, default 25) |
| slip_n | parameter, Rated slip at active current cur_n, 0 = off (rad/s mech, default 0) |
| cur_n | parameter, Rated active current (A peak, default 10) |
| acc | parameter, Acceleration (rad/s^2 mech, default 50) |
| dec | parameter, Deceleration (rad/s^2 mech, default 50) |
| i_stall | parameter, Accel stall prevention active current, 0 = off (A peak, default 0) |
| stall_dec | parameter, Deceleration while stalled (rad/s^2 mech, default 50) |
| dc_hold | parameter, DC link voltage above which deceleration holds, 0 = off (V, default 0, vf template conf0.high_dc_volt) |
| scale | input, Derate of i_stall, 1 = none (fault0.scale, default 1) |
| k_damp | parameter, Current damping gain, 0 = off (rad/s mech per A, default 0) |
| damp_hz | parameter, Damping high pass and active current low pass corner (Hz, default 3) |
| damp_lp_hz | parameter, Damping low pass corner (Hz, default 20) |
| k_vel | parameter, Speed damping gain, 0 = off (1, default 0) |
| vel_fb | input, Rotor speed for k_vel and the encoder path (rad/s mech, vf_enc template vel0.vel) |
| vel_src | parameter, k_vel input, 0 = vel_fb, 1 = estimate (default 0) |
| j | parameter, Inertia for the estimate, e.g. conf0.j (kg m^2, default 0) |
| r | parameter, Phase resistance for the estimate, e.g. conf0.r (ohm, default 0) |
| 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) |
| dc_volt | input, DC link voltage (V, hv0.dc_volt) |
| pwm_volt | input, Usable phase voltage, 0 = no voltage cap (V peak, hv0.pwm_volt) |
| duty | parameter, Voltage cap as a fraction of pwm_volt (default 0.9) |
| enc | parameter, 1 = slip frequency control on vel_fb, 0 = open loop (default 0, vf_enc template 1) |
| enc_kp | parameter, Encoder path slip per speed error (1, default 0.25) |
| enc_ki | parameter, Encoder path slip integral gain (1/s, default 5) |
| slip_max | parameter, Encoder path slip clamp, 0 = 2 * slip_n (rad/s mech, default 0) |
| vel | output, Ramped stator frequency less slip, the speed reference (rad/s mech) |
| vel_e | output, Synchronous electrical speed, to angle0.vel_cmd (rad/s) |
| u_cmd | output, Phase peak voltage, to hv0.d_cmd (V) |
| i_act | output, Active current, negative when braking (A) |
| slip | output, Slip compensation or encoder path slip (rad/s mech) |
| stall | output, Stall prevention, 1 = accel held, 2 = accel reversed, -1 = decel held, 0 = none |
| damp | output, Damping frequency offset (rad/s mech) |
| torque | output, Air gap torque estimate (Nm) |
| w_est | output, Estimated rotor speed swing (rad/s mech) |
| u_lim | output, 1 = u_cmd capped at duty * pwm_volt |
References #
Source: .c File