PID原理以及C语言的代码实现
PID控制系统的基本构架实际就是我们耳熟能详的反馈控制,能根据输出值对输入值进行调整。从而使输入值达到最优的效果。
这里将PID与之进行类比:
PID控制思想:
我们在单片机中不可能实现连续的控制(不可能说全部的时间都去进行PID控制,否则就进入了死循环,不能进行其他的操作),所以说这里在使用的是PID控制器离散型分析,顾名思义就是说我们获取的数据不是连续的,而是每隔相同的时间进行获取(这个和我们单片机的中断相吻合)
积分控制
下面是根据图16-8绘制的一条Ek与时间的关系曲线:
单位时间内Ek的加和即为Sk,所以简单的来表示的话Ek与坐标轴围成的面积大小,就是Sk的值
可以明显的看到,积分控制的最终目的就是慢慢使蓝色与绿色部分面积相等
微分控制
还有一个巧妙的地方是代码运用了积分分离法。这里的积分分离法的基本思想是在偏差大时不进行积分,仅当偏差的绝对值小于一预定的门限值ε时才进行积分累积。这样既防止了偏差大时有过大的控制量,也避免了过积分现象。
关于积分分离法的应用,例如说:
(这里在无人机中的应用就是飞行姿态的角度问题,在使用比例控制时最后会出现稳态误差,虽然可以用积分进行补偿。但是如果一开始就使用积分控制,这里在达到目标值的时候会有较大的起伏使得Sk=0从而保持稳态,但是这样的较大的起伏可能并不是我们想要的。所以才有了我们所谓的积分分离法,就是在设定值上下确定一个较小的门限值ε,只有在门限值内即:设定值-门限值ε<实际值<设定值+门限值ε 时,积分才参与控制,所以这里定义的有积分分离变量与积分限幅变量以及积分分离标志)
注意这里是定义的一个PID_TYPE的一个结构体变量方便了我们管理数据
函数的参数有:结构体指针,目标值,测量值,(以及采样时间dt这里没有设置)还有“->”的意思可能理解有些问题:
“->”是一个整体,它是用于指向结构体、C++中的class等含有子数据的指针用来取子数据。换种说法,如果我们在C语言中定义了一个结构体,然后申明一个指针指向这个结构体,那么我们要用指针取出结构体中的数据,就要用到“->”.
struct Data
{
int a,b,c;
}; /*定义结构体*/
struct Data * p;/*定义结构体指针*/
struct Data A = {1,2,3};/*声明变量A*/
int x;/*声明一个变量x*/
p = &A ; /*让p指向A*/
x = p->a;/*这句话的意思就是取出p所指向的结构体中包含的数据项a赋值给x*/
/*由于此时p指向A,因而 p->a == A.a,也就是1*/
这里简单的理解就是在一个名为PID的数组里面,是按Error,target,measure等等这些变量名来存储数据的(PID->Error == PID.Error)
-------------------------------------------------------------
最后还想分享一下无人机串级PID的实现思路,这里的串级PID就是将控制分为内环与外环:
外环:角度环
内环: 角速度环(新增加)
有什么不对的地方欢迎各位大佬指出
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!