PID Loop Controller with a Servo

Is it possible to use a servo as the output for for a PIDLoop? I am looking into some test vision tracking. The camera will be mounted to a servo and I wanted the camera to track the center of the target and move with it.

Great question!
I have not done this myself but I assume you would either need to add\subtract microseconds, or degrees, to your servo position signal in proportion to the error, and get your error from target position in the image.

I know 254 has a continuous rotation servo controlling the elevation of their shooter hood this year. I don’t know if they use PID or not.

Building off billbo911 post:

I was thinking about it and I have a theory. Grip reports back the distance to the center of the target; x and y. Let’s say the distance x was 50. If you did some testing to figure out how much the x error changes for each degree of rotation the servo makes then you could make a ratio. So basically you convert the error into degrees of change and then add it or subtract it to the current angle.

The only problem would be the ratio would change based on the distance from the target. That throws some difficulty in the theory.

Depending on the servo and controller (I might be completely wrong, I’ve only tested this on the arduino) you might run into an error where you receive no real feedback from the servo. Some arduino libraries will only report the last value you’ve sent to the servo, which makes testing for values useless. It might be worth your time to test this hypothesis out with the hardware you plan on using to make sure it truly reports its absolute location and not what the software thinks.

I am getting a test bed built to do some testing with it. The current servo angle you could store as a separate variable and use that to update the new location. Then replace the variable with the new location

Forgive me for not knowing, but how do you get feedback from a hobby servo? Don’t they already have PID built in too?

I think they do. The more I think about this the more I’m thinking of not using a PID loop and using the distance to the target as a ratio of the angle. The only problem is that the distance away from the target will change that ratio. For instance if you are two feet away changing the angle by one degree will be different if you are five feet away

Angle to center of target is independent of distance.
You will need to make less adjustment the further away you are but the error reported will be less as well.
What you may run into is a lack of resolution to adjust the servo accurately. That’s why I mentioned using microseconds instead of degrees. ie. (~ 1000 vs. ~180)

Yes resolution would fix that but how would you do that? Also if it’s a 180 servo how would you account for it being greater then 180 degrees

That would likely dictate that you would need to not direct mount to the servo. You would probably have to build a specific interface with gearing to account for the extra degrees of motion.

What I meant is how would you control the servo in code using microseconds?

Servos are written a signal that is 1000-2000 uS high, then 20ms low. The number of uS you write is directly proportional to the angle; 1000uS is 0*, 1500uS is 90*, and 2000uS is 180*. There is some error but for relative angle movement (turn 5* to the left) it should be fine.

Sounds good but how do you control that in Java based programming

Is the camera indeed mounted to the servo? Or is the camera mounted to a turret which is to be actuated by the servo?

There might be a way to access it in the Servo classes for the RIO, but I’m not familiar enough with it to say for sure.
You could also manipulate timers directly and make your own class for interfacing with them.
Or you could send data to an Arduino, which has built-in Servo libraries, at the cost of lag time.

For testing purposes the camera would be mounted on a turret which is actuated by a servo for both rotating the camera and angling the camera.

The purpose is to test vision tracking without having a robot that tracks the target but a camera that tracks the target. I don’t have a robot on hand just a test board with the camera turret mount.

Is the servo you’ve selected powerful enough to rotate the turret at the desired speed?

A typical (non-continuous) servo already implements closed-loop control onboard, so a PID loop is unnecessary. Just set it to the angle you want and it will handle going there. Servos are quite effective at moving to positions quickly and without overshoot.

You can set a servo in wpilib using Servo.setAngle(degrees)

I know I can do that. I am talking about live tracking a target. If the camera is mounted on a turret and the servo can turn it fast enough there needs to be a ratio between the distance to the center of the target and angle to turn. My question is if this is a good method?

If I’m following your question, there is a really nice thread discussing it here.

In very simple terms, divide your camera’s field of view in degrees by your horizontal resolution. That will give you degrees per pixel.
Now just multiply the numbers of pixels you are out of alignment by the degrees per pixel and you have your degrees to turn.