# Turret Control - PID + kS Only, PID + Full Feedforward, or something else?

We’re controlling a turret and currently we use a PID loop with a kS component for friction. Unfortunately, we’re having trouble tuning the pid loop to act well when the robot itself is turning at different speeds relative to the turret target position. Would you recommend using a feedforward algorithm based on the rate at which the robot’s angle is changing, or some other method of controlling the turret?

Thanks!

Can you give a bit more information about the problem you’re seeing when the robot is turning? I would expect that the forces involved would be small enough that they could be treated as a disturbance to be rejected by a well-tuned* PID. Adding a feed-forward based on the robot rotation rate should be possible, but I wouldn’t think it should be necessary unless you have a very heavy turret with very little friction.

* Note that well-tuned doesn’t just mean it responds quickly to a step input but also means it can reject disturbance forces on the turret.

We’re having a bit of trouble with a lagging response, which might be because we’re using non-custom PID on the two motors that drive our turret (We’re in FTC), and the i term takes a bit of time to accumulate. We’ve tried bumping up our kstatic terms and i terms on the turret positional pid but are still facing a bit of lag when reacting to quick movements. I will try tuning the PID and kStatic better though. It makes sense that the PID should treat robot movements as simple disturbances.

Thank you for the reply.

I’m not experienced in FTC, but personally I would say go for more feedforward. Generally the feedforward should be doing the majority of the work for your controls and the PID should adjust for inconsistencies and error-- in this case the relationship between the robot’s orientation change and the turret’s is quite consistent, so you should be able to describe it fairly easily.
For example, you could increase PID gains in an arm mechanism to counteract gravity, but it will fair much worse in comparison to one incorporating a feedforward that describes gravity(constantVoltage * sin(theta)) which is very consistent.

Remove the PID control and try, for example(i haven’t used a turret, citation needed), finding a constant value that you can multiply by the robot’s turn rate and apply to the turret opposing it so that it stays in place while the robot turns. Once it seems to accomplish this well enough, add the PID back and re-tune. The feedforward should negate the need for integral.

I’m gonna have to disagree here. The best control system is the simplest one that meets whatever requirements you set. Often in FRC (and FTC I assume) we need a feed-forward to get good response characteristics, like in the arm example you gave or even more so in a velocity system. But a turret is a good example of a plant that theoretically has no need for a feed-forward. There are very few external forces acting on it, no power is needed to maintain a constant setpoint (ignoring disturbances), and it’s very close to a linear system. If you can treat the robot rotation as a disturbance to be attenuated and just use PID, that makes for a simpler control system with less reliance on other sensors.

Also not sure about this:

Imagine the robot isn’t turning, so the feed-forward is zero. Depending on the friction and damping of the physical system there may be a need for an integrator in the controller to eliminate steady-state error.

4 Likes

We dealt with this situation by having our second driver control the turret - they would work on keeping it lined up to the target - when the driver would shoot our auto-targeting would use the limelight camera to find the target and PID control to adjust the turret.

1 Like

we’re having trouble tuning the pid loop to act well when the robot itself is turning at different speeds relative to the turret target position

I assumed it was camera tracking here, but I see this could also be robot relative, which sounds like what you are describing. The approach I mentioned is a way of avoiding lag in turret response to robot turning when aiming at a target, which sounded like the problem.

there may be a need for an integrator in the controller to eliminate steady-state error.

This is could be true here, but as far as I have seen/heard you should avoid integral term for most applications and (FRC) turrets. It is difficult to get a correct value, often needs additional criteria to be useful, and introduces instability into the system. Theoretically, the turret can avoid steady-state error with a better tuned P/D loop. In this case, the turret is probably pretty small and light with very little voltage required to induce acceleration which makes it difficult to model the system, and an integral term might be the only way to properly compensate.

1 Like

Ah, the pigeon-guided missile solution to a control systems problem

3 Likes

