Class: PIDController
- Inherits:
-
StatefulController
- Object
- Controller
- StatefulController
- PIDController
- Defined in:
- lib/device_control.rb
Overview
A PIDController is a StatefulController that calculates
-
Proportion (current error)
-
Integral (accumulated error)
-
Derivative (error slope, last_error)
The sum of these terms is the output
Constant Summary collapse
- ZN =
Ziegler-Nichols method for tuning PID gain knobs en.wikipedia.org/wiki/Ziegler%E2%80%93Nichols_method
{ # Kp Ti Td Ki Kd # Var: Ku Tu Tu Ku/Tu Ku*Tu 'P' => [1/2r], 'PI' => [9/20r, 4/5r, nil, 27/50r], 'PD' => [ 4/5r, nil, 1/8r, nil, 1/10r], 'PID' => [ 3/5r, 1/2r, 1/8r, 6/5r, 3/40r], 'PIR' => [7/10r, 2/5r, 3/20r, 7/4r, 21/200r], # less overshoot than standard PID 'some' => [ 1/3r, 1/2r, 1/3r, 2/3r, 1/11r], 'none' => [ 1/5r, 1/2r, 1/3r, 2/5r, 2/30r], }
Constants inherited from StatefulController
StatefulController::HZ, StatefulController::TICK
Instance Attribute Summary collapse
-
#d_range ⇒ Object
Returns the value of attribute d_range.
-
#i_range ⇒ Object
Returns the value of attribute i_range.
-
#kd ⇒ Object
Returns the value of attribute kd.
-
#ki ⇒ Object
Returns the value of attribute ki.
-
#kp ⇒ Object
Returns the value of attribute kp.
-
#o_range ⇒ Object
Returns the value of attribute o_range.
-
#p_range ⇒ Object
Returns the value of attribute p_range.
Attributes inherited from StatefulController
#dt, #error, #last_error, #sum_error
Attributes inherited from Controller
Class Method Summary collapse
-
.tune(type, ku, tu) ⇒ Object
ku = ultimate gain, tu = oscillation period output includes ti and td, which are not necessary typically kp, ki, and kd are used.
Instance Method Summary collapse
- #derivative ⇒ Object
-
#initialize(setpoint, dt: TICK) {|_self| ... } ⇒ PIDController
constructor
A new instance of PIDController.
- #integral ⇒ Object
- #output ⇒ Object
- #proportion ⇒ Object
- #to_s ⇒ Object
Methods inherited from StatefulController
Methods inherited from Controller
Methods included from Updateable
Constructor Details
#initialize(setpoint, dt: TICK) {|_self| ... } ⇒ PIDController
Returns a new instance of PIDController.
226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/device_control.rb', line 226 def initialize(setpoint, dt: TICK) super # gain / multipliers for PID; tunables @kp, @ki, @kd = 1.0, 1.0, 1.0 # optional clamps for PID terms and output @p_range = (-Float::INFINITY..Float::INFINITY) @i_range = (-Float::INFINITY..Float::INFINITY) @d_range = (-Float::INFINITY..Float::INFINITY) @o_range = (-Float::INFINITY..Float::INFINITY) yield self if block_given? end |
Instance Attribute Details
#d_range ⇒ Object
Returns the value of attribute d_range.
224 225 226 |
# File 'lib/device_control.rb', line 224 def d_range @d_range end |
#i_range ⇒ Object
Returns the value of attribute i_range.
224 225 226 |
# File 'lib/device_control.rb', line 224 def i_range @i_range end |
#kd ⇒ Object
Returns the value of attribute kd.
224 225 226 |
# File 'lib/device_control.rb', line 224 def kd @kd end |
#ki ⇒ Object
Returns the value of attribute ki.
224 225 226 |
# File 'lib/device_control.rb', line 224 def ki @ki end |
#kp ⇒ Object
Returns the value of attribute kp.
224 225 226 |
# File 'lib/device_control.rb', line 224 def kp @kp end |
#o_range ⇒ Object
Returns the value of attribute o_range.
224 225 226 |
# File 'lib/device_control.rb', line 224 def o_range @o_range end |
#p_range ⇒ Object
Returns the value of attribute p_range.
224 225 226 |
# File 'lib/device_control.rb', line 224 def p_range @p_range end |
Class Method Details
.tune(type, ku, tu) ⇒ Object
ku = ultimate gain, tu = oscillation period output includes ti and td, which are not necessary typically kp, ki, and kd are used
213 214 215 216 217 218 219 220 221 222 |
# File 'lib/device_control.rb', line 213 def self.tune(type, ku, tu) record = ZN[type.downcase] || ZN[type.upcase] || ZN.fetch(type) kp, ti, td, ki, kd = *record kp *= ku if kp ti *= tu if ti td *= tu if td ki *= (ku / tu) if ki kd *= (ku * tu) if kd { kp: kp, ti: ti, td: td, ki: ki, kd: kd } end |
Instance Method Details
#derivative ⇒ Object
255 256 257 |
# File 'lib/device_control.rb', line 255 def derivative (@kd * (@error - @last_error) / @dt).clamp(@d_range.begin, @d_range.end) end |
#integral ⇒ Object
251 252 253 |
# File 'lib/device_control.rb', line 251 def integral (@ki * @sum_error).clamp(@i_range.begin, @i_range.end) end |
#output ⇒ Object
241 242 243 244 245 |
# File 'lib/device_control.rb', line 241 def output (self.proportion + self.integral + self.derivative).clamp(@o_range.begin, @o_range.end) end |
#proportion ⇒ Object
247 248 249 |
# File 'lib/device_control.rb', line 247 def proportion (@kp * @error).clamp(@p_range.begin, @p_range.end) end |
#to_s ⇒ Object
259 260 261 262 263 264 265 266 |
# File 'lib/device_control.rb', line 259 def to_s super + [format(" Gain:\t%.3f\t%.3f\t%.3f", @kp, @ki, @kd), format(" PID:\t%+.3f\t%+.3f\t%+.3f\t= %.5f", self.proportion, self.integral, self.derivative, self.output), ].join("\n") end |