首页 > 编程语言 >常见的PID的算法及代码示例

常见的PID的算法及代码示例

时间:2024-08-05 19:27:46浏览次数:11  
标签:ek 示例 float PID 算法 LIMIT location out

常见的PID的算法及代码示例

PID(比例-积分-微分)算法是控制系统中常用的一种反馈控制算法,它通过计算误差的比例、积分和微分来调整控制输入,以达到预定的控制目标。以下是一些常见的PID算法及代码示例:

一、常见的PID算法

  1. 位置式PID算法
    • 位置式PID算法直接计算控制量的绝对值,每次输出都与过去的状态有关,因此计算量相对较大。其计算公式为:u(k)=Kpe(k)+K**ij=0k**e(j)+K**d[e(k)−e(k−1)]
    • 其中,u(k) 是第 k 次的控制量,e(k) 是第 k 次的误差,K**pK**iK**d 分别是比例、积分、微分系数。
  2. 增量式PID算法
    • 增量式PID算法只计算控制量的增量,即本次控制量与上一次控制量之差,因此计算量相对较小,且更易于实现无扰动切换。其计算公式为:Δu(k)=K**p[e(k)−e(k−1)]+Kie(k)+K**d[e(k)−2e(k−1)+e(k−2)]
    • 实际应用中,控制量 u(k) 可通过累加增量 Δu(k) 来获得。

二、代码示例

pid.c

#include "stm32f10x.h"
#include <math.h>
#include "sys.h"
#include "pid.h"
#define PID_LIMIT_MIN -10000		//PID输出最低值
#define PID_LIMIT_MAX 10000	//PID输出最大值
//注意:PID结构体必须定义为全局变量或静态变量,然后在函数中给KP,KI,KD赋值
/************************采样周期未知且不变************************************/
//位置式PID
//pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]
//setvalue : 设置值(期望值)
//actualvalue: 实际值
//由于全量输出,每次输出均与过去状态有关,计算时要对ek累加,计算量大
float PID_location(float setvalue, float actualvalue, PID_LocTypeDef *PID)
{ 
	PID->ek =setvalue-actualvalue;
	PID->location_sum += PID->ek;                         //计算累计误差值
	if((PID->ki!=0)&&(PID->location_sum>(PID_LIMIT_MAX/PID->ki))) PID->location_sum=PID_LIMIT_MAX/PID->ki;
	if((PID->ki!=0)&&(PID->location_sum<(PID_LIMIT_MIN/PID->ki))) PID->location_sum=PID_LIMIT_MIN/PID->ki;//积分限幅
	
  PID->out=PID->kp*PID->ek+(PID->ki*PID->location_sum)+PID->kd*(PID->ek-PID->ek1);
  PID->ek1 = PID->ek;  
	if(PID->out<PID_LIMIT_MIN)	PID->out=PID_LIMIT_MIN;
	if(PID->out>PID_LIMIT_MAX)	PID->out=PID_LIMIT_MAX;//PID->out限幅
	
	return PID->out;
}
//增量式PID
//pidout+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
//setvalue : 设置值(期望值)
//actualvalue: 实际值
float PID_increment(float setvalue, float actualvalue, PID_LocTypeDef *PID)
{                                
	PID->ek =setvalue-actualvalue;
  PID->out+=PID->kp*(PID->ek-PID->ek1)+PID->ki*PID->ek+PID->kd*(PID->ek-2*PID->ek1+PID->ek2);
//	PID->out+=PID->kp*PID->ek-PID->ki*PID->ek1+PID->kd*PID->ek2;
  PID->ek2 = PID->ek1;
  PID->ek1 = PID->ek;  
		
	if(PID->out<PID_LIMIT_MIN)	PID->out=PID_LIMIT_MIN;
	if(PID->out>PID_LIMIT_MAX)	PID->out=PID_LIMIT_MAX;//限幅
	
	return PID->out;
}
 

pid.h

#ifndef __PID_H
#define __PID_H
 
#include "stm32f10x.h"
#include <math.h>
#include "sys.h"
 
typedef struct
{
  float kp;                       //比例系数Proportional
  float ki;                       //积分系数Integral
  float kd;                       //微分系数Derivative
//	float ti;                       //积分时间常数
//  float td;                       //微分时间常数
//	float period;										//采样周期
  float ek;                       //当前误差
  float ek1;                      //前一次误差e(k-1)
  float ek2;                      //再前一次误差e(k-2)
  float location_sum;             //累计积分位置
	float out;											//PID输出值
}PID_LocTypeDef;
float PID_location(float setvalue, float actualvalue, PID_LocTypeDef *PID);
float PID_increment(float setvalue, float actualvalue, PID_LocTypeDef *PID);
#endif

