OCCRA
Go to Post Just as you and your team will make hard decisions as you struggle to build a robot, FIRST has had to make hard decisions concerning maximizing safety while making the number of rules as small as possible. - Mike Betts [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 Rating: Thread Rating: 3 votes, 5.00 average. Display Modes
  #1   Spotlight this post!  
Unread 02-08-2010, 02:07 PM
LyraS LyraS is offline
Registered User
FRC #2102
 
Join Date: Jan 2010
Location: California
Posts: 6
LyraS is an unknown quantity at this point
Unexpected results from Encoder::GetRate()

I'm trying to set up a speed controller using the US Digital E4P-250-250-D-D-D-B encoder and the WPI Encoder class. Everything basically works fine but I'm seeing an odd discrepency between the values out of GetRate() and GetDistance(). Spinning the encoder at a constant rate, I would expect that the rate returned by GetRate() (units/sec) would more or less match the one-second delta returned by GetDistance(). But what I see is this: the distance returned for one second is almost exactly half of GetRate(). Because GetRate() is fairly noisy, I'm testing using a 20 sample moving average (with a sampling rate of 40hz). I'm sure I'm missing something obvious... Can one of the WPIlib experts here clue me in on what it is? Thanks!

Update, possible clue:

Looking through the WPI source I noticed this comment in Counter.cpp (used by 1x and 2x Encoder):

/*
* Get the Period of the most recent count.
* Returns the time interval of the most recent count. This can be used for velocity calculations
* to determine shaft speed.
* @returns The period of the last two pulses in units of seconds.
*/
double Counter::GetPeriod()

Last edited by LyraS : 02-08-2010 at 02:26 PM. Reason: Update... more info
Reply With Quote
  #2   Spotlight this post!  
Unread 03-23-2010, 04:05 AM
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: 184
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: Unexpected results from Encoder::GetRate()

Just now seeing the same problem when running x1 with the kit encoders.

GetDistance() gives the correct value but the GetRate() gives double rate.

Anybody using this function with success?

We have all the latest updates in SW.

Update:

I decided to check the GetPeriod() in Encoder.cpp. I don't see any problem with the LyraS question but something else seems strange to me here and maybe someone can tell me why its correct.

double Encoder::GetPeriod()
{
if (m_counter)
{
return m_counter->GetPeriod() * DecodingScaleFactor(); //****THIS IS WHERE I SEE A PROBLEM ***
}
else
{
tEncoder::tTimerOutput output = m_encoder->readTimerOutput(&status);
double value;
if (output.Stalled)
{
// Return infinity
double zero = 0.0;
value = 1.0 / zero;
}
else
{
value = (double)output.Period / (double)output.Count;
}
wpi_assertCleanStatus(status);
return value * 1.0e-6 / (DecodingScaleFactor() * 4.0);
}
}


In the 1x and 2x the counters are used. The period that the counters return should be for the actual pulses not the spec pulse frame. Hence, the periods should be shorter when running 2x. So when

if (m_counter)
{
return m_counter->GetPeriod() * DecodingScaleFactor(); //****THIS IS WHERE I SEE A PROBLEM ***
}

occurs, it should correct the counter period to the spec period which would be longer. This statement makes the period the same or shorter since DecodingScaleFactor() returns 1 for 1x , .5 for 2x.

It seems that this should read

if (m_counter)
{
return m_counter->GetPeriod() / DecodingScaleFactor(); //****USE DIVISION TO CORRECT PERIOD ***
}

The division by DecodingScaleFactor() would then be similar to that used in the 4x return value.
If my reasoning is correct, then the 2x should be off by a factor of 4 but the 1x should be ok. So unfortunately this doesn't explain why we still are double the rate when running at 1x and maybe when I get some time, I'll check this hypothesis. Where is Joe Hershberger when we need him?

Last edited by vamfun : 03-23-2010 at 06:10 PM.
Reply With Quote
  #3   Spotlight this post!  
Unread 03-25-2010, 12:52 AM
Joe Hershberger Joe Hershberger is offline
National Instruments
AKA: jhersh
FRC #2468 (Appreciate)
Team Role: Mentor
 
Join Date: Nov 2005
Rookie Year: 1997
Location: Austin, TX
Posts: 148
Joe Hershberger is a name known to allJoe Hershberger is a name known to allJoe Hershberger is a name known to allJoe Hershberger is a name known to allJoe Hershberger is a name known to allJoe Hershberger is a name known to all
Re: Unexpected results from Encoder::GetRate()

Have you guys tried 2x and 4x modes? Do you get what you expect in those modes?

At a glance, it looks like the period should be divided by DecodingScaleFactor(), as suggested. I don't think the 4x version should have the "4.0" in the denominator either. I need to try it out when I'm at a system that has an encoder. I'm at the regional in Cleveland this weekend.

-Joe
Reply With Quote
  #4   Spotlight this post!  
Unread 03-25-2010, 01:16 AM
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: 184
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: Unexpected results from Encoder::GetRate()

Quote:
Originally Posted by Joe Hershberger View Post
Have you guys tried 2x and 4x modes? Do you get what you expect in those modes?

-Joe
Not yet..competing in LA regional this weekend also.

Quote:
I don't think the 4x version should have the "4.0" in the denominator either.
Yes, I could see no reason for that either. Thought this was a hold over from the 4x error days. Hard to believe no one has reported any problems with this function. Guess everyone is doing their own rate derivation which we were going to do , but I wanted to give the wpi lib a chance since I didn't remember these being a problem last year. We are using the GetRate() with a .5 multiplier. Seems to work ok then.
Reply With Quote
  #5   Spotlight this post!  
Unread 03-26-2010, 08:06 PM
Bigcheese Bigcheese is offline
C++0x FTW!
AKA: Michael Spencer
FRC #1771
Team Role: Mentor
 
Join Date: Feb 2008
Rookie Year: 2008
Location: GA
Posts: 36
Bigcheese is a jewel in the roughBigcheese is a jewel in the roughBigcheese is a jewel in the roughBigcheese is a jewel in the rough
Re: Unexpected results from Encoder::GetRate()

Encoder::GetRate() in 4x mode returns crap. And by crap I mean the value returned is proportional to the speed of the robot, but I know our bot is not going 80 feet per second (55 mph)... I tried changing (4x mode) to return:
Code:
value * 1.0e-6  / DecodingScaleFactor()
Instead of:
Code:
value * 1.0e-6  / (DecodingScaleFactor() * 4)
Which lowered the error, however it is still way too high.

I know I can just multiply the returned value by some gain, but I'd rather have the code actually be right. I'm about to go chuck the dang thing up in the lathe so I know what the value returned should be, and work from that.

Last edited by Bigcheese : 03-26-2010 at 08:08 PM.
Reply With Quote
  #6   Spotlight this post!  
Unread 03-27-2010, 02:42 AM
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: 184
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: Unexpected results from Encoder::GetRate()

Good to have another data point. Couple of questions.

Is the GetDistance() correct?

If so, can you use it to make a quantitative estimate on what the ratio of encoder rate to actual rate in x4 after you eliminated the 4 factor in the denominator? I'm guessing it might be off by a factor of two like the 1x. If it is, that could provide a clue to whats going on.

In my experience, using 4x to get rate always introduces extra noise due to inherent phase errors built into the code wheels.
http://www.chiefdelphi.com/forums/sh...=encoder+noise
Reply With Quote
  #7   Spotlight this post!  
Unread 03-29-2010, 02:40 AM
jhersh jhersh is offline
National Instruments
AKA: Joe Hershberger
FRC #2468 (Appreciate)
Team Role: Mentor
 
Join Date: May 2008
Rookie Year: 1997
Location: Austin, TX
Posts: 1,006
jhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond repute
Re: Unexpected results from Encoder::GetRate()

Quote:
Originally Posted by Bigcheese View Post
Encoder::GetRate() in 4x mode returns crap. And by crap I mean the value returned is proportional to the speed of the robot, but I know our bot is not going 80 feet per second (55 mph)...
Did you actually call SetDistancePerPulse() with the correct scale? The API can't magically know your gear ratios or wheel circumferances.
Reply With Quote
  #8   Spotlight this post!  
Unread 04-03-2010, 09:47 PM
Bigcheese Bigcheese is offline
C++0x FTW!
AKA: Michael Spencer
FRC #1771
Team Role: Mentor
 
Join Date: Feb 2008
Rookie Year: 2008
Location: GA
Posts: 36
Bigcheese is a jewel in the roughBigcheese is a jewel in the roughBigcheese is a jewel in the roughBigcheese is a jewel in the rough
Re: Unexpected results from Encoder::GetRate()

Quote:
Originally Posted by jhersh View Post
Did you actually call SetDistancePerPulse() with the correct scale? The API can't magically know your gear ratios or wheel circumferances.
Yes, GetDistance returns the correct distance when the bot is pushed.

1x and 2x are not as noisy. And are normally distributed. 4x is distributed towards the center and +- some value. It's either a code problem or an encoder problem. I'm going to hook it up to a function generator and figure out which it is.
Reply With Quote
  #9   Spotlight this post!  
Unread 04-04-2010, 07:05 PM
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: 184
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: Unexpected results from Encoder::GetRate()

Quote:
Originally Posted by Bigcheese View Post
Yes, GetDistance returns the correct distance when the bot is pushed......

I'm going to hook it up to a function generator and figure out which it is.
The function gen is a good idea, but you can use your GetDistance() to make an accurate estimate of the average rate. Could save you a little time.
Reply With Quote
  #10   Spotlight this post!  
Unread 04-04-2010, 10:53 PM
Bigcheese Bigcheese is offline
C++0x FTW!
AKA: Michael Spencer
FRC #1771
Team Role: Mentor
 
Join Date: Feb 2008
Rookie Year: 2008
Location: GA
Posts: 36
Bigcheese is a jewel in the roughBigcheese is a jewel in the roughBigcheese is a jewel in the roughBigcheese is a jewel in the rough
Re: Unexpected results from Encoder::GetRate()

Quote:
Originally Posted by vamfun View Post
The function gen is a good idea, but you can use your GetDistance() to make an accurate estimate of the average rate. Could save you a little time.
If you used a large enough dt, true. However, 1x or 2x using GetRate returns perfectly fine data and takes less time to implement. The point of using a function generator is simply to verify that it is indeed the encoder, not the FPGA code, that is the problem.

I could also just fix my stupid 2nd probe and look at the encoder output on the scope...

BTW, the FPGA code could be changed to account for the phase lag. It's actually a very easy fix, although it would require you to experimentally determine the phase lag and pass it to the FPGA. Determining this would simply require spinning the encoder at a constant speed and look at the channel B phase offset.
Reply With Quote
  #11   Spotlight this post!  
Unread 04-05-2010, 05:09 PM
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: 184
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: Unexpected results from Encoder::GetRate()

Quote:
Originally Posted by Bigcheese View Post
If you used a large enough dt, true. However, 1x or 2x using GetRate returns perfectly fine data and takes less time to implement.
Ok, then you are not seeing the factor of 2 on 1x rate that we are and determining avg rate would be unnecessary. How did you independently verified the 1x rate was ok?

It is hard to envision that the encoder could be in error if GetDistance() is working, so I vote for the code.
Reply With Quote
  #12   Spotlight this post!  
Unread 04-05-2010, 09:10 PM
Bigcheese Bigcheese is offline
C++0x FTW!
AKA: Michael Spencer
FRC #1771
Team Role: Mentor
 
Join Date: Feb 2008
Rookie Year: 2008
Location: GA
Posts: 36
Bigcheese is a jewel in the roughBigcheese is a jewel in the roughBigcheese is a jewel in the roughBigcheese is a jewel in the rough
Re: Unexpected results from Encoder::GetRate()

Quote:
Originally Posted by vamfun View Post
Ok, then you are not seeing the factor of 2 on 1x rate that we are and determining avg rate would be unnecessary. How did you independently verified the 1x rate was ok?

It is hard to envision that the encoder could be in error if GetDistance() is working, so I vote for the code.
The speed is still off by a constant factor, but that's not what I'm focusing on at the moment. I agree that this is a code issue because GetDistance is correct.

The encoders are the reason for the noisy data returned by 4x decoding. GetDistance isn't greatly effected by this because every rising/falling edge is offset an equal but opposite amount, so it averages out to be correct. The problem comes in when you try to take the derivative (GetSpeed), because now these offsets are no longer averaged out.

Last edited by Bigcheese : 04-05-2010 at 09:12 PM.
Reply With Quote
  #13   Spotlight this post!  
Unread 04-05-2010, 09:46 PM
mikets's Avatar
mikets mikets is offline
Software Engineer
FRC #0492 (Titan Robotics Club)
Team Role: Mentor
 
Join Date: Jan 2010
Rookie Year: 2008
Location: Bellevue, WA
Posts: 770
mikets is a name known to allmikets is a name known to allmikets is a name known to allmikets is a name known to allmikets is a name known to allmikets is a name known to all
Re: Unexpected results from Encoder::GetRate()

I did not follow the entire thread of discussion so if I misunderstood the issue, I apologize. But I do want to mention my experience on dealing with the accelerometer by integrating it twice to get distance. How did you differentiate the distance value to get speed? In particular, how did you get dt? The reason I ask is because I discovered that if you have code that is supposed to be run periodically at a fixed interval, don't count on the interval being accurate. For example, my integrator code is supposed to run every 10 msec, eventually I found out that it got called every 20+ msec instead. So don't use the period as your dt because it is not accurate. Your speed data will be all over the place. I scratched my head on the accelerometer for a while until I finally timed the interval of my code being called and found that I can't depend on it being constant. So I now wrote the code to measure the interval and use it as my dt instead. Then my integrator is now quite accurate.
__________________
Reply With Quote
  #14   Spotlight this post!  
Unread 04-06-2010, 01:42 AM
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: 184
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: Unexpected results from Encoder::GetRate()

Quote:
Originally Posted by Bigcheese View Post
The speed is still off by a constant factor..
So I was hoping that you would use GetDistance() with a large dt (say 10 revolutions) to determine this constant to verify that it matches our estimated factor of 2 constant.

Quote:
The encoders are the reason for the noisy data returned by 4x decoding. GetDistance isn't greatly effected by this because every rising/falling edge is offset an equal but opposite amount, so it averages out to be correct. The problem comes in when you try to take the derivative (GetSpeed), because now these offsets are no longer averaged out.
We are in full agreement here and as I stated before, our team never uses x4 because it really is unnecessary with 1 deg resolution encoders and why introduce the asymmetric 4x phase errors.

So the noise is expected, but the mean values being off by a constant is what I'm focused on. This smacks of a FPGA counter average period problem.
Reply With Quote
  #15   Spotlight this post!  
Unread 04-06-2010, 02:06 AM
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: 184
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: Unexpected results from Encoder::GetRate()

Quote:
Originally Posted by mikets View Post
For example, my integrator code is supposed to run every 10 msec, eventually I found out that it got called every 20+ msec instead. So don't use the period as your dt because it is not accurate. 't depend on it beingYour speed data will be all over the place. I scratched my head on the accelerometer for a while until I finally timed the interval of my code being called and found that I can constant. So I now wrote the code to measure the interval and use it as my dt instead. Then my integrator is now quite accurate.
This is a little off topic in that the encoders use pulse interval timers to derive speed and do not depend on periodic loops. But I suspect that the FPGA interval timer that measures an average pulse period may have a bug in it.

In support of your comments, we use the iterative robot class and a navigation function that integrates encoder rate resolved to field coordinates. Distance tests were off by a factor of 2. Either the speeds were double or the loop iteration rate was double. We integrated dt = 1/(Update_Rate) and checked that the computed time matched real time so this led us to the double encoder GetRate() error which we verified independently using motor rpm measurements.
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
[BB] An unexpected change in plans yodameister General Forum 22 12-01-2009 09:26 PM
Inconsistent reading from encoder get rate rwood359 National Instruments LabVIEW and Data Acquisition 5 01-13-2009 07:10 PM
Results from Drexel, thanks from 365. archiver General Forum 1 06-24-2002 02:44 AM
Results from GLR? archiver General Forum 0 06-24-2002 02:44 AM
results from regionals archiver General Forum 0 06-23-2002 10:31 PM


All times are GMT -5. The time now is 11:14 PM.

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