Utilities Package
The utilities package provides essential control design utilities, mathematical tools, and data processing functions for process control applications.
Note
This is part of the modern modular structure of SPROCLIB.
Submodules
Control Utils
Control Utilities for SPROCLIB
This module provides utility functions specifically for control system design, tuning, and performance evaluation.
Author: Thorsten Gressling <gressling@paramus.ai> License: MIT License
- sproclib.utilities.control_utils.tune_pid(model_params, method='ziegler_nichols', controller_type='PID')[source]
Automatic PID tuning using empirical rules.
- sproclib.utilities.control_utils.simulate_process(model, t_span, x0, u_profile, method='RK45', max_step=None)[source]
Simulate a process model with given input profile.
- Parameters:
- Returns:
Dictionary with simulation results
- Return type:
- sproclib.utilities.control_utils.calculate_ise(t, error)[source]
Calculate Integral of Squared Error (ISE).
- Parameters:
t (<MagicMock id='130137680248320'>) – Time array
error (<MagicMock id='130137678825856'>) – Error signal array
- Returns:
ISE value
- Return type:
- sproclib.utilities.control_utils.calculate_iae(t, error)[source]
Calculate Integral of Absolute Error (IAE).
- Parameters:
t (<MagicMock id='130137678826192'>) – Time array
error (<MagicMock id='130137676745088'>) – Error signal array
- Returns:
IAE value
- Return type:
- sproclib.utilities.control_utils.calculate_itae(t, error)[source]
Calculate Integral of Time-weighted Absolute Error (ITAE).
- Parameters:
t (<MagicMock id='130137676744752'>) – Time array
error (<MagicMock id='130137676744416'>) – Error signal array
- Returns:
ITAE value
- Return type:
- sproclib.utilities.control_utils.design_lead_lag(zero, pole, gain=1.0)[source]
Design lead-lag compensator transfer function.
- sproclib.utilities.control_utils.root_locus_design(plant_num, plant_den, desired_poles)[source]
Design controller using root locus method.
- Parameters:
- Returns:
Dictionary with controller design results
- Return type:
- sproclib.utilities.control_utils.frequency_domain_design(plant_num, plant_den, gain_margin_db=6.0, phase_margin_deg=45.0)[source]
Design controller using frequency domain specifications.
- Parameters:
- Returns:
Dictionary with controller design results
- Return type:
- sproclib.utilities.control_utils.step_response_test(data, step_time=None)[source]
Analyze step response test data.
- sproclib.utilities.control_utils.linearize(model_func, x_ss, u_ss, epsilon=1e-06)[source]
Linearize a nonlinear model around an operating point.
- Parameters:
- Returns:
A, B matrices for linear model dx/dt = A*x + B*u
- Return type:
Tuple[<MagicMock id=’130137676749792’>, <MagicMock id=’130137676750128’>]
- sproclib.utilities.control_utils.disturbance_rejection(plant_tf, controller_tf, disturbance_type='step', w=None)[source]
Analyze disturbance rejection performance.
- Parameters:
plant_tf (Tuple[<MagicMock id='130137676751808'>, <MagicMock id='130137676752144'>]) – Plant transfer function (num, den)
controller_tf (Tuple[<MagicMock id='130137676753824'>, <MagicMock id='130137676754160'>]) – Controller transfer function (num, den)
disturbance_type (str) – Type of disturbance (‘step’, ‘ramp’, ‘frequency’)
w (<MagicMock id='130137676755840'> | None) – Frequency vector for analysis
- Returns:
Dictionary with disturbance rejection analysis
- Return type:
- sproclib.utilities.control_utils.model_predictive_control(A, B, Q, R, prediction_horizon=10, control_horizon=None)[source]
Basic Model Predictive Control formulation.
- Parameters:
A (<MagicMock id='130137676756848'>) – State-space matrices
B (<MagicMock id='130137676757184'>) – State-space matrices
Q (<MagicMock id='130137676757520'>) – State and input weighting matrices
R (<MagicMock id='130137676757856'>) – State and input weighting matrices
prediction_horizon (int) – Prediction horizon N
control_horizon (int | None) – Control horizon M (default: same as prediction horizon)
- Returns:
Dictionary with MPC formulation matrices
- Return type:
Math Utils
Math Utilities for SPROCLIB
This module provides mathematical utility functions for process control including signal processing, numerical methods, and mathematical operations.
Author: Thorsten Gressling <gressling@paramus.ai> License: MIT License
- sproclib.utilities.math_utils.step_response(system, t=None, t_final=10.0, input_magnitude=1.0)[source]
Calculate step response of a system.
- Parameters:
- Returns:
Dictionary with ‘t’ and ‘y’ arrays
- Return type:
- sproclib.utilities.math_utils.bode_plot(system, w=None, plot=True, title='Bode Plot')[source]
Generate Bode plot for frequency response analysis.
- Parameters:
- Returns:
Dictionary with frequency, magnitude, and phase data
- Return type:
- sproclib.utilities.math_utils.linearize(model_func, x_ss, u_ss, epsilon=1e-06)[source]
Linearize a nonlinear model around an operating point.
- Parameters:
model_func – Function f(x, u) returning dx/dt
x_ss (<MagicMock id='130137679722352'>) – Steady-state states
u_ss (<MagicMock id='130137679722016'>) – Steady-state inputs
epsilon (float) – Perturbation size for finite differences
- Returns:
A, B matrices for linear model dx/dt = A*x + B*u
- Return type:
Tuple[<MagicMock id=’130137679721680’>, <MagicMock id=’130137679721344’>]
- sproclib.utilities.math_utils.stability_check(A)[source]
Check if a linear system is stable.
- Parameters:
A (<MagicMock id='130137678220656'>) – State matrix
- Returns:
True if stable, False otherwise
- Return type:
- sproclib.utilities.math_utils.frequency_response(num, den, w)[source]
Calculate frequency response.
- Parameters:
num (<MagicMock id='130137678221328'>) – Numerator coefficients
den (<MagicMock id='130137678221664'>) – Denominator coefficients
w (<MagicMock id='130137678222000'>) – Frequency vector
- Returns:
Magnitude and phase arrays
- Return type:
Tuple[<MagicMock id=’130137678222336’>, <MagicMock id=’130137678222672’>]
Data Utils
Data Utilities for SPROCLIB
This module provides data processing utilities for process control including filtering, resampling, and data analysis functions.
Author: Thorsten Gressling <gressling@paramus.ai> License: MIT License
- sproclib.utilities.data_utils.filter_data(data, filter_type='lowpass', cutoff=0.1, order=2, method='butterworth')[source]
Filter time series data.
- Parameters:
- Returns:
Filtered data array
- Return type:
<MagicMock id=’130137678227040’>
- sproclib.utilities.data_utils.resample_data(t, data, new_dt, method='linear')[source]
Resample time series data.
- Parameters:
- Returns:
New time array and resampled data
- Return type:
Tuple[<MagicMock id=’130137678228048’>, <MagicMock id=’130137678228384’>]
- sproclib.utilities.data_utils.detect_outliers(data, method='iqr', threshold=1.5)[source]
Detect outliers in data.
- sproclib.utilities.data_utils.smooth_data(data, window_size=5, method='moving_average')[source]
Smooth data using various methods.
- sproclib.utilities.data_utils.calculate_statistics(data)[source]
Calculate basic statistics for data.
Quick Usage
PID Controller Tuning:
from utilities.control_utils import tune_pid
# Define process model parameters
model_params = {
'K': 2.0, # Process gain
'tau': 5.0, # Time constant
'theta': 1.0 # Dead time
}
# Auto-tune PID controller
pid_params = tune_pid(
model_params,
method='ziegler_nichols',
controller_type='PID'
)
print(f"Kp = {pid_params['Kp']:.3f}")
print(f"Ki = {pid_params['Ki']:.3f}")
print(f"Kd = {pid_params['Kd']:.3f}")
Process Linearization:
from utilities.control_utils import linearize
import numpy as np
# Define nonlinear model
def reactor_model(x, u):
T, Ca = x
Tc = u[0]
# Reactor dynamics
dT_dt = 0.1 * (Tc - T) + 0.5 * Ca
dCa_dt = -0.2 * Ca * np.exp(-1000/T)
return np.array([dT_dt, dCa_dt])
# Linearize around operating point
x_ss = np.array([350, 2.0]) # Temperature, Concentration
u_ss = np.array([340]) # Coolant temperature
A, B = linearize(reactor_model, x_ss, u_ss)
print("State matrix A:")
print(A)
print("Input matrix B:")
print(B)
Mathematical Utilities:
from utilities.math_utils import numerical_derivative, integrate_ode
# Numerical differentiation
def f(x):
return x**3 + 2*x**2 - 5*x + 1
df_dx = numerical_derivative(f, x=2.0, method='central')
print(f"df/dx at x=2: {df_dx}")
Data Processing:
from utilities.data_utils import filter_data, resample_data
import numpy as np
# Generate noisy data
t = np.linspace(0, 10, 1000)
signal = np.sin(t) + 0.1 * np.random.randn(len(t))
# Filter data
filtered = filter_data(signal, filter_type='lowpass', cutoff=0.1)
# Resample data
t_new, signal_new = resample_data(t, filtered, new_rate=0.1)