一篇教会你 位置式PID 在写码中的应用。

news2024/9/28 1:22:28
                          前言:编写不易,仅供学习,参考,谢谢理解,请勿转载。

#位置式|增量式PID区别

        本系列的前两篇讲的是位置式PID  没有增量式  PID ,PID的变种有很多,常见的有  位置式PID  增量式PID   PI   PD  抗饱和PID  微分先行PID  自适应PID  模糊PID 这些都是PID算法的类型。

       位置式PID;这种PID算法应用在闭环系统中,输出影响下得到的值是新的输入值,这个新的输入值就是对整个闭环系统总共的作用量

                                公式:PID=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]

        增量式PID:顾名思义,增量式PID计算得出的值,是增量,是系统输入量的基础上再增加的量,增量并不是直接作用在闭环系统的值,这个值需要加上闭环系统原本的输入量,才是作用于闭环系统的输入值。

                                公式:PID=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]

        这两个公式Kp  还有Kd  是不一样的,如果在代码里面看到,计算相同的代码,就知道是增量式PID  还是位置式PID。

#位置式PID相关变量命名

         首先在闭环控制系统中,有期望值  目前值  还有差值,声明  期望值   和  目前值  差值   还有给 PID中的  P算法   I算法  D算法  先声明三个变量。

extern float Velcity_Kp,Velcity_Ki,Velcity_Kd;

          这里只讲位置式PID的代码,在位置式PID函数的作用下是一个闭环控制系统,也就是输出对输入有影响, CurrentVelocity 就是输出,那么这个值对输入有影响, CurrentVelocity 这个值要写到PID函数里面才能有影响,然后这个控制系统根据与 TargetVelocity 的差值,会产生一个新的输入值是 Control_Velocity,同理重复循环,形成了一个闭环控制系统,结论,TargetVelocity  Control_Velocity   是PID的参数之一。

int Control_Velocity;//  经过PID系统,新的作用系统的输出值。
 int CurrentVelocity ; //实际目前速度
int TargetVelocity;//目标速度

        同时 TargetVelocity  这个值,与 CurrentVelocity  进行比较的,计算出差值,这个差值经过PID算法后产生新的 Control_Velocity ,也就是说Error。这个参数也是PID控制系统所需要的。 

int Error;
Error = TargetVelocity - CurrentVelocity;//期望速度与目前速度的差值。

  

       

        同时 Kp  Ki  Kd 这三个变量因为组成了PID算法函数,是必须给数值的,同时调节PID参数也是调节这三个值的参数。从而达到更好的控制系统表现。

//定义PID参数
#define Kp  1.0
#define Ki  0.0
#define Kd  0.0

        前两篇讲解了,纯理论公式,同时也知道了,PID算法 由P算法(Kp)    比例   I算法(Ki)  积分  D算法(Kd)   微分   组成,实际应用中,更多的是使用这三种算法的组合形式,PI  PD  PID  。

        由于 D算法(Kd),是两次误差的值,如果差值过大,Kd也就越大对Kp的抑制也就越大,需要有三个参数,上次误差Last_Error,和Error,还有 derivate

        由于Ki算法,是对误差的累加算法,需要对其进行限制幅,这里需要两个参数  Ki_Max Ki*integral    因为是位置式PID 需要对Ki进行限幅度 ,如果是增量式PID 需要对输出限幅,同时Ki也就是积分是累加的,是用 integral(积分),进行命名。

        同时Kp算法,使用参数比较少,只需要Error,前面已经声明过了,到了这里,已经讲解了,位置式PID,需要用到的参数,如果像上面一个一个声明,太麻烦了,直接定义结构体,更好一点。下面定义结构体。

typedef struct //定义结构体参数
{
    float Velcity_Kp;
    float Velcity_Ki;
    float Velcity_Kd;
    float Error;
    float Last_Error;
    float integral;
    float derivate;
	int Control_Velocity;
}PID;

#相关PID组合函数进行编写

PID初始化函数编写

void PID_Init(PID*pid,float Velcity_Kp ,float Velcity_Ki,float Velcity_Kd)
{
    pid->Velcity_Kp = Velcity_Kp;
    pid->Velcity_Ki = Velcity_Ki;
    pid->Velcity_Kd = Velcity_Kd;
    pid->Error = 0;
    pid->Last_Error = 0;
    pid->integral = 0;
    pid->Control_Velocity = 0;
    pid->derivate = 0 ; 
}
//这里声明一个指针,然后对一个结构体 取地址& 代表要初始化的实例 

        首先定义初始化函数,用来对PID结构体里面的所有成员变量进行初始化,同时传入#define  kp | ki  | kd  的值,

        到这里将,前面所有讲解的代码整合,应该是这个样子的。

PI组合函数

        到了这一步还需要再声明一个函数,用来运行PID返回计算结果。

