# Using a PID to control rotation

I've been working on simulating drone flight in Gazebo (an open source robotics simulator).

Currently, I'm trying to control the drone's pitch / roll rotation using PIDs. It's important to remember that a drone moves linearly only by angular rotation (forward / backward requires pitch rotation, left / right requires roll).

Right now, I'm testing PID pitch control. The goal is to get the drone to rotate to a specified angle and hold that position - perfect job for a PID.

But the physics implementation complicates that. Essentially, the PID takes the setpoint - the desired pitch rotation angle (in radians), and the current pitch rotation angle (which I get directly form the simulation state).

The PID output is then used to calculate the resultant torque. The torque equation is t = I * a (torque = Intertia * angular acceleration). So, essentially, I'm using a PID to control the angular acceleration of the drone given the current and desired angles of rotation.

The problem, of course, is that a PID output scales linearly with time, so although it decreases to zero as the drone approaches the setpoint, it has been applying positive accelerations through the entire time. The result is that the drone has a lot of angular momentum, and so it naturally overshoots. Then, of course, the PID responds by reversing the rotation, but with the same problem.

In the end, what happens is that the drone starts with a horizontal attitude, rotates to the setpoint, then rotates back to horizontal, then back to the setpoint. If I add any I or D gain it becomes unstable.

The problem is really simple. It's like controlling a vehicle in space. Thrust is applied in pulses in order to give fine control over position / rotation. The PID however, provides a continuous output. Which means I need some sort of physical system that behaves as depicted here:

or I need to rewrite the physics so that the PID output scales appropriately to bring angular velocity to zero by the time it reaches the desired angle of rotation.

Solving this is proving more difficult than I thought - probably because I'm not a strong physics or controls guy.

where I get really specific. I'm afraid I wasn't able to articulate the problem well enough, partly because the guy who tried to help wasn't really familiar with PIDs (or C++).

Anyway, Any thoughts from someone who has dealt with this sort of thing (or thinks they know more about it than I do...) would be really welcome. :)

Edit: You can see the behavior in the following animated gif:

http://gph.is/2lKf9aT

• It sounds like it could very likely just be a tuning problem. How did you determine your constants? Feb 26 '17 at 19:01
• Apparently, You need to tune the control gains. I would Start with p, then d and finally I gains. There are wonderful answers at robotics stack exchange site, which also include external links to web sites for theoretical background. Feb 26 '17 at 21:10
• Using a genetic algorithm. I'm pretty sure it's not a tuning problem. The very nature of the PID is what's working against me. That is, so long as the PID hasn't reached it's set point, it continues to apply angular acceleration (in this case). So by the time it's reached it, it has applied way to much to be bale to correct quickly. In other words, it needs to reverse and start decreasing angular acceleration way before it reaches the set point. Much like trying to pilot a spaceship in a vaccuum. Feb 26 '17 at 21:32
• Does your d gain have the right sign? Feb 26 '17 at 21:51
• A PD controller behaves like a spring damper, which can be tuned not to overshoot. In this case it has to be atleast a PD controller or it will oscillate. However due to the nature of this problem i dont think a PID is at all apropriate some model based controller would be much better. Feb 26 '17 at 22:18

So, I'm going to base my answer off a simulation I just finished in a flight dynamics class I'm taking. The book is called Small Unmanned Aircraft Theory and Practice by Beard and McLain. There are slides available at http://uavbook.byu.edu/doku.php?id=lecture (check out chapter 6). While we are simulating fixed-wing UAVs, I think the concepts should be similar. For our pitch and roll loops (which are kind of the same thing in a quadrotor), we use a basic PD loop (no integral term because each is an inner loop). The equation for a commanded control input is $y=k_pE - k_d\dot{E}$. For convenience, we used $q$ (pitch rate) instead of $\dot{E}$ because we have measurements of it.
In your PID loop, you add $k_d\dot{E}$ instead of subtracting it. By subtracting, it reduces the input as you increase angular velocity. For instance, if I am $\frac{\pi}{2}$ radians off and not rotating, my input will be large. As I increase in angular velocity, my input decreases from both the decrease in error and the increase in angular velocity. Eventually, there must be 0 input and it will happen at some point before I get to my position. The UAV keeps rotating and error decreases. However, $\dot{E}$ remains at its previous level and the input becomes negative, decreasing my angular velocity. If, somehow, the angular velocity, got to 0 before achieving the setpoint, this whole process would be back at the beginning. This means you should only have to tune your gains.