3
$\begingroup$

I'm trying to implement a PID controller by myself and I've a question about the sum_error in I control. Here is a short code based on the PID theory.

void pid()
{
  error = target - current;

  pTerm = Kp * error;

  sum_error = sum_error + error * deltaT ;
  iTerm = Ki * sum_error;

  dTerm = Kd * (error - last_error) / deltaT;
  last_error = error;

  Term = K*(pTerm + iTerm + dTerm);
}

Now, I start my commands:

Phase 1, If at t=0, I set target=1.0, and the controller begins to drive motor to go to the target=1.0, Phase 2, and then, at t=N, I set target=2.0, and the controller begins to drive motor to go to the target=2.0

My question is, in the beginning of phase 1, the error=1.0, the sum_error=0, and after the phase 1, the sum_error is not zero anymore, it's positive. And in the beginning of phase 2, the error=1.0 (it is also the same with above), but the sum_error is positive. So, the iTerm at t=N is much greater than iTerm at t=0.

It means, the curves between phase 2 and phase 1 are different!!!

But to end-user, the command 1, and the command 2 is almost the same, and it should drive the same effort.

Should I set the sum_error to zero or bound it? Can anyone tell me how to handle the sum_error in typical?

Any comment will be much appreciated!!

Kevin Kuei

$\endgroup$
  • $\begingroup$ Questions: ONE Can you post plots of the response and errors? TWO You say "sum_error is positive", but that doesn't mean much. Can you provide an actual number? Is it 0.001 or 10000? THREE What are the actual targets? You have a phase 1 target of "1.0" and a phase 2 target of "2.0". This should not appear to anyone as "almost the same" because the phase 2 target is double the phase 1 target. $\endgroup$ – Chuck Dec 8 '15 at 14:04
  • $\begingroup$ Thanks for your comment. In my case, it's a position controller. So.. to end-users, the curves that motor perform from position 0.0 to 1.0 should be the same from position 1.0 to 2.0. Hope this clearify my question. $\endgroup$ – Kevin Kuei Dec 9 '15 at 0:47
  • $\begingroup$ Can you please post plots? You say, "The curves between phase 2 and phase 1 are different", but there are no curves provided. You speculate that integral error is to blame, but you don't provide any plots of PID error terms. Can you provide a simple drawing of your setup? How do you have a motor doing position control? Is this a linear actuator or something else? Basically, you provide a (somewhat) standard block of PID code (ditch the Term = K*... line), and then complain that the output isn't what you want, but you give no other information at all. $\endgroup$ – Chuck Dec 9 '15 at 15:02
2
$\begingroup$

I would recommend implementing

  • anti-windup
  • an averaging (or other) filter for the derivative term (spanning across 2-3-4 timesteps

Here is a referece implementation from Atmel in C with integrator reset.

EDIT: Please consider Chucks questions in the comments and his answer, since anti windup prevents unwanted error accumulation only in the case when the system is not able to execute the desired set-point.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Agree with @50k4. Usually I will only enable the integrator when settling around the target point. Otherwise you are accounting for the accumulated lag in motion for the entire trajectory, and will tend to overshoot. $\endgroup$ – SteveO Dec 8 '15 at 12:59
2
$\begingroup$

First, please respond to the questions I ask in the comments on your question.

You mention that the device to be controlled is a motor. Bear in mind that rotating power is $P = \tau \omega$, or torque times speed, so you won't get the same response at high speed that you get at low speed because motor torque typically declines with increasing speed.

I'm not sure if this is the cause of your differing responses or not, but I believe it would have a large impact unless you're just using "1.0" and "2.0" as placeholders for some other value, or they are literally 1 and 2 and are very close together percentage-wise in terms of the entire speed band of the motor.

Regarding wind-up, mentioned in 50k4's answer, I wouldn't think it would be an issue unless your process is saturating, which is to say that it shouldn't be an issue unless your motor is hitting some physical limits that would prevent it from responding, like a current limit or something similar. Note however that if you are getting to the point where your response is saturating that you are also likely operating at a point where motor power is limited and thus you are unlikely to get the same response curves no matter what actions you take to tune a standard PID controller.

Ultimately, if I were you, I would evaluate the errors and determine if there is a problem with your error accounting or if you are realizing the physical limitations of a motor. Keep in mind that the entire point of the integral term is to accumulate error - this will speed control response if it is "taking too long". Accumulated error before settling is both normal and desirable as long as the controller output is still able to effect change in the system. Only when the system becomes unresponsive: linear actuators at an end stop; motors at top speed; motor drivers at a current limit; etc., will wind-up become an issue.

I would output integral error, set the motor setpoint to 1.0, then wait until integral error is (effectively) zero, then change the setpoint to 2.0. If the output response is still inconsistent, then you have a problem with the physical limitations of the system (increasing torque required at higher speeds). If you get consistent responses then you are entering "Phase 2" at time "t=N', which is still inside the response time for Phase 1. As the controller is still actively responding it will naturally generate a different response. At that point, consider waiting longer to enter Phase 2 or increasing the gains on your controller to achieve a settled response by time "t=N".

As a final comment, the last line of your code has "Term = k * (error terms)". If you are doing everything else correctly (generally, have your sampling time correct), then you should leave $k=1$, or just use the sum of the PID terms as the controller output.

| improve this answer | |
$\endgroup$
  • $\begingroup$ The way it is implemented right now, the integral error will never be zero if the motion is always in the same direction. The integral error from yesterday, or last week (literarly) will still effect the actual motions... It is just a question of time when will the intergral part saturate.. $\endgroup$ – 50k4 Dec 8 '15 at 17:50
  • $\begingroup$ @50k4 - "Integral error will never be zero if the motion is always in the same direction." True, but this would also imply no overshoot, which in turn then also implies that it's not possible for the system to exceed the setpoint. I've never seen a system where this is the case (that has a controller). If the motion is not bi-directional then how could you ever possibly expect to control it? How would you turn it off? How could you go from a setpoint of 2.0 back to 1.0? $\endgroup$ – Chuck Dec 8 '15 at 18:53
  • $\begingroup$ Yes, correction: "Assuming the desired motion is in the same direction". Tho overshot will be smaller then the step it produces it and so the area above the step will most likely not be greater or at least comparable to the area below the step...and so the integral part will never be zero it will keep increasing (or decreasing, depending on the direction of the desired motion) if the setpoints are monotonically increasing (or monotonically decreasing) $\endgroup$ – 50k4 Dec 8 '15 at 19:02
  • $\begingroup$ @50k4 - This statement is incorrect. PID controller is strictly the sum of the (gain*error) terms. Consider a scenario where the controller has perfectly hit the setpoint such that derivative and proportional errors are zero. In this case, the only term that contributes to the output is the integral term. If integral error is positive (reference has been higher than output for some length of time), then the controller output will be higher than it would otherwise need to be - this is called "overshoot". $\endgroup$ – Chuck Dec 8 '15 at 19:48
  • 1
    $\begingroup$ Or you mean that the accumulation in the integrator causes the overshot, and would eventually "self regulate"? $\endgroup$ – 50k4 Dec 8 '15 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.