Help With PID Control of Servo Steering

I am trying to use the PID library to use a servo to control steering. The input is the heading error with a range of -180 to +180 degrees; the set point is 0 (no heading error); the output I am trying to control is a servo with range of 0 to 180 (0 full left turn, 90 is dead center, 180 full right turn).

The problem I am having is the "direction", it can be either Direct or Reverse depending on if the heading error is negative (requiring left turn) or positive (requiring a right turn). I can get test code to work with half of the possible range of heading errors, but not both.

Is there any way to accomplish this short of using two PIDs, one for each direction of turn, and switching between them based on the direction the vehicle needs to turn? Am I missing a simpler solution?

why not just add 180 to your input value the divide that result by 2

You'd then have the same range and mid point as your output.

Roger....interesting idea, but I don't think it would the lower range of input values (originally -180 to 0, in your suggestion 0 to 180), you need to decrease the input (turn left) to reduce the error; in the upper range of vales (originally 0 to 180), you need to increase the input (turn right) to reduce the error. It is the switch between increase/decrease in the PUD that I am struggling with....

You seem to misunderstand how PID works. The input to the PID algorithm is not the "heading error" but the actual heading and the desired heading. PID then provides an output which should work (if properly tuned) to decrease the difference between the two.

Furthermore, hobby type servos don't operate on angles, rather on pulse widths, with 1.5 ms being neutral and 1.0 or 2.0 usually being the extremes. You can map any continuous set of values to that range.

jremington thank you for the response. My understanding was that a PID algorithm expects a change of output to move the input in a fixed direction...that is, if you increase the output, the input will always increase (or decrease, but not some mix). Is that not correct?

If it is correct, how can a PID handle "compass wrap", or how do I code around it with a PID routine?

Example: to move from current heading of 90 degrees to a target heading of 10 degrees (a decrease of 80 for the input), you decrease the output/turn left; but to move from a current heading of 270 to a target of 10 (a difference of 260), you would instead take the shorter route of going RIGHT by 100 degrees, not left 260 degrees; so

Compass wrap is a different problem and has been discussed (and solved) many times. Google is your friend, but here is one discussion: