They have a ton of spirit but they are somewhat humble in their application of it. - firstfollower [more]
 Chief Delphi Unexpected results from Encoder::GetRate()
 portal register members calendar search Today's Posts Mark Forums Read FAQ rules

#16
04-06-2010, 06:07 AM
 mikets Software Engineer FRC #0492 (Titan Robotics Club) Team Role: Mentor Join Date: Jan 2010 Rookie Year: 2008 Location: Bellevue, WA Posts: 799
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by vamfun 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.
But what is Update_Rate? If it's derived from the period of some periodic loop, you need to verify the real interval of the periodic loop. How did you compute real time? I use the following code to measure my periodic intervals:
Code:
```UINT32 timeCurr = GetFPGATime(); // in usec
float period = (float)(timeCurr - m_timestamp)/1000000.0;
m_timestamp = timeCurr;```
__________________
#17
04-06-2010, 04:17 PM
 vamfun 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
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by mikets But what is Update_Rate? If it's derived from the period of some periodic loop, you need to verify the real interval of the periodic loop. How did you compute real time?
Update_Rate is a define... say 100. hz.
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 : 04-06-2010 at 05:20 PM.
#18
04-06-2010, 05:31 PM
 mikets Software Engineer FRC #0492 (Titan Robotics Club) Team Role: Mentor Join Date: Jan 2010 Rookie Year: 2008 Location: Bellevue, WA Posts: 799
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);
...
}
};```
"period" will be the accurate loop interval that can be used as dt in your differentiation or integration. In theory period should print out 0.01s (10 ms), but in our case, it is way off. It could be because our loop execution took longer than the 10ms to execute that may cause a period to be skipped in some cases. Therefore, as a good practice, never use the period you set in any time critical calculations.
__________________

Last edited by mikets : 04-06-2010 at 05:52 PM.
#19
04-06-2010, 06:40 PM
 vamfun 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
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by mikets In theory period should print out 0.01s (10 ms), but in our case, it is way off. It could be because our loop execution took longer than the 10ms to execute that may cause a period to be skipped in some cases.
I've done a lot of real time control systems and never had a problem with interrupt driven loops because we always verify that execution cannot exceed the loop period. So I suspect you have a problem delay in your loop and indeed if you are using a debug console printf(...) in a 10 ms loop then this can easily cause you a problem since it requires about 1ms per char and once you exceed the buffer, this becomes a realized delay.

Quote:
 Therefore, as a good practice, never use the period you set in any time critical calculations
... unless you have verified your computations can't exceed the loop time

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 : 04-07-2010 at 12:13 AM.
#20
04-09-2010, 12:53 AM
 vamfun 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
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.

http://www.scribd.com/doc/29635300/5...er-4-7-09-Test

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 : 04-09-2010 at 01:01 AM.
#21
04-09-2010, 01:02 AM
 Joe Ross Registered User FRC #0330 (Beachbots) Team Role: Engineer Join Date: Jun 2001 Rookie Year: 1997 Location: Los Angeles, CA Posts: 8,979
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by vamfun 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 cause a 1 count and the 1 input caused the count to decrement rather than accumulate. Huh?? So the GetRaw() just alternated between 1 and 0.
That would be expected for quadrature decoding. With the B channel stuck at a value, it looks like it's constantly changing directions.
#22
04-09-2010, 01:26 AM
 vamfun 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
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by Joe Ross That would be expected for quadrature decoding. With the B channel stuck at a value, it looks like it's constantly changing directions.
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 : 04-09-2010 at 03:23 AM.
#23
04-09-2010, 07:52 AM
 Jared Russell 4933T15 FRC #0254 (The Cheesy Poofs), FRC #0341 (Miss Daisy) Team Role: Engineer Join Date: Nov 2002 Rookie Year: 2001 Location: San Francisco, CA Posts: 3,561
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by vamfun 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.
There are many ways that one could implement a 1x quadrature decoder.

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
04-09-2010, 05:12 PM
 vamfun 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
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by Jared341 There are many ways that one could implement a 1x quadrature decoder. 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).
Ok, lets get specific. When we write our own interrupt encoder routines, the B channel is just looked at when a TEU pulse occurs on the A chan to get the direction. However, the tcounters in CRIO are a bit of a mystery to me still and I need some more tutoring.

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
04-10-2010, 01:56 AM
 Bigcheese C++0x FTW! AKA: Michael Spencer FRC #1771 Team Role: Mentor Join Date: Feb 2008 Rookie Year: 2008 Location: GA Posts: 36
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by vamfun 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.
That's definitely not what I get. How do you get a negative value when going full forward?

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.

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
04-10-2010, 03:16 AM
 vamfun 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
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by Bigcheese That's definitely not what I get. How do you get a negative value when going full forward? Here's the data I got for a bump test I did about a week ago. 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.
Well, this data looks better... I suspect we had a bad encoder or maybe hardware problem.

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 : 04-10-2010 at 03:20 AM.
#27
04-10-2010, 11:07 AM
 Bigcheese C++0x FTW! AKA: Michael Spencer FRC #1771 Team Role: Mentor Join Date: Feb 2008 Rookie Year: 2008 Location: GA Posts: 36
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by vamfun Only thing clear is a factor of 2 difference in your data so far.
The factor of two difference between the encoders is because one is about twice the pulses per rev as the other.

Quote:
 Originally Posted by vamfun 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?
• The units are in feet per second.
• Using a notifier that printed GetFPGATime(),GetJagOutput(),GetLeftRate(),GetRigh tRate() at 200Hz
• Hopefully today.
• The same value was used for both and was correct for one of them.
• I think I have one, but I'm not sure which it was (we were rushing to see the data, didn't mark any of it). The data was almost identical except for a little less noise. I'll run it again though.

I will do this today if I can get into the school.
#28
04-11-2010, 09:16 PM
 Bigcheese C++0x FTW! AKA: Michael Spencer FRC #1771 Team Role: Mentor Join Date: Feb 2008 Rookie Year: 2008 Location: GA Posts: 36
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;
}

/**```
The following data is in 1x and 2x mode. I didn't do a 4x test.

