Questions regarding PID Controller

Hi, I just came across this new thing called PID Controllers and I decided to try and implement one myself, inspired by this:
http://www.matthewpeterkelly.com/tutorials/pdControl/index.html

Following the wiki article (Proportional–integral–derivative controller - Wikipedia) I implemented only the proportional and derivative terms, but I believe that I’m doing the wrong calculations with the derivative one.

First, what I’m trying to do is something like in the first link, you consider the position of some object as your desired position, and any displacement or offset from that position is considered an error, and will try to correct it over time.

The proportional term was trivial to implement, taking the difference of the object’s position and later multiply
it by the proportional factor (kp from the wiki article).
2942817--217834--Screenshot_2.png

current_error = target.position - body.position;

Now, for the derivative term, if I understood correctly, you need to use the finite differentiation method to calculate the derivative of the error (with respect to time)
2942817--217835--Screenshot_3.png
and that implies doing something like:

(previous_error - current_error) / Time.deltaTime

(from this article Finite difference - Wikipedia)

My problem is that if I divide it by deltaTime, everything “blows up” with infinity or NaN errors, but if I multiply instead of divide, it “works”. But the derivative term doesn’t seem to be contributing anything to the result, no matter what derivative factor I use. Here is my full code for completeness

  Vector3 last_error;
public float kp=3f;
public float kd=1f;
void Update ()
    {
        Vector3 error = target.position - body.position;
  
        //                f(x) - f(x-h)       / h?
        Vector3 de_dt = (error - last_error) * Time.deltaTime;

        last_error = error;


        body.position += (kp * error + kd * de_dt) * Time.deltaTime;
    }

Also, I need to multiply once more the result by deltaTime…but I feel like it shouldn’t be the case.

Any help is appreciated, thanks!

New? PID controllers are over a hundred years old. :stuck_out_tongue:

Multiplying or dividing by Time.deltaTime won’t make a huge difference. Mathematically division is more correct, however in practice you are simply scaling the effect of the derivative term, and it’s roughly the equivalent of changing the value of kD. For simplicities sake I would simply leave off the time term.

Derivative terms do have a habit of blowing up and causing instability. Especially if you have a high noise signal. You may want to consider implementing a filter on the derivative term.

But really you shouldn’t be playing with a derivative term just yet. The intergral term is more important. Implement that first. There is a reason that the order is PID, in general P does the most work, I tunes the effect somewhat, and D does a small amount of finishing.

1 Like

Hi, thank you! I’ve a few more questions if you don’t mind:

  1. Is ignoring the division the usual way of calculating derivatives in this kind of environment? Unfortunately in my university classes ( I studied computer science) we didn’t take a look at numerical methods for solving derivatives, so I don’t have much experience doing this.
  2. The guy in the first link that I posted, used only the P and D terms, thats why I thought it wasn’t really necessary. Having said that, he got a really different result from mine using only those 2 terms (if the Kd term is low enough, he gets oscillation), do you think he is doing something else behind the scenes? or maybe I’m doing something wrong?

Anyway thanks for your detailed answer, I’ll try to implement the integral term and see what happens.