*
-- Author.
import java.util.*; public class pidsim { double timeunit = 0.02; //iteration time (guesstimated) double maxrotaterate = 1.00; //maximum rotation rate allowed //play with the following 3 constants double kp = 1.5; //proportional constant double ki = 1.0; //integral constant double kd = 1.0; //derivative constant double setpoint = 0; //target angle double maxturnrate = 0.1; //guess at motor maximum turning rate double accuracy = 0.50; //tolerance of target closeness double currheading = 0; //current reported gyro heading double error = 0.0; //difference (heading - setpoint) double preverror = 0; //prior error calculated double rr = 0.0; //rotation rate double i = 0.0; //integral variable double d = 0.0; //derivative variable static int src = 0; int rc = 0; //return code int approachside = 0; //1 = postive slope, -1 = negative slope int icount = 0; public static void main(String[] args) { pidsim t = new pidsim(); src = t.process(); System.out.println("E-O-P"); return; } public int process() { String keyline; Scanner sc = new Scanner(System.in); for(;;) { System.out.println("Please enter target angle"); keyline = sc.nextLine(); keyline = keyline.trim(); if(keyline.length() == 0) { System.out.println("Nothing entered, terminating"); break; } try { setpoint = Integer.parseInt((String) keyline); } catch(NumberFormatException e) { System.out.println("Non-integer detected"); continue; } rc = initvalues(); rc = pidprocess(); } sc.close(); return 0; } // end method public int pidprocess() { if ( (setpoint - currheading) > 0 ) //Recognize overshoot of target from any oscillation { approachside = 1; } else { approachside = -1; } while (Math.abs(setpoint - currheading) > accuracy) { currheading = currheading + (Math.abs(setpoint) * maxturnrate * rr); //a guess about amount of movement rr = calcPID(); //pause(1000); } return 0; } // end method public double calcPID() { error = setpoint - currheading; //amount still to go to reach target setpoint if (((error > 0) && (preverror < 0)) || ((error < 0) && (preverror > 0))) { approachside = approachside * -1; System.out.println("Setpoint approach direction change"); i = 0; //reset integral summation } i = i + (error * timeunit); //sum of the history of (errors * timeunit) double deltaerror = preverror - error; if (Math.abs(deltaerror) < timeunit) //employ only when change in error is small { d = deltaerror / timeunit; //slope of the current error differentiated over timeunit } else { d = 0; } preverror = error; //save value for next iteration rr = (kp * error) + (ki * i) + (kd * d); //rotation rate calculation if (rr > 0) //constrain on the interval (-1,1) or less { rr = Math.min((rr / Math.abs(setpoint)), maxrotaterate); } else { rr = Math.max((rr / Math.abs(setpoint) ), -1 * maxrotaterate); } System.out.printf("Interval: %3d Heading: %+7.2f Error: %+7.2f Integral: %+6.2f Derivative: %+5.2f RotateRate: %+5.2f ",icount,currheading,error,i,d,rr); System.out.println(""); icount++; return rr; } // end method public int initvalues() //Initialize variables { icount = 0; currheading = 0; error = 0.0; preverror = 0; rr = 0.0; i = 0; d = 0; approachside = 0; return 0; } // end method public static int pause(int d) // puts thread to sleep for d milliseconds { try { Thread.sleep(d); } catch (InterruptedException e1) { return 1; } return 0; } } // end class
} // end class
</pre>