Last Time � TODO add: � Estimating worst case execution time � PID material from Pont slides � Holistic scheduling: real-time guarantees over a CAN bus � Some inverted pendulum videos � Model-based control and other more sophisticated controllers? � More code speed issues – perf with and w/o FP on different processors Today Control Systems � Feedback (closed loop) control and PID controllers � Definitions: � Principles � Desired state variables: X*(t) � Implementation • These are given to the system from outside • E.g. “room temperature should be 70 � ” � Tuning � Estimated state variables: X’(t) • E.g. “room temperature is currently 67 � ” • Estimation uses standard data acquisition techniques – E.g. thermistor + ADC � Actions: U(t) • System commands U(t) converted into driving forces using transducers • E.g. “turn off the furnace” More Control Terms Early Feedback Control � Goal of a control system is to minimize error: � e(t) = | X*(t) – X’(t) | � Evaluating a control system � Steady-state controller error • Average e(t) � Transient response • How long the system takes to reach 99% of the desired final value after X*(t) is changed � Stability • Does the system reach a steady state (smooth constant output) or does it oscillate? � Centrifugal governor for a throttle 1
Simple Closed Loop Example Thermostat Code int Thigh, Tlow; � We’re designing a thermostat bool on = false; � Goal is to heat room to a set temperature � We can turn the furnace on and off timer_interrupt_handler (void) { � When furnace is off, room cools down by itself int T = read_adc(); � Fancy control is not needed here! if (T < Tlow && !on) { � Rather we just need two temperature settings turn_furnace_on(); � T low – temperature at which we turn on the furnace on = true; � T high – temperature at which we turn off the furnace } � The difference between these provides hysteresis if (T > Thigh && on) { � An on/off (“bang bang”) controller works well when turn_furnace_off(); the physical system is slow to respond on = false; } � What happens if control loop runs too fast or slow? } Another Simple Controller PID Controllers � We’re controlling a robot arm attached to a stepper � Simple controllers like previous two examples work motor but in many real situations � Need to get the arm to a certain position � Respond slowly � Position sensor tells us where the arm is � Have large errors � Algorithm: � Better answer: PID (Proportional Integral Derivative) � if E > 1mm then decrement position by 1mm � PID equation: � if E < -1mm then increment position by 1mm t � Pretty tough to go wrong with a strategy like this dE ( t ) � U ( t ) K E ( t ) K E ( ) d K = + τ τ + P I D � But slow to converge dt � What happens if control loop runs too fast or slow? 0 � K P , K I , and K D are design parameters � Can be fixed at zero to simplify the controller PID Intuition PID Loop Skeleton Code � K P – determines response to current error double UpdatePID (SPid *pid, � Too large � Oscillation double error, � Too small � Slow response double position) � Can’t eliminate steady-state error { � K I – determines response to cumulative error … � Can eliminate steady-state error but often makes transient } response worse � K D – determines response to rate of change of error position = ReadPlantADC(); � Damps response when error is moving in the right drive = UpdatePID (&plantPID, direction plantCommand - position, � Amplifies response when error is moving in the wrong direction position); � Can be used to increase stability and improve transient DrivePlantDAC (drive); response 2
Proportional Control Example System 1 double UpdatePID (SPid *pid, double error, double position) { double pTerm; pTerm = pid->pGain * error; return pTerm; } Example System 2 Example System 3 � Problem: Proportional control can’t always eliminate � Problem: When there is too much actuator delay, steady-state error proportional control cannot stabilize the system Integral Control Example 2 with PI Control double iTerm; pid->iState += error; if (pid->iState > pid->iMax) { pid->iState = pid->iMax; } else if (pid->iState < pid-> iMin) { pid->iState = pid->iMin; } iTerm = pid->iGain * iState; � In practice, always used in conjunction with proportional control � Steady state error is eliminated 3
Integrator Issues Differential Control � Sampling time becomes more important double dTerm; � Sampling time shouldn’t vary more than 1%-5% dTerm = pid->dGain * � On average, sampling should be periodic (position - pid->dState); � Integrator range is important pid->dState = position; � “Integrator windup” occurs when the integrator value gets stuck too high or too low � Basically just computes the slope of the system � Limiting the range makes this less of a problem state � Reasonable heuristic: Set integrator limits to drive limits � Usually, if you can’t stabilize a system with � Attempts to predict system future based on recent proportional control, you can’t stabilize it with PI past history control either Example 3 with PD Control Differential Issues � Derivative is very sensitive to noise � In practice, might keep a buffer of several samples into the past in order to smooth out noise • This is just a low-pass filter • Decreases responsiveness – which is the point of differential control in the first place � Important for sampling period to be very even � Do sampling in a high-priority interrupt or thread Full PID Source Code Implementation Issues typedef struct { � Example code uses floating point double dState; // Last position input double iState; // Integrator state � Convert to integer or fixed-point by hand double iMax, iMin; OR double iGain, // integral gain pGain, // proportional gain � Keep using FP if the control loop frequency is low or if HW dGain; // derivative gain FP is available } SPid; � Multiplies can be avoided by selecting constants that double UpdatePID (SPid * pid, double error, double position) { are multiples of 2 double pTerm, dTerm, iTerm; pTerm = pid->pGain * error; � Sampling rate pid->iState += error; if (pid->iState > pid->iMax) pid->iState = pid->iMax; � Too low � Slow response time else if (pid->iState < pid->iMin) pid->iState = pid->iMin; � Too high � Differential noise and integral overflow iTerm = pid->iGain * iState; dTerm = pid->dGain * (position - pid->dState); � Rule of thumb: Set sampling rate between 1/10 and 1/100 of pid->dState = position; desired settling time return pTerm + iTerm - dTerm; } � Difficult control problems argue for higher sampling rates 4
Tuning the Parameters Tuning Differential Gain � Method 1: Plug system model into Matlab, it hands � Start here unless you can do without dGain, in which you the parameters case set it to 0.0 and move to pGain � Method 2: Tune by hand � Start with small proportional gain, e.g. 1.0 � Happy fact: When the system is not too sensitive, control � Start with dGain == pGain * 100 parameters only have to be roughly correct to do a good job � Increase dGain until unacceptable oscillation, � Requirements for hand tuning: overshoot, or noise occurs � Need to be able to observe controller variables and output � Oscillation from too much dGain is much faster than � Need to be able to supply square-wave inputs oscillation from not enough � Note: Parameters can interact in complex ways � Back off by factor of 2-4 � Tuning is an art � System will now be sluggish – time to tune P and I � Tuning by hand will be difficult if system is barely controllable � System may be uncontrollable Tuning pGain and iGain Conclusions � Start with a pGain around 1-100 � Feedback control is a broadly useful technology for getting an embedded system to have some desired � By experimentation find the value of pGain where effect on the real world oscillation starts � In practice manual tuning replaces analytic solutions � Then back off by a factor of 2-4 � However, Matlab has great support for feedback � Start with iGain around 0.0001-0.001 control � Again find a value that gives reasonably good � Can generate efficient code too performance without causing oscillation 5
Recommend
More recommend