Skip to content

Commit 9375711

Browse files
committed
added tests and small improvements
1 parent cf8a4dc commit 9375711

File tree

5 files changed

+74
-23
lines changed

5 files changed

+74
-23
lines changed

examples/Examples.ipynb

+25-21
Large diffs are not rendered by default.

pyproject.toml

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ classifiers = [
1616
"Programming Language :: Python"
1717
]
1818

19+
[tool.pytest.ini_options]
20+
pythonpath = ["."]
1921

2022
# [project.urls]
2123
# Homepage = "https://example.com"

tests/test_pid.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import unittest
2+
from tinypid import PID
3+
4+
class TestPID(unittest.TestCase):
5+
def test_output_with_no_manual_output(self):
6+
pid = PID(K_p=1.0, K_i=0.5, K_d=0.2, setpoint=10.0, dt=0.1)
7+
process_variable = 8.0
8+
expected_output = 6.1 # P = 1.0 * (10.0 - 8.0) = 2.0, I = 0.5 * (10.0 - 8.0) * 0.1 = 0.1, D = 0.2 * ((10.0 - 8.0) / 0.1) = 4
9+
output = pid(process_variable)
10+
self.assertAlmostEqual(output, expected_output)
11+
12+
def test_output_with_manual_output(self):
13+
pid = PID(K_p=1.0, K_i=0.5, K_d=0.2, setpoint=10.0, dt=0.1)
14+
process_variable = 8.0
15+
manual_output = 5.0
16+
expected_output = manual_output # Since manual_output is provided, the output should be equal to it
17+
output = pid(process_variable, manual_output=manual_output)
18+
self.assertAlmostEqual(output, expected_output)
19+
20+
def test_output_with_anti_windup_disabled(self):
21+
pid = PID(K_p=1.0, K_i=0.5, K_d=0.2, setpoint=10.0, dt=0.1)
22+
process_variable = 8.0
23+
manual_output = 15.0
24+
expected_output = manual_output # Since manual_output is provided, the output should be equal to it
25+
output = pid(process_variable, manual_output=manual_output, anti_windup=False)
26+
self.assertAlmostEqual(output, expected_output)
27+
28+
if __name__ == '__main__':
29+
unittest.main()

tinypid/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .pid import PID

tinypid/pid.py

+17-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
A minimal PID controller.
44
55
Example usage:
6-
from tinypid import pid
6+
import tinypid
77
8-
controller = pid.PID()
8+
controller = tinypid.PID()
99
1010
output = controller(10)
1111
@@ -48,6 +48,8 @@ def __init__(
4848
"""
4949
if dt <= 0:
5050
raise ValueError("Time step (dt) must be positive.")
51+
if not 0 <= derivative_lowpass <= 1:
52+
raise ValueError("derivative_lowpass must be between 0 and 1")
5153

5254
self.K_p = K_p
5355
self.K_i = K_i
@@ -106,6 +108,19 @@ def limit(self, output: float) -> Tuple[bool, float]:
106108
saturated = output != unlimited
107109

108110
return saturated, output
111+
112+
def update_gains(self, K_p: float, K_i: float, K_d: float) -> None:
113+
"""
114+
Update the PID gains.
115+
116+
Parameters:
117+
K_p : The new proportional gain
118+
K_i : The new integral gain
119+
K_d : The new derivative gain
120+
"""
121+
self.K_p = K_p
122+
self.K_i = K_i
123+
self.K_d = K_d
109124

110125
def __call__(
111126
self, process_variable: float, manual_output: Optional[float] = None, anti_windup: bool = True

0 commit comments

Comments
 (0)