Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding PID controller Chapter. #346

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
* [Verlet Integration](contents/verlet_integration/verlet_integration.md)
* [Quantum Systems](contents/quantum_systems/quantum_systems.md)
* [Split-Operator Method](contents/split-operator_method/split-operator_method.md)
* [PID Controller](contents/pid_controller/pid_controller.md)
* [Data Compression](contents/data_compression/data_compression.md)
* [Huffman Encoding](contents/huffman_encoding/huffman_encoding.md)
* [Quantum Information](contents/quantum_information/quantum_information.md)
46 changes: 46 additions & 0 deletions contents/pid_controller/code/c/pid_controller.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <stdio.h>

struct pid_context {
double kp;
double ki;
double kd;
double setpoint;
double last_error;
double integral;
double dt; // Normally you calculate the change in time.
};

struct pid_context get_pid(double setpoint, double dt, double kp, double ki,
double kd) {

struct pid_context ctx = {0};
ctx.setpoint = setpoint;
ctx.dt = dt;
ctx.kp = kp;
ctx.ki = ki;
ctx.kd = kd;

return ctx;
}

double pid_calculate(struct pid_context ctx, double input) {
// Here you would calculate the time elapsed.
double error = ctx.setpoint - input;
ctx.integral += error * ctx.dt;
double derivative = (error - ctx.last_error) / ctx.dt;
ctx.last_error = error;

return ctx.kp * error + ctx.ki * ctx.integral + ctx.kd * derivative;
}

int main() {
struct pid_context ctx = get_pid(1.0, 0.01, 1.2, 1.0, 0.001);
double input = 0.0;

for (int i = 0; i < 100; ++i) {
input += pid_calculate(ctx, input);
printf("%g\n", input);
}

return 0;
}
83 changes: 83 additions & 0 deletions contents/pid_controller/pid_controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#Proportional-Integral-Derivative Controller
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does there need to be a space here?

# Proportional-Integral-Derivative Controller


The proportional-integral-derivative controller (PID controller) is a control loop feedback mechanism, used for continuously modulated control.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Proportional-Integral-Derivative controller (PID controller)

capitalize PID because the acronym follows

The PID controller is in three parts proportional controller, integral controller, and derivative controller.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would sounds better as: The PID controller is comprised of three parts: proportional controller, integral controller, and derivative controller


Before we get into how a PID controller works, we need a good example to use to explain how it work.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence sounds pretty strange. The repetition (how a PID controller works ... explain how it works) could use a little work.

Imagine you are making a self driving rc car that drives on a line, how wuld make it work given that the car moves with a constent speed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self driving -> self-driving
rc -> RC
wuld -> would
constent -> constant


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a sentence here like:

This could be done with a PID controller, which is a combination of Proportional, Integral, and Derivative (PID) controllers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer introducing it over time, to make it easier to follow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My argument was that it was not followable without a transitional sentence.

### Proportional Controller

If the car is too far to the right then you would turn left and visa versa.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

visa versa -> vice versa

Since there is a range of angles you can turn the wheel, you can turn with proportion to how far you are from the line.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not the biggest fan of this sentence either. The Since there is a range of angles... part sets up an explanation that's pretty much never expanded on.

Something like You can turn the wheel proportional to how far you are from the line. In fact, this is exactly what the proportional controller does. The formula describing its behavior is given by: would sound better I think.

Even if you leave the current version:
with proportion to -> proportional to

This is what the proportional controller (P controller) does, which is given by,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what the proportional controller (P controller) does, and it is described by,

There were just too many commas and it was confusing. Same problem with the D and I controllers below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not grammatically incorrect. What would you change it to?


$$ P = K_{p} e(t), $$

Where $K_{p}$ is a constant and $e(t)$ is the current error.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the error defined? Is it the distance from the line?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$$e(t)$$ is canonically defined as $$setpoint(t) − measured_value(t)$$

The performance of the controller improves with larger $K_{p}$;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The performance of the controller improves with larger $K_{p}$;
The performance of the controller improves with larger $$K_{p}$$;

if $K_{p}$ is too high then when the error is too high, the system becomes unstable, i.e. the rc car drives in a circle.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it zig zag out of control?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is also not clear to me. I would be expecting an instability like what we see with euler methods. Also: what if K is a function of the error? Is this common practice?


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a note should be made here that the car's motion can be completely corrected with the Proportional controller, but it has the problem of overshooting a lot, thus additional controllers are necessary to maintain proper control of the car.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, this was not addressed.

