当前位置: 首页 > news >正文

大连手机自适应网站建设晋江网站开发

大连手机自适应网站建设,晋江网站开发,wordpress apache nginx,网站建设层级图最近看到了Brett Beauregard发表的有关PID的系列文章#xff0c;感觉对于理解PID算法很有帮助#xff0c;于是将系列文章翻译过来#xff01;在自我提高的过程中#xff0c;也希望对同道中人有所帮助。作者Brett Beauregard的原文网址#xff1a;http#xff1a;//brettb…最近看到了Brett Beauregard发表的有关PID的系列文章感觉对于理解PID算法很有帮助于是将系列文章翻译过来在自我提高的过程中也希望对同道中人有所帮助。作者Brett Beauregard的原文网址http//brettbeauregard.com/blog/2017/06/proportional-on-measurement-the-code/ 在上一篇文章中我把所有的时间都花在解释了比例测量的好处上。在这篇文章中我将解释代码。人们似乎很欣赏我上次一步一步地解释事情的方式所以在此我也将采取这样的方式。下面的3个步骤详细介绍了我是如何将 PonM 添加到 PID 库的。 第一阶段–初始输入和比例模式选择 /*working variables*/ unsigned long lastTime; double InputOutputSetpoint; double ITermlastInput; double kpkikd; int SampleTime 1000; //1 sec double outMinoutMax; bool inAuto false;#define MANUAL 0 #define AUTOMATIC 1#define DIRECT 0 #define REVERSE 1 int controllerDirection DIRECT;#define P_ON_M 0 #define P_ON_E 1 bool PonE true; double initInput; void Compute() {if(!inAuto) return;unsigned long now millis();int timeChange (now - lastTime);if(timeChangeSampleTime){/*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 P-Term*/if(PonE) Output kp * error;else Output -kp * (Input-initInput);/*Compute Rest of PID Output*/Output 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 Kpdouble Kidouble Kdint pOn) {if (Kp0 || Ki0|| Kd0) return;PonE pOn P_ON_E;double SampleTimeInSec ((double)SampleTime)/1000;kp Kp;ki Ki * SampleTimeInSec;kd Kd / SampleTimeInSec;if(controllerDirection REVERSE){kp (0 - kp);ki (0 - ki);kd (0 - kd);} }void SetSampleTime(int NewSampleTime) {if (NewSampleTime 0){double ratio (double)NewSampleTime/ (double)SampleTime;ki * ratio;kd / ratio;SampleTime (unsigned long)NewSampleTime;} }void SetOutputLimits(double Mindouble 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) {bool newAuto (Mode AUTOMATIC);if(newAuto !inAuto){ /*we just went from manual to auto*/Initialize();}inAuto newAuto; }void Initialize() {lastInput Input;initInput Input;ITerm Output;if(ITerm outMax) ITerm outMax;else if(ITerm outMin) ITerm outMin; }void SetControllerDirection(int Direction) {controllerDirection Direction; } 随着输入的变化测量的比例提供了越来越大的阻力但如果没有参照系我们的表现会有些不稳定。如果我们第一次打开控制器时的PID输入是10000我们真的想从Kp*10000开始抵制吗不我们希望使用我们的初始输入作为参考点 (第108行)从那里开始随着输入的变化增加或减少阻力 (第38行)。 我们需要做的另一件事是允许用户选择是要在偏差上做比例或在测量上做比例。在最后一个帖子之后它看起来像 PonE 是无用的但重要的是要记住对于许多回路它工作的很好。因此我们需要让用户选择他们想要的模式 然后在计算中相应地操作。 第二阶段–动态更改整定参数 虽然上面的代码确实有效但它有一个我们以前看到的问题。当整定参数在运行时发生更改我们会得到一个不希望出现的信号。 为什么会这样 上次我们看到这一点时是积分项被一个新的Ki 重新调整。而这一次是比例项(输入-初始输入) 被新的Kp所更改。我选择的解决方案类似于我们为 Ki 所做的我们不再是将输入-初始输入作为一个整体乘以当前 Kp而是我把它分解成单独的步骤乘以当时的Kp /*working variables*/ unsigned long lastTime; double InputOutputSetpoint; double ITermlastInput; double kpkikd; int SampleTime 1000; //1 sec double outMinoutMax; bool inAuto false;#define MANUAL 0 #define AUTOMATIC 1#define DIRECT 0 #define REVERSE 1 int controllerDirection DIRECT;#define P_ON_M 0 #define P_ON_E 1bool PonE true; double PTerm; void Compute() {if(!inAuto) return;unsigned long now millis();int timeChange (now - lastTime);if(timeChangeSampleTime){/*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 P-Term*/if(PonE) Output kp * error;else{PTerm - kp * dInput;Output PTerm;}/*Compute Rest of PID Output*/Output 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 Kpdouble Kidouble Kdint pOn) {if (Kp0 || Ki0|| Kd0) return;PonE pOn P_ON_E;double SampleTimeInSec ((double)SampleTime)/1000;kp Kp;ki Ki * SampleTimeInSec;kd Kd / SampleTimeInSec;if(controllerDirection REVERSE){kp (0 - kp);ki (0 - ki);kd (0 - kd);} }void SetSampleTime(int NewSampleTime) {if (NewSampleTime 0){double ratio (double)NewSampleTime / (double)SampleTime;ki * ratio;kd / ratio;SampleTime (unsigned long)NewSampleTime;} }void SetOutputLimits(double Mindouble 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) {bool newAuto (Mode AUTOMATIC);if(newAuto !inAuto){ /*we just went from manual to auto*/Initialize();}inAuto newAuto; }void Initialize() {lastInput Input;PTerm 0;ITerm Output;if(ITerm outMax) ITerm outMax;else if(ITerm outMin) ITerm outMin; }void SetControllerDirection(int Direction) {controllerDirection Direction; } 我们现在保留一个有效的和组成的P项而不是将输入-初始输入作为一个整体乘以Kp。在每一步中我们只需将当前输入变化乘以当时的Kp并从P项(第41行) 中减去它。在这里我们可以看到变化的影响 因为旧的Kp是已经存储调整参数的变化只会影响我们后续的过程。 最终阶段–求和问题。 我不会进入完整的细节 (花哨的趋势等) 以及上述代码有什么问题。这相当不错但仍有重大问题。例如 类式积分饱和虽然最终的输出限制在OUTmin和OUTmax之间。当PTerm不应该增长时它有可能增长。它不会像积分饱和那样糟糕但仍然是不可接受的。 动态更改在运行时如果用户想从P _ On _ M 更改为P_ ON _E并在一段时间后返回那么P项将不会被初始化这会导致输出振荡。 还有更多但仅仅这些就足以让人看到真正的问题是什么。早在我们创建I项的时候我们已经处理过所有这些问题。我没有对P项重新执行相同的解决方案而是选择了一个更美观的解决方案。 通过将P项和I项合并到一个名为“outputSum”的变量中P _ ON _ M 代码将受益于已存在的所有上下文修补程序并且由于代码中没有两个总和因此不会出现不必要的冗余。 /*working variables*/ unsigned long lastTime; double InputOutputSetpoint; double outputSumlastInput; double kpkikd; int SampleTime 1000; //1 sec double outMinoutMax; bool inAuto false;#define MANUAL 0 #define AUTOMATIC 1#define DIRECT 0 #define REVERSE 1 int controllerDirection DIRECT;#define P_ON_M 0 #define P_ON_E 1 bool PonE true; void Compute() {if(!inAuto) return;unsigned long now millis();int timeChange (now - lastTime);if(timeChangeSampleTime){/*Compute all the working error variables*/double error Setpoint - Input;double dInput (Input - lastInput);outputSum (ki * error);/*Add Proportional on Measurementif P_ON_M is specified*/if(!PonE) outputSum- kp * dInputif(outputSum outMax) outputSum outMax;else if(outputSum outMin) outputSum outMin;/*Add Proportional on Errorif P_ON_E is specified*/if(PonE) Output kp * error;else Output 0;/*Compute Rest of PID Output*/Output outputSum - 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 Kpdouble Kidouble Kdint pOn) {if (Kp0 || Ki0|| Kd0) return;PonE pOn P_ON_E;double SampleTimeInSec ((double)SampleTime)/1000;kp Kp;ki Ki * SampleTimeInSec;kd Kd / SampleTimeInSec;if(controllerDirection REVERSE){kp (0 - kp);ki (0 - ki);kd (0 - kd);} }void SetSampleTime(int NewSampleTime) {if (NewSampleTime 0){double ratio (double)NewSampleTime / (double)SampleTime;ki * ratio;kd / ratio;SampleTime (unsigned long)NewSampleTime;} }void SetOutputLimits(double Mindouble Max) {if(Min Max) return;outMin Min;outMax Max;if(Output outMax) Output outMax;else if(Output outMin) Output outMin;if(outputSum outMax) outputSum outMax;else if(outputSum outMin) outputSum outMin; }void SetMode(int Mode) {bool newAuto (Mode AUTOMATIC);if(newAuto !inAuto){ /*we just went from manual to auto*/Initialize();}inAuto newAuto; }void Initialize() {lastInput Input;outputSum Output;if(outputSum outMax) outputSum outMax;else if(outputSum outMin) outputSum outMin; }void SetControllerDirection(int Direction) {controllerDirection Direction; } 现在你可以获得它。因为上述功能现在已存在于 V1.2.0版的Arduino PID库中。 但等等还有更多设定点加权。 我没有将下面的代码添加到Arduino库代码中但是如果您想滚动自己的代码这个特性可能会很有趣。设置点权重的核心是同时拥有PonE和PonM。通过指定0和1之间的比值可以得到100% PonM、100% PonE(分别)或介于两者之间的某个比值。如果您的流程不是完全集成的(比如回流炉)并且希望解释这一点那么这将非常有用。 最终我决定不在这个时候将它添加到库中因为它最终会成为另一个需要调整/解释的参数而且我不认为这样做的好处是值得的。无论如何如果你想修改代码使其具有设定值权重而不仅仅是纯PonM/PonE选择下面是代码 /*working variables*/ unsigned long lastTime; double InputOutputSetpoint; double outputSumlastInput; double kpkikd; int SampleTime 1000; //1 sec double outMinoutMax; bool inAuto false;#define MANUAL 0 #define AUTOMATIC 1#define DIRECT 0 #define REVERSE 1 int controllerDirection DIRECT;#define P_ON_M 0 #define P_ON_E 1 bool PonE truepOnM false; double PonEKppOnMKp; void Compute() {if(!inAuto) return;unsigned long now millis();int timeChange (now - lastTime);if(timeChangeSampleTime){/*Compute all the working error variables*/double error Setpoint - Input;double dInput (Input - lastInput);outputSum (ki * error);/*Add Proportional on Measurementif P_ON_M is specified*/if(pOnM) outputSum- pOnMKp * dInput;if(outputSum outMax) outputSum outMax;else if(outputSum outMin) outputSum outMin;/*Add Proportional on Errorif P_ON_E is specified*/if(PonE) Output PonEKp * error;else Output 0;/*Compute Rest of PID Output*/Output outputSum - 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 Kpdouble Kidouble Kddouble pOn) {if (Kp0 || Ki0|| Kd0 || pOn0 || pOn1) return;PonE pOn0; //some p on error is desired;pOnM pOn1; //some p on measurement is desired;double SampleTimeInSec ((double)SampleTime)/1000;kp Kp; ki Ki * SampleTimeInSec;kd Kd / SampleTimeInSec;if(controllerDirection REVERSE){kp (0 - kp);ki (0 - ki);kd (0 - kd);}PonEKp pOn * kp;pOnMKp (1 - pOn) * kp; }void SetSampleTime(int NewSampleTime) {if (NewSampleTime 0){double ratio (double)NewSampleTime / (double)SampleTime;ki * ratio;kd / ratio;SampleTime (unsigned long)NewSampleTime;} }void SetOutputLimits(double Mindouble Max) {if(Min Max) return;outMin Min; outMax Max;if(Output outMax) Output outMax;else if(Output outMin) Output outMin;if(outputSum outMax) outputSum outMax;else if(outputSum outMin) outputSum outMin; }void SetMode(int Mode) {bool newAuto (Mode AUTOMATIC);if(newAuto !inAuto){ /*we just went from manual to auto*/Initialize();}inAuto newAuto; }void Initialize() {lastInput Input;outputSum Output;if(outputSum outMax) outputSum outMax;else if(outputSum outMin) outputSum outMin; }void SetControllerDirection(int Direction) {controllerDirection Direction; } 没有将pOn设置为整数而是以双精度输入允许使用一个比率(第58行)。除了一些标记(第62行和第63行)外第77-78行计算了加权Kp项。然后在第37行和第43行将加权后的PonM和PonE贡献添加到整个PID输出中。 欢迎关注
http://www.pierceye.com/news/649323/