float   PID_Calculate (PID*pid,float Velcity_Kp ,float Velcity_Ki ,float Velcity_Kd )
{

    pid->Error    = pid->Current_Velocity  - pid->TargetVelocity;
    pid->integral +=pid->Error;
    pid->Control_Velocity  = pid->Velcity_Kp*pid->Error + pid->Velcity_Ki*pid->integral;     
    pid->Last_Error = pid->Error; 

    return pid->Control_Velocity;

}

PD组合函数

float   PID_Calculate (PID*pid,float Velcity_Kp ,float Velcity_Ki ,float Velcity_Kd )
{

    pid->Error    = pid->Current_Velocity  - pid->TargetVelocity;
    pid->derivate = pid->Error - pid->Last_Error;
    pid->Control_Velocity  = pid->Velcity_Kp*pid->Error  +pid->Velcity_Kd*pid->derivate;     
    pid->Last_Error = pid->Error; 

    return pid->Control_Velocity;

}

PID组合函数

float   PID_Calculate (PID*pid,float Velcity_Kp ,float Velcity_Ki ,float Velcity_Kd )
{

    pid->Error    = pid->Current_Velocity  - pid->TargetVelocity;
    pid->integral +=pid->Error;
    pid->derivate = pid->Error - pid->Last_Error;
    pid->Control_Velocity  = pid->Velcity_Kp*pid->Error + pid->Velcity_Ki*pid->integral +pid->Velcity_Kd*pid->derivate;     
    pid->Last_Error = pid->Error; 

    return pid->Control_Velocity;

}

        PID本身就是一个应用在 云台  编码电机上的东西,单讲PID不讲应用在云台或者电机,意义不大,本篇今天收藏过30,两天内立即更  PID应用在舵机云台,编码电机,附带调试细节,附带源码。

        最后整体程序是下图这个样子

//定义PID参数
#define Kp  1.0
#define Ki  0.0
#define Kd  0.0


typedef struct //定义结构体参数
{
    float Velcity_Kp;
    float Velcity_Ki;
    float Velcity_Kd;
    float Error;
    float Last_Error;
    float integral;
    float derivate;
	  int Control_Velocity;
}PID;


void PID_Init(PID*pid,float Velcity_Kp ,float Velcity_Ki,float Velcity_Kd);

int main()
{
    PID  servo;//声明PID 结构体 变量
    PID_Init(&servo,Kp,Ki,Kd);//这几个宏定义在PID.h文件里面。
while (1){
        int output = PID_Calculate(&servo,0,180);
        setAngle(0,output);
    }
}

void PID_Init(PID*pid,float Velcity_Kp ,float Velcity_Ki,float Velcity_Kd)
{
    pid->Velcity_Kp = Velcity_Kp;
    pid->Velcity_Ki = Velcity_Ki;
    pid->Velcity_Kd = Velcity_Kd;
    pid->Error = 0;
    pid->Last_Error = 0;
    pid->integral = 0;
    pid->Control_Velocity = 0;
    pid->derivate = 0 ; 
}

                欢迎指正,希望对你,有所帮助!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1914311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小公司是如何染上大公司病的

小公司,顾名思义就是小,船小好调头。​本应该是最具拼搏精神和灵活性的小公司却不幸染上了大公司病。创业难,守业更难,这些小公司是如何染上大公司病的? 一、管理过度 某公司规定,员工出差,到…

AIGC技术引领创意设计行业革新,“谁”能成职业发展新引擎?

随着科技的日新月异,生成式人工智能(AIGC)技术正迅速崛起,成为创意设计领域的一股强大新势力。该技术不仅显著提升了设计师的工作效率,更为他们打开了前所未有的创意空间。在这一波技术浪潮中,Adobe国际认证…

高考志愿怎么选专业,哪些是热门专业?

选专业看上去非常简单,但是真正做起来的时候确实不容易,因为对于很多结束高考的学生来说,选专业就意味着他们选择自己的未来,这可是直接关系到未来的学习和职业发展,关系到将来的就业方向,再加上现在的社会…

递归 猴子吃桃-java

有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个。 以后每天猴子都吃其中的一半,然后再多吃一个。 当到第10天时,想再吃时(即还没吃),发现只有一个桃子了。 问题:最初共多少个桃…

Visual studio 2023下使用 installer projects 打包C#程序并创建 CustomAction 类

Visual studio 2023下使用 installer projects 打包C#程序并创建 CustomAction 类 1 安装Visual studio 20203,并安装插件1.1 下载并安装 Visual Studio1.2 步骤二:安装 installer projects 扩展插件2 创建安装项目2.1 创建Windows安装项目2.2 新建应用程序安装文件夹2.3 添加…

生物素修饰稀土掺杂无机荧光纳米颗粒

一、基本概述 生物素,也被称为维生素H或辅酶R,是B族维生素的一种,主要参与代谢脂肪和蛋白质,维持人体的正常生长、发育和健康。稀土掺杂无机荧光纳米颗粒则因其良好的光学性能,如窄发射带、高稳定性、良好的生物相容性…

