Help PID programming on a catapult

Hello everyone, This is my team’s first year using C++ and we are interested in making a PID program for our catapult. We do not know where to start and any help would be greatly appreciated, Thank you in advance!

Some questions to ask yourselves first:

  1. What does PID do?
  2. How would PID apply to the catapult?
  3. Are there other control methods for the catapult that would work better?
  4. Are there other features of the robot that would benefit more from PID than the catapult?

I agree with @Mentor_355U if you can’t answer those questions, you shouldn’t be using it

For the record, we use a PID for our catapult; there is nothing wrong with doing this. If you decide you still want to use one after answering @Mentor_355U’s questions, I can help if you get stuck. :+1:

On the other hand, just because a PID works for a catapult, I think most people will agree that it is a little overkill. There could be a simpler way… Find it! :smiley:


Thank you so much! I would love to have your help. Can you please pm me, I am new and I have no idea how to pm lol.

I believe PID programming could help with my code that I am having issues with. When I have my velocity for my catapult at 50% it will hit the target about 50% of the time. When I have my velocity at 80% it will hit the target about 25% of the time. When I have my velocity at 30%, it nails it every time. 30% is just too slow for competition. I would like help in writing code that would keep slow down the motors the closer it got to the target. I have tried by looking online at other PID code but none of the code I try works. I want the zero position to be at the top because I want to move the catapult to different spots during the competition. Here is my code. Any help is appreciated.

