Go to Post its not that I cant spell, I'm just being international. . . . I like it - Stuart [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
 
 
Thread Tools Rate Thread Display Modes
Prev Previous Post   Next Post Next
  #30   Spotlight this post!  
Unread 11-02-2012, 12:01
khatamidk khatamidk is offline
Registered User
FRC #3847
 
Join Date: Jan 2012
Location: Houston
Posts: 1
khatamidk is an unknown quantity at this point
Re: Speed PID Function

Our team was also getting wild fluctuations with velocity, with an error range of upwards of 300 RPM and spikes that extend well past 1000 RPM beyond our setpoint. This was unacceptable for our PID control loop, so our mentor suggested we implement a moving average/median filter to smooth out the graph and get rid of those nasty rate spikes. We also changed the encoder rate to k1X instead of k4X (default).

We are working with the command-subsystem in Java, so this should might help those that are working with PIDSubsystems (which our Shooter class is). We only changed the returnPIDInput() method.

The result was an incredibly smooth graph, fluctuating within an acceptable range that can be tuned with the P constant (and maybe D depending on how close to the value we get).

Here is a picture of repeated tests.

In the above picture, there were 5 tests separated by the deep drops to zero (First 4 were set to 1000RPM, the last set to 2000RPM0. You can see how much smoother the fluctuation of RPM is (the fluctuation that still persists is a result of a much-needed PID constant tuning). As stated earlier, we went from a 300-1000 RPM spike/fluctuation to one less than 100 RPM. We also played around with the sampling size, and we chose 20. It did not affect cRIO CPU usage very much at all. 100 sampling size provided no advantage from what we saw compared to 20.


Here is our implementation of the returnPIDInput()
Code:
private double[] samplingValues = new double[HW.SAMPLING_SIZE];

    //MOVING MEDIAN/AVERAGE FILTER BASED ON A SAMPLING SIZE OF "N" VALUES (ex. 20)
    protected double returnPIDInput() {
        
        //LOOP THROUGH AND SHIFT ALL VALUES TO THE RIGHT BY ONE, REMOVING THE LAST VALUE
        for(int i = samplingValues.length-1; i > 0; i--){
            samplingValues[i] = samplingValues[i-1];
        }
        //PUSH IN A NEW VALUE BASED ON RATE (we are using RPS*60 = RPM)
        samplingValues[0] = shooter_encoder.getRate()*60;
        
        //TEMP ARRAY FOR PERFORMING MEDIAN OPERATION
        double[] median = Arrays.copy(samplingValues, 0, HW.SAMPLING_SIZE, 0, HW.SAMPLING_SIZE);
        Arrays.sort(median);
        
        //RETURNS THE MIDDLE OF THE SORTED MEDIAN ARRAY
        return median[median.length/2];
    }

Hope this helps,
David K.
Team Spectrum
FRC#3847
 


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

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


All times are GMT -5. The time now is 00:07.

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


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