I have a dual (sequential) loop control system controlling the angle of a rotational joint on a robot using an absolute encoder. I have tuned the inner control loop (for the motor) and am now working on tuning the outer loop (for the joint).

Example of a dual loop controller dual loop

When I disturb the system the response isn't what I would expect.

Kp = 0.4 enter image description here

Kp = 0.1 Kd = 0.001 enter image description here

I didn't add a Ki term because I don't have any steady state error.

I'm confused by the fact that the second overshoot in the first plot is larger than the first one. No matter how I adjust the parameters I can't seem to get rid of the oscillation in the velocity of the joint (seen in the second plot). One limitation I have is if I increase both Kp and Kd too high the gearbox of the becomes very noisy because the noise in the encoder signal creates larger adjustments in the position of the motor. I'm working on adding a filter to the output using the method described here.

The code I'm using for the outer loop is:

static float e_prev = 0.0;

e = joint_setpoint - joint_angle;
e_i += e/0.001; // dt = 0.001s
e_d = (e - e_prev)/0.001; // dt = 0.001s

e_prev = e;

motor_setpoint += k_p * e + k_i * e_i + k_d * e_d;

I'm beginning to think that the system might not be able to be modeled by a first order equation, but would this change the implementation of the control loop at all? Any advice is appreciated!


  • 2
    $\begingroup$ You said "non constant" velocity, but I presume you meant "non purely" exponential velocity, right? Then, what did you mean with your edit? What kind of disturbances did you apply to your system? What are the units in the plots? How is your control diagram arranged? $\endgroup$ Aug 21, 2015 at 9:27
  • 2
    $\begingroup$ If you want advice on what's wrong with your controller, you have to provide your controller. Please post the exact code you're using for the controller and the exact code you're using to create the test. $\endgroup$
    – Chuck
    Aug 21, 2015 at 13:05
  • 3
    $\begingroup$ What kind of joint is that? What does the robot look like? What equations did you use to model that robot? What controller are you using? What disturbance are you applying to the system? Your question is very vague, boiling down to "How do I get rid of this wobble in the line?" Please provide all the information that you have. $\endgroup$ Aug 21, 2015 at 15:12
  • $\begingroup$ Thanks for the feedback! I clarified my question and switched the graphs out for more informative ones. I also added the code for the outer loop controller. $\endgroup$ Aug 22, 2015 at 0:03
  • 1
    $\begingroup$ Again: please provide the required information. You are talking about if a first order equation can model the system properly. But you never mention what equation you are actually using nor do you explain the system. You talk about "sequential loops" and then you talk about "inner loop", which is a contradiction, an inner loop is not in sequence to the outer one. Please provide the full block diagram of EVERYTHING including ALL parameters so that we can stop the guesswork and start to do some science. thanks. $\endgroup$ Aug 22, 2015 at 13:13

1 Answer 1


If you see integral, think area. Derivative, think slope. Integral error is error times sample time (plus previous integral error), derivative error is the change in error divided by time.

Your derivative error term is correct, but your integral error term is not. This shouldn't be an issue because you aren't using an integral term (even though you should!)

Where I would guess your problem lies is with your controller output - you have

motor_setpoint += k_p * e + k_i * e_i + k_d * e_d;

Here you have the += operator, which indicates that motor_setpoint is accumulating the output of your controller. This is incorrect. The output of your PID controller alone is the input to your motor.

I would guess you might be thinking that you are adding the control signal to your reference, but remember that your reference was already taken into account when calculating the error!

This is, for me at least, the magical aspect of the PID controller. It doesn't care what is between the controller and the output, it just adjusts until there is zero error.

If error is accumulating quickly (integral error is high), the controller "opens up", but then if error starts to drop quickly (derivative error is high) it will "ease off" to minimize the overshoot.

If anything, I would suggest eliminating the derivative term and using only the PI controller - this is commonly done in industry because the derivative term is highly sensitive to noise.

Anyways, hopefully this fixes your issue, but if not please at least make the changes and then re-generate and re-post your plots. If the base controller isn't right we can't divine anything from the plots.

Also, check out Ziegler-Nichols tuning if you're looking for some professional PID tuning advice.

  • $\begingroup$ Thanks Chuck! I'm confused to how I apply the output of the controller to the setpoint of the motor. If I was to apply the output directly to the motor, for a joint setpoint of 1.0 and an error of 0 (for the sake of argument) the motor will want to go to a position of 0.0, instead of staying where is. This is why I added the +=. $\endgroup$ Aug 22, 2015 at 2:25
  • $\begingroup$ If the error is zero, then that means the joint angle is equal to the joint setpoint because error = joint_setpoint - joint_angle. In this case, for the sake of argument, if error is zero then the controller output kP*error is zero because error is zero. This is what you want - you want the signal to the motor to be zero when the output equals the input. $\endgroup$
    – Chuck
    Aug 22, 2015 at 2:38
  • $\begingroup$ In reality, just because error is zero doesn't mean the integral or proportional errors are zero, and this causes oscillations in the response. There is extensive literature regarding tuning for rise time, settling time, etc. Essentially, the oscillations in the output are the cost you pay for a faster response, and they are caused by inertia in the system. $\endgroup$
    – Chuck
    Aug 22, 2015 at 2:44
  • $\begingroup$ I think in my case I want the motor to stop moving when the proportional term is zero, not return to 0. I fixed this by having mostly integral gain and a lower proportional gain. $\endgroup$ Aug 22, 2015 at 3:15
  • 1
    $\begingroup$ @beenjaminnn, beside applying the corrections pointed out by Chuck, please provide also the complete diagram of your system, as suggested by Bending Unit 22 too. To me it's very unclear how the two sequential controllers are devised. $\endgroup$ Aug 22, 2015 at 10:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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