///| 工业闭环控制算法:PID 控制器功能块 (PID Controller)
///|
/// 工业 PID 控制器结构
pub(all) struct PidController {
// 调节参数
mut kp : Double // 比例增益 (Proportional Gain)
mut ti_ms : Double // 积分时间 (Integral Time Constant in ms)
mut td_ms : Double // 微分时间 (Derivative Time Constant in ms)
mut out_min : Double // 控制量下限限幅
mut out_max : Double // 控制量上限限幅
mut deadband : Double // 误差死区
// 状态变量
mut integral_acc : Double // 积分累加量
mut prev_pv : Double // 上周期被控量 (用于微分先行)
mut prev_error : Double // 上周期误差
mut manual : Bool // 手/自动模式切换 (true=手动, false=自动)
mut manual_val : Double // 手动开度给定
// 输出
mut output : Double // 当前计算控制输出 (MV - Manipulated Variable)
} derive(Debug)
///|
/// 创建默认工业 PID 控制器
pub fn PidController::new(
kp : Double,
ti_ms : Double,
td_ms : Double,
) -> PidController {
{
kp,
ti_ms,
td_ms,
out_min: 0.0,
out_max: 100.0, // 默认 0% ~ 100% 阀门开度
deadband: 0.0,
integral_acc: 0.0,
prev_pv: 0.0,
prev_error: 0.0,
manual: false,
manual_val: 0.0,
output: 0.0,
}
}
///|
/// 设置输出限幅区间
pub fn PidController::set_limits(
self : PidController,
min_val : Double,
max_val : Double,
) -> Unit {
self.out_min = min_val
self.out_max = max_val
}
///|
/// 设置误差死区
pub fn PidController::set_deadband(self : PidController, db : Double) -> Unit {
self.deadband = db
}
///|
/// 手动/自动模式无扰切换 (Bumpless Transfer)
pub fn PidController::set_manual(
self : PidController,
manual_mode : Bool,
man_val : Double,
) -> Unit {
self.manual = manual_mode
self.manual_val = man_val
if self.manual {
// 手动模式下,反向跟踪积分器以确保切回自动时无扰动
self.integral_acc = man_val
self.output = man_val
}
}
///|
/// PID 周期执行计算 (按采样周期 dt 毫秒计算输出)
pub fn PidController::compute(
self : PidController,
sp : Double,
pv : Double,
dt_ms : Double,
) -> Double {
if self.manual {
self.output = self.manual_val
return self.output
}
let dt = if dt_ms <= 0.0 { 1.0 } else { dt_ms }
let mut error = sp - pv
// 1. 死区滤波
if self.deadband > 0.0 {
let abs_err = if error < 0.0 { -error } else { error }
if abs_err < self.deadband {
error = 0.0
}
}
// 2. 比例项 (P)
let p_term = self.kp * error
// 3. 积分项 (I) 带抗积分饱和 (Anti-Windup)
if self.ti_ms > 0.0 {
let delta_i = self.kp * (dt / self.ti_ms) * error
// 只有在输出未饱和或反向纠偏时才累加积分
let next_i = self.integral_acc + delta_i
if next_i >= self.out_min && next_i <= self.out_max {
self.integral_acc = next_i
}
}
// 4. 微分项 (D) 采用微分先行 (Derivative on PV),防止给定值 SP 阶跃产生突变冲击
let mut d_term = 0.0
if self.td_ms > 0.0 {
let delta_pv = pv - self.prev_pv
d_term = -self.kp * (self.td_ms / dt) * delta_pv
}
// 5. PID 输出合成
let raw_output = p_term + self.integral_acc + d_term
// 6. 输出限幅与状态更新
let clamped = if raw_output > self.out_max {
self.out_max
} else if raw_output < self.out_min {
self.out_min
} else {
raw_output
}
self.prev_pv = pv
self.prev_error = error
self.output = clamped
self.output
}