Skip to content

Commit d4f55f5

Browse files
Fix inaccuracy in comparison of elapsed time (dt)
The inaccuracy is small, but it becomes visible when operating within tight margins of the `sample_time`, like for example, when working with a simulated clock in a test environment. Specifically, `dt` cannot be exactly zero because it is used as a divider. When it would be zero, it is set to a very small, conventional value instead, that I've renamed MIN_DT for clarity. When `dt == MIN_DT` it is really representing the case when it would be zero. Not taking that value into consideration when comparing the elapsed time since last computation does effectively increase `sample_time` by `MIN_DT`. It is not a lot, but it is not accurate either. By correcting the comparison, very precise use of `sample_time` becomes possible. One concrete use case is using simulated time for testing.
1 parent 6f92a88 commit d4f55f5

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

simple_pid/pid.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ def _clamp(value, limits):
1212
class PID(object):
1313
"""A simple PID controller."""
1414

15+
MIN_DT = 1e-16
16+
1517
def __init__(
1618
self,
1719
Kp=1.0,
@@ -114,11 +116,15 @@ def __call__(self, input_, dt=None):
114116

115117
now = self.time_fn()
116118
if dt is None:
117-
dt = now - self._last_time if (now - self._last_time) else 1e-16
119+
dt = now - self._last_time if (now - self._last_time) else PID.MIN_DT
118120
elif dt <= 0:
119121
raise ValueError('dt has negative value {}, must be positive'.format(dt))
120122

121-
if self.sample_time is not None and dt < self.sample_time and self._last_output is not None:
123+
if (
124+
self.sample_time is not None
125+
and dt < self.sample_time - PID.MIN_DT
126+
and self._last_output is not None
127+
):
122128
# Only update every sample_time seconds
123129
return self._last_output
124130

0 commit comments

Comments
 (0)