View Single Post
  #2   Spotlight this post!  
Unread 25-05-2010, 03:06
vamfun vamfun is offline
Mentor :Contol System Engineer
AKA: Chris
FRC #0599 (Robodox)
Team Role: Engineer
 
Join Date: Jan 2009
Rookie Year: 2003
Location: Van Nuys, California
Posts: 182
vamfun is a glorious beacon of lightvamfun is a glorious beacon of lightvamfun is a glorious beacon of lightvamfun is a glorious beacon of lightvamfun is a glorious beacon of lightvamfun is a glorious beacon of light
Send a message via AIM to vamfun
Re: Encoder::GetRate()

Quote:
Originally Posted by masoug View Post
Hi,
Just to clarify, what does Encoder::GetRate() do? I heard that it is a nasty function, but I have some other thoughts...
Well, if it didn't have any bugs, it does what you would expect. It gives the time rate of change of the encoder signal by deriving the frequency of the pulses detected by interrupts triggered by the A an B encoder channels.

http://www.chiefdelphi.com/forums/sh...ad.php?t=82171 addresses some obvious coding errors and suggests a code patch that corrects the function for an erroneous double output. Joe Hershberger is working the why's of the problem. This thread includes a long discussion of the problem , various algorithms used in encoder.c and some of the more subtle points that arise under unusual input oscillatory signals. If you have some time, wade through it and you will learn more than you wanted to about quadrature encoders and how to decode them conventionally (unconventional hysteresis decoding is debated but is not used in GetRate()).

If you just apply the proposed patch, it should work fine for you. There might be some additional fine tuning by Joe pending his analysis and my suggestions. Maybe Joe will chime in with some more info.

Edit: I have a little more time to comment today.

Since the encoder is a type of analog to digital converter it suffers from the same quantization errors as regular A/D's. Small amplitude signal variations within quantization thresholds will go undetected but when sustained over a threshold (ie from an oscillatory vibration) they are detected and amplified due to the round off errors. Joe's GetRate() algorithm will smooth out these amplified errors by detecting same edge reversals and not allowing rate changes until a new edge is detected.

Also , since the rate is derived from the actual period between pulses , it is insensitive to user iteration cycle time. If a user derives rate by simply taking differences in GetDistance() values and dividing them by the iteration cycle time he will have spikes equal to 1 count/(iter cycle time) on each pulse with a bunch of zeros in between. So usually additional filtering is required if these derived rates are to be used in robot control systems. Therefore, the GetRate() output can be quieter for use with indicators , logic comparators and as a rate term (D) in PID contollers.

The GetRate() does have some tricky features such as SetMinRate() or SetMaxPeriod(). Since the rate is based upon the period between the last two pulses, when the encoder stalls it will hold the last rate in its registers until a timer expires and the rate is forced to zero. This timer is set by SetMaxPeriod(). So if you set this too long, then an abrupt stall after a large rate will give you a distance error = last_rate_before_stall*timer_period if you are by chance integrating the GetRate() output. So I would not recommend integrating GetRate() and expecting to recover a position change that would match the change indicated by GetDistance(). Something like this might occur if you are resolving a body axis velocity computed from GetRate() into fixed inertial axes and integrating North/East components for a navigation function. Here it would be better to use the time derivative of GetDistance().

Last edited by vamfun : 25-05-2010 at 15:56.
Reply With Quote