Skip to content

Commit

Permalink
Added ability to see the contributions of the separate terms in the PID
Browse files Browse the repository at this point in the history
  • Loading branch information
m-lundberg committed Jan 30, 2019
1 parent b376820 commit 67b5e9e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
15 changes: 13 additions & 2 deletions simple_pid/PID.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ def __init__(self,
self._auto_mode = auto_mode
self.proportional_on_measurement = proportional_on_measurement

self._proportional = 0
self._error_sum = 0
self._derivative = 0

self._last_time = _current_time()
self._last_output = None
self._proportional = 0
self._last_input = None

def __call__(self, input_):
Expand All @@ -87,6 +88,7 @@ def __call__(self, input_):
error = self.setpoint - input_
self._error_sum += self.Ki * error * dt
d_input = input_ - (self._last_input if self._last_input is not None else input_)
self._derivative = -self.Kd * d_input / dt

# compute the proportional term
if not self.proportional_on_measurement:
Expand All @@ -101,7 +103,7 @@ def __call__(self, input_):
self._error_sum = _clamp(self._error_sum, self.output_limits)

# compute final output
output = self._proportional + self._error_sum - self.Kd * d_input / dt
output = self._proportional + self._error_sum + self._derivative
output = _clamp(output, self.output_limits)

# keep track of state
Expand All @@ -111,6 +113,15 @@ def __call__(self, input_):

return output

@property
def components(self):
"""
The P-, I- and D-terms from the last computation as separate components as a tuple. Useful for visualizing
what the controller is doing or when tuning hard-to-tune systems.
Note: when using *proportional_on_measurement*, the proportional error will be baked into the I-term.
"""
return self._proportional, self._error_sum, self._derivative

@property
def tunings(self):
"""The tunings used by the controller as a tuple: (Kp, Ki, Kd)"""
Expand Down
11 changes: 11 additions & 0 deletions tests/test_pid.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ def test_auto_mode():
assert pid(8) == 2


def test_separate_components():
pid = PID(1, 0, 1, setpoint=10, sample_time=0.1)

assert pid(0) == 10
assert pid.components == (10, 0, 0)
time.sleep(0.1)

assert round(pid(5)) == -45
assert tuple(round(term) for term in pid.components) == (5, 0, -50)


def test_clamp():
from simple_pid.PID import _clamp

Expand Down

0 comments on commit 67b5e9e

Please sign in to comment.