Arduino PID库 (5):开启或关闭 PID 控制的影响

embedded/2024/10/18 7:49:45/

PID_5_PID__0">Arduino PID库 (5):开启或关闭 PID 控制的影响

Arduino PID库 (4):Reset Windup

问题

尽管拥有一个PID控制器很好,但有时你并不关心它要说什么。
BadForcedOutput

PID On - User Overwritting Output:PID 开启 - 用户覆盖输出

Confused PID keeps asking for more:混乱的 PID 不断要求更多

图中,蓝色的竖虚线表示在时间轴上,PID 控制由开启状态转为关闭的状态。如果我们对于关闭 PID 采取的操作是强制设定输出为 “PID 由开启转关闭对应的输出值或更小或为 0”。由于输出被设为定值,由于输出的 “力度” 不够,那么被控量会缓慢减少。但对于 PID 控制器来说,他不知道 PID 已经关闭了,由于被控量减少了,他就会努力增加输出,以求改变这种态势。但现实是残酷的,为何 “肆意” 增加输出,被控量却没有按照我设定的方向发展。此时,若突然又将 PID 打开了,将会有一个极大的输出,稳定性降低。
假设在程序中的某个时刻,您希望将输出强制为某个值(例如 0),您当然可以在调用例程中执行此操作:

void loop()
{
Compute();
Output=0;
}

这样,无论 PID 说什么,您都只需覆盖其值。然而,这在实践中是一个糟糕的想法。PID会变得非常困惑:“我一直在移动输出,什么也没发生!给什么?!让我再动一下。因此,当您停止覆盖输出并切换回 PID 时,您可能会立即获得输出值的巨大变化。

解决方案

这个问题的解决方案是有一种关闭和打开PID的方法。这些状态的常用术语是“手动”(我将手动调整值)和“自动”(PID 将自动调整输出)。让我们看看这是如何在代码中完成的:

《代码》

/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double ITerm, lastInput;
double kp, ki, kd;
int SampleTime = 1000; //1 sec
double outMin, outMax;
bool inAuto = false;#define MANUAL 0
#define AUTOMATIC 1void Compute()
{if(!inAuto) return;  // 这里决定开启/关闭PIDunsigned long now = millis();int timeChange = (now - lastTime);if(timeChange>=SampleTime){/*Compute all the working error variables*/double error = Setpoint - Input;ITerm+= (ki * error);if(ITerm> outMax) ITerm= outMax;else if(ITerm< outMin) ITerm= outMin;double dInput = (Input - lastInput);/*Compute PID Output*/Output = kp * error + ITerm- kd * dInput;if(Output > outMax) Output = outMax;else if(Output < outMin) Output = outMin;/*Remember some variables for next time*/lastInput = Input;lastTime = now;}
}void SetTunings(double Kp, double Ki, double Kd)
{double SampleTimeInSec = ((double)SampleTime)/1000;kp = Kp;ki = Ki * SampleTimeInSec;kd = Kd / SampleTimeInSec;
}void SetSampleTime(int NewSampleTime)
{if (NewSampleTime > 0){double ratio  = (double)NewSampleTime/ (double)SampleTime;ki *= ratio;kd /= ratio;SampleTime = (unsigned long)NewSampleTime;}
}void SetOutputLimits(double Min, double Max)
{if(Min > Max) return;outMin = Min;outMax = Max;if(Output > outMax) Output = outMax;else if(Output < outMin) Output = outMin;if(ITerm> outMax) ITerm= outMax;else if(ITerm< outMin) ITerm= outMin;
}void SetMode(int Mode)
{inAuto = (Mode == AUTOMATIC);
}

一个相当简单的解决方案。如果未处于自动模式,请立即离开计算函数,而不调整输出或任何内部变量。

结果

BetterForcedOutput
确实,您可以通过不从调用例程调用 Compute 来实现类似的效果,但此解决方案保留了 PID 的工作原理,这正是我们所需要的。通过将事情保持在内部,我们可以跟踪处于哪种模式,更重要的是,当我们更改模式时,它可以让我们知道。这就引出了下一个问题…


http://www.ppmy.cn/embedded/90433.html

相关文章

SAP与九恒星资金系统集成案例(医药行业)

一、项目环境 江西某药业有限公司是一家以医药产业为主营、资本经营为平台的大型民营企业集团。公司成立迄今&#xff0c;企业经营一直呈现稳健、快速发展的态势集团总销售额超40亿元。 为了帮助企业更好的进行资金流、结算、资金调度和运作管理、风险控制&#xff0c;济民…

SDXL总结

SDXL base部分的权重&#xff1a;https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/tree/main diffusers库中的SDXL代码pipelines&#xff1a; https://github.com/huggingface/diffusers/tree/main/src/diffusers/pipelines/stable_diffusion_xl 参考&…

通过 ACM 论文模版学习 LaTeX 语法 【三、格式】

文章目录 一、LaTeX 简介二、ACM 论文模版三、格式3.1 文章格式3.1.1 注释3.1.2 空格3.1.3 换行3.1.4 列表 3.2 字体3.2.1 字体样式3.2.2 字体大小2.2.3 字体颜色 一、LaTeX 简介 通过 ACM 论文模版学习 LaTeX 语法 【一、LaTeX简介和安装】 二、ACM 论文模版 通过 ACM 论文…

一文掌握Python全部条件执行语句(基础篇)

前言 本文&#xff0c;小编将总结一个非常实用而且非常基础的Python知识点“条件语句”。熟练掌握python条件语句&#xff0c;让你的程序代码做出精准判断&#xff0c;实现智能决策。废话不多说&#xff0c;接下来在正文中&#xff0c;将结合实际代码案例进行详细说明。 正文…

el-ui 导航菜单重复点击报错问题解决

重复点击菜单报错 NavigationDuplicated: Avoided redundant navigation to current location: xxxxx 解决办法: 路由文件.js最下边加入这段代码 //NavigationDuplicated: Avoided redundant navigation to current location 解决重复点击路由报错 // 重写路由push方法 const…

模板方法模式

1.什么是模板方法模式&#xff1f; 模板方法模式是一种设计模式&#xff0c;用于定义算法的框架结构&#xff0c;将算法中不变的部分封装在父类中&#xff0c; 而将可变的部分延迟到子类中实现。 2.使用场景&#xff1a; 框架设计&#xff1a;在框架设计中&#xff0c;模板方法…

使用Chainlit接入通义千问快速实现一个自然语言转sql语言的智能体

文本到 SQL 让我们构建一个简单的应用程序&#xff0c;帮助用户使用自然语言创建 SQL 查询。 最终结果预览 ​ 先决条件 此示例有额外的依赖项。你可以使用以下命令安装它们&#xff1a; pip install chainlit openai​ 导入 应用程序 from openai import AsyncOpenAI…

HarmonyOS多目标产物构建最佳实践

背景 在Android或iOS开发时经常会有打“马甲”包的场景&#xff0c;就是一套代码打出不同主题的包&#xff0c;一个公司的产品可能针对不同用户提供不同的应用&#xff0c;比如抖音有国内版也有国外版&#xff0c;滴滴有个人版还有企业版&#xff0c;同样的在鸿蒙平台也有类似…