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

PID算法从入门到进门

在机器人、无人机、数控机床以及各种自动化设备中直流无生/有刷电机是最核心的动力源。而要让电机听话地停在指定位置或者稳定在某一转速最经典、最常用的算法莫过于PID 控制算法。1. 为什么电机需要 PID想象一下你正开着一辆车路上限速是 60 km/h因此我们将目标是把车速稳定在 60 km/h如果现在车速是 0你会一脚油门踩到底比例PPP的作用。当车速接近 60 km/h 时如果你还死踩油门车速绝对会超超调。所以你会提前松油门微分DDD的作用。如果上坡时风阻和坡度让车速死活卡在 58 km/h你会持续微调多踩一点油门积分III的作用。PID 控制器的核心思想就是利用系统的当前误差通过比例P、积分I、微分D三种趋势组合去计算一个控制量让误差趋近于 0。2. PID 核心公式与三大环节PID 的连续控制公式为u(t)Kpe(t)Ki∫0te(τ)dτKdde(t)dtu(t) K_p e(t) K_i \int_{0}^{t} e(\tau) d\tau K_d \frac{de(t)}{dt}u(t)Kp​e(t)Ki​∫0t​e(τ)dτKd​dtde(t)​其中e(t)r(t)−y(t)e(t) r(t) - y(t)e(t)r(t)−y(t)为目标值与当前实际值的误差。比例环节P - Proportion解决“跑得快不快”公式PKp⋅e(t)P K_p \cdot e(t)PKp​⋅e(t)特点误差越大输出越大。它是控制的主力。缺点单独的 P 控制会存在稳态误差Static Error。因为当误差小到一定程度P 的输出不足以克服电机的摩擦力时电机就会停下来误差永远无法消除。积分环节I - Integral解决“准不准消除稳态误差”公式IKi∫e(t)dtI K_i \int e(t) dtIKi​∫e(t)dt特点只要有误差存在积分项就会随时间不断累积输出就会越来越大直到逼着电机把最后的微小误差彻底消除。缺点积分具有滞后性容易导致系统超调Overshoot和振荡。微分环节D - Derivative解决“稳不稳抑制振荡”公式DKdde(t)dtD K_d \frac{de(t)}{dt}DKd​dtde(t)​特点反映误差的变化率速度。如果误差减小得太快D 就会产生一个反向的阻力相当于给系统踩刹车。缺点对噪声极其敏感。如果电机编码器反馈的数据有毛刺微分项会将其放大导致系统剧烈抖动。3. 电机控制中的“位置式”与“增量式” PID在计算机单片机/DSP这类数字系统中连续公式必须离散化。离散化后主要有两种形式① 位置式 PID直接计算当前时刻应该输出的总控制量如 PWM 占空比u(k)Kpe(k)Ki∑i0ke(i)Kd[e(k)−e(k−1)]u(k) K_p e(k) K_i \sum_{i0}^{k} e(i) K_d [e(k) - e(k-1)]u(k)Kp​e(k)Ki​i0∑k​e(i)Kd​[e(k)−e(k−1)]适用场景执行机构没有记忆功能必须持续输出信号如舵机角度控制、全向轮速度控制。缺点由于要计算历史所有误差的积分∑e(i)\sum e(i)∑e(i)一旦系统出现大偏差容易引发积分饱和Integral Windup。② 增量式 PID只计算当前时刻相比于上一时刻控制量需要增加或减少多少Δu(k)u(k)−u(k−1)Kp[e(k)−e(k−1)]Kie(k)Kd[e(k)−2e(k−1)e(k−2)]\Delta u(k) u(k) - u(k-1) K_p [e(k) - e(k-1)] K_i e(k) K_d [e(k) - 2e(k-1) e(k-2)]Δu(k)u(k)−u(k−1)Kp​[e(k)−e(k−1)]Ki​e(k)Kd​[e(k)−2e(k−1)e(k−2)]适用场景带步进电机、有位置保持能力的电机、或者只关心速度变化的控制。优点不需要累加误差只与最近 3 次的误差相关计算量小切换手动/自动时冲击小。4. MATLAB 仿真实战下面我们用 MATLAB 代码来模拟一个简单的直流电机速度 PID 控制系统。我们把直流电机简化为一个一阶传函带惯性和阻尼G(s)1JsbG(s) \frac{1}{J s b}G(s)Jsb1​离散化后在代码中体现。MATLAB 源码%% %% 基于全新二阶物理机理模型与抗饱和Anti-WindupPID 仿真%% clear;clc;close all;%% 仿真及采样参数设置Ts0.001;% 采样时间: 1msTime_End2.5;% 仿真总时长: 2.5st0:Ts:Time_End;% 时间向量Nlength(t);%% 重新设计电机物理参数及二阶状态空间模型% 基于直流电机物理方程% V R*i L*di/dt Ke*omega% T_e Kt*i J*domega/dt b*omega T_loadR2.0;% 电枢电阻 (Ohms)L0.05;% 电枢电感 (Henry)Kt0.1;% 转矩常数 (N.m/A)Ke0.1;% 反电动势常数 (V/(rad/s))J0.02;% 转动惯量 (kg.m^2)b0.05;% 摩擦阻尼系数 (N.m.s)% 建立连续时间状态空间模型% 状态向量 x [i; omega] (电枢电流; 电机角速度)% 输入向量 u [V_in; T_load] (输入电压; 负载转矩)% 输出向量 y omega (转速 rad/s后续转换为 rpm)Ac[-R/L,-Ke/L;Kt/J,-b/J];Bc[1/L,0;0,-1/J];Cc[0,30/pi];% 输出矩阵直接将 rad/s 乘以 30/pi 转换为 rpm 常用单位Dc[0,0];sys_css(Ac,Bc,Cc,Dc);% 使用零阶保持器 (ZOH) 对连续物理模型进行精准离散化sys_dc2d(sys_c,Ts,zoh);A_motorsys_d.A;B_motorsys_d.B;%% PID 控制器参数设定 (针对二阶模型重新整定)Kp4.5;Ki25.0;Kd0.12;U_max24;% 额定驱动电压上限 24VU_min-24;% 驱动电压下限 -24VK_aw10.0;% 抗积分饱和回路增益 (Anti-Windup Gain)%% 初始化变量与工况设置Target_Speed120*ones(1,N);% 目标转速设定为 120 rpm% 动态调整目标值1.5s 后阶跃至 160 rpmTarget_Speed(t1.5)160;% 重新设计负载扰动模拟转矩冲击 (N.m)T_loadzeros(1,N);T_load(t0.8t1.2)0.5;% 0.8s时突加0.5 N.m的外负载1.2s卸载% 状态变量初始化 [电流; 转速(rad/s)]xzeros(2,N);Actual_Speedzeros(1,N);uzeros(1,N);% 控制电压err_p0;% 当前误差 e(k)err_i0;% 误差积分err_d0;% 误差微分last_err0;% 上一次误差 e(k-1)aw_feedback0;% 抗饱和反馈修正量%% 仿真主循环 (带 Anti-Windup 的位置式PID)fork2:N% 计算转速误差err_pTarget_Speed(k)-Actual_Speed(k-1);% 误差微分计算err_d(err_p-last_err)/Ts;% PID 理想控制量输出计算u_idealKp*err_pKi*err_iKd*err_d;% 执行器限幅非线性饱和环节ifu_idealU_maxu(k)U_max;elseifu_idealU_minu(k)U_min;elseu(k)u_ideal;end% 升级——抗积分饱和Anti-Windup% 当控制器饱和时理想输出与实际输出存在偏差 (u_ideal - u(k))% 利用该偏差去削弱积分项防止积分无限膨胀导致系统退出饱和时剧烈超调aw_feedbacku_ideal-u(k);err_ierr_i(err_p-K_aw*aw_feedback)*Ts;% 更新物理状态空间方程 (输入包含控制电压 u(k) 和 负载转矩 T_load(k))u_input[u(k);T_load(k)];x(:,k)A_motor*x(:,k-1)B_motor*u_input;% 转换为测量输出 (转速 rpm)Actual_Speed(k)sys_d.C*x(:,k)sys_d.D*u_input;% 保存历史数据last_errerr_p;end%% 绘图展示figure(Color,[111],Position,[100,100,800,600]);% 子图 1转速动态跟踪subplot(3,1,1);plot(t,Target_Speed,r--,LineWidth,2);hold on;plot(t,Actual_Speed,b-,LineWidth,1.5);grid on;set(gca,GridLineStyle,:);title(升级后二阶电机物理模型 - 速度 PID 控制响应);xlabel(时间 (s));ylabel(转速 (rpm));legend(目标转速,实际转速,Location,SouthEast);% 子图 2控制电压输出饱和区观察subplot(3,1,2);plot(t,u,g-,LineWidth,1.5);hold on;plot([0,Time_End],[U_max,U_max],r:);plot([0,Time_End],[U_min,U_min],r:);grid on;set(gca,GridLineStyle,:);title(PID 限制器实际输出电压 (考虑 24V 饱和限幅));xlabel(时间 (s));ylabel(控制电压 (V));ylim([U_min-5,U_max5]);% 子图 3电枢电流响应一阶模型无法观察的物理量subplot(3,1,3);plot(t,x(1,:),m-,LineWidth,1.5);grid on;set(gca,GridLineStyle,:);title(电机内部电枢电流动态变化 (Motor Current));xlabel(时间 (s));ylabel(电流 (A));仿真结果解读运行上述代码后你会看到下图0∼0.5 s0 \sim 0.5\,\text{s}0∼0.5s阶段系统启动与电流、电压饱和转速蓝线电机从 0 rpm 开始加速呈现出非常漂亮的二阶系统 S 型加速曲线。在0.5 s0.5\,\text{s}0.5s左右平稳追踪到120 rpm120\,\text{rpm}120rpm目标值几乎没有任何超调。这正是Anti-Windup抗积分饱和的功劳。控制电压绿线在刚启动的瞬间误差最大PID 控制器直接“把油门踩死”输出达到了上限24 V24\,\text{V}24V的红线并持续了一小段时间。电枢电流洋红线配合电压踩死电流迅速飙升至接近12 A12\,\text{A}12A最大启动电流。随着转速上升电机产生反电动势抵消了部分电压电流逐渐回落稳定在约6 A6\,\text{A}6A的空载维持电流。细节点最开始的瞬间0.05 s0.05\,\text{s}0.05s前电流和电压出现了一个向下的负向尖峰这是二阶电感效应与数值离散化初期带来的短暂电磁暂态过渡属于真实的物理特征。0.8∼1.2 s0.8 \sim 1.2\,\text{s}0.8∼1.2s阶段突加负载冲击核心亮点在0.8 s0.8\,\text{s}0.8s时我们给电机突然加了一个阻力矩比如车子开始爬坡或者机械臂搬起了重物转速蓝线在0.8 s0.8\,\text{s}0.8s瞬间转速受阻轻微下跌。控制电压绿线PID 察觉到了转速下跌的误差立刻把电压从15 V15\,\text{V}15V左右再度拉满到24 V24\,\text{V}24V疯狂给电机“补油门”。电枢电流洋红线因为电压拉满且有外载荷电流瞬间从6 A6\,\text{A}6A飙升并稳定在11 A11\,\text{A}11A左右。在电机物理学中TKt⋅iT K_t \cdot iTKt​⋅i转矩与电流成正比电流的倍增代表电机正在输出更大的转矩来对抗阻力。1.2 s1.2\,\text{s}1.2s卸载在1.2 s1.2\,\text{s}1.2s阻力突然消失电机瞬间轻松了转速有个轻微的上冲趋势。PID 立马“松油门”电压猛跌电流也随之跌回6 A6\,\text{A}6A系统重新恢复平衡。1.5 s1.5\,\text{s}1.5s阶段目标值阶跃改写设定值在1.5 s1.5\,\text{s}1.5s时我们将目标转速从120 rpm120\,\text{rpm}120rpm突然提高到160 rpm160\,\text{rpm}160rpm控制电压绿线PID 再次做出极限反应直接反向触底限幅因为暂态误差突变导致的差分/微分冲击随后瞬间拉满到正向上限24 V24\,\text{V}24V。电枢电流洋红线伴随电压的剧烈切换电流出现了一个深度下摆下冲紧接着再次飙升至11 A11\,\text{A}11A左右提供巨大的电磁转矩推动电机二次加速。转速蓝线在经历了一个极其短暂的暂态波动后实际转速平稳、快速地爬升最终在2.0 s2.0\,\text{s}2.0s左右精准地咬死在160 rpm160\,\text{rpm}160rpm新目标线上。5. 经典工程调参口诀在实际调电机时如果不用 Simulink 仿真而是直接在硬件上调可以使用著名的试凑法配合以下口诀参数整定找最佳从小到大顺序查。先是比例后积分最后再把微分加。曲线振荡波形大比例系数要放大。恢复缓慢波形平比例系数往小加。曲线偏离回复慢积分时间往下降。曲线波动周期长积分时间再延长。曲线振荡频率快先减微分再看看。动辄生变大起落微分指数要加满。实际工程调试顺序先调 P把 I 和 D 设为 0。逐渐增大 P直到电机开始出现肉眼可见的轻微振荡然后把 P 乘以 0.6~0.7 作为当前值。再调 I此时电机已经能跟上目标但有稳态误差。从小到大加入 I直到稳态误差完全消失且超调在可接受范围内。后调 D如果系统在启动或者受到冲击时抖动厉害、超调过大加入微量的 D 进行抑制。如果是单纯的速度控制通常 D 可以设为 0因为速度反馈本身带有微分性质。在机器人、无人机、数控机床以及各种自动化设备中直流无生/有刷电机是最核心的动力源。而要让电机听话地停在指定位置或者稳定在某一转速最经典、最常用的算法莫过于PID 控制算法。
http://www.zskr.cn/news/1374691.html

