Positional PID control overshoots target ... by a lot

I’m using the NEO’s encoders with spark maxes to run positional PID control for our drivetrain and I’m having trouble with the distance it travels. The robot will start autonomous, drive way farther than it is supposed to and then stop.

I have been successful with this in the past but I am having trouble with this new robot for whatever reason. I tried modifying the successful code for the new robot but to no avail.

My first thought was the PID constants were wrong, so I ran the SYSID tool with the drivetrain configuration to calculate new PID constants. After the implementation, there is no oscillation around the setpoint, but the robot stops way farther than it’s supposed to.

I’m not sure if I’m missing something glaringly obvious here or if there is something fundamentally wrong with my implementation. If anyone could give my code a glance, that would be amazing!!

Here is the most recent version of the code: https://github.com/elliot1234567/QJ

Thanks!

Is it possible previously you were using brake mode for your drive motors and now are in coast mode? I don’t see anywhere in your code itself where you define the neutral mode for the NEOs.

Based on your DriveDistance command it looks like you are simply stopping output to the motors as soon as you reach your setpoint, which in coast mode would likely result in the robot continuing onward a bit further as it coasts to a stop.

2 Likes

Here’s some advice on how to set brake mode in a way that still lets you move the robot when it’s disabled.

1 Like

So the motors are in brake mode. When I imaged the spark maxes and set their IDs, I set the idle mode to brake mode. Furthermore, the robot comes to an abrupt halt at the end of its autonomous routine.

Should I be setting the position conversion factor on the spark maxes, could that be why it is overshooting?

General advice I have seen elsewhere: turn on the robot and then manually push it for some known distance. Check that the distance measured by the encoders matches how far out was pushed. You might have the calibration wrong.

2 Likes

Yes, this does feel like a the distance the PID controller thinks you have gone is different than the actual distance.

The encoders are outputting native units, I’m guessing I need to convert the encoders to output in inches like this:

mLeftEncoder.setPositionConversionFactor(Units.metersToInches(Constants.kGearBoxRatio/Constants.kWheelCircumference))

You could but you don’t have to. It depends on what you used when you characterized the chassis.

Sorry, I did not mean that you should explicitly look at the encoders. To be clear, you should look at the measured position/motion of the robot that the Ramsete controller is seeing. For us, we converted to distances in our Rio software and then fed that to the controller. So, output and monitor those values.

1 Like

It looks like you assume native units are revolutions since you didn’t use your ticks per rotation constant.

I see you tried to stick with revolutions so make sure the encoder is producing that. (Print statements.)

Compute the ratio of how far you request to drive and how far you actually drive. See if it’s a recognizable magic number or its reciprocal.

That ratio should have been included in this thread so commenters could help you. (See my comment in how to ask questions. Don’t ask a qualitative question to a quantitative problem. Give us the numbers and we can tell you what they mean.)

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