Skip to main content

pidgeon/
lib.rs

1// Pidgeon: A robust PID controller library written in Rust
2// Copyright (c) 2025 Security Union LLC
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10//! High-performance PID controller with `no_std` support, IIR-filtered derivative,
11//! configurable anti-windup, and optional thread safety.
12//!
13//! # Architecture
14//!
15//! The library is split into two layers:
16//!
17//! - **Pure function**: [`pid_compute`] takes a [`ControllerConfig`] and [`PidState`],
18//!   returns a control output and updated state. Works in `no_std` environments.
19//! - **Stateful controllers** (requires `std`): [`PidController`] and
20//!   [`ThreadSafePidController`] wrap the pure function with automatic state
21//!   management and performance statistics.
22//!
23//! # Quick start
24//!
25//! ```
26//! use pidgeon::{ControllerConfig, PidState, pid_compute};
27//!
28//! // 1. Build a validated config
29//! let config = ControllerConfig::builder()
30//!     .with_kp(2.0)
31//!     .with_ki(0.5)
32//!     .with_kd(0.1)
33//!     .with_setpoint(100.0)
34//!     .with_output_limits(0.0, 255.0)
35//!     .build()
36//!     .unwrap();
37//!
38//! // 2. Start with default state
39//! let mut state = PidState::default();
40//!
41//! // 3. Run the control loop
42//! let dt = 0.01; // 10 ms
43//! for _ in 0..100 {
44//!     let process_value = 80.0; // read from sensor
45//!     let (output, next_state) = pid_compute(&config, &state, process_value, dt).unwrap();
46//!     state = next_state;
47//!     // apply `output` to actuator
48//! }
49//! ```
50//!
51//! # Feature flags
52//!
53//! | Feature      | Default | Effect |
54//! |--------------|---------|--------|
55//! | `std`        | yes     | Enables [`PidController`], [`ThreadSafePidController`], and `Error` impl |
56//! | `debugging`  | no      | Streams PID telemetry via Iggy.rs (implies `std`) |
57//! | `benchmarks` | no      | Enables criterion benchmarks (implies `std`) |
58//! | `wasm`       | no      | Swaps `std::time` for `web_time` (implies `std`) |
59
60#![cfg_attr(not(feature = "std"), no_std)]
61
62mod compute;
63mod config;
64mod enums;
65mod error;
66mod state;
67
68#[cfg(feature = "std")]
69mod controller;
70
71#[cfg(feature = "std")]
72mod thread_safe;
73
74#[cfg(feature = "debugging")]
75mod debug;
76
77pub use compute::pid_compute;
78pub use config::{ControllerConfig, ControllerConfigBuilder};
79pub use enums::{AntiWindupMode, DerivativeMode};
80pub use error::PidError;
81pub use state::PidState;
82
83#[cfg(feature = "std")]
84pub use controller::{ControllerStatistics, PidController};
85
86#[cfg(feature = "std")]
87pub use thread_safe::ThreadSafePidController;
88
89#[cfg(feature = "debugging")]
90pub use debug::{ControllerDebugger, DebugConfig};
91
92#[cfg(test)]
93mod tests;