Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 23

Thread: WPILIB Encoder SetMinRate() problem

  1. #11
    Join Date
    Sep 2008
    Location
    National Instruments: Austin, TX
    Posts
    443

    Default Re: WPILIB Encoder SetMinRate() problem

    Quote Originally Posted by vamfun View Post
    Ok, great to see your changes. Can you explain what this statement is doing from the Counter::GetPeriod()

    period = (double)output.Period / (double)output.Count

    I see that you set the period to infinity if stalled, but what about a call that is made to the getPeriod() before it has stalled and we have no recorded pulses yet. As an example.. suppose the maxperiod is set to 20 seconds, the encoder is physically stalled but timer has yet to stall. What will the getPeriod return at 10 seconds? It would seem that we should initialize the "is stalled" flag to a stalled condition if this isn't already the case.
    There is averaging built in to the event timer. The output from the hardware is the number of samples that were summed and the sum of the samples. The division completes the average operation. The initial condition of the stalled flag is true for every event timer.

    In your example, the output would be the stalled already since you have not gotten any pulses. If you had gotten pulses in the past, the value would remain the last good value you timed up until the 20 seconds.

    Quote Originally Posted by vamfun View Post
    txs... by the way, when does the tdowney site get updated usually after an update?
    Please enlighten me. What is a tdowney site?

  2. #12
    Join Date
    Dec 2008
    Posts
    19

    Default Re: WPILIB Encoder SetMinRate() problem

    Quote Originally Posted by Joe Hershberger View Post
    There is averaging built in to the event timer. The output from the hardware is the number of samples that were summed and the sum of the samples. The division completes the average operation.
    Sorry Joe, I still don't see where the averaging samples are coming from. If the output.period is actually the time between the last two valid encoder edge pulses sent to the timer then it seems that it should be reset after each pulse and the count would always be 1. .

    If indeed there are multiple "periods" averaged then, where are these extra events coming from? Could it be that you are returning the average period between GetPeriod() or GetRate() calls?? If so, we need to talk

    Is there some documentation on the counter.output methods that could would help us newbies to Crio. I know the LABVIEW routines are fairly clear but don't see much for the C++ code beyond the WPILIB documents.

    Please enlighten me. What is a tdowney site?
    This is a site maintained by John Downey. http://www.chiefdelphi.com/forums/member.php?u=15970 The programmers just use this site as an unofficial quick reference. Guess we have to wait for him to update his site.

    http://jtdowney.com/wpilib/annotated.html
    Last edited by vamfun; 02-28-2009 at 09:34 PM. Reason: update jtdowney

  3. #13
    Join Date
    Sep 2008
    Location
    National Instruments: Austin, TX
    Posts
    443

    Default Re: WPILIB Encoder SetMinRate() problem

    Quote Originally Posted by vamfun View Post
    Sorry Joe, I still don't see where the averaging samples are coming from. If the output.period is actually the time between the last two valid encoder edge pulses sent to the timer then it seems that it should be reset after each pulse and the count would always be 1.
    That is indeed the behavior you get if you configure the number of samples to average to 1.

    Quote Originally Posted by vamfun View Post
    If indeed there are multiple "periods" averaged then, where are these extra events coming from? Could it be that you are returning the average period between GetPeriod() or GetRate() calls?? If so, we need to talk
    No... the values returned have nothing to do with calls to GetPeriod or GetRate. When you configure the averaging to 4 for instance, there is a sliding window buffer of the last 4 consecutive valid samples on that channel. When you read, the output.Period contains the sum of the samples in that buffer. If there have only been 2 consecutive valid samples, then the output will be the sum of those 2 and the count will == 2.

    Consecutive valid samples are defined as samples in the same direction with no stall conditions.

    Quote Originally Posted by vamfun View Post
    Is there some documentation on the counter.output methods that could would help us newbies to Crio. I know the LABVIEW routines are fairly clear but don't see much for the C++ code beyond the WPILIB documents.
    The API level is documented. The register level is not especially well documented. If you have questions, please just ask here and I will answer them for you.

  4. #14
    Join Date
    Dec 2008
    Posts
    19

    Default Re: WPILIB Encoder SetMinRate() problem

    Quote Originally Posted by Joe Hershberger View Post
    When you configure the averaging to 4 for instance, there is a sliding window buffer of the last 4 consecutive valid samples on that channel. When you read, the output.Period contains the sum of the samples in that buffer. If there have only been 2 consecutive valid samples, then the output will be the sum of those 2 and the count will == 2.

    Consecutive valid samples are defined as samples in the same direction with no stall conditions.
    Ok, Joe, I think I'm with you now. You've got a moving average going on which is a real nice feature to have. I knew that the counter/timer had this capability and was eventually going to try programming this into our encoder filters. Glad to see its already there!!! So....

    What is the default pulse averaging count?

    How do we as users modify this to optimize it for our use when setting up the encoder constructor?

    I have a IIR exponential filter implemented currently, but I would rather have a moving average. I suggest we update the Encoder documentation to clarify that this filtering is going on (hidden to most of us) and hopefully get us a SetPulseAveragingCount() method in the encoder class.
    Last edited by vamfun; 03-02-2009 at 02:13 AM.

  5. #15
    Join Date
    Sep 2008
    Posts
    561

    Default Re: WPILIB Encoder SetMinRate() problem

    Quote Originally Posted by vamfun View Post
    This is a site maintained by John Downey. http://www.chiefdelphi.com/forums/member.php?u=15970 The programmers just use this site as an unofficial quick reference. Guess we have to wait for him to update his site.

    http://jtdowney.com/wpilib/annotated.html
    Most of that information is located in C++Reference.pdf or C++Reference.chm installed in C:\WindRiver\docs\extensions\FRC and that is updated with every release.

    If you like the html, you could do it yourself by downloading doxygen (which is a really cool tool)
    Team 330 beta tester

  6. #16
    Join Date
    Sep 2008
    Location
    National Instruments: Austin, TX
    Posts
    443

    Default Re: WPILIB Encoder SetMinRate() problem

    Quote Originally Posted by vamfun View Post
    What is the default pulse averaging count?
    1

    Quote Originally Posted by vamfun View Post
    How do we as users modify this to optimize it for our use when setting up the encoder constructor?
    Edit WPILib to support calling writeTimerConfig_AverageSize on the tCounter or tEncoder object. The minimum value is 1 and the maximum is 127.

    Quote Originally Posted by vamfun View Post
    I have a IIR exponential filter implemented currently, but I would rather have a moving average. I suggest we update the Encoder documentation to clarify that this filtering is going on (hidden to most of us) and hopefully get us a SetPulseAveragingCount() method in the encoder class.
    The filtering is disabled by default (since it is 1).

  7. #17
    Join Date
    Dec 2008
    Posts
    19

    Default Re: WPILIB Encoder SetMinRate() problem

    Thanks Joe. Lets conclude this thread and continue further discussions on a new thread called "Encoder period/rate moving average"

    http://forums.usfirst.org/showthread...7995#post27995

  8. #18
    Join Date
    Dec 2008
    Posts
    19

    Default Re: WPILIB Encoder SetMinRate() problem

    Joe,
    Sad to say, we have some hiccups in the Encoder data when we tested the SetMinRate. We hooked one encoder up and made two x1 instances of it...A) with SetMinRate(1) as a reference and B) with SetMinRate(10) as a test case. We expected to see no rates on B when A was below 10 and when A was greater than 10 we expected to see output on B too.

    The data showed intermittent failures in both cases. I have enclosed an excel spread sheet showing the data we took. I have no clue why this occuring...so I defer to you for possible suggestions or wonder if you can duplicate the test.
    Attached Files Attached Files
    Last edited by vamfun; 03-05-2009 at 10:43 PM.

  9. #19
    Join Date
    Sep 2008
    Location
    National Instruments: Austin, TX
    Posts
    443

    Default Re: WPILIB Encoder SetMinRate() problem

    I need to know a couple things about your experiment to try to reproduce it. What decoding mode are you using? Do you have any averaging enabled? What is your DistancePerCount scaling configured to? Perhaps you can post a code snippet that shows your configuration.

  10. #20
    Join Date
    Dec 2008
    Posts
    19

    Default Re: WPILIB Encoder SetMinRate() problem

    Quote Originally Posted by Joe Hershberger View Post
    I need to know a couple things about your experiment to try to reproduce it. What decoding mode are you using? Do you have any averaging enabled? What is your DistancePerCount scaling configured to? Perhaps you can post a code snippet that shows your configuration.
    We used a vex motor to drive a kit encoder. Sample code looks like this
    class OurRobot : public SimpleRobot
    {
    RobodoxEncoder *A;
    RocodoxEncoder *B;
    etc.
    }


    Constructor:

    A = new RobodoxEncoder(4,1,4,2, false, Encoder::k1X);
    B = new RobodoxEncoder(4,1,4,2, false, Encoder::k1X);
    A->SetDistancePerPulse((6.0*PI)/250);
    B->SetDistancePerPulse((6.0*PI)/250);
    A->SetReverseDirection(true);
    A->SetMinRate (1.);//sets minimum rate to 1 in/sec
    B->SetMinRate (10.);//sets minimum rate to 10 in/sec
    // we had these reference wheels programmed but no encoders installed
    rightRef = new RobodoxEncoder (4,5,4,6, false, Encoder::k1X);
    leftRef = new RobodoxEncoder (4,7,4,8, false, Encoder::k1X);
    leftRef->SetDistancePerPulse((3.0*PI)/250);
    rightRef->SetDistancePerPulse((3.0*PI)/250);
    rightRef->SetMinRate(1.);
    leftRef->SetMinRate(1.);
    // no moving average pulses set.. used default one pulse

    .....
    Simple robot
    void OurRobot::OperatorControl(void) {

    while ( IsOperatorControl() )
    {
    GetWatchdog().Feed();
    FilterEncoderSpeeds(); // this just reads encoders and provides a low pass filter..no data from this was used in test. We have seen the minrate problem without this operational.
    printf("%f\t %f\t %f\t\n", (float)time->Get(),(float)A->GetRate(), (float)B->GetRate();//source of excel data
    DriveCode();
    LiftCode();
    RollerCode();
    }
    } // end operator control

    void FilterEncoderSpeeds(){
    float v_l_raw;
    float v_r_raw;
    float v_lref_raw;
    float v_rref_raw;
    static const float weight = 1.;// Weight values must range between [0 , 1];

    //read the wheel speeds
    v_l_raw=A->GetRate();
    v_r_raw=B->GetRate();
    v_lref_raw=leftRef->GetRate();
    v_rref_raw=rightRef->GetRate();
    //check for stall condition just in case old encoder cpp is running. If stalled, this output was + or - inf. So set to zero if > 10*max rate.
    if(fabs(v_l_raw>120.))v_l_raw=0.;
    if(fabs(v_r_raw>120.))v_r_raw=0.;
    if(fabs(v_lref_raw>120.))v_lref_raw=0.;
    if(fabs(v_rref_raw>120.))v_rref_raw=0.;
    //now filter with weighted average between existing global value and new encoder read value
    v_l = v_l + weight*(v_l_raw - v_l);
    v_r = v_r + weight*(v_r_raw - v_r);
    v_lref = v_lref + weight*(v_lref_raw - v_lref);
    v_rref = v_rref + weight*(v_rref_raw - v_rref);
    }

    The RobodoxEncoder is the same as given in this post: http://forums.usfirst.org/showpost.p...43&postcount=5 . We have had similar results with the unmodified WPILIB Encoder class. We did not call the SetMovingAveragePulseCount() function.

    Not sure why, but the printf statement was using 60ms per pass. Seemed a little high to me. It ran the first seven passes with less than 1ms per pass and then jumped to 60ms per pass for the rest. Is this a buffer filling up and causing extra delays?
    Last edited by vamfun; 03-06-2009 at 04:50 PM.

Page 2 of 3 FirstFirst 123 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •