Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Best way to measure period between pulses? Counters and FPGA (http://www.chiefdelphi.com/forums/showthread.php?t=112193)

Mr. Lim 27-01-2013 17:42

Best way to measure period between pulses? Counters and FPGA
 
We have a digital optical sensor, and we want to measure the time between between pulses. Once we get the time, we would then calculate the rotational speed of a wheel.

I thought the Counter class did this for us using the FPGA?

Using the GearTooth class (which extends Counter), for some reason we're getting very poor resolution from getPeriod().

GearTooth geartooth = new GearTooth(1);
rpm = ??? / geartooth.getPeriod();

Our RPM steps up and down in increments of 375 RPM!

You might ask how many pulses per revolution we have, but should that even matter? I was under the impression that the resolution should be dependent on the precision of the timing device?

Ironically, we did the math, and the resolution of 375 RPM is what we would get if we polled the Counter every 20ms, and calculated the period by dividing 20ms by the number of pulses received.

What am I missing here? Do I need to explicitly set up the Counter to use the FPGA / Timers / etc? Or is this all a ruse, and the Counter doesn't measure time between pulses at all, but polls every 20ms instead?

Has anyone successfully calculated a wheel speed by measuring time between pulses using the FPGA via the Counter/GearTooth class?

Mr. Lim 27-01-2013 18:05

Re: Best way to measure period between pulses? Counters and FPGA
 
I need to clarify this post...

I am having problems with how the period is being calculated.

There is a BIG difference between these two approaches:

1) Polling the counter every 20ms and counting how many pulses occurred. Period = 20ms / pulses

2) ACTUALLY measuring the time between two pulses using the FPGA. Period = the measured time

Approach 2 results in a much higher resolution in our application, and the documentation in WPILib is unclear when 1 or 2 is used with Counter/GearTooth objects.

From looking at source more, I'm lead to believe approach 2 ONLY happens if you've specifically setup a 4x Encoder object and you can't do approach 2 at all with a Counter/GearTooth object.

Has anyone else seen otherwise?

Mr. Lim 27-01-2013 18:43

Re: Best way to measure period between pulses? Counters and FPGA
 
Well, to answer my own question...

It seems it is possible to directly measure time between transitions with a Counter object by using SemiPeriodMode.

Thanks to Joe Hershberger's post on the FIRST Forums here:
http://forums.usfirst.org/showpost.p...8&postcount=12

flargen507 27-01-2013 18:44

Re: Best way to measure period between pulses? Counters and FPGA
 
I am currently trying to do the same thing, using a light sensor to create a custom tachometer. As it has been explained to me (correct me if I am wrong) the crio FPGA has an integrater function built in, so even if pulses moving faster than 20ms can be measured. I calculated that on our shooter even with a 1 tick tachometer it will be sending a pulse every 1-2ms, which may be too fast for the AndyMark optical sensors, but I haven't checked too closely. However, it does seem like a good idea for certain high speed feedback.

jhersh 28-01-2013 01:13

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Mr. Lim (Post 1222923)
Well, to answer my own question...

It seems it is possible to directly measure time between transitions with a Counter object by using SemiPeriodMode.

Thanks to Joe Hershberger's post on the FIRST Forums here:
http://forums.usfirst.org/showpost.p...8&postcount=12

That's not quite an accurate interpretation of my post. You can measure the frequency in any of the counter / encoder modes. The point I was trying to make was that the semi-period mode is pretty much useful only for timing.

From reading your application description, you probably want to use Up/Down counter mode, and only specify the "up source". When you read the timer output, it will be reporting the speed based on "method 2" that you described above.

Cheers
-Joe

Thad House 28-01-2013 01:51

Re: Best way to measure period between pulses? Counters and FPGA
 
So for our shooter last year we used a counter with a light sensor. How we got the correct value is we took the period, then took the reciprocal. We then divided that number by how many pulses you get per rotation, and then multiply that by 60. That gives the RPM.

saikiranra 28-01-2013 03:05

Re: Best way to measure period between pulses? Counters and FPGA
 
Oooh, we were doing this today! Thank you for potentially solving any questions that we might have come up with!

Also, teams who have done this before, how accurate is finding the RPM using an optical sensor compared to using an encoder?

