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

【PID】基本PID控制 chaprt1 学习笔记

1 PID控制原理

PID控制器是一种线性控制器,常作为模拟控制系统中的控制器,根据给定值$y_d(t)$实际输出值$y(t)$构成的控制偏差来进行控制。
err(t)=yd(t)−y(t) err(t)=y_d(t)-y(t) err(t)=yd(t)y(t)
传递函数在零初始条件下被定义为系统输出量的拉普拉斯变换输入量的拉普拉斯变换之比。

而在计算机系统中,我们需要采用离散化的方法,将模拟PID控制算法离散化:

  • 采样时刻点kT代替连续时间t
  • 矩阵法数值积分近似替代积分
  • 一阶向后差分近似替代微分

1.1 PID控制系统的基本结构 chapt1_1.mdl

在这里插入图片描述
注意PID控制的目标,一般都是希望输出跟随控制量(或者两者符合某种函数关系)

此处我们调整的目标,是希望输入,经过一个系统(传函),其输入和输出曲线尽可能的重合。

看结果:
在这里插入图片描述
在这里插入图片描述
第二路PID(黄色曲线)基本跟随了第一路(期望输出),而第三路(未经过任何控制,直接输入给模型)则完全偏离第一路。

1.2 系统描述的两种形式–状态空间和传递函数 chap1_2.mdl

对比状态空间和传函两种形式的结果。连接两者的桥梁就是微分方程
在这里插入图片描述
在这里插入图片描述

1.3 s-function 实现(连续系统) chap1_3.xls

前两个案例分别是通过传递函数和状态空间是实现系统模型,用的是matlab提供的现有控件。对于更加复杂的模型,我们可以通过s-function来实现。

所谓的s-function,就是一套固定的模板,matlab的求解器会按照这个固定的模板去调用你定义的函数。接下来,我们将先对s-function做一个简单介绍,在利用s-function分别实现PID控制器和被控系统。
在这里插入图片描述
注意:不知道为什么,我在仿真的时候,发现两个系统模块不能并存,必须删除另一个才能正常。(就是switch没有起作用。后面有经验了再解决吧。)

(1)s-function

如下为一个s-function基本的结构:

[SYS,X0,STR,TS,SIMSTATECOMPLIANCE] = SFUNC(T,X,U,FLAG,P1,...,Pn)
switch flag,%%%%%%%%%%%%%%%%%%% Initialization %%%%%%%%%%%%%%%%%%%case 0,[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;%%%%%%%%%%%%%%%% Derivatives %%%%%%%%%%%%%%%%case 1,sys=mdlDerivatives(t,x,u);%%%%%%%%%%% Update %%%%%%%%%%%case 2,sys=mdlUpdate(t,x,u);%%%%%%%%%%%% Outputs %%%%%%%%%%%%case 3,sys=mdlOutputs(t,x,u);%%%%%%%%%%%%%%%%%%%%%%%% GetTimeOfNextVarHit %%%%%%%%%%%%%%%%%%%%%%%%case 4,sys=mdlGetTimeOfNextVarHit(t,x,u);%%%%%%%%%%%%%% Terminate %%%%%%%%%%%%%%case 9,sys=mdlTerminate(t,x,u);%%%%%%%%%%%%%%%%%%%%% Unexpected flags %%%%%%%%%%%%%%%%%%%%%otherwiseDAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));end

SFUNC某一时刻T的输出,取决于FLAG,当前状态向量X和当前的输入向量U。

不通过的FLAG,执行的结果如下所示:

%   FLAG   RESULT             DESCRIPTION
%   -----  ------             --------------------------------------------
%   0      [SIZES,X0,STR,TS]  Initialization, return system sizes in SYS,
%                             initial state in X0, state ordering strings
%                             in STR, and sample times in TS.
%   1      DX                 Return continuous state derivatives in SYS.
%   2      DS                 Update discrete states SYS = X(n+1)
%   3      Y                  Return outputs in SYS.
%   4      TNEXT              Return next time hit for variable step sample
%                             time in SYS.
%   5                         Reserved for future (root finding).
%   9      []                 Termination, perform any cleanup SYS=[].

我们需要做的,就是实现每个FLAG case下,具体的功能函数。
(2)PID的s-function案例
对于PID,只需要实现初始化、和输出部分。

