P.I.D.(s)

Proportional Integral Derivative?

Yes!

I found this resource online here and have to pass them on.

If you know nothing abouts PIDs they are what control your car's 'cruise control' and maybe your drone's responsiveness to input. They take in 'an error to be corrected' and output a response. Over time the output adjusts to the change in the error. If tuned right the PIDs will reduce the error to nothing in a relatively efficient manner.

In the example of a car: A car is moving at 20km. The driver sets 'cruise control' to 80km and the PIDS register an error of 80km -20km or 60km. The PIDS output a response to the throttle control which makes the car go slower or faster. Now the error should have changed. As the error gets greater or smaller the output responds proportionally.

This stuff is super useful for any kind of control system where a lerp or slerp won't do.

This is Andeee's code:

[System.Serializable]
public class PID {
	public float pFactor, iFactor, dFactor;
		
	float integral;
	float lastError;
	
	
	public PID(float pFactor, float iFactor, float dFactor) {
		this.pFactor = pFactor;
		this.iFactor = iFactor;
		this.dFactor = dFactor;
	}
	
	
	public float Update(float setpoint, float actual, float timeFrame) {
		float present = setpoint - actual;
		integral += present * timeFrame;
		float deriv = (present - lastError) / timeFrame;
		lastError = present;
		return present * pFactor + integral * iFactor + deriv * dFactor;
	}
}


and the example that implements the PID : (go to the first link for the original Unity package. stills works)

using UnityEngine;
using System.Collections;

public class PIDTest : MonoBehaviour {

	public PID pid;
	public float speed;
	public Transform actual;
	public Transform setpoint;

	void Update () {
		setpoint.Translate(Input.GetAxis("Horizontal") * Time.deltaTime * speed, 0, 0);
		actual.Translate(pid.Update(setpoint.position.x, actual.position.x, Time.deltaTime), 0, 0);
	}
}


Thanked by 1NickCuthbert

