![]() |
PID with encoder
Last spring was my first introduction to FRC and with my 17 years of Automation controls background I help a team figure out how to use some of their feedback devices I.E. pot, Ultrasonic, encoders. They had a lifting arm that fit itself well to a pot and PID subsystem. They where using Iterative type coding and with a little research and video tutorial on Command Base programming I quickly became a fan special with the test mode and how easily it was to test code bits and PID systems. The past few weeks during pre-launch I was teaching a new bunch of programmers the command base system and how the different parts work. We have only a robot drive train sub system currently with four wheels and encoders on each. Diving with joysticks and selecting different modes on the smartdashboard has been successful. Today I thought why don't we try a PID subsystem. We created a new project with only a PID subsystem with a motor and associated encoder. With 360 pulses per one rev of the output wheel verified by manually spinning the motor in test mode. When I enable the PID the motor shacks rapidly. It seems real hot but with turning down the P and leaving the I,D at 0 dose not seem to help.
Is using an encoder not a good idea for PID? Is there a way to set the max output so if the error is large the motor output can not raise above 50%? Maybe its because the resolution is to course? Maybe we should try setting the units per pulse to .1 and set point to 3600? |
Re: PID with encoder
How much play is there between your motors and your encoder mount?
|
Re: PID with encoder
I'm not super familiar with PID theory, but I do know that for 2016 they've added a velocity mode that does the PID calculations slightly differently. That might explain why you're having issues.
Here's a link to the new code: https://github.com/robotpy/allwpilib...ller.java#L265 |
Re: PID with encoder
I have a few questions about your system so that we might be able to help you better, if you don't mind me asking.
What language are you using? Are you controlling speed or position with your PID system? Getting the encoder speed has been known to not work entirely properly all the time, having large jumps in value, because of how the roboRIO does timing loops. Taking a manual derivative [(oldSpeed - currentSpeed) / periodicInterval (20 ms, unless you are making your own loops)] works much better and smoother. Is there any other system controlling the motor? I know that in labVIEW, the same motor set to different values in different places will cause the motor to rapidly twitch between them, due to the parallel nature of the language. Our team hasn't run into this problem in any of the text based options, but we also haven't had as much experience with them, and have very little experience in command-based programming (we've programmed all our new robots iteratively). If you are doing any threading or parallel processes, then definitely search for race conditions. Now, to answer your questions: "Is using an encoder not a good idea for PID?" Encoders work great - they are the best (only?) method of getting the position and velocity of a robot. We've used them ourselves in 2014 on our drive train and had great success with them. If you know what you're doing, you can do some really cool things with them (note: this isn't completely PID, but it is motion profiling with encoders as feedback sensors) "Is there a way to set the max output for PID?" the PIDSubsystem and PIDController classes both seem to have "setOutputRange" methods. I haven't used them myself, but the documentation says "Sets the maximum and minimum values to write", so I would start there. "Maybe its resolution is too coarse?" Most teams use encoders with resolutions of 360 or 256 and have reasonable success with both, so it's not likely that the resolution is where the problem lies. "Maybe we should try setting the units per pulse to .1 and set point to 3600?" If you are controlling the position of the encoders, then that would work well for finding any offending behaviors in the PID controller (obviously it's not a permanent solution). Best of luck, it's good to see mentors helping students learn and explore more advanced control options in FRC :) |
Re: PID with encoder
BL0X3R was on the money, but I will add graph it. When I graph our encoder data, depending on a number of factors I have seen very "jittery" velocity data (solutions are as mentioned, calculate yourself, if necessary calculate an average velocity over the last n encoder reads).
If you are using labVIEW visualizing data in real time is trivial. If not, I have taken to writing my logs in JSON and then using javascript and the browser for visualizing (I use http://www.flotcharts.org/), rather than trying to write code in C++ or Java to display graphs. In many cases seeing is understanding. |
Re: PID with encoder
By shakes (shacks?), do you mean that the motor just reciprocates but doesn't make any net revolution, or that it goes in the right direction but have a shake riding on top of that?
If it's the first, you may want to try swapping your encoder channels. If it's the second, check for loose connections, especially on the encoder but also on the power. |
Re: PID with encoder
Quote:
Quote:
Quote:
As virtuald stated and I found it was set to velocity. Is there any other system controlling the motor? No this is a fresh program with only the few components declared. Some of my ideas posted where me brain storming for tonight to get the community input. Thanks for the kind words too. Quote:
Quote:
Thanks to all lots of great ideas given and confirmed. |
Re: PID with encoder
Another thing you can do to work on this issue is to leverage the smartdashboard (I know you can't use it very much while in test mode) to display the distance/rate as you run the system manually (outside the PID loop) and see that things are changing as you expect (direction, magnitude, sensitivity).
|
Re: PID with encoder
SUCCESS!
The setOutputRange worked perfectly to slow things down so not to overshoot so violently. Also with closer examination of Robotbuilder and only after manually entering the code into the PID subsystem there is a check box and min/max value boxes. With kDistance selected as PID source I was able to tune the P factor to .005 and eliminate the overshoot. Tonight will be a successful learning experience thanks to your input. |
Re: PID with encoder
A very lightly loaded motor is going to be extremely difficult to tune for speed control, unless (as you discovered) you limit the power. What really works best is limiting the acceleration so the system is not as prone to oscillation. You can do that in software by limiting the rate of change of motor power, or you can do it in hardware by adding inertia.
|
Re: PID with encoder
Quote:
|
Re: PID with encoder
Quote:
My favorite method is to limit the voltage difference from the BEMF voltage. That will limit the current, which will limit the torque. You won't be able to do that with the standard PID controller, but it isn't very hard to write a new one. |
Re: PID with encoder
Quote:
CANTalons have a "setVoltageRampRate" function |
Re: PID with encoder
Quote:
|
Re: PID with encoder
Quote:
In this case, that would be doing a current loop and limiting the current, or feeding a motion profile into the talon (or from outside the talon). There are other methods that also work, but they won't work without being able to modify the firmware on the talon. |
| All times are GMT -5. The time now is 22:15. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi