Skip to content

Commit cf8a4dc

Browse files
committed
small bugfix and examples added
1 parent 6781849 commit cf8a4dc

File tree

3 files changed

+204
-8
lines changed

3 files changed

+204
-8
lines changed

examples/Examples.ipynb

+156
Large diffs are not rendered by default.

pyproject.toml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[project]
2+
name = "tinypid"
3+
version = "0.1"
4+
5+
requires-python = ">=3.8"
6+
authors = [
7+
{name = "Alexander Steppke", email = "[email protected]"},
8+
]
9+
10+
description = "Tiny PID controller"
11+
readme = "README.md"
12+
license = {file = "LICENSE.txt"}
13+
# keywords = ["egg", "bacon", "sausage", "tomatoes", "Lobster Thermidor"]
14+
15+
classifiers = [
16+
"Programming Language :: Python"
17+
]
18+
19+
20+
# [project.urls]
21+
# Homepage = "https://example.com"
22+
# Documentation = "https://readthedocs.org"
23+
# Repository = "https://github.com/me/spam.git"
24+
# "Bug Tracker" = "https://github.com/me/spam/issues"
25+
# Changelog = "https://github.com/me/spam/blob/master/CHANGELOG.md"
26+

tinypid/pid.py

+22-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
"""PID controller
2+
3+
A minimal PID controller.
4+
5+
Example usage:
6+
from tinypid import pid
7+
8+
controller = pid.PID()
9+
10+
output = controller(10)
11+
12+
"""
113
from typing import Optional, Tuple
214

315

@@ -95,7 +107,9 @@ def limit(self, output: float) -> Tuple[bool, float]:
95107

96108
return saturated, output
97109

98-
def __call__(self, process_variable : float, manual_output: Optional[float] = None, anti_windup: bool = True) -> float:
110+
def __call__(
111+
self, process_variable: float, manual_output: Optional[float] = None, anti_windup: bool = True
112+
) -> float:
99113
"""
100114
Process the input signal and return the controller output.
101115
@@ -110,9 +124,7 @@ def __call__(self, process_variable : float, manual_output: Optional[float] = No
110124

111125
self.P = self.K_p * error
112126
self.I = self.K_i * self.integral
113-
self.D = self.K_d * (
114-
self.alpha * derivative + (1 - self.alpha) * self._previous_derivative
115-
)
127+
self.D = self.K_d * (self.alpha * derivative + (1 - self.alpha) * self._previous_derivative)
116128

117129
output = self.P + self.I + self.D
118130

@@ -127,12 +139,14 @@ def __call__(self, process_variable : float, manual_output: Optional[float] = No
127139

128140
if manual_output:
129141
# Use setpoint tracking by calculating integral so that the output matches the manual setpoint
130-
self.integral = -(self.P + self.D - manual_output) / self.K_i
142+
self.integral = -(self.P + self.D - manual_output) / self.K_i if self.K_i != 0 else 0
131143
output = manual_output
132144

133145
return output
134146

135147
def __repr__(self):
136-
return (f"PID controller\nSetpoint: {self.setpoint}, Output: {self.P + self.I + self.D}\n"
137-
f"P: {self.P}, I: {self.I}, D: {self.D}\n"\
138-
f"Limits: {self.lower_limit} < output < {self.upper_limit}")
148+
return (
149+
f"PID controller\nSetpoint: {self.setpoint}, Output: {self.P + self.I + self.D}\n"
150+
f"P: {self.P}, I: {self.I}, D: {self.D}\n"
151+
f"Limits: {self.lower_limit} < output < {self.upper_limit}"
152+
)

0 commit comments

Comments
 (0)