I'm aiming to control a motorized joint at a specific speed. To do this, I'm planning on attaching a rotary encoder to do this.
I'll be controlling the motor with a PID controller. With this PID controller, I need to control the joints based on their velocity.
Since:
speed = distance / time
It would make sense to do something like this:
double getCurrentSpeed() {
return (currentAngle - lastAngle) / samplingRate;
}
However, there's an issue; the encoder doesn't provide a high enough resolution to accurately calculate the speed (the sample rate is too high). I want to have updated data every 5-15 ms (somewhere in that range as my current motors seem to be able to respond to a change in that range)
Some more information:
- 14 bit precision (roughly 0.0219726562 degrees per "step" of encoder
- I'd like to be able to calculate as small of speed differences as possible
- As the motors will be going fairly fast (120+ degrees/second at highly variable speeds and directions), so the feedback has to be accurate and not delayed at all
So, a couple of ideas:
- I can find encoders that I can sample at a very high rate. I was thinking about sampling the time between the changes of the encoder's value. However, this seems finicky and likely to be noise-prone
- I could do some sort of rolling average, but that would cause the data values to "lag" because the previous values would "hold back" the output of the calculations somewhat and this would play with my PID loop some
- Noise filter of some sort, although I don't know if that would work given the rapidly changing values of this application
However, none of these seem ideal. Is my only option to get a 16 bit (or higher!) encoder? Or is there another method/combination of methods that I could use to get the data I need?