Class: DeviceControl::PIDController
- Inherits:
-
StatefulController
- Object
- Controller
- StatefulController
- DeviceControl::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.
227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/device_control.rb', line 227 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.
225 226 227 |
# File 'lib/device_control.rb', line 225 def d_range @d_range end |
#i_range ⇒ Object
Returns the value of attribute i_range.
225 226 227 |
# File 'lib/device_control.rb', line 225 def i_range @i_range end |
#kd ⇒ Object
Returns the value of attribute kd.
225 226 227 |
# File 'lib/device_control.rb', line 225 def kd @kd end |
#ki ⇒ Object
Returns the value of attribute ki.
225 226 227 |
# File 'lib/device_control.rb', line 225 def ki @ki end |
#kp ⇒ Object
Returns the value of attribute kp.
225 226 227 |
# File 'lib/device_control.rb', line 225 def kp @kp end |
#o_range ⇒ Object
Returns the value of attribute o_range.
225 226 227 |
# File 'lib/device_control.rb', line 225 def o_range @o_range end |
#p_range ⇒ Object
Returns the value of attribute p_range.
225 226 227 |
# File 'lib/device_control.rb', line 225 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
214 215 216 217 218 219 220 221 222 223 |
# File 'lib/device_control.rb', line 214 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
256 257 258 |
# File 'lib/device_control.rb', line 256 def derivative (@kd * (@error - @last_error) / @dt).clamp(@d_range.begin, @d_range.end) end |
#integral ⇒ Object
252 253 254 |
# File 'lib/device_control.rb', line 252 def integral (@ki * @sum_error).clamp(@i_range.begin, @i_range.end) end |
#output ⇒ Object
242 243 244 245 246 |
# File 'lib/device_control.rb', line 242 def output (self.proportion + self.integral + self.derivative).clamp(@o_range.begin, @o_range.end) end |
#proportion ⇒ Object
248 249 250 |
# File 'lib/device_control.rb', line 248 def proportion (@kp * @error).clamp(@p_range.begin, @p_range.end) end |
#to_s ⇒ Object
260 261 262 263 264 265 266 267 |
# File 'lib/device_control.rb', line 260 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 |