相关文章:

  • 在网站上如何做天气预报栏wordpress 分类列表
  • 做网站需要投资多少钱做网站的销售团队
  • 苏州哪个公司做门户网站seo优化方案报价
  • 电力建设官方网站做网站送优化
  • 门户网站建设模式包括网站群和中企动力企业邮箱登陆首页
  • 做调查网站的问卷哪个给的钱高wordpress邮箱注册功能
  • 上海php网站开发基于php网站建设
  • 大丰专业做网站做旅游网站当地人服务赚钱吗
  • 长沙网站制作公司推荐seo关键词排名优化
  • 内蒙古住房与城乡建设部网站广州十大软件公司排名
  • 营销型网站 易网拓德阳做网站
  • 网站建设seo虾哥网络购物网站技术实施方案
  • 门户网站框架下载陕西省建设工会网站
  • 网站有信心做的更好做外贸到什么网站上发布比较好
  • wex5做网站wordpress页面的设置
  • 绍兴市建设银行网站网站建设的基本术语
  • 建筑企业网站模板免费下载seo 网站换程序
  • wordpress怎么做排名seo怎么样
  • 电商网站开发平台哪家好百度运营怎么做
  • 门户网站 源码网站建设推广公司范围
  • 网站字体大小wordpress用户登录页面
  • 影院禁止18岁以下观众入内宿迁新站seo
  • 龙岗网站设计机构网站开发开始阶段的主要任务包括( )。
  • 宿州公司网站建设教做世界美食的网站
  • 网站建设价格很 好乐云seo免费自学编程
  • 网站哪家做的好公共资源交易中心级别
  • html5网站开发工具自己做微信电影网站怎么做
  • 学院网站制度建设成品大香伊煮蕉免费在线
  • 做网站的域名和空间是什么意思佛山建站专
  • 网站是哪个公司做wordpress 底部修改插件