Alan Anderson 28-01-2013 08:36

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by saikiranra (Post 1223181)
Also, teams who have done this before, how accurate is finding the RPM using an optical sensor compared to using an encoder?

The typical quadrature encoders used on FRC robotis are optical sensors. The accuracy is going to be the same, assuming the sensor detects all the marks it's looking for. The precision will be a function of the number of "ticks" per revolution and the consistency of the spacing of the light and dark marks. In general, more marks seen going by in a given time gives better precision.

Mr. Lim 28-01-2013 09:03

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by jhersh (Post 1223163)
That's not quite an accurate interpretation of my post. You can measure the frequency in any of the counter / encoder modes. The point I was trying to make was that the semi-period mode is pretty much useful only for timing.

From reading your application description, you probably want to use Up/Down counter mode, and only specify the "up source". When you read the timer output, it will be reporting the speed based on "method 2" that you described above.

Cheers
-Joe

This is odd, because all weekend we were have major resolution problems.

We had a Counter set up exactly as you describe above. The periods we were getting had a very pronounced stepwise response. As a result, our RPM readings changed in increments of about 375 RPM.

We did the math, and these increments corresponded with 1 count / 20ms, which led us to believe the reads were still being done via method 1.

Very strange.

Is it possible that the other modes (other than semi-period) use the FPGA to count pulses over a 20ms period instead of measuring the time between pulses directly?

saikiranra 28-01-2013 09:43

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Alan Anderson (Post 1223212)
The typical quadrature encoders used on FRC robotis are optical sensors.

So in theory, is it possible to use the WPI Encoder Libraries with an optical sensor and a piece of reflective tape?

Mr. Lim 28-01-2013 09:52

Re: Best way to measure period between pulses? Counters and FPGA
 
Code:

public double getPeriod() {
        double period;
        if (m_counter.readTimerOutput_Stalled()) {
            return Double.POSITIVE_INFINITY;
        } else {
            period = (double) m_counter.readTimerOutput_Period() / (double) m_counter.readTimerOutput_Count();
        }
        return period / 1.0e6;
    }

Something isn't jiving here. In the above code, why would you take the period and divide by the count? If the FPGA is measuring the period directly, should we just be taking the period directly? Will count ever be anything other than 1?

Alan Anderson 28-01-2013 11:36

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by saikiranra (Post 1223229)
So in theory, is it possible to use the WPI Encoder Libraries with an optical sensor and a piece of reflective tape?

The FPGA encoder support requires a pair of sensors in order to give a quadrature signal. In one direction of motion, A goes high, then B goes high, then A goes low, then B goes low. In the other direction, B goes high, then A goes high, then B goes low, then A goes low. If you can arrange your sensors and marks so that's what you get, the WPI library encoder functions should work.

But the counter functions should work just fine with a single sensor.

Joe Ross 28-01-2013 12:02

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Mr. Lim (Post 1223234)
Something isn't jiving here. In the above code, why would you take the period and divide by the count? If the FPGA is measuring the period directly, should we just be taking the period directly? Will count ever be anything other than 1?

The FPGA doesn't return floating point values, so the period isn't in units you can use directly. Presumably, the Period is actually the period in clock cycles, and the count is the number of clock cycles per second. Dividing those two gives you a period in seconds.

Thad House 28-01-2013 12:54

Re: Best way to measure period between pulses? Counters and FPGA
 
I dont know about in Java or C++, but in labview the library already converts it into period per pulse in seconds. So if you do 1/x on that, you get pulses per period. Then you have pulses per second, and that is easy to convert to rotations per minute with just unit conversions. We used geartooth mode for this purpose and it worked perfectly.

Ken Streeter 28-01-2013 16:15

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Mr. Lim (Post 1223219)
This is odd, because all weekend we were hav[ing] major resolution problems.

We had a Counter set up exactly as you describe above. The periods we were getting had a very pronounced stepwise response. As a result, our RPM readings changed in increments of about 375 RPM.

As described in another post, hidden in the LabVIEW programming forum (even though we were doing this in Java), Team 1519 had success last year using the Encoder object at 1X sampling to count pulses from a USDigital E7P encoder with a 250CPR optical wheel spinning at around 4000RPM. However, we performed our RPM computation in a different manner than using the built-in functions. We found our approach to give excellent accuracy. This same strategy should work just fine for a Counter object.

First off, we set up a separate task in Java to periodically compute the RPM of our shooter wheels. (This task also will control the motor for the wheels, too.) Below is a code excerpt showing how to set this up:

Code:

    private Encoder wheelEncoder = new Encoder(RobotMap.SHOOTER_WHEEL_ENCODER_A, RobotMap.SHOOTER_WHEEL_ENCODER_B, false, CounterBase.EncodingType.k1X);
    private static final long WHEEL_SPEED_PERIOD = 20; // milliseconds

    timer = new java.util.Timer();
    timer.scheduleAtFixedRate(new ShooterWheelTask(), 10000, WHEEL_SPEED_PERIOD);

Below is the definition for the ShooterWheelTask, of which the "run" method will be executed every 20 milliseconds. This code computed the wheel RPM by dividing the number of counts observed since the last invocation by the elapsed time since the last invocation, with appropriate unit conversions. Time was measured using the FPGATimestamp, which has a resolution of approximately 6.5usec 1usec. (Edit: updated resolution per jhersh posting, below.) We then compared the measured RPM against the desired RPM, and used a "Bang - Bang" controller to set the wheel speed. This simplistic approach worked incredibly well. We plan to use it again this year.

We can't take the credit for the "Bang - Bang" controller application -- lengthy CD discussions on this last year led to Ether's white paper on the subject.

Below is a snippet of our "ShooterWheelTask" code. Various declarations of variables are not in this code snippet, but I think you'll be able to figure out what they are from the context.

PS: See you at GSR, Mr. Lim!

Code:

    private class ShooterWheelTask extends java.util.TimerTask {
        public void run() {
            double power;
           
            double now = Timer.getFPGATimestamp();
            int count = wheelEncoder.get();

            wheelEncoder.reset();
            // NOTE:  60 seconds per minute;  250 counts per rotation
            actualWheelSpeed = (60.0 / 250.0) * count / (now - prevWheelTime);
            prevWheelTime = now;
           
            if (actualWheelSpeed >= wheelSpeed) {
                power = 0;
            } else {
                power = 1;
            }
           
            if (automatic) {
                setWheelJag(power);
            }
            else {
                setWheelJag(0);
            }
        }
    }


jhersh 28-01-2013 17:25

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Ken Streeter (Post 1223437)
Below is the definition for the ShooterWheelTask, of which the "run" method will be executed every 20 milliseconds. This code computed the wheel RPM by dividing the number of counts observed since the last invocation by the elapsed time since the last invocation, with appropriate unit conversions.

This is "method 1" above. This is what he claims not to want.

Quote:

Originally Posted by Ken Streeter (Post 1223437)
Time was measured using the FPGATimestamp, which has a resolution of approximately 6.5usec.

This is inaccurate. The FPGATimestamp itself has a resolution of 1 us. The digital I/O that it timestamps (in the case of digital interrupts or encoder pulse measurements, etc.) is 6.525 us.

Cheers,
-Joe

jhersh 28-01-2013 17:50

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Mr. Lim (Post 1223234)
Code:

public double getPeriod() {
        double period;
        if (m_counter.readTimerOutput_Stalled()) {
            return Double.POSITIVE_INFINITY;
        } else {
            period = (double) m_counter.readTimerOutput_Period() / (double) m_counter.readTimerOutput_Count();
        }
        return period / 1.0e6;
    }

Something isn't jiving here. In the above code, why would you take the period and divide by the count? If the FPGA is measuring the period directly, should we just be taking the period directly? Will count ever be anything other than 1?

The variables are not terribly verbose... the "count" is the number of samples in the sliding window average. Count will always be 1 if you specify not to average (NumberOfSamplesToAverage = 1).

The FPGA does not like to divide without using up a bunch of gates, where and the RT CPU with an FPU has no problem doing this. This is an optimization where all the addition and synchronization is done in hardware where it needs to be done, but the divide operation to get the actual average period is pushed to the driver.

If you want "Method 1", you have to do it the way Ken Streeter described. If you want "Method 2", you must use the FPGA.

Cheers,
-Joe

Ken Streeter 28-01-2013 17:53

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by jhersh (Post 1223475)
This is inaccurate. The FPGATimestamp itself has a resolution of 1 us. The digital I/O that it timestamps (in the case of digital interrupts or encoder pulse measurements, etc.) is 6.525 us.

