How to use pid to make small moves?

Hello everyone,

We are trying to use pid to control our robot’s move in auton stage, while it works really well for big moves, for example, turn 45 degree left, or move 36 inches backwards, it really sucks at small moves, for example turn 3 degree right, or move 2 inch forward. It either moves very slowly or didn’t move at all, this makes our aiming at high goal very inconsistent, especially when we need to make a small adjustment.

Does anyone have good suggestions? One thing we thought would be make two large moves where the difference is actually our goal. For example, in order to turn 3 degree left, we can turn 15 degree left first, then turn 12 degree right. But this looks really inefficient. Curious to know if there are any better suggestions.


1 Like

It’s possible you might need to explicitly address backlash in your drivetrain. Sanity check: do a slow (ideally, limited jerk to avoid bouncing around within backlash) small rotation right immediately after a slow smooth large rotation right. Does that come out OK? That might suggest the whole problem is backlash in the drivetrain. If that doesn’t come out well and you’re using an independent odometry rig, that might need some attention. Given that this is auton, you could consider either designing the route to apply jerk when backlash is sitting the way you need it, or use smaller backlash elimination moves. What happens when you precondition the backlash (presumptious on my part) with a turn of fewer than 15 degrees?
Feel the backlash directly yourself by gently waggling the wheels by hand with the vehicle lifted. That’s how much you need to absorb somehow.
I would expect some folk to have built a backlash learning and compensation system in their code. They’re not obliged to hand it out, largely because supporting code - along with marking work and hoping a third party will do what they’re supposed to do - is a canonical pain of real life. But you never know, someone might chime in. :slight_smile:


Thanks for your suggestion, u89djt. Our guess is that we might need to use different kp, ki and kd for small move since the proportional part is small, our motors may not get enough power to move against backlash. Also, we don’t expect to get other people’s code since it’s probably not going to work on our robot, but some guideline would be helpful since this is our first year competing in VRC. Again, thank you for your suggestions.

Yeah, you’ll be looking for gaps in the response to changes in motor demand followed by a sharp pickup when all the gears have re-seated with each other. Agree with potentially aiming for smaller amplitude control oscillations when you’ve investigated absence of control during backlash transitions.

1 Like

Ya the theory of PID says the same gains should work but the theory is already neglecting several things. (There being a maximum voltage for example)
So it is reasonable to expect you need different gains for the very different tasks.

Interestingly this is one place where motion profiling is beneficial, it acts to make different distance targets appear the same to the controller. So gains would work equally well on every task.


In case when it fails to move over the short distance, I think, that you are relying on P (proportional) too much (Kp is way too big), and not enough on I (integral) (Ki is too small).

I would try to switch to PID+C algorithm, where you apply a small constant power offset in the direction of motion to overcome static drivetrain friction, and then re-tweak PID coefficients. For example, you can initialize “I” component with that constant power level that is just roughly enough to start moving.

If this works, then you can even increase that initial constant but then, once the robot starts moving, decay it quickly from the level corresponding to static friction down to (smaller) level of the dynamic friction in the drivetrain.


I am the biggest PID cheerleader, but this really feels like a mechanical problem first and foremost.
If you are using a purely inertial PID, backlash will not stop your motors from trying to get the IMU to a desired value. If you are using an Inertial Meter, then it is a programming problem.

However if you are using motor values only, then the slop is likely the problem. If you can move your robot forward and backwards a bit or turn it left and right a bit while the motors are set to hold, then there is clearly a lot of backlash, causing a disconnect between the motor’s reading and the actual position of the robot.

In the case that you are using an IMU, and you are still getting those issues, its likely your gain: kp and ki. Also, as technik3k said, use a feedforward / constant term to make sure that no matter how big or small your motor is sufficient to get moving. However, I believe a good integrating term will fix this.

1 Like