Go to Post Team spirit is not all about the tools/noise makers. The Tigertrons didn't have any sort of noise makers. Consider other aspects of the award by making signs, mascots, cheers, and how you interact with other teams. - team222badbrad [more]
Home
Go Back   Chief Delphi > Technical > Programming > C/C++
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 24-05-2010, 21:40
masoug's Avatar
masoug masoug is offline
Food Consumer
FRC #0114
Team Role: Programmer
 
Join Date: Jan 2010
Rookie Year: 2009
Location: Planet Earth
Posts: 78
masoug is an unknown quantity at this point
Question Encoder::GetRate()

Hi,
Just to clarify, what does Encoder::GetRate() do? I heard that it is a nasty function, but I have some other thoughts...

THANKS!!!

-Masoug
__________________

JabbaScript
Reply With Quote
  #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
  #3   Spotlight this post!  
Unread 25-05-2010, 15:35
masoug's Avatar
masoug masoug is offline
Food Consumer
FRC #0114
Team Role: Programmer
 
Join Date: Jan 2010
Rookie Year: 2009
Location: Planet Earth
Posts: 78
masoug is an unknown quantity at this point
Re: Encoder::GetRate()

Thanks for the quick reply, so if there are no errors, it returns the number of pulses over time?

How would I get a speed value from it? IF GetRate() is REALLY not THAT good, then would GetDistance() work?

THANKS!!!

-Masoug
__________________

JabbaScript
Reply With Quote
  #4   Spotlight this post!  
Unread 26-05-2010, 00:17
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
Thanks for the quick reply, so if there are no errors, it returns the number of pulses over time?

How would I get a speed value from it? IF GetRate() is REALLY not THAT good, then would GetDistance() work?

THANKS!!!

-Masoug
GetRate() automatically scales the pulse rate to get speed. The output = distance_per_pulse/pulse_period, where pulse_period is the time between the last two recorded pulses unless there is a stall condition. In a stall condition, pulse_period is set to "infinity" after the max_period time is exceeded. This drives GetRate() to zero.

GetDistance() is working ok. Only GetRate() has a few bugs. As I mentioned before, a temporary patch has been defined to get this operational on first forge and will surely be corrected in a software update before next season.

Last edited by vamfun : 26-05-2010 at 01:48.
Reply With Quote
  #5   Spotlight this post!  
Unread 26-05-2010, 13:28
mikets's Avatar
mikets mikets is offline
Software Engineer
FRC #0492 (Titan Robotics)
Team Role: Mentor
 
Join Date: Jan 2010
Rookie Year: 2008
Location: Bellevue, WA
Posts: 667
mikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of light
Re: Encoder::GetRate()

I am sorry if I don't understand. If the goal is to get velocity, wouldn't it be easier to do this instead:
Code:
vel = (currentDistance - previousDistance)/period;
This should work unless there is a problem with GetDistance() too.
__________________
Reply With Quote
  #6   Spotlight this post!  
Unread 28-05-2010, 15:48
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 mikets View Post
I am sorry if I don't understand. If the goal is to get velocity, wouldn't it be easier to do this instead:
Code:
vel = (currentDistance - previousDistance)/period;
This should work unless there is a problem with GetDistance() too.
If the period is identical to the pulse period, then this is the same as GetRate() (less some filtering).

If the period is set by a periodic loop outside of encoder.c and not the actual pulse period, then vel is an average speed over that sample period. As I mentioned in the first post, if the sample period is much shorter than the actual pulse period, then this "vel" approaches an impulse train with zeros in between. These impulses can cause trouble if there are nonlinearities in the system such as limits or threshold detectors. So with very high sample rates, additional filtering is needed to negate these effects. The simplest way to filter the impulses is to increase the sample period over which you obtain the average rate, but this causes added delays is detecting speed changes.

So the GetRate() output is a nice compromise. It detects when a pulse has changed and then adjusts the rate and holds it in a register for whoever wants to use it. The averaging time varies with the pulse period and it has an artificial max period but it eliminates the impulses present with very high sample rates and minimizes the need for additional filtering.

I might add that encoder rate noise from other sources often dictates that even GetRate() be further filtered.

Last edited by vamfun : 28-05-2010 at 16:13.
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Unexpected results from Encoder::GetRate() LyraS C/C++ 90 16-04-2012 20:27
Encoder Error Haragorn NI LabVIEW 15 31-01-2010 20:29
Screwing Encoder into Encoder Mount? Adrien Electrical 3 25-01-2009 18:14
encoder.c Gary Bonner Programming 2 14-01-2005 13:41


All times are GMT -5. The time now is 13:51.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi