Log in

View Full Version : Custom GetRate not working.


Mk.32
30-03-2012, 21:13
Hi all,

We've heard that the WIPlib Encoder method getRate() is inconsistent, so we're trying to write out our own (better) without any success. Any suggestions?

Code:

private static double currGet = 0.0;

public static double getRate() {
double prevGet = currGet;
currGet = shooterEncoder.get();
int scalar = 50;
double rateDegreePerSec = Math.abs(currGet-prevGet)*scalar;

double rpm = rateDegreePerSec/6.0;
System.out.println("Rate: " + rpm);

return rpm;
}

Ether
30-03-2012, 22:58
We've heard that the WIPlib Encoder method getRate() is inconsistent, so we're trying to write out own (better) without any success.

It's not entirely clear what you mean by "without any success". I will assume what you meant is that you are getting a signal, but it is very noisy.


private static double currGet = 0.0;

public static double getRate() {
double prevGet = currGet;
currGet = shooterEncoder.get();
int scalar = 50;
double rateDegreePerSec = Math.abs(currGet-prevGet)*scalar;

double rpm = rateDegreePerSec/6.0;
System.out.println("Rate: " + rpm);

return rpm;
}

In the above code, you are not using the actual elapsed time since the previous sample to compute rate. You are assuming the scheduler's timing jitter can be ignored. Try reading a high-res system clock and dividing the delta_counts by the actual elapsed time.

Also, if you are not sampling the encoder at 1x, you might try that also:

With 4x encoding, you get more noise in the velocity due to quadrature phase errors in the encoder wheel. I recommend 1x for velocity and 4x for distance.

Mk.32
30-03-2012, 23:39
Sorry for the confusion, we are getting data back however it is very noisy and unstable.

Ether
31-03-2012, 01:02
Sorry for the confusion, we are getting data back however it is very noisy and unable.

Unstable.

Try using 1x instead of 4x, and try using actual measured elapsed time since last sample instead of a fixed scale factor.

If that doesn't work, check to make sure your encoder disk is installed properly.

Mk.32
31-03-2012, 03:18
Here is a quick re-write I did, using all the above comments. Encoder is set to 1x.

Wouldn't get to test till next Wednesday. But comments are welcome.

public static void shooterEncoderStart() {
shooterEncoder.start();
shooterEncoder.setDistancePerPulse(1.0 / 360.0);
}

public static void shooterEncoderReset() {
shooterEncoder.reset();
}

public static double getRate() {
double get1 = shooterEncoder.get();
double time = Timer.getFPGATimestamp();
double get2 = shooterEncoder.get();
time -= Timer.getFPGATimestamp();
double rateDegreePerSec = Math.abs(get2-get1)/Math.abs(time);
return rateDegreePerSec/6.0; //RPM
}

Ether
31-03-2012, 09:46
Here is a quick re-write I did, using all the above comments. Encoder is set to 1x.

Wouldn't get to test till next Wednesday. But comments are welcome.

public static double getRate() {
double get1 = shooterEncoder.get();
double time = Timer.getFPGATimestamp();
double get2 = shooterEncoder.get();
time -= Timer.getFPGATimestamp();
double rateDegreePerSec = Math.abs(get2-get1)/Math.abs(time);
return rateDegreePerSec/6.0; //RPM
}

The above won't work. "get1" and "get2" will be equal to each other and you'll always return zero.

You want to get the encoder count and the time once per iteration, and compare those values to the previous iteration.

Pseudocode:

new_counts = get_counts();
new_time = get_time();

rate = (new_counts - previous_counts)/(new_time - previous_time);

previous_counts = new_counts;
previous_time = new_time;

Mk.32
31-03-2012, 16:33
Thank you for the help Ether, I will try it out next meeting!