相关文章:

  • Java NIO 状态守卫:AlreadyBoundException 源码深度剖析与网络通道绑定契约
  • 未来趋势洞察:后端开发技术的前沿动态与发展方向
  • CentOS 7无线网络配置避坑指南:wpa_supplicant vs NetworkManager,我该选哪个?
  • 开源HARNode系统:高精度多设备可穿戴人体活动识别方案
  • 安卓So层Hook实战:ARM64函数定位与参数还原五步法
  • Vespucci Linter:专为机器学习笔记本设计的代码质量检查工具
  • 机器学习如何为Yannakakis算法打造智能开关,提升数据库查询性能
  • C++ 智能指针简介
  • 机器学习原子势能建模:深度集成与贝叶斯神经网络的不确定性估计对比
  • Kali NetHunter移动渗透实战:Magisk模块化部署与外设适配
  • 中国半导体行业展会详解,挑选适配企业的参展平台 - 品牌2025
  • oauthd:轻量级开源OAuth2.0授权中心与企业权限治理实践
  • AI驱动的红队渗透工具包:Nmap语义解析与Metasploit动态编排
  • Unity根运动偏移问题:原理、诊断与五种生产级解决方案
  • 量子噪声模拟:从原理到NISQ时代的实践优化
  • Rockchip Debian编译卡在QEMU?别慌,可能是Ubuntu 18.04的锅(附升级20.04避坑指南)
  • BCLinux for Euler 21.10最小化安装后必做的5件事:从系统验证到基础服务部署
  • 在VMware里给统信UOS服务器V20装个Web服务:从虚拟机配置到Apache跑起来的完整流程
  • LISA探测极端质量比双星系统的引力波信号
  • 机器学习驱动的量子噪声建模:数据高效与物理约束融合实践
  • 从零开始:用Python和Simulink复现经典倒立摆建模与控制(附代码)
  • 业务比例:压测真实性的核心标尺
  • 别再手动切镜头了!用Cinemachine的ClearShot和State-Driven Camera实现智能镜头管理(Unity教程)
  • 为Nreal眼镜开发AR应用?手把手教你配置Unity Vuforia的安卓发布参数(从环境到真机调试)
  • Burp Suite Galaxy插件实战:AES_CBC加解密与请求头签名校验
  • JMeter临界部分控制器:业务节奏建模与资源争用压测核心
  • 深度强化学习在自动驾驶赛车中的控制优化与应用
  • 京东商品详情API动态参数加密解析与服务端复现
  • Keil µVision调试技巧:跟踪缓冲区记录与分析
  • Skybox AI生成的全景图效果不行?可能是你的Unity天空盒材质设置错了(附不同渲染管线适配教程)