Thanks for the correction, Joe! I'll edit my post above to fix it!

jhersh 28-01-2013 17:58

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Mr. Lim (Post 1223219)
We had a Counter set up exactly as you describe above. The periods we were getting had a very pronounced stepwise response. As a result, our RPM readings changed in increments of about 375 RPM.

There is a finite resolution on the timing of the pulses. That period is 6.525 us per edge. In your system, does that correspond to 375 RPM? You may want to turn on averaging to improve the resolution (but increase the latency).

Quote:

Originally Posted by Mr. Lim (Post 1223219)
We did the math, and these increments corresponded with 1 count / 20ms, which led us to believe the reads were still being done via method 1.

Sounds like a coincidence, maybe? Where are you getting 20ms as the refresh period? Just because that's the Driver Station's packet rate?

Quote:

Originally Posted by Mr. Lim (Post 1223219)
Is it possible that the other modes (other than semi-period) use the FPGA to count pulses over a 20ms period instead of measuring the time between pulses directly?

No. The FPGA only implements method 2.

jhersh 28-01-2013 18:02

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Joe Ross (Post 1223291)
The FPGA doesn't return floating point values, so the period isn't in units you can use directly. Presumably, the Period is actually the period in clock cycles, and the count is the number of clock cycles per second. Dividing those two gives you a period in seconds.

Close. The "period" is in microseconds. The "count" is the number of samples accumulated by the averaging engine. The code also divides by 1.0e6 before returning to give the required "seconds" unit.

Ken Streeter 28-01-2013 18:28

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by jhersh (Post 1223475)
This is "method 1" above. This is what he claims not to want.

I had missed that in the original post. However, now I understand why the original poster doesn't want to use "Method 1." Given the statement of seeing RPM values with a resolution of 375 RPM and a hypothesized 20ms sampling period, their system must be using a wheel that has only 8 counts per revolution. In order to get greater RPM measurement resolution while keeping their 8 CPR sensor, they would need to have a longer sampling interval (longer than 20ms).

Similarly, with a 250 CPR sensor such as 1519 used in 2012, our computed RPM values are discretized at units of 12RPM. Measuring wheel speed to the nearest multiple of 12RPM was fine for our wheel shooter last year. Measuring to the nearest 375RPM might be troublesome.

DrakusDarkus 28-01-2013 20:29

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Ken Streeter (Post 1223437)
As described in another post, hidden in the LabVIEW programming forum (even though we were doing this in Java), Team 1519 had success last year using the Encoder object at 1X sampling to count pulses from a USDigital E7P encoder with a 250CPR optical wheel spinning at around 4000RPM. However, we performed our RPM computation in a different manner than using the built-in functions. We found our approach to give excellent accuracy. This same strategy should work just fine for a Counter object.

First off, we set up a separate task in Java to periodically compute the RPM of our shooter wheels. (This task also will control the motor for the wheels, too.) Below is a code excerpt showing how to set this up:

Code:



    private Encoder wheelEncoder = new Encoder(RobotMap.SHOOTER_WHEEL_ENCODER_A, RobotMap.SHOOTER_WHEEL_ENCODER_B, false, CounterBase.EncodingType.k1X);
    private static final long WHEEL_SPEED_PERIOD = 20; // milliseconds

    timer = new java.util.Timer();
    timer.scheduleAtFixedRate(new ShooterWheelTask(), 10000, WHEEL_SPEED_PERIOD);

Below is the definition for the ShooterWheelTask, of which the "run" method will be executed every 20 milliseconds. This code computed the wheel RPM by dividing the number of counts observed since the last invocation by the elapsed time since the last invocation, with appropriate unit conversions. Time was measured using the FPGATimestamp, which has a resolution of approximately 6.5usec 1usec. (Edit: updated resolution per jhersh posting, below.) We then compared the measured RPM against the desired RPM, and used a "Bang - Bang" controller to set the wheel speed. This simplistic approach worked incredibly well. We plan to use it again this year.

We can't take the credit for the "Bang - Bang" controller application -- lengthy CD discussions on this last year led to Ether's white paper on the subject.

Below is a snippet of our "ShooterWheelTask" code. Various declarations of variables are not in this code snippet, but I think you'll be able to figure out what they are from the context.