Emacs编辑器:Codigger操作系统中的编程艺术

在Codigger分布式操作系统中,我们荣幸地引入了Emacs编辑器,这是一款全球公认的、功能强大且用途广泛的文本编辑器。它为广大的用户提供了前所未有的文本编辑和软件开发体验。通过与Codigger操作系统以及SIDE的无缝集成,用户在使用过程中可以感…

我的AI音乐梦:ChatGPT帮我做专辑

​🌈个人主页:前端青山 🔥系列专栏:AI篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来ChatGPT帮我做音乐专辑 嘿,朋友们! 想象一下,如果有个超级聪明的机器人能帮你写…

linux自动化内存监控与告警

文章目录 前言一、脚本实现1. shell脚本实现2. 脚本功能概览 二、设置定时执行1. 编辑cron任务表2. 设置定时任务 三、通知结果示例总结 前言 在当今数字化与网络化日益普及的时代,系统管理与维护成为了确保业务连续性和数据安全的关键环节。其中,监控系…

fastadmin框架后台列表固定第一行列表固定头部

在列表中,如果列表字段很多,并且每页数量很多,往下拉的时候就不好辨别数据是哪个字段的,对用户造成不好的浏览体验。 通过以下方法,可以实现将列表的第一行,也就是头部,固定在第一行显示,这样就能轻松辨别每个数据对应是哪个字段的,增加用户的使用体验。 打开项目的…

Java面试八股之为什么要使用Redis

为什么要使用Redis 1. 性能提升:高速缓存 要点:Redis作为内存数据库,数据存放在内存中,访问速度远超传统的关系型数据库(如MySQL)。在项目中,将热点数据(如经常被查询但不频繁变更…

AI大模型知识点大梳理_ai大模型的精度以下哪项描述的准确

AI大模型是什么 AI大模型是指具有巨大参数量的深度学习模型,通常**包含数十亿甚至数万亿个参数。**这些模型可以通过学习大量的数据来提高预测能力,从而在自然语言处理、计算机视觉、自主驾驶等领域取得重要突破。 AI大模型的定义具体可以根据参数规模…

汇凯金业:天然橡胶的用途和作用

天然橡胶是一种由橡胶树(Hevea brasiliensis)的乳汁加工而成的弹性体,具有弹性好、强度高、耐磨性好、耐寒性好、电绝缘性好、易于加工等优点,是世界上重要的战略物资和不可缺少的工业原料。 天然橡胶的用途十分广泛,主要应用于以下领域&…

ASUS NUC 14 Pro+:掌中宇宙,性能无界

在这个追求多样性的斜杠时代,ASUS NUC 14 Pro 顺势而生,将浩瀚宇宙般的强大性能浓缩于方寸之间,它不仅是一款设备,更是助您探索多重身份的斜杠伙伴! 浑然天成,简约而不简单 小巧的机身、简约的线条、精致的…

康谋分享 | 自动驾驶联合仿真——功能模型接口FMI(三)

在之前的两篇文章中(文末往期回顾中可查看),我们主要介绍了功能模型接口FMI的主要组成部分和一些使用场景,今天就以康谋自动驾驶仿真软件aiSim为例,来展示一下如何建立一个FMU并实现基于UDP和FMI联合仿真(c…

IT专业入门,高考假期预习指南(C++学习路线)

目录 IT专业入门,高考假期预习指南 一、V C的学习内容: 二、C学习书籍: 三、学习网站: 四、技术学习路线图: IT专业入门,高考假期预习指南 七月来临,各省高考分数已揭榜完成。而高考的完结并不意味着学习的结束,而…

buuctf 二维码

文件下载下来是一个png的文件 做misc永远的好习惯就是先运行,后010 先运行,这个运行肯定就是扫码 啥也没有 里面还有个ZIP文件(zip的发明人名字是PK) 放在kali上binwalk分离 CTF工具隐写分离神器Binwalk安装和详细使用方法_binwalk下载-CSDN博客 里面有个text,需要密码 我…

安卓腾讯桌球多功能助手直装版

安卓13自测效果,安卓12-安卓12以下一定可以的,QQ登陆的话扫码登陆,两个手机,一个扫码,一个游戏,一个手机的话,你可以下载个虚拟机,然后本机直装,用虚拟机QQ扫码即可 微信…

美国商超入驻Homedepot,会成为传统家织厂家跨境赛道吗?

近年来,随着全球化步伐的加快和电子商务的蓬勃发展,越来越多的企业开始寻求跨境拓展的机会。在这样的背景下,美国知名的家居用品零售商超——Homedepot成为了许多国内外家织厂家关注的焦点。那么,美国商超入驻Homedepot究竟如何呢…

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第56-agent自动发送短信

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第56-agent自动发送短信 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引…