In the previous note I mentioned that there were 3 basic methods of implementing a velocity PID loop in software. A variation of the first method which combines a feed forward with a PID loop can make the motor system look like a torque device rather than speed device in the steady state. The torque command is the output of the PID loop and goes to zero when the PID error is zero. In this case no speed command is necessary to hold the motor speed since it is the integration of the torque and remains steady when the torque command goes to zero.

**Canceling the Back Emf Voltage makes a motor a torque device**.

With a stead state voltage command a motor would continue to increase its speed were it not for the opposing back emf voltage generated by the motor. In the resistive model of a motor torque is proportional to the current which in turn is proportional to the difference between the input voltage and the back emf voltage generated by the flux rate of change in the motor armature.

**torq**** = kt*(****V_cmd – V_bemf)/R – torq_o**

where

V_cmd = the input voltage command

V_bemf = the motor induced back emf voltage

kt = the motor torque constant

R = the motor resistance

torq_0 = the motor drag torque loss due to friction.

We can rewrite V_cmd as a sum of a torque command plus the back emf voltage:

** V_cmd = Vcmd_torq + V_bemf**

then the resistive model reduces to a torque that is proportional to Vcmd_torq:

**torq = kt* Vcmd_torq/R -torq_0**

**Where do we get back emf?**

There are ways to exactly measure the back emf using an A/D to sample the motor voltage when the controller PWM signal is in its off state, however, this technique is not available to most FRC teams. We can instead approximate the voltage using specification parameters of the motor, gear box and measured wheel speed.

**Software Implementation: Click on Figure to see full size**.

If in software we feedback a computed back emf of the opposite sign then the input will be a torque command.

The back emf voltage =- ke*w_m

A JAG or Victor output to the motor must contain a back emf canceling term = + ke*w_m

where ke is the motor back emf constant, w_m = motor speed rad/s .

This term can be computed indirectly from the measured wheel speed knowing w_max, the maximum wheel speed and the motor supply voltage V_s, ke and the transmission gear ratio: ie

w_max = V_s/ke/Gear_ratio ;

Then the controller output back emf term = w/w_max *V_s where w is the wheel speed.

The cancellation scheme works so long as the system remains linear. The JAG/Victor limits the feedback to +-1 so large torque inputs will saturate the controller and the cancellation term will not work. The motor will return to a speed device while the command is saturated.

This topology has a nice feature in that the torque command is broken out explicitly and hence if there are large loads on the wheel that can cause excessive currents in the motor, a torque command limit can be placed after the pid controller to limit the currents. This is not particularly useful in a shooter wheel, however, if used during autonomous drive modes it can protect the motors from an over current if the robot were to inadvertently contact an object and stall the motors.

**Computing the PID gains:**

In Laplace notation, the motor system transfer function G(s) ** **before back emf cancellation is 1/(tau_m*s +1) . With cancellation,** **

G(s) = 1/(tau_m *s);

Recall that the PID compensator transfer function is of the form GC(s) = KP + KD*s +KI/s

We would like to have KD be zero to avoid feeding back differentiated motor speed because differentiating a noisy signal amplifies the noise considerably. Also there is not much need for KI since we have a forward path integrator in G(s). So the open loop transfer function is

GC(s)*G(s) = KP/(tau_m*s)

**The closed loop transfer function**

**GC(s)*G(s)/(1 + GC(s)*G(s) ) = 1/(1 + tau_d*s)**

**where tau_d = tau_m/KP is the desired closed loop system time constant.**

Since the PID loop doesn’t contain an integrator now, any biases down stream of the PID loop that create a command offset must be held by an error in velocity = command_bias/KP. Typically , with a properly tuned motor system, the bias will be less than 5% of the speed. This error will be reduced by 1/KP . So we like to set KP as high as possible while minimizing system noise levels and saturation effects. We know speed derived from encoders is noisy if the bandwidth is high. Typically unfiltered it runs about 5% of the speed. This noise if multiplied by KP so usually the encoder rate is filtered and KP is kept less than 3.

The KP used above assumes that the feedbacks are normalized to the max wheel speed w_max.

If you use rpm directly as a feedback, then divide KP by max_rpm = w_max*60/2/pi;