PS: See you at GSR, Mr. Lim!

Code:

    private class ShooterWheelTask extends java.util.TimerTask {
        public void run() {
            double power;
           
            double now = Timer.getFPGATimestamp();
            int count = wheelEncoder.get();

            wheelEncoder.reset();
            // NOTE:  60 seconds per minute;  250 counts per rotation
            actualWheelSpeed = (60.0 / 250.0) * count / (now - prevWheelTime);
            prevWheelTime = now;
           
            if (actualWheelSpeed >= wheelSpeed) {
                power = 0;
            } else {
                power = 1;
            }
           
            if (automatic) {
                setWheelJag(power);
            }
            else {
                setWheelJag(0);
            }
        }
    }


Thanks, we will try utilizing this in some way because we are having similar problems

Ether 28-01-2013 20:52

Re: Best way to measure period between pulses? Counters and FPGA
 
1 Attachment(s)
Quote:

Originally Posted by jhersh (Post 1223492)
the "count" is the number of samples in the sliding window average.

Joe,

How is this implemented under the hood in FPGA? Is there a ring buffer in the FPGA which the FPGA populates with the 6.525us_resolution_timestamp for each rising edge it detects (assuming it's not in semi-period mode), and then when requested retrieves the elapsed time between the N+1 most recent samples in the ring (which the cRIO CPU then divides by N)?

Quote:

Count will always be 1 if you specify not to average (NumberOfSamplesToAverage = 1).
How large can "NumberOfSamplesToAverage" be? I searched the 2012 C++ and the 2013 Java WPILib code but couldn't find that search string.


EDIT:

@all:

I attached a small Excel app that computes the RPM jitter caused by the 6.525us timing resolution of the edge detections. There will be additional jitter due to manufacturing tolerances in the physical locations of the edges in the sensor, but I've not included those here.

Note how large the jitter is with a 360 PPR sensor at 5000 RPM with averaging set to 1. If you set the averaging to 120 (1/3 revolution) you can reduce the jitter dramatically, at the cost of some phase lag in the signal.

If you make a 1 PPR sensor with averaging set to 1 you'll be able to get an updated reading every 12ms at 5000 RPM with very low jitter.



jhersh 28-01-2013 22:41

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Ether (Post 1223581)
How is this implemented under the hood in FPGA? Is there a ring buffer in the FPGA which the FPGA populates with the 6.525us_resolution_timestamp for each rising edge it detects (assuming it's not in semi-period mode), and then when requested retrieves the elapsed time between the N+1 most recent samples in the ring (which the cRIO CPU then divides by N)?

There is a buffer that will hold up to 127 samples for each counter / encoder. It has write pointer that does form a ring buffer. The sum of the samples between the write pointer - average_size (usually) and write pointer are summed every 0.1 us * average_size (yeah I know... overkill) and made available to the driver (i.e. not on demand) along with the number of samples available. When a counter is reset, the write pointer is moved to mark all samples unwritten (so the "count" returned would be 0).

The I/O is 6.525 us from sample to sample. The timer used has a 1 us resolution. So the actual resolution is 6..7 us. However, the error is not cumulative across the average. Regardless of the number of samples averaged, the error is less than 7.525 us.

Quote:

Originally Posted by Ether (Post 1223581)
How large can "NumberOfSamplesToAverage" be? I searched the 2012 C++ and the 2013 Java WPILib code but couldn't find that search string.

The FPGA interface function is called writeTimerConfig_AverageSize(). Looks like we never exposed that to the WPILib API layer in C++ (and therefore Java). It's exposed in LabVIEW.

Cheers,
-Joe

apalrd 29-01-2013 00:52

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by jhersh (Post 1223657)
The FPGA interface function is called writeTimerConfig_AverageSize(). Looks like we never exposed that to the WPILib API layer in C++ (and therefore Java). It's exposed in LabVIEW.

And I was sitting in this discussion wondering how nobody knows that you can configure the hardware averaging. It's a register in the FPGA's counter/encoder timer config register, exposed by the Set Timer functions, and is very useful.

Our 2012 robot (with a 4-line handmade aluminum and gaffers tape disc) averaged 12 samples (three whole rotations) to get a perfect signal with ~2.5rpm minimum step. If I set the graph to autosize I could see the controller oscillate between exactly one step above or below the target speed, when steady state.

Ether 29-01-2013 01:10

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by apalrd (Post 1223723)
It's a register in the FPGA's counter/encoder timer config register, exposed by the Set Timer functions

What source code file would that be in? I cannot find it.

It's not in the 2012 C++ WPILib source rev3111 timer.cpp



jhersh 29-01-2013 01:13

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Ether (Post 1223727)
What source code file would that be in? I cannot find it.

It's not in the 2012 C++ WPILib source rev3111 timer.cpp



Encoder.cpp and Counter.cpp

Ether 29-01-2013 01:18

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by jhersh (Post 1223729)
Encoder.cpp and Counter.cpp

OK, so we're talking about modifying and re-compiling the WPILib source, not simply passing a parameter?



jhersh 29-01-2013 01:23

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Ether (Post 1223732)
OK, so we're talking about modifying and re-compiling the WPILib source, not simply passing a parameter?

Quote:

Originally Posted by jhersh (Post 1223657)
The FPGA interface function is called writeTimerConfig_AverageSize(). Looks like we never exposed that to the WPILib API layer in C++ (and therefore Java). It's exposed in LabVIEW.

That is what I was saying. It is not in the WPILib API layer in C++ and Java. That means if you care to use the hardware feature, you need to move down a layer.

Cheers,
-Joe

Ether 29-01-2013 01:42

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by jhersh (Post 1223733)
That is what I was saying. It is not in the WPILib API layer in C++ and Java. That means if you care to use the hardware feature, you need to move down a layer.

Got it.



Mr. Lim 29-01-2013 11:01

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by jhersh (Post 1223497)
There is a finite resolution on the timing of the pulses. That period is 6.525 us per edge. In your system, does that correspond to 375 RPM? You may want to turn on averaging to improve the resolution (but increase the latency).



Sounds like a coincidence, maybe? Where are you getting 20ms as the refresh period? Just because that's the Driver Station's packet rate?



No. The FPGA only implements method 2.

Thanks a TON Joe!

This post clarified pretty much everything we're seeing.

We WERE hitting the 6.525us timing resolution per edge. That corresponded (coincidentally) with the resolution of 375 RPM we were seeing, at our desired speed.

There'll be a more detailed post, or even a whitepaper once we've sorted everything out, but we've got a really neat solution together involving SetSemiPeriod(true), a mostly white disc with a single small black sector, and an averaging window that holds about 10ms worth of reads at our slowest speed.

Ether 29-01-2013 12:23

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Mr. Lim (Post 1223868)
we've got a really neat solution together involving SetSemiPeriod(true), a mostly white disc with a single small black sector, and an averaging window that holds about 10ms worth of reads at our slowest speed.

May I ask? What is the slowest speed you want to control, and what speed are you running your speed control algorithm?




AdamHeard 29-01-2013 13:00

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by jhersh (Post 1223657)
There is a buffer that will hold up to 127 samples for each counter / encoder. It has write pointer that does form a ring buffer. The sum of the samples between the write pointer - average_size (usually) and write pointer are summed every 0.1 us * average_size (yeah I know... overkill) and made available to the driver (i.e. not on demand) along with the number of samples available. When a counter is reset, the write pointer is moved to mark all samples unwritten (so the "count" returned would be 0).

The I/O is 6.525 us from sample to sample. The timer used has a 1 us resolution. So the actual resolution is 6..7 us. However, the error is not cumulative across the average. Regardless of the number of samples averaged, the error is less than 7.525 us.



The FPGA interface function is called writeTimerConfig_AverageSize(). Looks like we never exposed that to the WPILib API layer in C++ (and therefore Java). It's exposed in LabVIEW.

Cheers,
-Joe

So, we are unable to use this with C++?

Ether 29-01-2013 13:06

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by AdamHeard (Post 1223933)
So, we are unable to use this with C++?

See post #29 in this thread:

http://www.chiefdelphi.com/forums/sh...3&postcount=29



TravSatEE 01-02-2013 01:39

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by jhersh (Post 1223733)
That is what I was saying. It is not in the WPILib API layer in C++ and Java. That means if you care to use the hardware feature, you need to move down a layer.

Cheers,
-Joe

Are you aware of any other features that are not implemented in C++ or Java but are in LabView (even outside of counters)?

I'd also appreciate any clarification on what you mean by moving down a layer. Other than switching to LabView, is there some other action that can be taken? I thought the FPGA code was handled by the cRIO imaging tool and no modifications to the FPGA programming are allowed. Is this your understanding as well? I am not sure if your comment implies more is available.

jhersh 01-02-2013 01:55

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by TravSatEE (Post 1225722)
Are you aware of any other features that are not implemented in C++ or Java but are in LabView (even outside of counters)?

I think Java is missing SPI maybe?

In general we try to make everything the same.

Quote:

Originally Posted by TravSatEE (Post 1225722)
I'd also appreciate any clarification on what you mean by moving down a layer. Other than switching to LabView, is there some other action that can be taken? I thought the FPGA code was handled by the cRIO imaging tool and no modifications to the FPGA programming are allowed. Is this your understanding as well? I am not sure if your comment implies more is available.

The FPGA code is there. It does not need to be edited.

The layer that most people write their code is only in the "User Code" layer. The layer below that is the "WPILib" layer. That is the layer that I mean that you need to edit if you want this functionality in that language. You may even be able to call into the FPGA interface layer directly from your user code if you call it at a time that it won't be overwritten by WPILib.

Joe Ross 01-02-2013 12:01

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by TravSatEE (Post 1225722)
Are you aware of any other features that are not implemented in C++ or Java but are in LabView (even outside of counters)?

I've been filing bugs in the WPILIB Java tracker when I find something that is implemented in LabVIEW but not in Java. See http://firstforge.wpi.edu/sf/tracker...ilib_java_bugs

The things I've found are SPI, DMA, and CAN periodic status. Someone else filed a bug about digital input interrupts only being partially implemented. For SPI, I attached an implementation that works for me in the tracker.

TravSatEE 01-02-2013 12:31

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by jhersh (Post 1225726)
I think Java is missing SPI maybe?

In general we try to make everything the same.



The FPGA code is there. It does not need to be edited.

The layer that most people write their code is only in the "User Code" layer. The layer below that is the "WPILib" layer. That is the layer that I mean that you need to edit if you want this functionality in that language. You may even be able to call into the FPGA interface layer directly from your user code if you call it at a time that it won't be overwritten by WPILib.

Thanks for your clarification, jhersh. I understand what you mean now. The students do edit WPILIB also. However, this year the netbeans plugin makes this more difficult. The wpilib netbeans project directory and source code were placed in .zip files. I have not understood why this was done. I think we need to make the code more quickly accessible, and this repackaging does the opposite.

Quote:

Originally Posted by Joe Ross (Post 1225863)
I've been filing bugs in the WPILIB Java tracker when I find something that is implemented in LabVIEW but not in Java. See http://firstforge.wpi.edu/sf/tracker...ilib_java_bugs

The things I've found are SPI, DMA, and CAN periodic status. Someone else filed a bug about digital input interrupts only being partially implemented. For SPI, I attached an implementation that works for me in the tracker.

Joe, thanks for this input. I had actually stopped looking at this website since it seemed like the development work slowed down there and WPI had since created other websites. I do know that java wpilib has changed some since last year, but the underlying squawk java virtual machine is still timestamped December 2011 when the cRIO boots. There are other features missing as well, such as UDP networking support. This is actually highly misleading in the wpilib javadoc, as the documentation implies that the functionality exists. However, the code executes with a runtime exception. Frustrates the students to be this misleading. Some of the javadoc in general leaves a lot to be desired also.

I'll happily work with the key java developers on the above.

Joe Ross 01-02-2013 12:41

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by TravSatEE (Post 1225890)
I had actually stopped looking at this website since it seemed like the development work slowed down there and WPI had since created other websites.

The Support Page on screenstepslive says to file bugs in the firstforge tracker. There have been 7 java bugs closed since kickoff (4 documentation and 3 fairly simple bugs).

I figure that if there isn't a bug filed, you can't complain about it not being fixed.

nightpool 01-02-2013 13:38

Re: Best way to measure period between pulses? Counters and FPGA
 
Hey, kinda a thread hijack, but this seemed like the best place to ask. We're using a photo-eye based encoder on our team (due to issues mounting traditional shaft encoders) and are having issues with GetPeriod() when we drop below 20 rps where it returns infinity about half of the time, and the correct speed the rest of the time. GetPeriod() apparently returns infinity only if the counter is "stalled". Does anyone know what this means, or if there's a way around it? Overriding GetPeriod doesn't work, as m_counter is private, not protected. I'm guessing that the FPGA has some kind of threshold where if it doesn't see an edge it assumes the wheel has stopped. Is there any way of modifying that, maybe giving it a large tolerance?

Thad House 01-02-2013 13:43

Re: Best way to measure period between pulses? Counters and FPGA
 
The is a function you can use to set what the FPGA sees as stopped. its the setMinRate function.

Joe Ross 01-02-2013 14:41

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by sst.thad (Post 1225927)
The is a function you can use to set what the FPGA sees as stopped. its the setMinRate function.

In the Encoder class it's called setMinRate, in the Counter class it's called setMaxPeriod.

MisterG 01-02-2013 14:56

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by sst.thad
The is a function you can use to set what the FPGA sees as stopped. its the setMinRate function.

Quote:

Originally Posted by Joe Ross (Post 1225977)
In the Encoder class it's called setMinRate, in the Counter class it's called setMaxPeriod.

Sounds like the answer to our problems.

I imagine that we don't want to use the stalled feature at all. Is there a downside to setting the max period to a high value? e.g. 6 seconds period is equivalent to 10 RPM. This would seem safe at any reasonably low speeds. Is there any functionality trade off to setting a high max period?

nightpool 01-02-2013 15:10

Re: Best way to measure period between pulses? Counters and FPGA
 
Doesn't that mean it wouldn't be able to tell if the wheel is actually stopped?

Thad House 01-02-2013 15:16

Re: Best way to measure period between pulses? Counters and FPGA
 
If you look at the code the only reason it has that function is to not have a divide by 0 error. In the get period function, it uses that bool in order to not make it divide by 0.

MisterG 01-02-2013 15:21

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by nightpool (Post 1225994)
Doesn't that mean it wouldn't be able to tell if the wheel is actually stopped?

Oh, yeah. Basically it will continue returning some higher speed that represents the last valid transition even though the wheel may have stopped some time earlier.

So we probably need to decide some happy medium rotational velocity that we want to control and set the period accordingly.

-al g

MisterG 01-02-2013 15:44

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by sst.thad (Post 1225997)
If you look at the code the only reason it has that function is to not have a divide by 0 error. In the get period function, it uses that bool in order to not make it divide by 0.

Note: the problem that we are dealing with is primarily due to the one pulse per revolution setup.

Agree that the stall feature is solving the zero divide problem but probably more importantly its dealing with the issue of period growing dramatically as rotational velocity approaches zero.

Take the following scenario: you decelerate very rapidly and your last transition happens at a time that is equivalent to 200 RPM. The wheel is stopped but the code continues to report 200 RPM. If the timeout (max period/min rate) is set for 10 RPM this will continue for 6 seconds.

Another interesting C++ fact that I never realized before (or once I knew but forgot):
For IEEE floats, division of a finite nonzero float by 0 is well-defined and results in +infinity (if the value was >zero) or -infinity (if the value was less than zero). The result of 0/0 is NaN. If you use integers, the behaviour is undefined.

Greg McKaskle 03-02-2013 10:42

Re: Best way to measure period between pulses? Counters and FPGA
 
The IEEE defined behavior is the same for LV, and I presume Java.

Greg McKaskle

matthewkennedy 07-02-2013 23:29

Re: Best way to measure period between pulses? Counters and FPGA
 
Quote:

Originally Posted by Greg McKaskle (Post 1226900)
The IEEE defined behavior is the same for LV, and I presume Java.

It is pretty certain that is is going to be the same for C++/Java/LV as this behavior is typically determined by the FPU in the processor. I know that PPC conforms to the IEEE spec, and it properly handles x/0 for the three cases above.

Greg McKaskle 08-02-2013 07:18

Re: Best way to measure period between pulses? Counters and FPGA
 
I agree that PPC is IEEE 754 compliant, but some languages will have their own conventions, and since Java in interpreted, it would be pretty easy and efficient for them to have thrown an exception or taken some other action.

Greg McKaskle


All times are GMT -5. The time now is 21:45.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi