Skip to content

Instantly share code, notes, and snippets.

@rringler
Created July 21, 2018 18:25
Show Gist options
  • Save rringler/239bd943d584bc51f4b48ece5a9d1d17 to your computer and use it in GitHub Desktop.
Save rringler/239bd943d584bc51f4b48ece5a9d1d17 to your computer and use it in GitHub Desktop.
Ruby PID Controller
class PID
attr_reader :delta_t,
:kp,
:ki,
:kd,
:output_p_prev,
:output_i_prev,
:output_min,
:output_max,
:setpoint,
:t_prev,
:t_interval
def initialize(options)
@setpoint = options.fetch(:setpoint).to_f
@kp = options.fetch(:kp, 1.0)
@ki = options.fetch(:ki, 1.0)
@kd = options.fetch(:kd, 1.0)
@output_p_prev = 0.0
@output_i_prev = 0.0
@output_min = options.fetch(:output_min, 0)
@output_max = options.fetch(:output_max, 1000)
@t_prev = Time.now.to_f
@t_interval = options.fetch(:interval, 1)
end
def control(process_variable)
@t_now = Time.now.to_f
if delta_t >= t_interval
error = setpoint - process_variable
output_p = output_p(error)
output_i = output_i(error)
output_d = output_d(error)
@t_prev = t_now
@output_p_prev = output_p
@output_i_prev = output_i
output = (kp * output_p + ki * output_i + kd * output_d)
output.clamp(output_min, output_max)
end
end
alias_method :<<, :control
private
attr_reader :t_now
def delta_t
t_now - t_prev
end
def output_p(error)
error
end
def output_i(error)
i_term = output_i_prev + (error * delta_t.to_f)
i_term.clamp(output_min, output_max)
end
def output_d(error)
(error - output_p_prev) / delta_t.to_f
end
def error(process_variable)
setpoint - process_variable
end
end
@rringler
Copy link
Author

Usage:

pid = PID.new(setpoint: setpoint_value)
pid << current_value       # => input_value
pid << new_current_value   # => new_input_value
pid << newer_current_value # => newer_input_value

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment