专家PID

2023-11-18

专家PID

专家控制

专家控制是模拟人类专家控制的方式。它具有大量的专门知识和经验,和专家控制一样不需要知道对象的模型的情况下,对系统进行控制。

专家控制的基本结构

和人类专家控制一样,知识库越是丰富,推理机越是精确,控制效果也就越好。不同的知识库和推理机,控制效果也不经相同。这也是专家控制的一个特点,利用这个特点,可以设计属于自己的专家控制系统。

在这里插入图片描述

专家控制的基本实现

直接性专家控制

专家控制器直接对执行机构进行控制。
在这里插入图片描述

间接型专家控制

专家控制通过控制算法,对控制器进行操作,由控制器对执行机构进行控制。
在这里插入图片描述

专家PID

专家PID是专家控制和PID的结合,两者都不需要知道被控对象的模型。

简单的专家PID
下面的例子是增量式PID的实现方式,理解了思路,也就是对偏差和偏差增量的判断采取控制。便可以用C语言进行实现。

通过偏差偏差的增量来判断应采用的PID控制类型,从而更快更平稳地实现收敛。

下面是这个是普遍型的规则库的实现:

当前时刻误差
在这里插入图片描述
误差增量
在这里插入图片描述
上次误差增量在这里插入图片描述
K1和K2为增益系数,K1>K2
M1,M2为设定的误差界限,M1>M2>M3

这里的专家控制有5条控制规则:

1:误差超过设定的最大值(M1),输出PID控制器的最大值,进行开环控制,对极限情况进行控制。以迅速达到偏差作用。

在这里插入图片描述

2:误差的绝对值在变大或者维持常值,实施较强的控制作用

在这里插入图片描述
再次对偏差进行判断,选择不同的控制强度。

若误差超过设定的最大值(M2),实行较强控制,减少误差

控制器输出:
在这里插入图片描述
若误差小于设定的最大值(M2),实现一般较弱控制

控制器输出:也可以减少K1的值
在这里插入图片描述
说明此时误差仍然较大,可将 k1增大,反之可以减小。这样可以比分别使用两套参数减少2个待调参数,当然模型的容量也有一定程度下降。

3:误差的绝对值减少后者误差已经达到平衡状态,维持控制器输出不变

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

4:误差处于极值状态

在这里插入图片描述
再次对偏差进行判断,选择不同的控制强度。

若误差超过设定的最大值(M2),实行较强控制,减少误差

控制器输出:
在这里插入图片描述
若误差小于设定的最大值(M2),实现较弱控制

控制器输出:

在这里插入图片描述

5:若误差小于设定的最小值(M3),增加控制精度

在这里插入图片描述
设置控制精度,可能是由系统的静差导致的,用PI控制,减少静差。
在这里插入图片描述
Kp和Ki可以适当减小,以减小控制作用。当偏差小到一定程度后,甚至可以引入死区的概念,是系统稳定下来而不需要去进行调节。

思维导图

在这里插入图片描述

C语言实现:增量式专家PID

//输出限幅
#define OUT_MIN		-1000
#define OUT_MAX		1000

#define DEAD_BAND 10 //死区控制线
#include"math.h"           
//PID结构体
//PID结构体
typedef struct
{
	volatile double    Proportion; // 比例常数 Proportional Const
	volatile double    Integral; // 积分常数 Integral Const
	volatile double    Derivative;// 微分常数 Derivative Const
	volatile double      Error1; // Error[n-1]
	volatile double      Error2; // Error[n-2]
	volatile double      iError;  // Error[n]
	volatile double		 Error_sum;//积分值
	volatile double		 iIncpid;//PID输出值
	volatile double    inc_iError;//Error[n]增量
	volatile double    inc_Error1;//Error[n-1]增量
	volatile double		 Error_abs_Max;//偏差绝对值最大值
	volatile double		 Error_abs_Mid;//偏差绝对值最中值
	volatile double		 Error_abs_Min;//偏差绝对值最小值
} PID;

