So I’m having a problem that I’ve never encountered before. When the robot is turning in autonomous mode, if the motors are running at anything upwards of 25% the robot drastically overshoots the desired target angle. This is my code:
If anyone has any suggestions that would be great!
Is it only autonomous? I.e., does this also occur when turning in teleop?
It looks from a quick glance at your code that you’re simply turning at some speed until you reach the desired angle, then setting the motors to zero. The robot has inertia and will not instantly stop. So your issue has nothing to do with the gyro reading, but rather your control of the motors. You should look into features such as ProfiledPIDController to control your turn by smoothly ramping up and ramping down power at the start and end of the turn to avoid overshoot and correct for errors along the way.
Does the SYSID tool have functionality for that or would I need to tune the PID controller manually. Also what is the difference between a PID controller and a Profiled PID Controller?
A PID controller uses simple math. Naively: Constant * (desired location - current location). This results in full output at a given distance. A profiled pid incorporates acceleration and velocity to craft a motion profile that the motor follows, attempting to stay away from saturating outputs while getting to the set point smoothly and quickly.
Does anyone have any suggestions on how to tune a profiled pid controller for rotational motion?
I do not. We are using standard pid because we can tune it very quickly and we are far behind. I had wanted to use profiled pid everywhere this year, but it isn’t happening until at least after our first competition.
Have you checked the Gyro reading on the dashboard compared to actual robot turn? The ADXRS450 has a higher potential to get mixed up quality gyro than a lot of those used in FIRST and using it for auto turning is not ideal. Yes, you can use a PID controller and low speeds, but if you can get your team to invest in a better gyro, you will be faster at lining up and more precise. I linked the one my team uses below, but there are others that work well.
The difference in performance is very minor on the timescales we care about in FRC. The last thing the OP needs to do right now is worry about getting a more expensive gyro.
I put the adxrs450 on my team’s robot and tried to do trajectory following; it quickly became up to 30-40 degrees off. The difference is big enough, at least for our team, that it matters significantly.
I suspect that was a defective gyro, then (I’ve had these even with more expensive models).
I had the same effect as Berkeli, with 3 different ADXRS450’s - drifting about 40-60 degrees in a random direction after 30 seconds of driving
I have used ADXRS450s for trajectory following for multiple years now. No issues at all.
So I’ve implemented a PID controller for the rotational control and I have the PID controller constants set up to turn to 90 degrees and it does that very consistantly but as soon as I try to turn to a different angle, the pid controller doesn’t work anymore and I have to change the constants to work with the new angle. For example, I tried turning to 15 degrees and the robot barely moved. The code is the same link above. Any suggestions would be very helpful. Thanks!
This is how we do it…
You have a goal. The angle you want to robot to be facing when you are done.
You have the current angle.
You calculate the error. The difference between the goal and the current.
In you command’s execute method:
- calculate the current error
- feed the error into a PID
- take the result of the PID.calculate and send that as the motor powers in your drivetrain. (Instead of having a slow and a fast make it a variable)
Once error reaches your tolerance end the command.
I do use the PID controller class built in to WPIlib which seems to work great for one angle at a time. Instead of setting the motors individually I use arcade drive. The issue is that when I change the angle, the robot doesn’t want to turn to the new angle with the same PID constants. As I said before, the robot would barely even move when I changed the desired angle to 15 degrees from 90 degrees (with the constants staying the same). Is this normal? do the PID constants need to be changed every time I change the desired angle?
No. They shouldn’t. You can try a simple feed forward by adding to the result of the PID the smallest amount of power that moves the robot.
How would tuning a feed forward work? Does it just act as a minimum speed that the motors spin?
Essentially yes. You should tune P so that it over shoots. Then add a little D. I would avoid I…
wpilib has a feed forward class for a more sophisticated solution.
so with the feedforward class, how do I know what velocity I want, is there a way to figure out the max velocity and acceleration I can have without the robot overshooting the desired angle?