After re-reading this a couple times, thinking really hard, and staring at the rose petals covering my desk, I have a few comments/questions:

You mentioned a bit of lagging, what are you using for feedback? Sometime cameras provide really slow feedback, which can result in “lagging” responses.

How hard is it to turn your turret? I haven’t myself heard many people using a kS term with turrets, normally because there isn’t a huge load to turn them.

Something you might want to try to return it again from start. It almost sounds like you don’t have enough P, and you are majorly compensating for it with an I term.

Do you have any videos of said movement?

1 Like

I wonder if 254’s Vision tutorial may be helpful. They go from basic to technical quite smoothly.

Instructions unclear, roboRIO is cooing and there is a mysterious white substance accumulating on the practice field.

4 Likes

This is exactly the correct approach. The angular velocity setpoint of your turret needs to be the desired angular velocity with respect to the robot (i.e. what you’d get out of an ordinary PID controller), minus the angular velocity of the robot.

In practice, depending on how you’re measuring that latter quantity, you might need to do some filtering to get this to work. It’s definitely doable, though. Keep trying!

3 Likes

There isn’t lag from feedback, we’re using deadwheel odometry and our update times are about 100 hz.

The turret is moderately hard to turn for FTC motors because it has quite a bit of inertia, but it can definitely pick up a lot of speed if it needs to.

I do agree, it does seem like we are compensating for a low P term with a very high I term. We had some trouble bumping P up too high though with heavy oscillations that I couldn’t damp out without really high D, which caused weird tremors and things like that.

Edit:
The oscillations might be because we were tuning PID while rotating the robot faster than it is likely to move during a match. Maybe tuning under more realistic conditions will help out a lot.

We’re using deadwheel odometry with a 100hz update frequency.

Would having a properly tuned static constant for feedforward eliminate the need for an integrator?

Yes. You should never need an integrator for a position controller.

Integrators in general are a “tool of last resort.”

The control law for a PIDf controller is:

u(t) = K_p e(t) + K_i \int_{0}^{t} e(\tau) d\tau + K_d \frac{du}{dt} + F(t,\dots)

where u(t) is the control signal (i.e. the voltage given to the motors), e(t) = x-x_{setpoint} is the error, K_p K_i and K_d are constants, and F(t,\dots) is some feedforward function. If I’m understanding the question correctly, you’re suggesting a constant feedforward function

F(\dots) = K_f

This feedforward doesn’t make much sense, and I’ll explain why. Think about the case where we want the turret to settle at some setpoint. If the turret is sitting exactly at the setpoint with no velocity then we don’t want to give the motor any voltage or it will move away from the setpoint. In that case the P, I, and D components of the control law will all be zero, just as we want. But the feedforward will be K_f \neq 0.

The goal of a feedforward is to balance any known forces acting on the system so the PID part of the controller only has to deal with the unknown forces (aka disturbances). A feedforward like the one I described above would be good for some system with a spring where the force acting on the system is proportional to the system’s position. But for a turret, there are no major external forces acting on the system that need to be cancelled out, so there shouldn’t be a need for a feedforward term.

If you find that the effect of the relative motion from the robot base turning does affect the turret more than can be rejected as a disturbance, then you could consider adding a feedforward to cancel out that “force”. But the “force” will be proportional to the angular acceleration of the chassis, which will need to be measured by some sensor in order to be cancelled out.

1 Like

We constantly know where the target position is so we don’t need a driver to help with tracking.

That is not what he’s suggesting, hence the mention of “static friction.”

He’s suggesting cascading the output of his position PID to a velocity feedforward. Which is totally valid, and likely to improve performance. WPILib’s SimpleMotorFeedforward will work fine for this purpose.

We currently just have positional PID and no velocity PID. Do you think adding a Velocity PID with the negative of the robots turning rate would help? It seems kind of overkill but I’m not super sure. As you said, noise might be a problem because the velocity / acceleration values of our robot will probably be noisy.