% chap1_3s.m PID实现
function [sys,x0,str,ts] = pid_controller_with_antiwindup(t,x,u,flag)
% 带积分限幅的PID控制器S-function
% 输入: u(1)=error, u(2)=derror, u(3)=errori
% 输出: 控制量utswitch flagcase 0[sys,x0,str,ts]=mdlInitializeSizes;case {2, 4, 9}sys=[];case 3sys=mdlOutputs(t,x,u);otherwiseDAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));
endfunction [sys,x0,str,ts]=mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates  = 0;
sizes.NumDiscStates  = 0;
sizes.NumOutputs     = 1;
sizes.NumInputs      = 3;
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 0;sys = simsizes(sizes);
x0  = [];
str = [];
ts  = [];
function sys=mdlOutputs(t,x,u)
error = u(1);
derror = u(2);
errori = u(3);% PID参数
kp = 60;
kd = 3;
ki = 1;% 积分限幅参数
integral_max = 100;   % 积分上限
integral_min = -100;  % 积分下限% 应用积分限幅
errori_limited = min(max(errori, integral_min), integral_max);% 计算PID输出
ut = kp*error + kd*derror + ki*errori_limited;% 输出限幅(可选)
output_max = 200;
output_min = -200;
ut_limited = min(max(ut, output_min), output_max);sys(1) = ut_limited;

(3) SYSTEM案例

同样的,系统也可以直接用S-function实现。(其效果等同于传递函数或状态空间。只不过S-FUNCTION是matlab提供的一个更通用的接口)
注意看初始化部分的变量注释。

unction [sys,x0,str,ts] = chap1_3plant(t,x,u,flag)
% 连续系统S-function实现
% 用于Simulink中的连续系统建模switch flagcase 0[sys,x0,str,ts]=mdlInitializeSizes;case 1sys=mdlDerivatives(t,x,u);case 2sys=[];case 3sys=mdlOutputs(t,x,u);case 4sys=[];case 9sys=[];otherwiseDAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));
endfunction [sys,x0,str,ts]=mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates  = 2;% 如果为连续系统,状态变量的数量/维度 注意,是列向量
sizes.NumDiscStates  = 0;% 如果为离散系统,状态变量的数量/维度 注意,是列向量
sizes.NumOutputs     = 1;% 输出变量的维度数
sizes.NumInputs      = 1;% 输入变量的维度数
sizes.DirFeedthrough = 0; % 直馈 就是控制量u是否加入输出 y=Cx+Du,即此处是否出现u(注意,不是D的值),取值为0或1
sizes.NumSampleTimes = 1; % 模块采样周期的个数sys = simsizes(sizes);
x0  = [0; 0];% 注意,这里是列向量
str = [];
% ts 是一个 m×2 的矩阵,其中 ‌m 等于 sizes.NumSampleTimes 的值‌
% ts 矩阵的每一行定义了一个采样时间,其格式为 [采样周期, 偏移量]
% ‌连续采样时间‌(CONTINUOUS_SAMPLE_TIME):值为0.0,适用于连续系统
%‌ 继承采样时间‌(INHERITED_SAMPLE_TIME):值为-1.0,从驱动模块继承采样率% 固定最小步长偏移‌(FIXED_IN_MINOR_STEP_OFFSET):值为1.0% 可变采样时间‌(VARIABLE_SAMPLE_TIME):值为-2.0
ts  = [0 0];function [sys]=mdlDerivatives(t,x,u)
% 状态导数计算,确保数值稳定性
sys = zeros(2,1);% 状态方程: dx1/dt = x2
sys(1) = x(2);% 使用有界随机扰动,避免数值不稳定
rand_factor1 = max(min(randn(1), 2.0), -2.0);  % 限制在[-2,2]范围内
rand_factor2 = max(min(randn(1), 2.0), -2.0);% 状态方程: dx2/dt = -(25+10*rand_factor1)*x2 + (133+30*rand_factor2)*u
sys(2) = -(25 + 10 * rand_factor1) * x(2) + (133 + 30 * rand_factor2) * u(1);% 确保导数结果为有限值
if ~all(isfinite(sys))sys = zeros(2,1);
endfunction sys=mdlOutputs(t,x,u)
% 输出方程: y = x1
sys = x(1);