注意:上述代码,在实际应用中,可能需要使用操作系统的定时器或中断来实现。

标签:ek,示例,float,PID,算法,LIMIT,location,out
From: https://www.cnblogs.com/zkbklink/p/18343915

相关文章

  • 贪心算法-活动安排问题
    贪心算法贪心算法总是选择当前看起来最优的选择(局部最优解),希望得到的结果是一个整体最优解。但是,并非总是选择局部最优解就能够得到整体最优解,这一点需要在问题具有贪心选择性和优化子结构时才成立。贪心选择性贪心选择性:第一次做出贪心选择是正确的。优化子结构问题......
  • emsdk安装和编译2个C++基础示例
    参考地址:Downloadandinstall—Emscripten3.1.65-git(dev)documentation 环境:ubuntu24.04LTSgcc(Ubuntu13.2.0-23ubuntu4)13.2.0g++(Ubuntu13.2.0-23ubuntu4)13.2.0cmakeversion3.28.3 Firstcheckthe Platform-specificnotes belowandinstallan......
  • leetcode200. 岛屿数量C++题解,精美图例和流程图,一题带你弄懂图的dfs遍历算法
    leetcode200.岛屿数量给你一个由‘1’(陆地)和‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。示例1:输入:grid=[[“1”,“1”,“1”,......
  • v-md-editor示例
    pnpmcreatefarm@latest#选择vue3cdprojectpnpmi@kangc/v-md-editor@next修改index.ts:import{createApp}from'vue';//import'./style.css';importAppfrom'./App.vue';importVueMarkdownEditorfrom'@kangc/v-md-ed......
  • 代码随想录算法训练营day04之字符串
    题目及链接:344.反转字符串541.反转字符串||卡码网54.替换数字151.翻转字符串里的单词卡码网55.右旋字符串28.找出字符串中第一个匹配项的下标459.重复的子字符串344.反转字符串太简单就不写了541.反转字符串||题意:给定一个字符串s和一个整数k,从字符串开头算起,每......
  • Kotlin 布尔值教程:深入理解与应用示例
    Kotlin布尔值在编程中,您经常需要一种只能有两个值的数据类型,例如:是/否开/关真/假为此,Kotlin有一种布尔数据类型,可以取true或false值。布尔值布尔类型可以用Boolean关键字声明,并且只能取true或false值:示例valisKotlinFun:Boolean=truevalisFish......
  • 空域滤波算法
    空域滤波算法是图像处理中用于去除噪声的一类方法,它们直接在图像的像素坐标系中操作,通过分析图像中像素与周围像素的关系来去除噪声。以下是几种常见的空域滤波算法的原理描述及其在MATLAB中的实现代码。  1.均值滤波均值滤波是一种简单的线性滤波方法,它通过替换图像中每个......
  • vue2 - 最新详细实现高德地图绘制动态热力图详细教程,在某区域或城市地图上做“热力图
    效果图在vue2、nuxt2项目开发中,详解引入使用高德地图接收热力图数据并渲染“热力图”效果功能,在地图上的某个区域或某个城市(可多个)、省份等自由绘制对应的热力图层,各城市地区同时加载渲染热力流量区域用以对比,根据不同的颜色代表人口密度、客流量、旅游人数、交通流量......
  • Kotlin 布尔值教程:深入理解与应用示例
    Kotlin布尔值在编程中,您经常需要一种只能有两个值的数据类型,例如:是/否开/关真/假为此,Kotlin有一种布尔数据类型,可以取true或false值。布尔值布尔类型可以用Boolean关键字声明,并且只能取true或false值:示例valisKotlinFun:Boolean=truevalisFi......
  • 可用于机器学习的排列组合枚举算法含passcal - c shap-c源码
    可用于机器学习的排列组合枚举算法含passcal-cshap-c源码1机器学习和数据挖掘• 特征选择:在机器学习中,需要从多个特征中选择最有价值的组合。通过枚举不同的特征组合,可以找到最佳的特征集合。• 超参数优化:在训练模型时,需要调整多个超参数。通过枚举不同的超参数组......