PSA: P Control

Are you using a robot with a motor actuated tilting tray? If so, have you noticed it’s hard to tilt precisely without knocking cubes over? P Control may be the solution for you!

P Control stands for proportional control. It basically ramps down motor power as you head towards a rotation target. It’s fairly easy to implement. I implement it by calculating the proportion in an integer and calling the integer as motor power for my tilter motor. It goes something like this(pseudocode):

int tilterPControl = thresholdValue + 100(-1(tilterMotor.rotation(degrees)/rotationTarget));

This is basically saying that as the motor gets closer to that rotation target, ramp down motor power. The threshold gives a little bit of leeway, just in case the tilter does not start in the correct place. You could use a ternary operator to override it under a certain value but I prefer it to stop on its own.


I like this idea, especially for teams that have faster tilters. Personally though, I dont have this issue, although that’s probably because my tilter is super slow.
Still, a good idea for teams that suffer from this issue.


What ratio and rpm motor are you using?

100 rpm, double stacked 12 tooth:84 tooth(or is it 80 tooth)

Have you tried running with a 200rpm cartridge?

20 charssssssss

It’s a 3-time per game actuation like itz mogos and with 11+ cube stacks torques probably better anyways

1 Like

I’d suggest giving a justification for why a team would use a manually-coded P loop instead of move_absolute (i.e. built-in, on-motor PID control).


Sorry, I’m talking in terms of vexcode.

What about adding integral of derivative to the motor. Wouldn’t it be even more precise, as there may be a constant error rate, when tilting the tray, such as the weight of the cubes.

P control moves down motor power as the rotation nears the limit. rotateFor (on vexcode) is blocking, which doesn’t play well with drive controls. And I don’t think V5 PID ramps down, which is why some bots last year would fling the rear of their chassis up after they brake, because there’s no ramp down.

E: changed PID to V5 PID. I don’t think it’s actually PID, though. Just a spin loop.

1 Like

I feel that’s extra math for this problem. The ID control would make the rotation values I’m recieving from the motor more accurate but I don’t think that’s neccesary



And I think this is Integral Derivative. The black dots are the actual readout per cycle and the green line is the smoothed value.

I think it really just depends if there is or isn’t steady state error.

1 Like

As described in the documentation, both rotateTo and rotateFor have an optional third parameter which can be used to disable that behaviour. Also, rotateTo is the equivalent to what you’re describing (going to an absolute rotation target), rather than rotateFor (which moves relative to the current position).

This is incorrect. PID does ramp down much in the same way that P does.

Braking is an entirely different discussion. So is using this for drives (which are more complex to control than other mechanisms, because they are 2-dimensional). Built-in PID works fine on things like arms and lifts, in my experience.

To be clear: what algorithm you use does not affect the accuracy of the encoder data.

This is not an accurate depiction of how either algorithm performs. Both will be relatively smooth curves, which will reach the target gradually. the “I” term ensures that enough power is given to overcome friction and other resistances in the system, while “D” ensures that it ramps down enough and avoids oscillating.

I’m not sure where you’re getting the data for these graphs from, but these aren’t accurate either. Firstly, V5 “PID” is in fact real PID, and does not just give a constant voltage until it reaches the target. It may not be perfectly tuned to your use case, but a) the tuning is technically modifiable (though not recommended unless you know what you’re doing), and b) it’s never going to be that flat of a line anyway. I’d suggest grabbing some real data from the V5 and graphing it in Excel or equivalent if you want representative graphs.

The PID graph isn’t accurate because the D term will reduce the voltage as the velocity increases, to avoid overshooting. If you’re seeing a graph like that in real life, your I coefficient is definitely way too high. Also, on both the P and PID graphs, you show the voltage starting at 0, which isn’t accurate; while they both ramp down, neither ramps up. They should both start at a fairly high velocity, and P should be pretty linear (depending on what your x-axis is).

Unfortunately I don’t have access to a V5 right now, but I’ll try to gather some real sample data when I do and graph it.


Thanks for the detailed answer. I’ll try rotateTo for tilter rotation again.

1 Like

If tuning the built-in pod is a bad idea, what are the options if the built-in pid doesn’t work as well as needed?

If you feel that you do need PID (for example, if there’s enough friction or momentum that P alone is not adequate), and the built-in tuning isn’t working for you at all, then you can implement the PID algorithm yourself in code.

I don’t mean to completely discourage messing with the smart motors’ PID constants, but in general you shouldn’t need to for most applications. If you do, then just make sure you’ve worked through the physics at a high level and can justify the numbers you’re giving it (don’t start by guess-and-check), including checking your units, and be prepared to turn it off if it starts accelerating too harshly, especially changing directions (this is the easiest way to accidentally damage a motor).