Looks perfect to me
#29
04-12-2010, 04:15 AM
 vamfun 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
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by Bigcheese The following data is in 1x and 2x mode. I didn't do a 4x test. https://spreadsheets.google.com/ccc?...0JZe UE&hl=en Looks perfect to me
Thanks for running a nice data set. So this is what I get from it:
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 : 04-12-2010 at 01:10 PM.
#30
04-12-2010, 09:14 PM
 vamfun 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
Re: Unexpected results from Encoder::GetRate()

Quote:
 Originally Posted by vamfun Thanks for running a nice data set. So this is what 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.
Todays runs showed that output.Count = 1 as it should.... so output.Period is the remaining suspect.

 Thread Tools Display Modes Rate This Thread Linear Mode Rate This Thread: 5 : Excellent 4 : Good 3 : Average 2 : Bad 1 : Terrible

 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 User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home Announcements     User Announcements FIRST     General Forum     Rumor Mill     Career     Robot Showcase Technical     Technical Discussion     Robotics Education and Curriculum     Motors     Electrical         CAN     Programming         NI LabVIEW         C/C++         Java         Python     Sensors     Control System     Pneumatics     Kit & Additional Hardware     CAD         Inventor         SolidWorks         Creo     IT / Communications         3D Animation and Competition         Website Design/Showcase         Videography and Photography         Computer Graphics Competition     Awards         Chairman's Award     Rules/Strategy         Scouting     Team Organization         Fundraising         Starting New Teams         Finding A Team         College Teams     Championship Event     Regional Competitions     District Events     Off-Season Events     Thanks and/or Congrats     FRC Game Design     OCCRA         OCCRA Q&A Other     Chit-Chat         Games/Trivia         Fantasy FIRST     Car Nack's Corner     College & University Education     Dean Kamen's Inventions     FIRST-related Organizations         The Blue Alliance     FIRST In the News...     FIRST Lego League     FIRST Tech Challenge     VEX     Televised Robotics     Math and Science     Robot in 3 Days (RI3D)     NASA Discussion ChiefDelphi.com Website     CD Forum Support     Extra Discussion

 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 NI LabVIEW 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 06:34 AM.

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

 -- English (12 hour) -- English (24 hour) Contact Us - Chief Delphi - Rules - Archive - Top