so2nostd
Second-Order no_std Controller for Embedded Systems
so2nostd is a lightweight, high-performance no_std Rust crate implementing a discrete-time second-order (SO2) control system. Designed for embedded environments like MCUs (e.g., RP2040), it provides stable, physics-based dynamics using Euler integration.
Update Version 0.2.0
#![forbid(unsafe_code)] for safety and opt-level = 3 for speed
GPL-2.0-or-later licensed to ensure community protection against privatization. Optimized for minimal footprint and maximal reliability.
Table of Contents
π Features
- β
Pure
no_std: Zero standard library dependencies, perfect for bare-metal/RTOS. - β‘ Flexible Floating-Point:
f64(default) orf32feature for memory-constrained devices. - π§ Size-Optimized: Compatible with
opt-level="z", LTO, andstrip = true. - π‘οΈ Numerical Safety: Handles
dt <= 0, NaN/Inf, and prevents divergence. - π Physics-Based SO2: Models natural frequency (
Ο_n), damping ratio (ΞΆ), and static gain. - π― Setpoint Tracking: Smooth convergence toward
setpoint. - βοΈ Optional Safety Limits:
max_velocityandmax_accelerationfor embedded safety constraints.
π οΈ Installation
Add to your Cargo.toml:
[]
= "0.2.0"
e.g., Cortex-M):
= {="0.2.0", = ["f32"] }
π Quickstart
````rust
So2Controller;
{
// Ο_n=10 rad/s, ΞΆ=0.7 (underdamped), initial=0.0, gain=1.0
= So2Controller::new(10.0, 0.7, 0.0, 1.0);
// Desired setpoint
// Optional velocity limit
// Optional acceleration limit
= 0.01; // 10ms timestep
// Run controller update loop
100 {
= controller.update(0.0, dt);
// output smoothly approaches setpoint following SO2 dynamics
}
}
π API Reference
| Method | Signature | Description |
|---|---|---|
new |
So2Controller::new(w_n: Float, zeta: Float, initial_value: Float, gain: Float) -> Self |
Creates a new controller instance. |
update |
&mut self.update(input: Float, dt: Float) -> Float |
Updates system state toward setpoint. Safe for dt <= 0. |
set_target |
&mut self.set_target(target: Float) |
Updates the internal setpoint. |
reset |
&mut self.reset(value: Float) |
Resets states (y, y_prev, setpoint) to value. |
set_max_velocity |
&mut self.set_max_velocity(max_v: Float) |
Optional: clamps max velocity. |
set_max_acceleration |
&mut self.set_max_acceleration(max_a: Float) |
Optional: clamps max acceleration. |
Type: Float = f64 (default) or f32 with feature flag.
Public fields: w_n, zeta, setpoint, gain (inspectable/tunable).
β‘ Performance & Optimization Binary Size: Minimal, optimized with opt-level="z", LTO, strip = true. CPU Cost: Constant time O(1) per update. Memory: Stack-only, zero allocation. Ideal for 100β10kHz control loops on MCUs. π§ͺ Testing
Includes tests for:
Step response stability and convergence. Zero/negative dt handling. Setpoint tracking and safety limit enforcement.
Run:
cargo test -- --nocapture
βοΈ License
GPL-2.0-or-later Β© 2026 Jorge Andre Castro.
Free to use, modify, and distribute. Any derivative works must also be GPL-2.0-or-later.