/****************************************************************************************/																												//								增量式专家
//										//pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]	
/****************************************************************************************/
double Exper_Pid_Inc (double iError,PID* sptr) 
{
   double result=0;
   sptr->iError=iError;  //传入当前误差
   sptr->inc_iError=sptr->iError-sptr->Error1;//得到这次增量
   sptr->inc_Error1=sptr->Error1-sptr->Error2;//得到上次增量
   if(abs(sptr->iError)>sptr->Error_abs_Max)//误差超过设定的最大值(M1)
   {
		if(sptr->iError>0)  result=OUT_MAX;
   	 	if(sptr->iError<0)  result=OUT_MIN;
   }

	if(abs(sptr->iError)<=sptr->Error_abs_Min)//若误差小于设定的最小值(M3)
   {
   	if(fabs(sptr->iError)>DEAD_BAND) //死区控制
   	{
	 result=sptr->iIncpid+0.5*sptr->Proportion * sptr->inc_iError  // P
         +0.3*sptr->Integral * sptr->iError;                // I
     }
     else result=0;
   }
     if((sptr->iError*sptr->inc_iError<0)&&(sptr->inc_iError*sptr->inc_Error1>0))||(sptr->iError==0))
    //说明误差正在减小,或者为零,此时维持原输出
  {
    result=sptr->iIncpid;//保持上一次输出
  }
  
	if((sptr->iError*sptr->inc_iError<0)&&(sptr->inc_iError*sptr->inc_Error1<0)))//误差处于极值状态
  {
  	if(abs(sptr->iError)>sptr->Error_abs_Mid)    result=sptr->iIncpid+1.2*sptr->Integral*sptr->iError;
    if(abs(sptr->iError)<sptr->Error_abs_Mid)    result=sptr->iIncpid+0.6*sptr->Integral*sptr->iError;
  }

  	if(((sptr->iError*sptr->inc_iError>0)||(sptr->inc_iError==0))//误差在变大,或维持长值
  {
  	if(abs(sptr->iError)>sptr->Error_abs_Mid)    result=sptr->iIncpid+2*(sptr->Integral*sptr->iError+sptr->Proportion*sptr->inc_iError+sptr->Derivative*(sptr->inc_iError-sptr->inc_Error1));
  	
    if(abs(sptr->iError)<sptr->Error_abs_Mid)    result=sptr->iIncpid+1.2*(sptr->Integral*sptr->iError+sptr->Proportion*sptr->inc_iError+sptr->Derivative*(sptr->inc_iError-sptr->inc_Error1));
  }

  //更新值
  sptr->iIncpid=result;    
  sptr->Error2=sptr->Error1; 
  sptr->Error1=sptr->iError;	
  result=PID_OutputLimit(result);//PID输出限幅								
  return(result);          // 返回计算值
	
}

//PID输出限制,根据PWM的输出值进行增量式PID输出限制
double PID_OutputLimit(double output)  
{
		
    if (output < OUT_MIN)
		{
        output = OUT_MIN;
    }		
		else if (output > OUT_MAX)
		
		{
        output = OUT_MAX;
    }
    return output;
}

C语言实现:位置式专家PID

//输出限幅
#define OUT_MIN		-1000
#define OUT_MAX		1000
//积分限幅
#define INERGRAL_MAX 200
#define INERGRAL_MIX -200

#include"math.h"           
//PID结构体
typedef struct
{
	volatile double    Proportion; // 比例常数 Proportional Const
	volatile double    Integral; // 积分常数 Integral Const
	volatile double    Derivative;// 微分常数 Derivative Const
	volatile double      Error1; // Error[n-1]
	volatile double      Error2; // Error[n-2]
	volatile double      iError;  // Error[n]
	volatile double		 Error_sum;//积分值
	volatile double		 iIncpid;//PID输出值
	volatile double    inc_iError;//Error[n]增量
	volatile double    inc_Error1;//Error[n-1]增量
	volatile double		 Error_abs_Max;//偏差绝对值最大值
	volatile double		 Error_abs_Mid;//偏差绝对值最中值
	volatile double		 Error_abs_Min;//偏差绝对值最小值
} PID;

/****************************************************************************************/																												//								位置式专家PID
//										//pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]	
/****************************************************************************************/
#include "math.h"
//********************************PID算法部分************************************//
#define OUT_MIN		-500
#define OUT_MAX		500

//积分限幅
#define INERGRAL_MAX 200
#define INERGRAL_MIN -200

//PID初始化
void PID_Init(PID *sptr)
{
	sptr->Derivative = 0;//Kd
	sptr->Proportion = 0;//Kp
	sptr->Integral = 0;//Ki
	sptr->Error2 = 0;
	sptr->Error1 = 0;
	sptr->iError = 0;
	sptr->Error_sum = 0;
	//sptr->index=1;
	sptr->iIncpid = 0;
	sptr->inc_iError = 0;
	sptr->inc_Error1 = 0;
	sptr->Error_abs_Max = 150;
	sptr->Error_abs_Mid = 100;
	sptr->Error_abs_Min = 50;

}

//PID输出限幅处理
double PID_OutputLimit(double output)
{
	double x;
	x = output;
	if (x <= OUT_MIN)
	{
		x = (double)OUT_MIN;
	}
	else if (x >= OUT_MAX)

	{
		x = (double)OUT_MAX;
	}
	return x;
}

/****************************************************************************************/																												//								增量式专家
//										//pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]	
/****************************************************************************************/
double Exper_Pid_Pos(double iError, PID* sptr)
{
	double result = 0;
	sptr->iError = iError;  //传入当前误差
	sptr->inc_iError = sptr->iError - sptr->Error1;//得到这次增量
	sptr->inc_Error1 = sptr->Error1 - sptr->Error2;//得到上次增量
	  sptr->iError=iError;                                    // 计算当前误差
  
	sptr->Error_sum+=sptr->iError;//积分项	
		///当输出限幅的时候,积分累加部分也应同时进行限幅,以防输出不变而积分项继续累加,也即所谓的积分饱和过深。
	//积分量限幅
	if(sptr->Error_sum >=INERGRAL_MAX)
	{
		sptr->Error_sum = INERGRAL_MAX ;
	}
	if(sptr->Error_sum < INERGRAL_MIN)
	{
		sptr->Error_sum =INERGRAL_MIN ;
	}

	if (fabs(sptr->iError) > sptr->Error_abs_Max)//误差超过设定的最大值(M1)
	{
		if (sptr->iError > 0)  result = OUT_MAX;
		if (sptr->iError < 0)  result = OUT_MIN;
	}

	if (fabs(sptr->iError) <= sptr->Error_abs_Min)//若误差小于设定的最小值(M3)
	{
		if (fabs(sptr->iError) > DEAD_BAND) //死区控制
		{
			result = 0.5*sptr->Proportion * sptr->iError// P
				+ 0.3*sptr->Integral * sptr->Error_sum ;                // I
		}
		else result = 0;
	}
	if (((sptr->iError*sptr->inc_iError < 0) && (sptr->inc_iError*sptr->inc_Error1 > 0)) || (sptr->iError == 0))
		//说明误差正在减小,或者为零,此时维持原输出
	{
		result = sptr->iIncpid;//保持上一次输出
	}

	if (((sptr->iError*sptr->inc_iError < 0) && (sptr->inc_iError*sptr->inc_Error1 < 0)))//误差处于极值状态
	{
		if(fabs(sptr->iError)>sptr->Error_abs_Mid)    result=1.8*sptr->Integral*sptr->Error_sum;
   	    if(fabs(sptr->iError)<sptr->Error_abs_Mid)    result=1.2*sptr->Integral*sptr->Error_sum;
	}

	if ((sptr->iError*sptr->inc_iError > 0) || (sptr->inc_iError == 0))//误差在变大,或维持长值
	{
  	if(abs(sptr->iError)>sptr->Error_abs_Mid)    result=2*(sptr->Integral*sptr->Error_sum+sptr->Proportion*sptr->iError+sptr->Derivative*sptr->inc_iError);
  	
    if(abs(sptr->iError)<sptr->Error_abs_Mid)    result=1.1*(sptr->Integral*sptr->Error_sum+sptr->Proportion*sptr->iError+sptr->Derivative*sptr->inc_iError);
	}

	//更新值
	sptr->iIncpid = result;
	sptr->Error2 = sptr->Error1;
	sptr->Error1 = sptr->iError;
	result = PID_OutputLimit(result);//PID输出限幅								
	return(result);          // 返回计算值

}