### Derivative Controller

The P controller works well but it has the added problem of overshoting a lot.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overshoting -> overshooting

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted that I believe this statement should be in the previous section.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer it here.

we need to dampen the oscillation, on way to solve this is to make the rc car resistant to sudden changes of error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we -> We.
on -> one

I would split the sentences instead of using the comma

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make a more robust controller, we need to...

This is what the derivative controller (D controller) does, which is given by,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The controller is not "given" by the formula. The behavior of the controller is described by the formula. The same problem is present in the P and I parts as well.


$$ D = K_{d} \frac{de(t)}{dt}$$
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are de and dt? Maybe note that this is something like a derivative?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a derivative.


Where $K_{d}$ is a constant.
If $K_{d}$ is too high then the system is overdamped, i.e. the car takes too long to get back on track.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Where $K_{d}$ is a constant.
If $K_{d}$ is too high then the system is overdamped, i.e. the car takes too long to get back on track.
Where $$K_{d}$$ is a constant.
If $$K_{d}$$ is too high then the system is overdamped, i.e. the car takes too long to get back on track.

If it's too low the system is underdamped, i.e. the car oscillates around the line.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If it's too low the system is underdamped, i.e. the car oscillates around the line.
If it's too low, the system is underdamped, i.e. the car oscillates around the line.

When the car is getting back on track quickly with little to no oscillations then the system is called critically damped.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the car returns to the track quickly...


### Integral Controller

I looks like we are done, we start driving but if some wind starts pushing the car then we get a constant error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I -> It

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something like:

The Proportional and Derivative controllers are enough to robustly control our system, but if some wind starts pushing the car while we are driving, then we will get a constant error.

We need to know if we are spending too long on one side and account for that.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To correct this error, we need...

The way to do that is to sum up all the errors and multiply it by a constant.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe

Well, we would need to know if we are spending too long on one side and account for that, and we can figure that out by summing up all the errors and multiply it by a constant.

This is what the integral controller (I controller) does, which is given by,

$$ I = K_{i} \int_{0}^{t} e(x) dx, $$
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a different e? Its dependent on position instead of time. Maybe it would be nice to create three separate errors e_P, e_D and e_I so we can differentiate?

Also, is the integral going from 0 -> t but in terms of dx?


Where $K_{i}$ is a constant.
The peformance of the controller is better with higher $K_{i}$; but with higher $K_{i}$ it can introduce oscillations.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, a side-by-side animation would do well here


### Proportional-Integral-Derivative Controller

The PID controller is just a sum of all there three constrollers, of the form,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PID controller is just a sum of all three controllers and is of the form,


$$ U = K_{p} e(t) + K_{i} \int_{0}^{t} e(x) dx + K_{d} \frac{de(t)}{dt} $$

To use a PID controller, you need to tune it, by setting the constants, $K_{p}$, $K_{i}$, and $K_{d}$.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tune it, -> tune it (it doesn't need the comma)

There are multiple methods of tuning like, manual tuning, Ziegler–Nichols, Tyreus Luyben, and more.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to see one of those method expanded later, I've tried to make a PID controlled segway-type device using an arduino once, but I could never quite get the constants right manually.


The uses of PID controllers are theoretically any process which has mesurable output and a known ideal output,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mesurable -> measurable

but controllers are used mainly for regulating temperature, pressure, force, flow rate, feed rate, speed, and more.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

speed, and more -> speed and more


## The Algorithm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## The Algorithm
## Putting it all together


Luckily the algorithm is very simple, You just need to make the PID equation discrete.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You -> you

Thus, the equation looks like this,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this, -> this:


$$ U = K_{p} e(t_{j}) + \sum_{l=0}^{j} K_{i} e(t_{l}) \Delta t + K_{d} \frac{e(t_{j-1}) - e(t_{j})}{\Delta t}. $$

In the end the code looks like this:

{% method %}
{% sample lang="c" %}
[import:26-34, lang:"c_cpp"](code/c/pid_controller.c)
{% endmethod %}

## Example Code

This example is not calculating the time elapsed, instead it is setting a value called dt.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not clear from the code what this example is supposed to output or do, in general.

I just need a clear description of what this example code is trying to do. I am having a little trouble figuring out what the code is supposed to be doing, but I think it's a 1D analog to the car example, right? We are trying to keep the car on setpoint?


{% method %}
{% sample lang="c" %}
[import, lang:"c_cpp"](code/c/pid_controller.c)
{% endmethod %}

<script>
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
</script>