Shop OBEX P1 Docs P2 Docs Learn Events
PID general question — Parallax Forums

PID general question

QuadrtrFlyrQuadrtrFlyr Posts: 73
edited 2011-12-29 10:51 in Propeller 1
Hello folks,

I have been recently working on implementing a PID controller into my project. I believe I understand the theory behind it but I have trouble understanding the scaling at the very end.

My scenario is as follows:

-let us say the setpoint is zero
-range for sensor input is between -90 and 90

The problem is that I need an output to be between 1000-2000 in order to run a servo. I am only using the proportional gain right now
and have linearized my data so the output works with what I have. (similar to adding a constant to the Kp term in order to control my motors)
Did I implement the proportional term correctly? it seem to always overshoot past 2000 if I increase the Kp gain a little.. I guess this is supposed to happen
and the only thing to do is to limit the upper and lower values using max and min.. <# and #> ....
PRI PwmMonitor | upper, lower, angleupper, anglelower

  'PID Algorithm
  'Kp = 1.0
  upper := 2000.0         'upper limit for esc control
  lower := 1000.0         'lower limit for esc control
  angleupper := 90.0     'max sensor data
  anglelower := 0.0       'min sensor data


  'linearize data by calculating m and b in y=mx+b
  slope := math.FDiv(math.FSub(upper,lower),math.FSub(angleupper,anglelower))
  b := math.FAdd(math.FMul(slope,-anglelower),lower)
  
  repeat
    sensorInputP := imu.get_angle_Pitch
    sensorInputR := imu.get_angle_Roll
      
    errorP := math.FSub(setpointP, sensorInputP)
    errorR := math.FSub(setpointR, sensorInputR) 


    ' Calculate proportional term.
    pP := math.FMul(Kp, errorP) 
    pR := math.FMul(Kp, errorR)
    
    ' Calculate output y=mx+b
    
    ' Pitch
    pwm1 := math.FAdd(math.FMul(slope,pP),b) #> 1000.0
    pwm4 := math.FAdd(math.FMul(slope,math.FNeg(pP)),b) #> 1000.0
    ' Roll
    pwm3 := math.FAdd(math.FMul(slope,pR),b) #> 1000.0
    pwm2 := math.FAdd(math.FMul(slope,math.FNeg(pR)),b) #> 1000.0 


    pwm1f := math.FRound(pwm1)
    pwm4f := math.FRound(pwm4)
    pwm3f := math.FRound(pwm3)
    pwm2f := math.FRound(pwm2)
    

Many Thanks!

Robert

Comments

  • T ChapT Chap Posts: 4,223
    edited 2011-12-29 10:07
    It would be a good idea to set a max value to limit how high the value can rise to. Otherwise, the integral value can just keep on adding, usually called 'windup'. PID usually requires some customization to the application as needed. For proportional overshoot, you may need to adjust the P input value, but the same applies to max and min requirements.
  • QuadrtrFlyrQuadrtrFlyr Posts: 73
    edited 2011-12-29 10:17
    Thank you T Chap. I added the max value and have adjusted the kP in order to get a decent motion in my mechanism. Seems to be working fine. Now moving on to integral action!

    Robert
  • T ChapT Chap Posts: 4,223
    edited 2011-12-29 10:51
    Proportional only will be pretty jerky. Integral will allow more adjustment in terms or how fast the PID loop responds(gets to max). Use a lower accumulate factor to make the output 'wind up' slower, a faster accumulate rate will get you to the integral max faster. It is often nice to be able to see the result of the formula in action, although observing the loop with LCD or terminal viewing code may affect the rate of the loop, so keep that in mind. Experimenting with the P and I factors will help find a good balance. I like to be able to adjust all values on the fly to see how the result works:

    Proportional
    Integral (Accumulate Rate: how slow or fast to get to Max)
    Derivative (often not needed)
    Output Max (and/or Min if required)
    Deadband Range (in a case of using an encoder, may be useful to stop oscillation when stopped)
Sign In or Register to comment.