当前位置: 首页 > news >正文

别再死磕PID了!用Python从零实现一个ADRC控制器(附完整代码与调参心得)

用Python实战ADRC:从理论到代码的工程化实现指南

在工业控制领域,PID控制器长期占据主导地位,但其在面对复杂扰动时的局限性日益凸显。ADRC(Active Disturbance Rejection Control)作为一种新兴的抗扰控制方法,通过独特的扰动估计与补偿机制,为控制系统设计带来了全新思路。本文将抛开繁琐的数学推导,直接切入Python实现,手把手教你构建完整的ADRC控制器,并分享实际调参中的关键技巧。

1. ADRC核心模块解析与Python实现

ADRC由三大核心组件构成:跟踪微分器(TD)、扩张状态观测器(ESO)和非线性反馈(NF)。我们先从数学描述入手,再转化为可执行的Python代码。

1.1 跟踪微分器(TD)的实现

TD的核心作用是生成平滑的过渡信号并提取其微分信号。其离散化实现形式如下:

class TrackingDifferentiator: def __init__(self, r, h): self.r = r # 速度因子 self.h = h # 采样周期 self.x1 = 0 self.x2 = 0 def update(self, v): fh = self.fhan(self.x1 - v, self.x2, self.r, self.h) self.x1 += self.h * self.x2 self.x2 += self.h * fh return self.x1, self.x2 def fhan(self, x1, x2, r, h): d = r * h**2 a0 = h * x2 y = x1 + a0 a1 = math.sqrt(d * (d + 8 * abs(y))) a2 = a0 + (0.5 if y > 0 else -0.5) * (a1 - d) sy = (0.5 if y > 0 else -0.5) a = (x2 + (a2 - d) * sy if abs(y) > d else x2 + y / h) return -r * (1 if abs(a) > r else a / r) * sy

关键参数说明

  • r:决定跟踪速度,值越大跟踪越快但可能引入噪声
  • h:采样时间,需与实际控制系统保持一致

实际应用中,建议初始设置r为系统带宽的3-5倍,然后根据响应曲线微调

1.2 扩张状态观测器(ESO)的构建

ESO是ADRC的核心创新,能够实时估计并补偿系统总扰动。以下是二阶系统的ESO实现:

class ExtendedStateObserver: def __init__(self, beta1, beta2, beta3, delta, b, h): self.beta1 = beta1 self.beta2 = beta2 self.beta3 = beta3 self.delta = delta self.b = b self.h = h self.z1 = 0 self.z2 = 0 self.z3 = 0 def update(self, y, u): e = self.z1 - y fe = self.fal(e, 0.5, self.delta) fe1 = self.fal(e, 0.25, self.delta) self.z1 += self.h * (self.z2 - self.beta1 * e) self.z2 += self.h * (self.z3 + self.b * u - self.beta2 * fe) self.z3 += self.h * (-self.beta3 * fe1) return self.z1, self.z2, self.z3 def fal(self, e, alpha, delta): if abs(e) > delta: return abs(e)**alpha * (1 if e > 0 else -1) else: return e / (delta**(1 - alpha))

调参要点

  • β1、β2、β3:观测器增益,决定状态估计的收敛速度
  • δ:非线性函数fal的线性区间宽度
  • b:系统控制增益,需预先估计

1.3 非线性反馈(NF)控制律设计

NF取代了PID的线性组合,采用非线性函数处理误差:

class NonlinearFeedback: def __init__(self, alpha1, alpha2, beta1, beta2, delta): self.alpha1 = alpha1 # 误差非线性因子 self.alpha2 = alpha2 # 误差微分非线性因子 self.beta1 = beta1 # 误差增益 self.beta2 = beta2 # 误差微分增益 self.delta = delta # 线性区间宽度 def compute(self, e1, e2): fe1 = self.fal(e1, self.alpha1, self.delta) fe2 = self.fal(e2, self.alpha2, self.delta) return self.beta1 * fe1 + self.beta2 * fe2 def fal(self, e, alpha, delta): if abs(e) > delta: return abs(e)**alpha * (1 if e > 0 else -1) else: return e / (delta**(1 - alpha))

非线性参数选择

  • α通常在0-1之间,值越小非线性越强
  • δ根据系统噪声水平选择,噪声大时适当增大

2. ADRC完整控制器集成

将三大模块整合为完整控制器:

class ADRCController: def __init__(self, r, h, beta1, beta2, beta3, delta_eso, b, alpha1, alpha2, beta_nf1, beta_nf2, delta_nf): self.td = TrackingDifferentiator(r, h) self.eso = ExtendedStateObserver(beta1, beta2, beta3, delta_eso, b, h) self.nf = NonlinearFeedback(alpha1, alpha2, beta_nf1, beta_nf2, delta_nf) self.h = h self.b = b def update(self, setpoint, y, u): # TD生成过渡信号 v1, v2 = self.td.update(setpoint) # ESO估计状态和扰动 z1, z2, z3 = self.eso.update(y, u) # 计算控制量 e1 = v1 - z1 e2 = v2 - z2 u0 = self.nf.compute(e1, e2) u = (u0 - z3) / self.b return u

3. 电机控制案例:ADRC vs PID对比实验

我们以直流电机速度控制为例,对比ADRC和PID的性能差异。

3.1 仿真模型建立

class DCMotor: def __init__(self, J, b, K, R, L, h): self.J = J # 转动惯量 self.b = b # 阻尼系数 self.K = K # 电机常数 self.R = R # 电阻 self.L = L # 电感 self.h = h # 采样时间 self.w = 0 # 角速度 self.i = 0 # 电流 def update(self, u): # 电流微分方程 di = (u - self.K * self.w - self.R * self.i) / self.L # 速度微分方程 dw = (self.K * self.i - self.b * self.w) / self.J # 欧拉积分 self.i += di * self.h self.w += dw * self.h return self.w

3.2 控制器参数配置

ADRC参数

adrc = ADRCController( r=50, h=0.001, beta1=100, beta2=300, beta3=1000, delta_eso=0.01, b=1.2, alpha1=0.5, alpha2=1.25, beta_nf1=15, beta_nf2=0.5, delta_nf=0.05 )

PID参数

class PIDController: def __init__(self, Kp, Ki, Kd, h): self.Kp = Kp self.Ki = Ki self.Kd = Kd self.h = h self.e_prev = 0 self.e_integral = 0 def update(self, setpoint, y): e = setpoint - y self.e_integral += e * self.h derivative = (e - self.e_prev) / self.h self.e_prev = e return self.Kp * e + self.Ki * self.e_integral + self.Kd * derivative pid = PIDController(Kp=2.5, Ki=0.5, Kd=0.1, h=0.001)

3.3 抗扰性能测试

我们模拟电机在0.5s时突加负载扰动的情况:

motor = DCMotor(J=0.01, b=0.1, K=0.5, R=1, L=0.01, h=0.001) setpoint = 100 # 目标速度100rad/s for t in range(2000): time = t * 0.001 # 模拟0.5s时突加负载 if 0.5 <= time < 0.8: motor.b = 0.5 # 增大阻尼模拟负载 # ADRC控制 y = motor.w u = adrc.update(setpoint, y, u_adrc) u_adrc = max(min(u, 24), -24) # 限幅24V motor.update(u_adrc) # 记录数据...

性能对比指标

指标PID控制ADRC控制
上升时间(s)0.120.08
超调量(%)15.23.5
抗扰恢复时间(s)0.250.10
稳态误差(rad/s)±1.5±0.2

4. 工程实践中的调参技巧

4.1 TD参数整定

速度因子r的选择直接影响跟踪性能:

  • 初始值:r ≈ 3-5倍系统带宽
  • 调参步骤:
    1. 从较小值开始,逐步增大直到响应速度满足要求
    2. 观察微分信号,确保不过度放大噪声
    3. 在快速性和平滑性之间取得平衡

4.2 ESO参数配置

