package com.mh.quartz.util; import com.mh.quartz.domain.FuzzyLevel; /** * @author LJF * @version 1.0 * @project EEMCS * @description 风柜系统PID调节工具类 * @date 2025-05-30 13:47:40 */ public class AHUPIDControlUtil { private double kp = 2.0, ki = 0.1, kd = 0.0; private double integral = 0; private double previousError = 0; private static final double MAX_INTEGRAL = 100; private static final double MIN_INTEGRAL = -100; // 模糊增益修正比例 private double deltaKpScale = 0.5; private double deltaKiScale = 0.01; private double deltaKdScale = 0.01; public double compute(double setTemp, double currentTemp, double deltaTime) { double error = currentTemp - setTemp; double dError = (error - previousError) / deltaTime; // 模糊映射 FuzzyLevel eLevel = toFuzzyLevel(error); FuzzyLevel ecLevel = toFuzzyLevel(dError); // 获取PID参数调整 FuzzyLevel kpAdjust = FuzzyRuleBase.getKpAdjust(eLevel, ecLevel); FuzzyLevel kiAdjust = kpAdjust; // 简化处理 FuzzyLevel kdAdjust = kpAdjust; kp += fuzzyDeltaToValue(kpAdjust, deltaKpScale); ki += fuzzyDeltaToValue(kiAdjust, deltaKiScale); kd += fuzzyDeltaToValue(kdAdjust, deltaKdScale); // 限幅 kp = Math.max(0, Math.min(kp, 10)); ki = Math.max(0, Math.min(ki, 1)); kd = Math.max(0, Math.min(kd, 1)); // PID 计算 // 积分项限幅 integral += error * deltaTime; integral = Math.max(MIN_INTEGRAL, Math.min(MAX_INTEGRAL, integral)); double output = kp * error + ki * integral + kd * dError; System.out.println("计算输出值:" + output + ",误差:" + error + ",误差变化:" + dError); previousError = error; // 输出冷冻水阀开度,限制在0~100% return Math.max(0, Math.min(100, Math.abs(output))); } // 将数值误差映射为模糊等级 public static FuzzyLevel toFuzzyLevel(double value) { if (value <= -3) return FuzzyLevel.NB; else if (value <= -2) return FuzzyLevel.NM; else if (value <= -1) return FuzzyLevel.NS; else if (value <= 1) return FuzzyLevel.ZO; else if (value <= 2) return FuzzyLevel.PS; else if (value <= 3) return FuzzyLevel.PM; else return FuzzyLevel.PB; } // 将模糊等级转为实际数值调整量 public static double fuzzyDeltaToValue(FuzzyLevel level, double scale) { switch (level) { case NB: return -3 * scale; case NM: return -2 * scale; case NS: return -1 * scale; case ZO: return 0; case PS: return 1 * scale; case PM: return 2 * scale; case PB: return 3 * scale; default: return 0; } } }