Dual independent PLLs desynchronize on a shared Hall signal in open-loop gimbal mode #413
Unanswered
HenkBoshoff-MCI
asked this question in
Q&A - Tinymovr
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
With a Hall sensor used for both commutation and position feedback on a gimbal-type motor,
velocity_mode()/position_mode() cause the rotor to lock and jitter between two adjacent Hall
sectors (observed jumping between phases 3 and 4) once commanded current/torque exceeds
roughly 0.5 A, even though pure open-loop current_mode() at the same current is stable.
controller.current.Iq_estimate reads 0 at all times under this motor type (a diagnostic
side-effect, not itself a fault -- see below).
commutation_sensor_p and position_sensor_p can be pointed at the same physical Hall
sensor object (both set to SENSORS_SELECT_..._CONNECTION_HALL), but
commutation_observer and position_observer remain two separate Observer structs
(obse/rver.h:53-54) with independently configurable bandwidth
(sensors.select.commutation_sensor.bandwidth vs. ...position_sensor.bandwidth)
and independent internal PLL state. Both are fed the identical raw signal -- a 6-state Hall staircase
hall_update(), hall.h:64) -- but converge on it independently, at different rates, from different initial
phase.
In the non-gimbal branch, a real current sense + PI current loop exists downstream of the Park
transform: if e_phase is momentarily wrong, the current loop measures the resulting current error and
corrects it every cycle. The gimbal branch has no such correction path -- Vd/Vq are applied exactly as
computed from R, L and the (possibly out-of-phase) angle/velocity estimate. As the outer
velocity/position loop (driven by position_observer) commands larger Iq_setpoint changes,
any disagreement between the two PLLs' notion of "where the rotor is right now" is applied directly,
uncorrected, to the drive voltage vector -- right at a Hall sector boundary this can flip the effective
torque direction from motoring to braking, pulling the rotor back into the previous sector and producing
a limit cycle between two adjacent states.
controller.current.Iq_estimate reads 0 and is explained by the same branch split:
state.Iq_estimate (controller.h:33) is only ever written inside the non-gimbal branch
(controller.c:297-298); for a gimbal motor that code never executes, so the field simply keeps its 0.0f
initializer (controller.c:46) for the lifetime of the process. This confirmed which code path was active,
but is not itself a defect.
TRIGGER CONDITION
ALL of the following simultaneously:
(1) motor.type == MOTOR_TYPE_GIMBAL (controller.c:279 branch);
(2) sensors.select.commutation_sensor.connection == HALL;
(3) sensors.select.position_sensor.connection == HALL pointing at the same physical
sensor as (2);
(4) controller mode ³ CONTROLLER_MODE_VELOCITY (velocity, position, trajectory or
homing -- anything that reads position_observer's velocity estimate in the outer loop).
Pure CONTROLLER_MODE_CURRENT does not trigger it, because the outer loop (and hence
position_observer) is not in the loop at all. Mismatched commutation_sensor.bandwidth
vs. position_sensor.bandwidth widens the phase disagreement between the two PLLs and
worsens the effect, but is not required to trigger it -- two independently-initialized PLL instances will
drift out of phase even with identical bandwidth.
All reactions