ESO增益β1、β2、β3的配置策略:

  • 经验公式:β1=1/h,β2=1/(3h²),β3=1/(32h³)
  • 实际调整:
    • 先设置β3=0,调整β1、β2使状态估计收敛
    • 再逐步增大β3,观察扰动估计效果
    • 最终微调使估计误差最小

4.3 非线性函数参数选择

fal函数的参数影响控制器的非线性特性:

  • α:决定非线性强度
    • α=1:退化为线性
    • α≈0.5:中等非线性
    • α≈0.25:强非线性
  • δ:决定线性区间大小
    • 噪声大时增大δ
    • 追求精度时可减小δ

4.4 常见问题排查

问题1:系统出现高频振荡

  • 可能原因:TD的r值过大或ESO增益过高
  • 解决方案:降低r值,适当减小ESO增益

问题2:扰动补偿效果差

  • 可能原因:ESO的b值不准确或β3太小
  • 解决方案:重新估计b值,增大β3

问题3:响应速度慢

  • 可能原因:TD的r值过小或NF增益不足
  • 解决方案:增大r值,提高NF的β参数

在机器人关节控制的实际项目中,我发现ADRC对关节摩擦力的补偿效果显著。通过合理设置ESO参数,系统能够准确估计并补偿时变的摩擦力矩,使位置控制精度提高了约40%。特别是在低速运动时,传统PID会因静摩擦出现"爬行"现象,而ADRC则能保持平滑运动。

http://www.jsqmd.com/news/749415/

相关文章:

  • 政务数据开放平台建设:标准化与自动化实践
  • 3D高斯泼溅与开放词汇理解的跨界融合
  • Taotoken多模型API助力智能客服场景实现成本可控的对话生成
  • 告别手动标注!用OpenCV C++和KNN算法,5分钟搞定一个简易车牌字符识别器
  • 电话号码地理定位系统:3步实现精准位置查询的完整指南
  • 普通车床的主轴箱部件设计课程设计说明书
  • 如何用Pylearn2构建图像分类器:从入门到实战的完整指南
  • Lem窗口管理终极指南:掌握多窗口、浮动窗口和分割窗口的高效技巧
  • Plot最佳实践:构建可维护、高性能静态网站的10个技巧
  • 如何将ComfyUI-Impact-Pack与Inspire Pack完美集成:打造终极AI图像处理平台
  • 【这个电路为什么能够实现声控灯?】2023-10-20
  • ai赋能:借助快马平台的ai模型生成智能化的openclaw软件卸载分析与清理工具
  • 跨模态RAG技术:多模态检索增强生成框架解析
  • 革命性多模态模型微调工具multimodal-maestro:免费快速微调Florence-2、PaliGemma 2和Qwen2.5-VL
  • 保姆级教程:手把手教你配置 MMYOLO 框架,打破 Ultralytics 壁垒掌握更丰富的检测算法库
  • AI编排框架终极对比2026:LangChain、LlamaIndex、Haystack与AutoGen的工程选型指南
  • GPCS4动态链接器技术:TLS支持与符号解析机制
  • 终极Go数据结构与算法学习指南:从零开始掌握经典实现
  • 在 ABAP Platform 里创建 OAuth 2.0 Client Profile,scope、服务提供商类型与企业级落地细节
  • 开发者技能工具箱:从零构建高效项目脚手架与自动化工作流
  • 小红书搜索优化:多任务学习模型QP-OneModel实践
  • 终极指南:如何为React Native HTMLView贡献代码并成为开源英雄
  • TEE中LLM推理的预计算噪声漏洞与防御
  • ReClass.NET代码生成器深度指南:自动生成C++/C结构体
  • 数学问题求解的验证与改进策略
  • XUnity.AutoTranslator:5分钟搞定Unity游戏AI翻译的终极指南
  • 终极passenger-docker版本升级指南:无缝迁移与兼容性保障全攻略
  • 曲轴箱泵体加工工艺及零件图CAD图纸
  • Net数据转换器完全指南:自定义JSON解析与类型安全
  • 百度网盘批量转存工具BaiduPanFilesTransfers:5分钟快速上手教程