|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools |
Rating:
|
Display Modes |
|
#16
|
||||
|
||||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
Code:
UINT32 timeCurr = GetFPGATime(); // in usec float period = (float)(timeCurr - m_timestamp)/1000000.0; m_timestamp = timeCurr; |
|
#17
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
dt = 1/Update_rate; We use iterative class SetPeriod(dt); Then we measure cumulative time rather than loop period: We put this in the loop : time = time + dt : and simply compare time print out with a stop watch. Since we were looking for a factor of 2 this was accurate enough. We easily checked within a few %. Last edited by vamfun : 06-04-2010 at 17:20. |
|
#18
|
||||
|
||||
|
Re: Unexpected results from Encoder::GetRate()
I am sorry. I am probably not helping with your particular problem. I am merely trying to point out that in the iterative robot class, don't count on the period being accurate and use it as dt for differentiation or integration. You said your Update_Rate is 100 Hz. That makes the period 10 ms. If you put "time = time + 1/Update_Rate" in your loop, your time is really summing a constant 10 ms on every loop period, not real time. If you do this instead:
Code:
class MyRobot: public IterativeRobot
{
private:
UINT32 m_timestamp;
....
public:
void AutonomousInit()
{
m_timestamp = GetFPGATime();
....
}
void AutonomousPeriodic()
{
UINT32 timeCurr = GetFPGATime(); // in usec
float period = (float)(timeCurr - m_timestamp)/1000000.0;
m_timestamp = timeCurr;
printf("loop period is %f\n", period);
...
}
};
Last edited by mikets : 06-04-2010 at 17:52. |
|
#19
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
Quote:
![]() Edit: Actually this is a design issue rather than good practice. Either you design it as a periodic loop or not. Often programmers don't understand the hardware fully and run into these types of problems and wind up adding the type of compensation programming that you are suggesting. In fact, IMHO, when things are time critical, the periodic loop is often preferred since it is more predictable than non periodic solutions. Last edited by vamfun : 07-04-2010 at 00:13. |
|
#20
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Ok, back to Encoder Problem:
I got hold of a CRIO finally and ran some encoder outputs while we bench drove the robot. I set the iterative loop rate to 10 hz and printed to the console : printf( ..... ", GetDistance(), GetRate(), Derived rate) where derived rate was the avg rate over the 100ms period. Ran full forward, full reverse, partial forward, partial reverse cases for 1x,2x,4x. Data can be downloaded from http://www.scribd.com/doc/29635300/5...er-4-7-09-Test I recommend downloading and viewing the plots since they are cutoff on scrid site. For some reason the encoder counts were about 1/5.7 of what they should have been... ie the avg derived rate was 1.2 fps rather than 6.8 fps. So the encoder might be broken but it did register linear GetDistance(). Aside from this, the GetRate() was consistent for 1x,2x,4x and showed plots with basically two interwoven levels. One close to the derived rate of 1.2 fps and the other around 12 fps when running max speed. So there is definitely something odd for all modes. So, today, I tried some more direct debug of encoder.cpp. I disconnected the encoder inputs and replaced them with a periodic pulse on the A channel and open (pull up value) on the B channel. We figured we could manually cause the counters to increment by alternating between open and ground on the A input. Well, something really weird happened. The 0 input caused a 1 count and the 1 input caused the count to decrement to 0 count again. Huh?? So the GetRaw() just alternated between 1 and 0 rather than accumulate. So must be some good explaination... right? Maybe more on Monday. Last edited by vamfun : 09-04-2010 at 01:01. |
|
#21
|
||||||
|
||||||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
|
|
#22
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Joe, I would expect that for 2x and 4x but not 1x, since with 1x only A channel leading edge determines the count and the B channel is always the same value on the leading edge. Unless I'm missing something.
Last edited by vamfun : 09-04-2010 at 03:23. |
|
#23
|
|||||
|
|||||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
For a few reasons, a 1x decoder that requires a transition on both phases prior to incrementing the count is advantageous (namely, it can discriminate between the constantly changing direction vs. constant direction case). |
|
#24
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
Here, the upSource is A chan and the downSource is B chan. This is called by encoder.cpp. Counter::Counter(EncodingType encodingType, DigitalSource *upSource, DigitalSource *downSource, bool inverted) { wpi_assert(encodingType == k1X || encodingType == k2X); InitCounter(kExternalDirection); SetUpSource(upSource); SetDownSource(downSource); if (encodingType == k1X) SetUpSourceEdge(true, false); // THis is clear to me else SetUpSourceEdge(true, true); // This is clear to me SetDownSourceEdge(inverted, true); // This needs explanation } As I understand it, the tcounters have independent sources than can be set to count up or down. How does setting the B chan to always count down on a TED and down on TEU if inverted=true set up the counter to give the proper direction? |
|
#25
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
Here's the data I got for a bump test I did about a week ago. The setup is really weird because we were rushing to get it before we had to leave for a week (spring break). There are two different encoders on the left and right drive trains (I don't remember which is which at the moment). We set the robot on its butt and set the jags to output 0.6, waited for 2 seconds, and then set them back to 0. The code is set to 2x decoding and a 0.005 period (200 HZ) between every sample. https://docs.google.com/leaf?id=0B3I...NTFjM2Iz&hl=en Again, I don't know exactly what value should be returned, but obviously there is a difference in what our GetRate()s are returning. I should have access to the bot tomorrow, so I'll try adding a plot of the derived rate. |
|
#26
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
Only thing clear is a factor of 2 difference in your data so far. What are the units? How did you acquire data? Can you also print GetDistance or GetRaw? Was SetDistancePerPulse checked for each encoder? Can you run a 1x case if you have time? Last edited by vamfun : 10-04-2010 at 03:20. |
|
#27
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
Quote:
I will do this today if I can get into the school. |
|
#28
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Ok, I finally have good data. First, I edited Encoder.cpp, here's the diff.
Code:
Index: Encoder.cpp
===================================================================
--- Encoder.cpp (revision 2130)
+++ Encoder.cpp (working copy)
@@ -258,7 +258,7 @@
{
if (m_counter)
{
- return m_counter->GetPeriod() * DecodingScaleFactor();
+ return m_counter->GetPeriod() / DecodingScaleFactor();
}
else
{
@@ -275,7 +275,7 @@
value = (double)output.Period / (double)output.Count;
}
wpi_assertCleanStatus(status);
- return value * 1.0e-6 / (DecodingScaleFactor() * 4.0);
+ return value * 1.0e-6 / DecodingScaleFactor();
}
}
@@ -380,7 +380,7 @@
*/
double Encoder::GetRate()
{
- return m_distancePerPulse / GetPeriod() * (GetDirection() ? 1.0 : -1.0);
+ return (m_distancePerPulse / GetPeriod() * (GetDirection() ? 1.0 : -1.0)) / 2;
}
/**
https://spreadsheets.google.com/ccc?...0JZe UE&hl=en Looks perfect to me ![]() |
|
#29
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
1) Confirmed that the 1x is off by factor of 2. 2) Confirmed that 2x is off by same factor of 2 if corrected for inverted Decoding scale factor error. 2x rate exhibits more noise as expected. 3) We have not explained why the counter GetPeriod() is off by 2. 4)TBD for 4x. If the problem is in the counter GetPeriod() we might expect that the factor of 2 used in GetRate() will not be correct for 4x since it uses the FPGA. So this needs confirmation. The next step is to find out where the counter period problem is. This is where the factor of 2 should be fixed rather than in the GetRate() function. In the counter.cpp period = (double)output.Period / (double)output.Count; So either output.Period is wrong or output.Count is defaulting to 2 instead of 1. I suspect the latter and will try to check this today. Also still waiting for Joe or other expert to explain how B channel works to set count direction in WPI libs . post http://www.chiefdelphi.com/forums/sh...3&postcount=24 Edit: Looking at the counter constructor for the quad encoder...seems that if InitCounter(kExternalDirection); is present then SetDownSourceEdge(inverted, true); has a special meaning. It sets direction externally with chan B rather than actually change the down count with chan B edges as the name implies. If this is the case, I really have the urge to yell at an overworked WPI programmer for this style of coding. Mike: can you post a snippit of your notifier code and tell us how the printf data was sent to the console? We might try that tomorrow. Last edited by vamfun : 12-04-2010 at 13:10. |
|
#30
|
|||
|
|||
|
Re: Unexpected results from Encoder::GetRate()
Quote:
|
![]() |
| 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 |