Registry / simple-pid

simple-pid

JSON →
library2.0.1pypypi✓ verified 22d ago

simple-pid is a Python library that provides a simple and easy-to-use PID controller. It is designed to be robust and operate without external dependencies, making it suitable for various control system applications. The library is actively maintained, with the current version being 2.0.1, and new major versions released approximately every 2-3 years, supplemented by minor and patch releases as needed.

pip install simple-pid
INSTALL
IMPORT
SIG · SIMPLE-PID
S
simple-pid
pythonv2.0.1
Install
1.5s avg
Import
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v2.0.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.000s · 17.8MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.5s · import 0.000s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

PID
from simple_pid import PID

This quickstart demonstrates the basic usage of `simple-pid`. It initializes a `PID` controller with proportional, integral, and derivative gains, and a target setpoint. The controller is then used within a loop to regulate a simulated system, updating its control output periodically based on the system's current value. Key parameters like `sample_time` and `output_limits` are configured for robust operation.

import time from simple_pid import PID # A dummy controlled system for demonstration class ControlledSystem: def __init__(self, initial_value=0.0): self.value = initial_value self.time_step = 0.1 def update(self, control_input): # Simulate system response, e.g., a simple first-order system self.value += (control_input - self.value) * (self.time_step * 0.5) return self.value # Initialize PID controller: Kp, Ki, Kd, setpoint # Here, a setpoint of 10 is desired. pid = PID(2.0, 0.5, 0.2, setpoint=10.0) # Configure PID parameters pid.sample_time = 0.1 # Update every 0.1 seconds pid.output_limits = (-10, 10) # Limit output to avoid integral windup # Initialize the controlled system system = ControlledSystem(initial_value=0.0) print(f"Initial system value: {system.value:.2f}") # Run the control loop for a few iterations for i in range(100): # Compute new output from the PID according to the system's current value control_output = pid(system.value) # Feed the PID output to the system and get its current value system_value = system.update(control_output) # Optional: Print current state if i % 10 == 0: print(f"Iteration {i}: Setpoint={pid.setpoint:.2f}, System Value={system_value:.2f}, Control Output={control_output:.2f}") time.sleep(pid.sample_time) print(f"Final system value: {system.value:.2f}") # Expected output will show the system value approaching 10.0
Debug
Known issues
breakingOfficial support for Python 2 was dropped in version 2.0.0. While the code might still function, it is no longer tested against Python 2 environments, and no guarantees are provided for its compatibility or future functionality.
fix
Upgrade to Python 3.6 or newer to ensure full compatibility and support.
affects: >=2.0.0
gotchaIntegral windup is a common issue in PID controllers where the integral term accumulates error even when the controller output is saturated. simple-pid mitigates this by automatically clamping the integral term when `output_limits` are set. Failing to set appropriate `output_limits` can lead to this problem and unstable control.
fix
Always set meaningful `pid.output_limits = (lower, upper)` to prevent integral windup. The library uses these limits to constrain both the output and the integral term.
affects: <2.0.1
gotchaThe derivative term can cause a 'derivative kick' (a sharp output spike) on sudden setpoint changes if calculated on the error. By default, `simple-pid` calculates the derivative on the measurement (`differential_on_measurement=True`) to avoid this. If classic derivative-on-error behavior is desired, explicitly set `differential_on_measurement=False` during initialization.
fix
Understand the `differential_on_measurement` parameter (defaulting to `True` since v2.0.0) and adjust it based on your system's requirements to prevent derivative kick.
affects: All
gotchaThe accuracy of time-based calculations (integral and derivative terms) depends on reliable time measurements. `simple-pid` defaults to `time.monotonic()`, but if you override `PID.time_fn` or manually set `dt` (especially if `sample_time` is `None`), ensure your custom time source provides consistent and monotonic time to avoid calculation errors.
fix
If providing a custom `time_fn`, ensure it is monotonic. If `sample_time` is `None` and you're manually managing `dt`, ensure `dt` reflects the actual time elapsed between calls.
affects: All
gotchaWhen switching a system from manual control to PID auto mode, or starting PID on a system already at its setpoint, the PID might initially output zero (causing a 'bump') as its internal state is zero. Version 2.0.0 introduced `starting_output` for a smoother transition, and `auto_mode=True` can take a `last_output` value.
fix
For new PID instances or when enabling auto mode, provide a `starting_output` value to the constructor (v2.0.0+) or pass the system's `last_output` value when calling `pid.auto_mode = True` to provide a 'bumpless' transfer.
affects: All
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'simple-pid'
The user is attempting to import the library using the package name 'simple-pid' (with a hyphen) instead of the correct module name 'simple_pid' (with an underscore).
fix
from simple_pid import PID
TypeError: PID.__init__() missing 3 required positional arguments: 'Kp', 'Ki', and 'Kd'
The PID controller constructor requires at least the proportional (Kp), integral (Ki), and derivative (Kd) gains as arguments during initialization.
fix
pid = PID(1.0, 0.1, 0.05, setpoint=50)
TypeError: PID.compute() missing 1 required positional argument: 'input'
The `compute` method of the PID controller requires the current process variable (`input`) as its first argument, which was not provided.
fix
output = pid.compute(current_value)
AttributeError: module 'simple_pid' has no attribute 'PID'
The user is attempting to access the `PID` class as an attribute of the `simple_pid` module, but it needs to be explicitly imported from the module.
fix
from simple_pid import PID
Upgrade
Version history
2.0.1latest on PyPI · released Jul 21, 2024
Audit
Dependencies
pythonrequiredRequires Python 3.6 or higher for compatibility.
Agent activity
9 hits · last 30 days
node
6
Resources