Discrete PID Controller in Rust
A PID controller for robotics and discrete control systems in rust.
| Step Response | Quadrotor Rate Control |
|---|---|
![]() |
![]() |
Why This PID?
-
Principled and Reliable
- Inspired by Brett Beauregard's battle-tested and well documented[^1] PID for Arduino
- Verified in an extensive test suite, including numerical verification against Simulink’s Discrete PID Controller --- this controller has the same behavior you remember from your first controls course
- Supports functionally pure (stateless) PID computation, enabling perfectly reproducible control outputs and easy thread-safety
-
Real-World Ready
- Explicitly designed for discrete-time control --- supports variable sample time and tunable LPF on derivative.
- Supports fine-grained control over PID activity: online (de)activation, (re)initialization, and pausing/resuming integration
- As an alternative to the functional PID controller, the stateful PID controller is competitive with the naive PID law in terms of speed
-
Lightweight and Dependency-Free
- Usage in
#![no_std]mode only requires core float traits fromnum_traits
- Usage in
Application Example
One of the most notable achievements of PID controllers in recent years has been the stabilization and control of quadrotors. We demonstrate just that using our PID controller in an example.

Run the example:
Visualize the results:
In this example, we used our PID controller to track quadrotor body rates computed by an upstream geometric tracking controller. The README for the examples contains more details about the cascaded controller and the quadrotor simulation.
Quick Start
use Duration;
use ;
let loop_time = from_micros;
let cfg = default
.kp
.ki
.sample_time
.filter_tc
.build
.expect;
let controller = new;
let mut ctx = new_uninit;
let pos_meas = 0.5;
let pos_setpoint = 1.0;
let timestamp = Micros;
let vel_setpoint = 2.0;
let =
controller.compute;
Shoutouts
-
pid-rs: well-known and effective; You may consider using their crate instead if you:-
Are working with simple, slow-acting processes that don't benefit from sample time handling and D-term filtering
-
Need to use integer process values/setpoints
-
Need to apply clamping on P, I, and D terms separately
-
[!WARNING]
We doubt the usefulness of per-term clamping since it breaks linear superposition of the terms, generating subtle nonlinearities and potentially disrupting tuning techniques
-
pidgeon: Strong support for synchronization and built-in visualization; You may consider using their crate instead if you:- Need support for concurrent PID control and don't mind depending on
stdthroughstd::sync::Mutex
- Need support for concurrent PID control and don't mind depending on
Documentation and Links
📦 View on crates.io
📚 API Docs on docs.rs
License
This project is licensed under the MIT License © 2025 Hs293Go
[^1]: Beauregard, B. Improving the Beginner's PID. http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/

