目录
一·传统PID
PID(比例 - 积分 - 微分)控制器是一种广泛应用的反馈控制算法,其控制规律可以表示为:
其中,u(t)是控制器的输出,e(t)是设定值与实际输出的偏差,Kp是比例系数,Ki是积分系数,Kd是微分系数。传统 PID 控制器的参数是固定的,对于具有时变、非线性等特性的系统,控制效果可能不佳。
二·模糊PID控制原理
模糊控制是基于模糊集合理论和模糊逻辑推理的一种智能控制方法。它模仿人类的思维方式,将输入变量(如偏差 e 和偏差变化率 Delta e进行模糊化处理,根据预先制定的模糊规则进行推理,然后将推理结果进行解模糊处理得到精确的控制输出。
三·模糊自适应PID工作机制
模糊自适应 PID 结合了传统 PID 控制和模糊控制的优点。它以偏差 e 和偏差变化率 Delta e 作为模糊控制器的输入,通过模糊推理在线调整 PID 控制器的三个参数 Kp、Ki 和 Kd,以适应系统的动态变化。具体步骤如下:
- 输入模糊化:将精确的输入变量 e 和 Delta e转换为模糊集合,例如将其划分为 “负大(NB)”、“负中(NM)”、“负小(NS)”、“零(ZO)”、“正小(PS)”、“正中(PM)”、“正大(PB)” 等模糊子集,并确定它们的隶属度函数。
- 模糊规则制定:根据专家经验和系统特性,制定一系列模糊规则。例如:“如果 e 为负大且Delta e为负大,则Kp取正大,Ki取负小,Kd 取正小”。
- 模糊推理:根据输入的模糊集合和模糊规则,采用合适的推理方法(如 Mamdani 推理法)得到模糊输出。
- 解模糊:将模糊输出转换为精确的参数调整量,常用的解模糊方法有重心法、最大隶属度法等。
- 参数调整:根据解模糊得到的调整量,对 PID 控制器的参数 Kp、Ki 和 Kd 进行实时调整。
四·代码实例
import numpy as np
# 定义模糊集合和隶属度函数
class FuzzySet:
def __init__(self, name, params):
self.name = name
self.params = params
def membership(self, x):
a, b, c, d = self.params
if x <= a or x >= d:
return 0
elif a < x <= b:
return (x - a) / (b - a)
elif b < x <= c:
return 1
elif c < x < d:
return (d - x) / (d - c)
# 定义模糊控制器
class FuzzyController:
def __init__(self):
# 定义输入变量的模糊集合
self.e_fuzzy_sets = [
FuzzySet("NB", [-np.inf, -3, -2, -1]),
FuzzySet("NM", [-2, -1.5, -1, -0.5]),
FuzzySet("NS", [-1, -0.5, 0, 0.5]),
FuzzySet("ZO", [-0.5, 0, 0, 0.5]),
FuzzySet("PS", [0, 0.5, 1, 1.5]),
FuzzySet("PM", [0.5, 1, 1.5, 2]),
FuzzySet("PB", [1, 2, 3, np.inf])
]
self.de_fuzzy_sets = self.e_fuzzy_sets.copy()
# 定义输出变量(Kp, Ki, Kd)的模糊集合
self.Kp_fuzzy_sets = self.e_fuzzy_sets.copy()
self.Ki_fuzzy_sets = self.e_fuzzy_sets.copy()
self.Kd_fuzzy_sets = self.e_fuzzy_sets.copy()
# 模糊规则表(简化示例)
self.Kp_rules = [
[3, 3, 2, 2, 1, 0, 0],
[3, 3, 2, 1, 1, 0, -1],
[2, 2, 2, 1, 0, -1, -1],
[2, 2, 1, 0, -1, -1, -2],
[1, 1, 0, -1, -1, -2, -2],
[0, 0, -1, -1, -2, -2, -3],
[0, -1, -1, -2, -2, -3, -3]
]
self.Ki_rules = [
[-3, -3, -2, -2, -1, 0, 0],
[-3, -3, -2, -1, -1, 0, 1],
[-2, -2, -2, -1, 0, 1, 1],
[-2, -2, -1, 0, 1, 1, 2],
[-1, -1, 0, 1, 1, 2, 2],
[0, 0, 1, 1, 2, 2, 3],
[0, 1, 1, 2, 2, 3, 3]
]
self.Kd_rules = [
[0, 0, 1, 1, 1, 2, 2],
[0, 1, 1, 1, 2, 2, 3],
[1, 1, 1, 2, 2, 3, 3],
[1, 1, 2, 2, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[2, 2, 3, 3, 3, 3, 3],
[2, 3, 3, 3, 3, 3, 3]
]
def fuzzy_inference(self, e, de):
# 输入模糊化
e_memberships = [fs.membership(e) for fs in self.e_fuzzy_sets]
de_memberships = [fs.membership(de) for fs in self.de_fuzzy_sets]
# 模糊推理
Kp_agg = np.zeros(len(self.Kp_fuzzy_sets))
Ki_agg = np.zeros(len(self.Ki_fuzzy_sets))
Kd_agg = np.zeros(len(self.Kd_fuzzy_sets))
for i in range(len(self.e_fuzzy_sets)):
for j in range(len(self.de_fuzzy_sets)):
firing_strength = min(e_memberships[i], de_memberships[j])
Kp_agg[self.Kp_rules[i][j]] = max(Kp_agg[self.Kp_rules[i][j]], firing_strength)
Ki_agg[self.Ki_rules[i][j]] = max(Ki_agg[self.Ki_rules[i][j]], firing_strength)
Kd_agg[self.Kd_rules[i][j]] = max(Kd_agg[self.Kd_rules[i][j]], firing_strength)
# 解模糊(重心法)
def defuzzify(agg, sets):
numerator = 0
denominator = 0
for i in range(len(sets)):
# 这里简单取隶属度函数的中心值
center = (sets[i].params[1] + sets[i].params[2]) / 2
numerator += agg[i] * center
denominator += agg[i]
if denominator == 0:
return 0
return numerator / denominator
delta_Kp = defuzzify(Kp_agg, self.Kp_fuzzy_sets)
delta_Ki = defuzzify(Ki_agg, self.Ki_fuzzy_sets)
delta_Kd = defuzzify(Kd_agg, self.Kd_fuzzy_sets)
return delta_Kp, delta_Ki, delta_Kd
# 定义PID控制器
class PIDController:
def __init__(self, Kp, Ki, Kd):
self.Kp = Kp
self.Ki = Ki
self.Kd = Kd
self.prev_error = 0
self.integral = 0
def update(self, setpoint, current_value, delta_t):
error = setpoint - current_value
self.integral += error * delta_t
derivative = (error - self.prev_error) / delta_t
output = self.Kp * error + self.Ki * self.integral + self.Kd * derivative
self.prev_error = error
return output
# 模糊自适应PID控制器
class FuzzyAdaptivePID:
def __init__(self, Kp, Ki, Kd):
self.pid = PIDController(Kp, Ki, Kd)
self.fuzzy_controller = FuzzyController()
def update(self, setpoint, current_value, delta_t):
error = setpoint - current_value
delta_error = error - self.pid.prev_error
# 模糊推理得到参数调整量
delta_Kp, delta_Ki, delta_Kd = self.fuzzy_controller.fuzzy_inference(error, delta_error)
# 更新PID参数
self.pid.Kp += delta_Kp
self.pid.Ki += delta_Ki
self.pid.Kd += delta_Kd
# 计算PID输出
output = self.pid.update(setpoint, current_value, delta_t)
return output
# 示例使用
if __name__ == "__main__":
# 初始PID参数
Kp = 1.0
Ki = 0.1
Kd = 0.01
# 设定值
setpoint = 50
# 初始输出值
current_value = 0
# 时间步长
delta_t = 0.1
# 模拟时间
total_time = 10
# 迭代次数
num_steps = int(total_time / delta_t)
fuzzy_pid = FuzzyAdaptivePID(Kp, Ki, Kd)
for _ in range(num_steps):
output = fuzzy_pid.update(setpoint, current_value, delta_t)
# 这里简单假设系统的响应是线性的
current_value += output * delta_t
print(f"Output: {output}, Current Value: {current_value}")
五·代码解释
- FuzzySet 类:定义了模糊集合及其隶属度函数。
- FuzzyController 类:实现了模糊控制器的主要功能,包括输入模糊化、模糊推理和解模糊。
- PIDController 类:实现了传统 PID 控制器的基本功能。
- FuzzyAdaptivePID 类:将模糊控制器和 PID 控制器结合起来,实现了模糊自适应 PID 控制。
- 示例使用部分:模拟了一个简单的控制系统,展示了模糊自适应 PID 控制器的使用方法。
需要注意的是,这只是一个简化的示例,实际应用中可能需要根据具体的系统特性和要求对模糊规则、隶属度函数等进行调整。
PID代码请看:PID控制器简述(附代码)-CSDN博客