(4) 运行结果
两条曲线也基本重合。
在这里插入图片描述

1.4 s-function实现(离散系统)

对于离散系统和离散PID控制而言,离散化是实现系统的第一步。
一般而言,我们用物理规律写出的系统方程(微分方程的 状态空间形式或传递函数形式),都是针对连续系统的描述。但在控制领域中,更多的是以“步(长)”为单位对系统进行控制。因此,对连续系统的离散化十分必要。

s-function的实现后续再补充吧。

1.4.1 系统离散化方法

  • 传递函数的离散形式:
    s变换->z变换。
    这部分方法很多,这里就举一个 双线性变换 的方法:
    s=2Tz−1z+1 s=\frac{2}{T} \frac{z-1}{z+1} s=T2z+1z1
    用上述公式替代s方程中的s,然后执行Z变换。

案例:在matlab中,可通过调用如下函数实现:

ts = 2;% 采样时间
sys = tf(1,[10,1]) % 连续系统
dsys = c2d(sys, ts, 'z') % 离散化 'z'/'zoh':零阶保持器方法,这是默认选项
[num1, den1] = tfdata(dsys,'v') % 离散化后的零点和极点参数 'v'表示以向量的形式返回参数

输出如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 状态空间的离散形式
    因为有状态变量导数项的存在,可直接用 差分近似导数的方法实现。(即欧拉法。)
    除此之外,还有向后欧拉、向前欧拉、梯形法等多种近似方法。
    同样的,也可以用双线性变换实现。

案例:
x˙=Ax+Bu \dot{x}=Ax+Bu x˙=Ax+Bu
x[k+1]=Gx[k]+Hu[k] x[k+1] = Gx[k] + Hu[k] x[k+1]=Gx[k]+Hu[k]

% 定义连续系统矩阵
A = [0 1; 1 -2];
B = [0; 1];
% 设置采样周期
Ts = 0.01;
% 使用c2d函数进行离散化
[G, H] = c2d(A, B, Ts);

在这里插入图片描述
在这里插入图片描述

http://www.dtcms.com/a/528310.html

相关文章:

  • 【大语言模型 103】推理服务监控:性能指标、故障诊断与自动恢复实战
  • 网站广东海外建设集团有限公司做网站工资多钱
  • Julia 字符串处理指南
  • volatile关键词探秘:从咖啡厅的诡异订单到CPU缓存之谜
  • 嵌入式Lua脚本编程核心概念
  • VScode开发环境搭建(本文为个人学习笔记,内容整理自哔哩哔哩UP主【非学者勿扰】的公开课程。 > 所有知识点归属原作者,仅作非商业用途分享)
  • 基于springboot的车辆管理系统设计与实现
  • WPF GroupBox 淡入淡出
  • Dify从入门到精通 第33天 基于GPT-4V构建图片描述生成器与视觉问答机器人
  • 网页制作与网站建设实战教程视频网站一般用什么数据库
  • React 05
  • srpingboot 推rtsp/rtmp等流地址给前端播放flv和ws
  • 游戏任务简单设计
  • 平台网站建设ppt模板下载阿里巴巴的电子商务网站建设
  • GitHub等平台形成的开源文化正在重塑脱离了
  • Linux18--进程间的通信总结
  • 基于脚手架微服务的视频点播系统-脚手架开发部分-FFmpeg,Etcd-SDK的简单使用与二次封装
  • 【教学类-120-01】20251025旋转数字
  • 制作网站多少钱一个有哪些做企业点评的网站
  • 网站会员营销上海注册公司哪家好
  • 【深度学习新浪潮】深入理解Seed3D模型:参数化驱动的下一代3D内容生成技术
  • GitHub等平台形成的开源文化正在重塑和人家
  • 免费网站收录入口有了域名空间服务器怎么做网站
  • 5.go-zero集成gorm 和 go-redis
  • Linux系统入门:System V进程间通信
  • 第一章 蓝图篇 - 全景认知与项目设计
  • mormot.net.server.pas源代码分析
  • 丹阳网站建设价位php网站搭建
  • 【工具分享】另一个免费开源的远程桌面服务-Apache Guacamole
  • RabbitMQ TTL机制详解