|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
||||
|
||||
|
High Speed Encoder Problem
Hey, we have a 128 click encoder for our shooter speed. Our java programmers managed to get an encoder velocity, but it updates constantly and is all over the place, it ranges +/- 1000 clicks per second when we run a constant speed on the shooter motors, any way to clean up the "noise," if that's the problem. Thanks.
|
|
#2
|
||||
|
||||
|
Re: High Speed Encoder Problem
How are you calculating the rate? Are you using WPILib?
|
|
#3
|
||||
|
||||
|
Re: High Speed Encoder Problem
It that a lab view feature? We're using a pre-made java class from the 2012 API. It has a " .getRate() " that returns the angular velocity.
|
|
#4
|
||||
|
||||
|
Re: High Speed Encoder Problem
WPILib is basically the whole thing. I think encoder.getRate() works by reading the number of encoder counts from the FPGA and then dividing by the time elapsed between readings. As your RPMs increase, your noise will increase. Have you tried a moving average?
1000 ticks per second is actually pretty darn slow. That equates to about 470rpm. Is that the speed you're looking for? |
|
#5
|
||||
|
||||
|
Re: High Speed Encoder Problem
That's the encoder we gave you
.The getrate from the library is an instananeous rate. You'll be better off using the 'get count' function, and then measureing the time between loop updates like this: (New count - old count ) / loop time If that ends up still being noisy, you can average, or calculate over more than one loop. Also, make sure you're running in single sample mode rather than 4x to remove phase errors. |
|
#6
|
||||
|
||||
|
Re: High Speed Encoder Problem
Yeah.
I thought about an average value too, but our programmers don't know how to implement that. |
|
#7
|
||||
|
||||
|
Re: High Speed Encoder Problem
Quote:
new_filtered_value = K*previous_filtered_value + (1-K)* new_sample ... that's all there is to it. "K" is a tuning constant, which you use to adjust the "strength" of the filter. K must be in the range zero to +1. When K=0, there is no filtering. When K=1, the filtering is so "strong" that the filtered value never changes. |
|
#8
|
||||
|
||||
|
Re: High Speed Encoder Problem
Quote:
With our recent encoder issue (sorry I don't know how to link to it)... I tried using the blend, but found that it would introduce latency when it is tuned too high. I prefer this over averaging though, but the real winner is the Kalman filter... that one gave good enough results without the latency. And latency makes it much more difficult to tune the PID. (Especially to someone who has not yet mastered the skill of it yet). |
|
#9
|
||||
|
||||
|
Re: High Speed Encoder Problem
We have a similar filter in our library but we called it MovingAverage filter. In a sense, it is averaging the last N points.
Code:
/* * MovingAverage of N points: * MovingAverage = (MovingAverage*(N - 1) + CurrData)/N * = MovingAverage*(N - 1)/N + CurrData/N * = MovingAverage*(1 - Kf) + CurrData*Kf * where 1/N = Kf * (N - 1)/N = 1 - 1/N = 1 - Kf */ |
|
#10
|
||||
|
||||
|
Re: High Speed Encoder Problem
Quote:
As you've shown, it's identical to what was posted earlier. Last edited by Ether : 15-04-2012 at 11:31. Reason: edited for clarity |
|
#11
|
||||
|
||||
|
Re: High Speed Encoder Problem
You are right, it does carry the history of all pass data points.
|
|
#12
|
||||
|
||||
|
Re: High Speed Encoder Problem
Here is the Kalman Filter:
Code:
/***********************************************************************************************************/
/* KalmanFilter */
/***********************************************************************************************************/
void KalmanFilter::Reset()
{
m_FirstRun=true;
//initial values for the kalman filter
m_x_est_last = 0.0;
m_last = 0.0;
}
KalmanFilter::KalmanFilter(): m_Q(0.022),m_R(0.617) //setup Q and R as the noise in the system
{
}
double KalmanFilter::operator()(double input)
{
//For first run set the last value to the measured value
if (m_FirstRun)
{
m_x_est_last=input;
m_FirstRun=false;
}
//do a prediction
double x_temp_est = m_x_est_last;
double P_temp = m_last + m_Q;
//calculate the Kalman gain
double K = P_temp * (1.0/(P_temp + m_R));
//the 'noisy' value we measured
double z_measured = input;
//correct
double x_est = x_temp_est + K * (z_measured - x_temp_est);
double P = (1- K) * P_temp;
//update our last's
m_last = P;
m_x_est_last = x_est;
//Test for NAN
if ((!(m_x_est_last>0.0)) && (!(m_x_est_last<0.0)))
m_x_est_last=0;
return x_est;
}
|
|
#13
|
||||
|
||||
|
Re: High Speed Encoder Problem
Yeah, I was wondering if we could do that. All the java classes for encoder need an A and B channel. Could we just sample pulses from one digital port and compare it against the code's timer????
|
|
#14
|
||||
|
||||
|
Re: High Speed Encoder Problem
Quote:
|
|
#15
|
||||
|
||||
|
Re: High Speed Encoder Problem
Perfect, Thanks.
![]() |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|