PID Controllers in Unity3D (2021)
vazgriz.com
vazgriz.com
The last few systems I've worked on professionally have been nested PI controllers with some filters on the front or back of them. Just needed the correct framing for the problem (the hard part) and it becomes straightforward to solve.
I'd think that even if you stop applying a delta the second you hit the set-point, if you've built up non-trivial inertia, then you'll overshoot the target fairly significantly?
For the domains I've worked in, with physical components, system response isn't instantaneous, but some level of overshoot is tolerable as long as the system rapidly converges and (this is the important part) cannot end up in a positive feedback scenario. The derivative term tends to amplify noise, which is never what you want.
A little anti-windup, some generous limits around your max extents, and perhaps a gear-shift to switch bandwidths when you approach steady-state, and it's surprising how many problems can be solved with a filter and a PI controller for the closed-loop component of the system. Maybe the actuator is walking you up and down a complicated model space, maybe you've got multiple PIs driving multiple models...but there's a good chance a PI will do a decent job somewhere in the solution.
Use a PID if you want to make more work for yourself.
Specifics will depend on your exact system.
Of course, a "perfectly" tuned PID loop will be "better" - more efficient, faster to reach setpoint, and minimize overshoot. But the effort/engineering time/operation time involved in tuning it, combined with the risks presented by a subtly poorly tuned loop that goes haywire one day when the system paradigm (characteristic) changes...just isn't worth it.
Obviously there are times when you really do need a D term, but I can confidently say that they're not commonly used in HVAC or petrochemical plants. I'm sure there are other domains where the D term is needed, but in my time as a controls engineer I didn't run across them.
A really good way to tell is to consider the relationship between your input and output. PID get's thrown around all the time because a lot of the time you are talking about controlling an accerlation (gas pedal, throttle) to effect a position, so you theoretically need a PID to stand in for a 2nd order differential equation since position and acceleration are two derivatives apart with respect to time. But as you pointed out, you usually can generalize your input and not worry about the D term.
In the video game I'm making, I don't really worry about derivative control, but PID control is mostly there to give the illusion that someone is driving a vehicle rather than it be controlled perfectly by a computer program. I don't want to model out how "skilled" the driver is - all I have to do to give that impression is just give the vehicle better handling.
With a heater,once you get to zero error, any overshoot will reduce back the opposite way because heat is always lost.
Where you do you get the derivative? If you have to differentiate the input, and there is noise, the raw derivative will have huge variations. Then you need a low pass filter before the differentiator. This introduces lag. So you now have both D gain and filter frequency to tune.
See any classical control theory book for the theory on this.
When the rocket had an angle error it needed to point it's thrust to rotate itself back to 0. There is no built in stopping force that stops the rocket rotating when the thrust is not angled. So a D term was needed in order to take into account how fast the rotation was happening. When it was rotating to 0 degrees of error, it needed that d term to not overshoot. With the d term, the thrust would swing in the opposite direction to prevent it overshooting.
For a surprisingly large number cases, setting a P value in the 1-3 range and a I value as P/10 works extremely well.
I now write Python for my day job. This code was written before that and now that I look at it, it is quite ugly:
https://austinsnerdythings.com/2021/10/19/coding-a-wing-leve...
A different part of my day job includes, tangentially, tuning PID control parameters for 200-500 HP electric submersible pumps in oil wells. Again, it is amazing how setting an P value in the 1-3 range and an I value P/10 works there as well.
A slightly more advanced autopilot with altitude set and hold (code is even more ugly):
https://austinsnerdythings.com/2021/12/06/coding-a-pitch-rol...
We used cameras for the screen-display (we could either show you the VR player's perspective, or one of several cameras), and for the jumbotron in the stadium. This ended up being really cool for downfield throws. When you bombed the ball 45 yards to a receiver, it could be a little hard to see the action. It was really natural to be able to glance up at the jumbotron in the stadium to get a closer view of what's happening downfield.
A small custom little PID controller worked really well for tracking the ball in flight, and giving a more natural "human operated" camera feel than perfectly tracking the ball.
We'd also randomly vary the terms within a set range for different virtual camera operators, so you'd get a little bit of variance in the tracking between different cameras and different play sessions.
Also a lot of pretty fun "bugs" from badly tuned PIDs.
Generally though, It would be pretty trivial to add noise for this stuff. You would probably want some noise on the orientation if you wanted to model more of a camera shake. Perlin noise is my go to if I want to introduce randomness to positions really quickly.
It was, like, 15 minutes of work to find a range of acceptable PID values, then generate a random variable from a normal distribution with a mean at the expected value (we just hard-trimmed the random value at 1 std deviation, because we didn't want a 99th percentile result to cause craziness).
Other than the hilarity that ensued while I was playing around with PID values to find the acceptable ranges, I can't recall ever seeing a bug that was problematic from this, so I didn't really give it much thought. Honestly, there were much bigger things to work on.
The nice thing about this system though, is it created "personality" for the camera. If a virtual camera operator had a lower D-value, they'd overshoot just a little bit, semi-consistently. Another one might have a slightly lower I-value, and end up just a little bit further back in the tracking.
It was a super quick way to give a little bit of organic variance to the camera operation, so it didn't feel "samey" every time.
No need to model your system, just increase the P gain until the system oscillates naturally. Measure the oscillation period, and then refer to the tables at [1] to choose the P, I, D gains depending on how you like your system response to look like.
[1]: https://en.wikipedia.org/wiki/Ziegler%E2%80%93Nichols_method
Ah I remembered something else… it needs to find the max Kp which in some cases is just not possible (or wise) to attempt with a real world plant.
Most professionals tune with starting values obtained using model inversion (IMC, direct synthesis) and then hand tune. There is also software like Loop Pro that analyzes the data and proposes tunings.
https://www.youtube.com/watch?v=wkfEZmsQqiA&list=PLn8PRpmsu0...
https://www.wescottdesign.com/articles/pid/pidWithoutAPhd.pd...
I think that was posted here on HN but I can't find the link...
And discussion https://news.ycombinator.com/item?id=37637006
I dont know how I messed up my first search.
Here's another. These pages interactively go over tuning pid controllers for position, velocity, and position with gravity compensation.
These docs are designed for high schoolers to learn about programming PID.
There's a lot of terrible things people do in ignorance of control theory while trying to come up with solutions in that space.
I ended up writing a program in another language - can't recall which - which interfaced with the controller and linked to unity c# through some obscure windows IPC (I think it was Pipes?).
Fun days in early Unity... nostalgia ;-)