When using integrator term on PID controller to set rpm 2 ball shoots farther

My team is using a neo brushless motor to power our shooter. In order to set the velocity of the shooter, I use the integration part of the WPILib PID controller. The shooter gets to the correct RPM and the first ball shoots accurately but upon shooting the second loaded ball the shooter shoots inaccurately. The feeder wheel is at 25% power. What could be the problem? What should I do to ensure that we get consistent shots?

Here is my PID definition
private final PIDController shooterController = new PIDController(0, 2e-4, 0);
shooterController.setIntegratorRange(-1, 1);

Here is how I am setting my shooter velocity
public void setShooterVelocity(double speed) {
double velocity = MathUtil.clamp(shooterController.calculate(getVelocity(), speed), -1.0, 1.0);

Here is a video depicting my dilemma (0:35):

Watching the video it looks like your shooter is shooting the cargo once the rpm hits the desired rpm, the problem is that the cargo takes a some time to get to the shooter and meanwhile the shooter is in the process of overshooting the desired set point.

You should graph your velocity to the smart dashboard, glass or shuffle board to get a better picture of what is happening. It looks like you need to tune your PID constants to lower your overshooting of the setpoint.

Another thing that you could implement to ensure the shooter rpm is at the correct range by using an exponential smoothing function and checking that is at the desired rpm before shooting. The exponential smoothing function uses a weighted average to ensure a more consistent velocity before triggering the shooting

Integral-only control (P and D terms set to 0) is uncommon because it is prone to oscillation and long settling times. Given that you’re controlling the speed of a flywheel, why not use PF (proportional+feedforward) control instead?


You could also try a bang-bang controller, which might work and is quite simple.

What the others have said regarding a PF controller is spot on. Another thing you can consider is lowering your feeder speed. Your shots are coming out very fast, not allowing the shooter much time to correct in-between shots. If you can slow the feed down, you allow the shooter wheel to settle a bit more before the second ball reaches it.

1 Like

2 Possibilities:

  • The first ball blocks the limelight momentarily
  • The rpm is not recovering fast enough from the first shot (requires further tuning of p/d term)

How would you recommend I tune the feed forward and proportional constants to achieve that

Actually, now that I see the video and see that the second ball is shooting further its possible that:

  • The first ball blocks the limelight momentarily (issue we had and the second ball overshot every time)
  • The P term is too high and D is too low so it overcompensates for the dip in RPM

Highly recommend graphing the following values with Glass:

  • wanted RPM (look for huge jitters)
  • current RPM (look for overshooting after first ball)
  • target y offset from limelight (look for huge jitters)

As others have said, you’ll want to first set up some plotting, so you can see what happens to the velocity of the flywheel over time, especially during shooting.

Set up the motor controller in voltage compensation mode to start with. This will mean that your outputs will be in volts.

Then, try setting different voltages until the unloaded velocity (i.e., not shooting cargo) settles at about how much you want for shooting. Take the ratio of that voltage to velocity (e.g., volts per [encoder ticks/second], or whatever units it comes out in). Your entire feedforward term should be that constant (call it kF), multiplied by the setpoint you want to achieve (speed, in setShooterVelocity()), in the correct units.

Add to that a proportional term, which could come from a the wpilib PIDController you’re already using:

…or you could just recreate it. The error term is going to be [speed - getVelocity()] in your setShooterVelocity() method, you’ll have a proportional gain (kP) and the total proportional term will be kP * error.

Start with the proportional gain at 0 (as well as the I and D – leave those at 0) and try shooting a few cargo. As you slowly increase the proportional gain (alternating shots and increases in kP), the speed of the flywheel should recover more quickly after shots. As you exceed the ideal proportional gain, the settling time will go up again.

You can get more complex with the modeling/characterization as well, if this is something you’re interested in:



If you set your feed wheel to spin at max speed it is likely not up to speed before the first ball enters the shooter wheel, and it may have accelerated more by the time the second one gets there. A perfectly tuned shooter won’t shoot consistently if the feed isn’t consistent unless you have a long distance to correct for this (more than just 90 deg wrap around a wheel). The plotting suggestions are good too, but I’d be surprised if you were seeing that large of a shot difference in PID tuning.

If the team directly drives the mechanism setpoint(s) based only on the instantaneous target capture, losing vision lock can be an issue. If we expect to lose vision, auto aiming and auto ranging can be driven by a pose to the target that persists, and automatically updates using odometry, even when the vision lock is lost. This was a major technology development for 2363 this year. The goal was to build a system that could estimate the position of the robot on the field at all times using odometry (reliable but drifty) and vision (unreliable but absolute). It results in a robot that can continuously adjust the shooter wheel speed and hood angle while driving, even if the camera can’t see the target. We rolled this code onto the bot between our week 1 and week 3 events and saw our shot percentages drastically improve.


For an example of using a control loop to set motor velocity, watch this video. This example uses P gain and feedforward. https://youtu.be/hhgN-wp53s4

Also, a wordy but interactive exercise for tuning by hand.

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.