Comments

  • Yeah I've used PIDs a few times, and I've been trying to find a way to completely understand them and to internalise how they work across different things (rotation, physics, rigidbodies, etc), but basically every time I have to use it again I feel like I'm having to re-learn and re-tweak all my understanding of it :/
    Thanked by 1Moga
  • Implementing a PID is easy. Getting the coefficients right is super hard, in my experience. Guessing numbers is so inefficient, but solving them is thesis material on its own.
    Thanked by 2Moga francoisvn
  • @Elyaradine Yeah the first time implementing them on a new method I could have sworn something was messed up, but no it was just the coefficients. I agree tuning is the hardest part, Depending on the system the values can be wildly different. I have read of a few complex examples with nested PIDs where a higher level PID controls the coefficients on the lower level PID.

    @Tuism. Me too! And my understanding is beginning to fill in by trial and error. Error.. haha my brain PID is pushing its own integral hard! Says "hurry up old brain!"
  • So... control theory is a rather difficult subject, but let me try give some insights into it. Sorry if this is a bit rambling!

    What are control systems trying to do? Why even use them? Well, usually the problem is that you want one thing to track another thing, but you only have some sort of indirect control over the first thing, and no control over the second thing. For example, maybe you have a radar that need to track a projectile. You have zero control over the projectile, it's literally far away. You have some indirect control over the radar. You can turn on the motors to move it around, but you can't just immediately get it to point in any arbitrary direction. So you can use a control system to manage the signals to your radar's motors, thereby controlling its pointing direction.

    How does this apply to games? Often in games you can literally just move something on the screen instantaneously, or at least over a single frame, so there is usually no need for any sort of control system. If you want the image of the radar to point at 273 degrees, then you just set it and voila - it's there. The problem with this is that it often doesn't look very realistic, and sometimes you want something to look more realistic in a game. So you can tween/lerp things between the old and new values, and 99% of the time this works really well in a game. There's a whole host of different easing functions you can use, and when you start to layer them on top of each other you can get magic. But, sometimes tweening isn't enough. So enter control systems...

    First, some terms (you can try skip this para if it gets too hairy): control systems are all about signals being passed around. These signals can represent pretty much anything, from position to angle to weight to light levels. Ultimately, the most important signal is the output signal. This might represent the angle of the radar in our example. And generally you'll have one or more actuating signals, that indirectly control the output signal. Those might be the motor controls with our example. Between those signals you have some sort of model, which explains how the actuating input signals get processed into the output. With "proper" control theory, you'll determine what this model looks like, usually some sort of equation (often a Laplace equation cause it's more useful) and then figure out some sort of system that can more directly control the output signal. What you usually do is have an input signal that you try get the output signal to match, and any difference between the two is the error signal, which you want to minimize.

    Hopefully you're still with me here...

    So, the most basic control system is bang-bang (or on-off) control, and it's very simple: when the error signal is bigger than 0, which means your output signal is too low, then you send the strongest signal you can to get it right, and when the error signal is less than 0 you do the opposite (your +/- signs might be the opposite way). In our example, if the radar is pointing too far left, then you turn on the motor that pulls/pushes it right and wait. If the radar is pointing too far right then you do the opposite. This is actually a pretty useful control system considering how simple it is, and it's used super widely. If you're trying to design a new control system, you should almost definitely start with this. The downside of this approach is that you can race past the target before you have a chance to react, and then reverse and race past it in the other direction. It might basically never stop oscillating back and forward. So you can try a very simple change: add a small threshold. Instead moving at max input when you have any error signal, rather just move when the error signal is larger than some threshold. So maybe if your radar is within 2 degrees of the right direction then you turn off the input, and only if it's larger than that then you turn on the input to the motors.

    So bang-bang didn't work for you? Are you sure, did you actually try it? You basically have 2 variables, the error threshold, and the magnitude of the input. Maybe it'll work better at 50% input, or only 20%? I think bang-bang control will probably work for another 90% of games that need a control system.

    But you really need something more? Ok, then try proportional control. Instead of turning on the actuating signals to the max (or min) values, adjust it according to the magnitude of the error signal. So a large error signal will send a larger actuating signal, whereas a smaller error signal will send a smaller actuating signal. Turns out, that if you wire up things correctly and get your +/- signs right, you can just have a single value to control: the constant proportion of error signal to feed into the actuating input signal. This can work super well, but it's not always perfect. If I'm at this point and it doesn't work, I'll often just tweak things and bit, maybe I just tweak the constant value? Maybe I add some thresholds, like a minimum error, or a max actuating signal, or something a little more custom? Maybe I take the square of the error (or some other power), or larger errors get amplified and smaller errors are suppressed? (this isn't very standard, cause anything like squaring or other powers are non-linear and very difficult to model theoretically, but in practice it often works really well, and we're not designing rockets here). I think this will catch another 99% of games. I can't think of any time in my career that I've gone past this point (in games).

    So if you're looking at the math, by now about 99.999% of your problems can be solved with tweening, bang-bang or proportional control. But you're the 1 in 100 000? Ok, well then maybe you should look into PID control, where the P part is the proportional part from before, the derivative (D) part is about trying to follow signals that change frequently, and the integral part (I) is about trying to compensate for errors that build up over time. If you don't have a good understanding of what these parts are trying to do, it can be very difficult to get working. There are many other potential things to take into account when designing a control system, ranging from discrete vs continuous signals to non-linear systems to systems where the model changes over time. I don't want to be a naysayer, but this is a notoriously difficult field. Even if you know what you're doing, it's not often that you'll need PID control in a game. If none of the simpler approaches are working, most of the time that's cause you've made some error somewhere, and PID control isn't gonna fix that for you. So start with the simpler stuff, and then only come back to improve it if it will make your game more fun. That should be your metric for deciding to try something more complex: 1) have you tried the simpler approach and it failed? and 2) would the more complex approach be more fun? Only if you have 2 yes answers should you move to the next approach.

    I hope that was somewhat helpful, and sorry again for the ramblings - I don't have time to edit this into the resource it could be, but feel free to ask any questions if things are unclear! /ramble
    Thanked by 2Elyaradine Moga
  • Implementing a PID is easy. Getting the coefficients right is super hard, in my experience. Guessing numbers is so inefficient, but solving them is thesis material on its own.
    The convention wisdom for Tuning PIDs is to start with with a low P and set I and D to 0. LINK Increase P until you see oscillations then half that number and begin to bring in I and D. Depending on the situation I like to add a small amount of D first to see dampening before adding I to increase to the rate. Looks like we all know how to use PIDs woot! BANG Bang baby! Now we just wait for questions.
Sign In or Register to comment.