An introduction to PID control with DC motor
How to be a good autonomous and environment-aware robot
In this post I will introduce to you the basics of PID control, and why it comes in handy for robotic applications. You don’t need much of background to read this, but knowing the basics of motors is always a good idea: my previous posts on this subject are listed here: Welcome to the jungle.
Now it’s time for serious business.
You already theoretically know how to change the spinning speed and direction of a DC brushed motor — if not, you just have to read a few posts (see above) to get quickly updated.
Yet, you may find out that some improvement is needed if you want to give your motors — your robots — some robotic behaviors.
Robotic behaviors… what are they? Basically, it can be the fact of being autonomous: no remote control. Also, it’s how a robot react with its direct environment.
Let’s take an example: you managed to design and produce this nice rover of yours, you casually build a rocket to put it inside, then successfully leave Earth atmosphere and get your rover safely to the ground of Venus in no time. That’s quite a good job, really. But at this point your rover is only good to be radio-controlled from your comfy sofa on Earth, so allow me to wish you great skills of patience — and a whole set of cutting-edge technology. Yes, now that you think about it, you’d rather have made an autonomous rover.
In this example, being autonomous for the rover is living its own life while exploring the wonders of Venus. What I call environment is, for example, the load at the end of the rover’s robotic arm that will apply a force to its joint — hence a torque; it’s also the rock under its 7th wheel, or the slope of the steep mountain it’s trying to climb to see the view that will reduce its programmed speed, etc.
Your rover must get along with these factors and continue being a rover in spite of the fact that they all kindly but firmly work together in order to try to prevent it from doing whatever you programmed it to do on its brand-new planet.
Life is hard.
How to be autonomous and get along with environment?
Getting autonomous (for a robot, that is) basically involves you writing a kick-ass programming code that will cover all the single actions you want your robot to do, but also all the possibilities of bad turn of events that could happen in its life. This code could as well include some deep-learning functions so that your robot has its own evolving intelligence. The goal being that it can act accordingly with what it is supposed to do, along with its external environment.
If I summarized, you need to give a purpose to your robot, and put a brain inside it so that it can manage to fulfill it.
But let’s not forget I’m discussing the subject of DC brushed motors in robotics, not every parts and every aspects of a robot. So I must narrow the subject to this question:
How to get a motor being autonomous?
We can now talk about control loop feedback system.
Note: Here I use the same word — control — that in the post How to stop being controlled by your DC motor: reverse the roles! (part 1: direction and part 2: speed). This is a generic word, and the control I’m talking about today is actually closer than engineering control, which is more complex than giving a simple speed order to a motor.
Let’s first define the system as:
- An actuator (for example a motor) and its control board (e.g. this board)
- A sensor (speed, torque, position, etc.)
- A micro-controller board
All of them must be supplied with proper electric energy. As a user, you want the actuator to reach a value, that is called a setpoint.
A control loop feedback system is a system that runs in a close loop, with a setpoint to reach. The command given to the actuator to reach the setpoint depends on the feedback. This feedback consists in the actuator’s value measured by the sensor and compared to the setpoint value. The resulting error is computed and re-injected into the initial order as a command that automatically corrects and adjusts the value of the actuator, in order to reach the setpoint.
Applied to the motor-sensor-system I defined above, it follows a simple recipe (please note it’s highly simplified for now):
- An initial order is given to the motor (for example: please spin at 10 rad/s).
- The sensor retrieves the status of the motor (the motor is spinning at 8 rad/s).
- The error is calculated (10 minus 8 equals 2).
- The error is re-injected and computed into the initial order (Please go 2 rad/s faster, if it’s not too much to ask you).
- And so on.
This illustration will help you understand:
Now you see through this example how the speed is controlled: the system will try to reach
Wanted speed (setpoint) by computing the
error and re-injecting it into the initial command. If someone has the brillant idea to add some load on the output of the motor, the system will detect the change of speed due to that load, the error will rise, and the correction will be higher.
This is an adaptation to environment, and it’s called a feedback loop.
There are different ways of controlling a DC motor. Speed-control and position-control are two common examples, but torque-control is possible as well. You can even make a temperature- or a noise-control if you wish. Logically enough, an appropriate sensor will be needed in each case — i.e. a speed control will work well with a speed sensor.
How can you apply that control loop feedback to your motor?
You will use a PID controller.
A PID controller is a good exemple of motor loop control (though it can be used with various different things, like a kitchen oven or a space-exploration rocket), and widely used in robotic applications.
First, let’s emphasize on something: how does it look? If I run into a PID in the street, will I recognize it as one? Actually PID can be hardware (with resistances, doors, wires, etc.) or virtually anything but a code. Today the second case is the most common, because PID can be implemented in a micro-controller.
Now, that code you’re writing with obvious delight is part of the program uploaded in the micro-controller. The micro-controller then gives orders to the motor control board, and this order is applied as a power signal into the motor. You already knew that, right?
But what really is a PID programming code? The term PID stands for proportional, integral, derivative. They are the three main components of the code (associated to three respective constants that I will talk about later).
These three components will be calculated in function of the error given by the sensor. To simplify things, let’s call these components functions: e.g.
F_i(e) is the integral function in function of the error e. The original target is called setpoint.
Note that this kind of command can be sometimes simplified into a PI, PD, or even a P command. It depends on the system you’re working with, as some of them don’t really need the full PID command to work properly:
Note: I choose to say nothing much more right now about these three functions f. We consider them at black-magic box for now, and we will discuss about them on next posts. Let’s just say that if the error is null, the functions are null.
Here is a new example:
You want your motor to stop fooling around, to get its life on track, and to spin at a rate of 50. No matter the unit, it can be 50 ETR/μC (Elephant-tail rotations per micro-century), I don’t even care. Just 50.
Note: the following is simplified pseudo-code, not written in an actual kick-ass programming language.
-Your desired speed:
setPoint = 50 -The actual speed of the motor:
-The speed command with the PID functions in function of the error:
speed = Fp(error) + Fi(error) + Fd(error)
- 1. In the very first loop, the motor is not running:
The first command is
speed = Fp(0) + Fi(0) + Fd(0) = 0
sensorValue = 0
error = setPoint-sensorValue = 50–0 = 50
Error is 50. Big.
- 2. The associated command changes in the second loop, and so the motor has began to spin, it’s rotating at 5, that’s why the error is a bit lower.
speed = Fp(50) + Fi(50) + Fd(50)
sensorValue = 5
error = setPoint-sensorValue = 50–5 = 45
- 3. On the third loop the motor has accelerated a lot.
speed = Fp(45) + Fi(45) + Fd(45)>>
sensorValue = 60>>
error = setPoint-sensorValue = 50 — 60 = -10
The error is negative because the motor is spinning too fast now.
- 4. The command to correct that on the fourth loop:
speed = Fp(-10) + Fi(-10) + Fd(-10)>>
sensorValue = 50
error = setPoint-sensorValue = 50–50 = 0
On the fifth loop, the micro-controller is quite happy because the motor is obeying. Good.
So it will provide a null command
speed = Fp(0) + Fi(0) + Fd(0) = 0, because the error is null. But too bad: the motor, receiving a null order, is slowing down. This will results in a rising error, and in a new positive command, and so on. In the end, the motor is getting orders to keep to the setpoint value whatever happened.
Viewed on a curve, it will look like this:
We see that the curve — which is the motor speed versus the time — is trying to reach the setpoint value
1. Don’t worry, we will discuss more about that in the next following posts.
That’s all for now. To summarize, keep in mind that a PID controller is a widely used control loop feedback system — written as a code most of the time — that allows your motor to reach a setpoint value (of position, speed, etc.) and to keep it that way as long as you don’t change this value. It uses a maximum of three main functions to correct the command — Proportional, Integrate, Derivative — which values change in function of the error between the setpoint and the actual measure.
On the next posts, we will try to dig in these proportional, integral and derivative components.
Thank you for reading.
— If you liked what you read, please clap the hell out of it and follow us on Medium!
I am an engineer in mechatronics, co-founder of Luos Robotics. We are developing new technologies in order to build robots easier and faster.