Quadcopter PID Controller for distance

589 views Asked by At

I am trying to use a PID controller to stop a quadcopter at a specific location while travelling horizontally, however currently it overshoots/undershoots depending on the max velocity. I have tried manually tuning the P,I and D gains with limited success. Essentially the velocity needs to go from maxSpeed to 0 at the very end of the flight path.

I run a loop that executes every 0.1 of a second. The pitch input to the quadcopter is in m/s and I recalculate the distance to the target on each iteration.

some pseudo code

kP = 0.25
kI = 0.50
kD = 90
timeStep = 0.1
maxSpeed = 10

currentError = initialDistanceToLocation - currentDistanceToLocation
derivativeError = (currentError - previousError) / timeStep
previousError = currentError
output = kP * currentError + kI * integralError + kD * derivativeError
integralError = integralError + currentError * timeStep

if >= maxSpeed {
    output = maxSpeed
} else if output <= 0 {
    output = 0
}
return output

Is there a way to reliably tune this PID controller to this system that will work for different max velocities, and/or are there other factors I need to consider?

2

There are 2 answers

0
Gabriel Staples On

Summary

To stop on a point, one easy way is to switch from a velocity PID controller to a position PID controller whenever you want to stop on a point, and turn up D (which dampens velocity in a position controller) to prevent position overshoot of your target point. See below for details.

Reminder: D in a velocity controller = useless. D in a position controller = essential. See my comment here, and notes below.

Details

I've done this before. I didn't spend a ton of time optimizing it, but what I found to work well was to switch from a velocity controller which tries to overfly waypoints, to a position controller which tries to stop on them, once you are near the desired stopping point.

Note that your position controller can also be forced into a velocity controller by scaling your gains to produce desired velocities, or even by scaling your position error to arbitrarily produce a desired velocity, and by moving the desired position point continually to keep the vehicle following a path. The video below demos that last part too.

The position controller was a PID controller on position: the vehicle's pitch angle was directly proportional to the distance from the target in the y-axis, and the vehicle's roll angle was directly proportional to the distance from the target in the x-axis. That's it. The integral would take out steady-state error to ultimately stop perfectly on the desired position, despite disturbances, wind, imperfections, etc., and the derivative was a dampening term which would reduce the pitch and roll angles as velocity increased, so as to not overshoot the target. In other words: P and D fight against each other, and this is good and intended! Increasing P tries harder to make the vehicle tilt when the vehicle has no velocity, and increasing D causes the vehicle to tilt less and therefore overshoot less the more velocity (derivative of position) that it has! P gets it moving quickly (increases acceleration), and D stops it from moving at too high of a velocity (decreases velocity).

For any controller where neutralizing the driving force (pitch and roll in this case) instantly stops a change in the derivative of the error, D is NOT needed. Ex: for velocity controllers, the second you remove throttle on a car for instance, velocity stops changing, assuming small drag. So, D is NOT needed. BUT, for position controllers, the second you remove throttle on a car (or tilt on a quadcopter), position keeps changing rapidly due to inertia and existing velocity! So, D very much is needed. That's it! That's the rule! For position-based controllers, D very much is needed, since it dampens velocity and acts as the dampening term to prevent overshoot of the target.

Watch this video here, from 0:49 to 1:10 to see the vehicle quickly take off autonomously in this PID position control mode, and auto-position itself at the center of the room. This is exactly what I'm talking about. enter image description here

At approximately 3:00 in the video I say, "[the target waypoint] is leading the vehicle by two-and-one-half meters down the waypoint path." You should know that that 2.5 meters is the forced distance error (position error) that I am enforcing in the position PID controller in order to keep the vehicle moving at the shown fixed velocity at that point in the video. So...I'm basically using my position controller as a crude sort of velocity controller with a natural filter on the commanded path shape due to my "pure pursuit" or "vector flow-field" waypoint-following algorithm.

Anyway, I explain a lot of the above concepts, and much more, in my more-thorough answer here, so study this too: Physics-based controls, and control systems: the many layers of control.

2
link On

A few ideas:

  • check in your code if you calculate the integralError after you calculate the output, too. This can, of course, lead to undefined behavior since in the output calculation, integralError could be anything depending on the programming language.
  • From my experience, you should get rid of the D part entirely, since in a digital environment and due to measurement noise, it could have destabilizing effects
  • I highly recommend looking at this tutorial which guides you through important aspects (even though it concentrates on fixed-point PI controllers)