|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools |
Rating:
|
Display Modes |
|
|
|
#1
|
|||
|
|||
|
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 : 08-02-2010 at 14:26. Reason: Update... more info |
|
#2
|
|||
|
|||
|
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 : 23-03-2010 at 18:10. |
|
#3
|
|||
|
|||
|
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 |
|
#4
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
Quote:
|
|
#5
|
|||
|
|||
|
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() Code:
value * 1.0e-6 / (DecodingScaleFactor() * 4) 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 : 26-03-2010 at 20:08. |
|
#6
|
|||
|
|||
|
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 |
|
#7
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Did you actually call SetDistancePerPulse() with the correct scale? The API can't magically know your gear ratios or wheel circumferances.
|
|
#8
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
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. |
|
#9
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
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.
|
|
#10
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
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. |
|
#11
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
It is hard to envision that the encoder could be in error if GetDistance() is working, so I vote for the code. |
|
#12
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
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. Last edited by Bigcheese : 05-04-2010 at 21:12. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| [BB] An unexpected change in plans | yodameister | General Forum | 22 | 01-12-2009 21:26 |
| Inconsistent reading from encoder get rate | rwood359 | National Instruments LabVIEW and Data Acquisition | 5 | 13-01-2009 19:10 |
| Results from Drexel, thanks from 365. | archiver | 2001 | 1 | 24-06-2002 02:44 |
| Results from GLR? | archiver | 2001 | 0 | 24-06-2002 02:44 |
| results from regionals | archiver | 2000 | 0 | 23-06-2002 22:31 |