//PID输出限制,根据PWM的输出值进行增量式PID输出限制
double PID_OutputLimit(double output)  
{
		
    if (output < OUT_MIN)
		{
        output = OUT_MIN;
    }		
		else if (output > OUT_MAX)
		
		{
        output = OUT_MAX;
    }
    return output;
}

总结

通过这个简单的例子,大概了解直接性专家控制。最明显的优势,控制决策的灵活性,可以根据不同的系统,选择不同和设计不同的控制策略,通过修改、增加控制规则,可不断积累知识,改进控制性能。能够满足任意动态过程的控制需要,尤其适用于带有时变、非线性和强干扰的控制;但问题是,调试比普通PID复杂,设计的控制规则需要经验。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

专家PID 的相关文章

随机推荐

  • Apache HTTP Server 2.4.49 路径穿越漏洞复现及利用

    漏洞介绍 Apache HTTP Server是Apache基金会开源的一款流行的HTTP服务器 在其2 4 49版本中 引入了一个路径穿越漏洞 满足下面两个条件的Apache服务器将会受到影响 版本等于2 4 49 穿越的目录允许被访问
  • html任务3 模拟滚动条,vue3系列:vue3.0自定义虚拟滚动条V3Scroll

    Desc Vue3 0虚拟滚动条组件V3Scroll Time andy by 2021 01 About Q 282310962 wx xy190310 props Vue3 x自定义指令写法 监听DOM尺寸变化 directives r
  • 微信小程序之基础指南

    目录 1 申请账号 2 微信开发者工具 3 小程序代码构成 3 1 JSON配置 3 1 1 小程序全局配置app json 3 1 2 小程序页面配置 3 1 3 sitemap 配置 4 小程序框架 4 1 场景值 4 2 注册小程序
  • 探密微信小程序开发中的OpenlD

    说到微信小程序开发 我们不得不提到原生系统中自带的OPENiD 用户在跟公众号交互时 为了让程序识别用户的身份 需要有一个身份标识 出于对用户信息安全的考虑 保护用户隐私 微信没有暴露用户的微信号 而是对开发者提供OpenlD 它是一个由数
  • 数学建模(三)—— 自动化车床管理

    一 题目要求 二 相关的基础知识 2 1 正态分布的假设检验 2 2 正态分布的概率 三 问题分析 四 模型的建立与求解 4 1 数据处理及分析 4 2 问题一模型的建立与求解 4 2 1 问题一模型的建立 4 2 2 问题一模型的求解 4
  • 面试复习题--音视频

    1 音频处理 oboe openSL es AAudio 2 视频处理 ffmpeg 3 图片处理 GPUImage OpenCV fastCV 4 图形基础 skia Vulkan
  • 匿名信V1.4.5.1版本更新“数据大屏”功能

    匿名信V1 4 5 1版本更新 数据大屏 功能 源码下载 匿名信h5源码 万策云盘 匿名信安装教程 匿名信v1 4 4源码下载 安装教程 匿名信 廖万里的博客 本文链接 匿名信V1 4 5 1版本更新 数据大屏 功能 匿名信 廖万里的博客
  • java中long最大值源码表示_通过JDK源码角度分析Long类详解

    概况 Java的Long类主要的作用就是对基本类型long进行封装 提供了一些处理long类型的方法 比如long到String类型的转换方法或String类型到long类型的转换方法 当然也包含与其他类型之间的转换方法 除此之外还有一些位
  • MySQL简述1

    MySQL是什么 MySQL优点 MySQL的四种分类 数据库的三大范式 多表查询 左连接 右连接 内连接 交叉连接 显式 隐式 子查询 事物 特性 原子性 一致性 隔离性 持久性 并发问题 脏读 读未提交 不可重复读 读已提交 幻读 可重
  • 机器学习之高斯过程

    高斯过程 高斯过程 Gaussian Process 高斯分布 置信区间 随机过程 高斯分布的特点 核函数 白噪声处理 实战 高斯过程 Gaussian Process 在机器学习领域里 高斯过程是一种假设训练数据来自无限空间 并且各特征都
  • Fiddler 微信小程序抓图教程(非常详细)从零基础入门到精通,看完这一篇就够了

    前言 本篇文章主要给大家详细讲解如何用Fiddler爬取微信小程序的图片 内容图文并茂 流程非常简单 我们开始吧 目录 一 获取软件并打开 二 点击工具设置相关代理 三 如何抓图 四 答疑 五 总结 一 获取软件并打开 1 通过百度网盘下载
  • 因果推断----do演算

    do演算 合法 的do表达式变换 规则1 如果我们观察到变量W与Y无关 其前提可能是以其他变量Z为条件 那么Y的概率分布就不会随W而改变 即 P Y d
  • vue3+elementPlus-浏览器告警解决error.ts:14 ElementPlusError: [ElPagination] 你使用了一些已被废弃的用法,请参考 el-pagination

    问题 在使用elementuiPlus的分页器组件的时候 发现会有如下图警告 检查代码
  • 微信小程序父组件向子组件传参,子组件样式无效问题处理

    微信小程序父组件向子组件传参 子组件样式无效问题处理 父组件代码 引入 json usingComponents evaluate evaluate evaluate wxml
  • dp 1.4协议_浅析关于HDMI接口与DP接口

    显示器现在主流已经为HDMI接口与DP接口 那么这些接口都有什么区别 以下表格会大致做个区分 建议优先使用DP接口 HDMI2 1接口目前仅发布协议 尚未大规模商用在高清电视机上有部分应用 Mini DP接口版本为DP1 2 HDMI2 1
  • libcurl库安装心得

    一 libcurl简介 libcurl是一个跨平台的网络协议库 支持http https ftp gopher telnet dict file 和ldap 协议 libcurl同样支持HTTPS证书授权 HTTP POST HTTP PU
  • JSON工具类

    在实际开发中通服都是使用JSON格式数据 那么如何跟JSON打交道呢 下面就写一些JSON的常用转换工具 以及JSON数据提取 目录 阿里的FastJSON JSONObject类 JSON类 JSONArray JSONPath Json
  • 分子对接教程

    TCGA GEO 文献阅读 数据库 理论知识 R语言 Bioconductor 服务器与Linux 接前文 分子对接教程 1 软件安装准备 分子对接教程 2 选择合适的蛋白受体 分子对接教程 3 配体分子文件格式转换 分子对接教程 4 蛋白
  • QT 中文版信息提示框

    引言 在QT设计UI程序过程中 整套系统都是中文版本 然而信息提示默认只有中文 难免有点小纠结 这里针对QMessageBox稍微做了一点点改进 使其支持完美的中文提示框 调用方式非常简单 只需要将QMessageBox调用地方 改为QSh
  • 专家PID

    专家PID 专家控制 专家控制是模拟人类专家控制的方式 它具有大量的专门知识和经验 和专家控制一样不需要知道对象的模型的情况下 对系统进行控制 专家控制的基本结构 和人类专家控制一样 知识库越是丰富 推理机越是精确 控制效果也就越好 不同的