void onEventR1Pressed(){
  catapult.spinFor(forward, 0.1, turns, true); //releases catapult from hold position
  wait(.25,sec);                                                         //makes sure catapult has completely stopped
  rSensor.setPosition(0,degrees);                   //resets rotation sensor to 0
    if (rSensor.position(degrees) <= -79.0){   //check to see if the sensor has reach target
        catapult.stop(brake);                                  //if it reaches target stop the catapult and break the loop
    else {
      catapult.spin(forward);                                //if it does not reach target, spin forward

edit: code tags added by mods

No worries. :laughing: We used to be able to PM people, but after a certain escalation of events… we can no longer PM through discourse here.

(unless I missed something. It wouldn’t be the first time I missed something, and certainly not the last)

Despite this, I think we can keep the discussion here… for now. :+1:

1 Like

For a catapult, a simple P-loop should be sufficient.

A quick explanation -

A P-loop employs the P part of a PID. This means that as the catapult is being loaded / drawn back, you keep track of how far you are from your target. This is known as Error. You can then multiply this Error by a coefficient to produce a speed. This speed will be applied to the motor. As the catapult gets closer to its target, Error becomes smaller, causing the catapults speed to drop as well.

Here is an example for your code:
I believe a lot can be learned from others code, but I dislike posting copy-paste-able code.

I removed the line where you reset the rotation sensor’s position, usually you don’t have to do this. (though if you do need it, you can always try adding the line back in :person_shrugging:)

If you are interested in a PID for your other robot’s functions, a quick search in vex forum for “PID” will probably bring up a bunch of tutorials. If you have any questions about a specific aspect of a PID I can help you; The “I” (integral) and “D” (derivative) part of a PID can be tricky to wrap your head around when starting.

1 Like

i dont think PID is very useful for cata. we have always run our cata at 100% and there have not been any problems. using PID will only slightly increase the reload time of the cata, which has no benefit.

if you have problems with the cata motor overshooting like @JRstearns, using a limit switch might solve your problem, since it is more reliable than the motor encoders. instead of using a limit switch, you can also just change the angle that the cata brakes and increase the angle to release it.

1 Like

We used a limit switch last year and it worked great until it broke on us on an important match at state! This year we want our catapult to stop in different positions. The lowest point so it can intake and a higher point so it acts as a stopper when pushing a triball around. That’s why we feel the rotation sensor is the best fit for our robot. We have tried different speeds with our catapult and the higher the speeds the more inaccurate it is. We have done hours of testing with speed variables and angel variables so we are trying to look at other possibilities such as PID code. but as @Pi_way said, maybe just need a P code.

1 Like

Thank you so much for helping us with this code, unfortunately it didn’t work. Our catapult won’t even move, but I do understand a bit more on how you did the p code and we plan on trying some different things with our code. Our team has probably watched about six hours on different PID code videos on YouTube so we are trying to do our research but we don’t have C++ class at our school. We only have 80 kids in our whole high school.

We understand everything in your code except the top part with the wrapAngleDeg. Could you explain what exactly is happening here. We looked up fmod to see that it divides those two numbers and we also looked up that “?” is trying to figure out if those statements to the right of it are true false. Would you mind explaining what exactly is happening in that part of the code because we are confused? Thank you

1 Like

Have you tried tuning the Kp value?
You also might want to change the delay in the loop from 5 msec to 20 msec. 5 msec is overkill, I missed that the first time I read your code.

Sure. :+1:

The function wrapAngleDeg will take an angle in degrees (say, -3949 degrees) and “wraps” it around to an equivalent angle between -180 and 180.

So, -3949 degrees would then become 11 degrees. This is just a precaution to make sure that the error calculation is more robust.

This is what the function does:

  • First we get the remainder of the angle (offset by +180) divided by 360.
  • Second, we either add 180 or subtract 180 to that remainder depending on if the remainder is greater than or less than zero.
  • Lastly, we return the above number.

Good point, We might try and see if we can get away with running our cata at 100% only. Although, I still have my doubts.

I feel the need to point out that a PID (or P-loop) would only be used for the occasional launching of a tri-ball in later periods of a match (or when playing defense); During the ‘flood the zone / match loading’ period during the beginning of a match, we would simply run the catapult at full power.

I don’t think they were using the motor encoders.

This is another good point! If you do this, then you can probably forego using a PID or similar (like you said).


Out of curiostity what does pid stand for

PID stands for Proportional Integral Derivative. the last two are both named after their respective calculus concepts.


Effects velocity directly proportional to the error.

The greater the error, the greater proportional is; The greater the error, the greater your velocity will be.


Effects velocity directly proportional to the accumulation of error.

If you made a function of error vs time, Integral would be the integral (area under curve) of that function.

Integral will help if you have a very small error that proportional cannot take care of; over time (not very much time) this small error will accumulate into a larger error (integral). Eventually Integral will be large enough to overcome this small error, without the help of P.


Effects velocity directly proportional to the rate of change of error.

If you made a function of error vs time, Derivative would be the derivative (slope) of that function (at a certain point).

This means that as error drops, the slope/derivative is negative; since velocity is effected directly proportional to derivative, when derivative is negative than velocity will actually be reduced by the derivative portion of a PID.

Derivative will make sure that you don’t approach your target too fast.


Thanks alot for explaining i kept seeing this post and was wondering what it was about.

No problem :+1:

I believe PID programming could help with my code that I am having issues with. When I have my velocity for my catapult at 50% it will hit the target about 50% of the time.

This seriously sounds like a mechanical problem and not a programming one. If you have to slow down your catapult to hit a reasonable target, you probably need either less bands or slower gearing. Running the motor at anything less than full speed simply loses torque during the pullback.

If you want the catapult to slow down as it pulls back, then a P loop should work fine, although it should already naturally slow down due to the tension from the rubberbands as it pulls further downward. Also: the speed of the motor should not affect your catapult arc at all. The power of a shot doesn’t come from the speed of the motor, but rather the stored tension in the bands. For any shot at any speed, you still pull the catapult back the same amount, storing the same amount of tension.

Also: I would strongly suggest not using motor braking for this. You’re essentially leaving it up to the motor to hold the catapult down, which is going to waste a lot of power and potentially overheat your motor over the course of the match. Using a ratchet to prevent the catapult gear from ever backdriving is much more ideal in this scenario.