完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
/* ==================================================================================File name: PID_REG3.H (IQ version) =====================================================================================*/#ifndef __PIDREG3_H__#define __PIDREG3_H__typedef struct [ _iq Ref; // Input: Reference input _iq Fdb; // Input: Feedback input _iq Err; // Variable: Error _iq Kp; // Parameter: Proportional gain _iq Up; // Variable: Proportional output _iq Ui; // Variable: Integral output _iq Ud; // Variable: Derivative output _iq OutPreSat; // Variable: Pre-saturated output _iq OutMax; // Parameter: Maximum output _iq OutMin; // Parameter: Minimum output _iq Out; // Output: PID output _iq SatErr; // Variable: Saturated difference _iq Ki; // Parameter: Integral gain _iq Kc; // Parameter: Integral correction gain _iq Kd; // Parameter: Derivative gain _iq Up1; // History: Previous proportional output ] PIDREG3; typedef PIDREG3 *PIDREG3_handle;/*-----------------------------------------------------------------------------Default initalizer for the PIDREG3 object.-----------------------------------------------------------------------------*/ #define PIDREG3_DEFAULTS [ 0, 0, 0, _IQ(1.3), 0, 0, 0, 0, _IQ(1), _IQ(-1), 0, 0, _IQ(0.02), _IQ(0.5), _IQ(1.05), 0, ]/*------------------------------------------------------------------------------ PID Macro Definition------------------------------------------------------------------------------*/#define PID_REG3_MACRO(v) v.Err = v.Ref - v.Fdb; /* Compute the error */ v.Up= _IQmpy(v.Kp,v.Err); /* Compute the proportional output */ v.Ui= v.Ui + _IQmpy(v.Ki,v.Up) + _IQmpy(v.Kc,v.SatErr); /* Compute the integral output */ v.OutPreSat= v.Up + v.Ui; /* Compute the pre-saturated output */ v.Out = _IQsat(v.OutPreSat, v.OutMax, v.OutMin); /* Saturate the output */ v.SatErr = v.Out - v.OutPreSat; /* Compute the saturate difference */ v.Up1 = v.Up; /* Update the previous proportional output */#define PID_REG3_POS_MACRO(v) v.Err = v.Ref - v.Fdb; /* Compute the error */ if (v.Err >= _IQ(0.5)) v.Err -= _IQ(1.0); /* roll in the error */ else if (v.Err <= _IQ(-0.5)) v.Err += _IQ(1.0); /* roll in the error */ v.Up= _IQmpy(v.Kp,v.Err); /* Compute the proportional output */ v.Ui= v.Ui + _IQmpy(v.Ki,v.Up) + _IQmpy(v.Kc,v.SatErr); /* Compute the integral output */ v.Ud = _IQmpy(v.Kd,(v.Up - v.Up1)); v.OutPreSat= v.Up + v.Ui + v.Ud; /* Compute the pre-saturated output */ v.Out = _IQsat(v.OutPreSat, v.OutMax, v.OutMin); /* Saturate the output */ v.SatErr = v.Out - v.OutPreSat; /* Compute the saturate difference */ v.Up1 = v.Up;#endif // __PIDREG3_H__// Add the lines below if derivative output is needed following the integral update位置在ticontrolSUITElibsapp_libsmotor_controlmath_blocksv4.3/
在给出的文档中似乎没有对这个的说明(看大家用的这个,也打算用这个。把Kd设为0就是PI了吧) 1、Kc,积分校正增益,没明白是什么作用 2、这个是增量式PID吗? 3、SatErr,饱和差,好像是v->SatErr = v->Out - v->OutPreSat;,但不知道什么用 4、v.Ui= v.Ui + _IQmpy(v.Ki,v.Up) + _IQmpy(v.Kc,v.SatErr);也即是// Compute the integral output v->Ui = v->Ui +v->Ki*v->Up + v->Kc*v->SatErr;其中的v->Kc*v->SatErr;怎么理解啊,为什么加上v->Ki*v->Up + v->Kc*v->SatErr,加上当前误差乘以Ki不就可以了吗? 5、// Compute the derivative output v->Ud = v->Kd*(v->Up - v->Up1);计算微分的时候为什么用的是比例输出。 6、_iq换成了float32, _IQ(1.3)换成1.3也可以吧。想换成浮点型的。 谢谢 |
|
相关推荐
19 个讨论
|
|
|
你好!
我是一个DSP的菜鸟不知理解的对不对,2你的这个算法好像不是增量式的PID,好像是位置式的PID, Up= _IQmpy(v.Kp,v.Err),比例环节,Ui= v.Ui + _IQmpy(v.Ki,v.Up)积分环节,Ud = _IQmpy(v.Kd,(v.Up - v.Up1))微分环节,饱和差我也不是很清楚,但是位置式的PID由于积分一直在累加求和因此需要退饱和,具体怎么退饱和我没有接触过所以我说不清楚。Ud = v->Kd*(v->Up - v->Up1)这是微分环节离散化之后的公式,以上的三个PID都是经过离散化的,Kd(du/dt),离散化就是前后两个时间的差值,也就是Kd*(v->Up - v->Up1)。而增量式PID比位置式的多一步,增量式是前后两个时间位置PID的差值。不知我理解的对不对,仅供你参考!谢谢! |
|
|
|
|
|
|
|
Jayden888 发表于 2020-5-29 15:22 谢谢您的回答,不过_iq换成了float32, _IQ(1.3)换成1.3也可以吧。想换成浮点型的。 Ui= v.Ui + _IQmpy(v.Ki,v.Up)积分环节,这个是得出积分的输出,但是不应该是v.Ui +KI*Err吗,为什么是_IQmpy(v.Ki,v.Up),谢谢 |
|
|
|
|
|
|
|
nvhyfwe 发表于 2020-5-29 15:38 您好! 关于这个问题,我也有疑问,我比较同意你的看法v.Ui +KI*Err,不知是不是这个PID中间还有其他的传递环节,因为我上面写的那个参考是最简单的数学模型,你的这个应该比较复杂点,所以我也没什么把握!我再查查资料,如果你弄明白了也请给我留言谢谢! |
|
|
|
|
|
|
|
|
我新下载了control suit ,但是找到的pid_reg3.h和你的不一样
我的文件位置是: 内容: /* ================================================================================== File name: PID_REG3.H (IQ version) =====================================================================================*/ #ifndef __PIDREG3_H__ #define __PIDREG3_H__ typedef struct [ _iq Ref; // Input: Reference input _iq Fdb; // Input: Feedback input _iq Err; // Variable: Error _iq Kp; // Parameter: Proportional gain _iq Up; // Variable: Proportional output _iq Ui; // Variable: Integral output _iq Ud; // Variable: Derivative output _iq OutPreSat; // Variable: Pre-saturated output _iq OutMax; // Parameter: Maximum output _iq OutMin; // Parameter: Minimum output _iq Out; // Output: PID output _iq SatErr; // Variable: Saturated difference _iq Ki; // Parameter: Integral gain _iq Kc; // Parameter: Integral correction gain _iq Kd; // Parameter: Derivative gain _iq Up1; // History: Previous proportional output ] PIDREG3; typedef PIDREG3 *PIDREG3_handle; /*----------------------------------------------------------------------------- Default initalizer for the PIDREG3 object. -----------------------------------------------------------------------------*/ #define PIDREG3_DEFAULTS [ 0, 0, 0, _IQ(1.3), 0, 0, 0, 0, _IQ(1), _IQ(-1), 0, 0, _IQ(0.02), _IQ(0.5), _IQ(1.05), 0, ] /*------------------------------------------------------------------------------ PID Macro Definition ------------------------------------------------------------------------------*/ #define PID_MACRO(v) v.Err = v.Ref - v.Fdb; /* Compute the error */ v.Up= _IQmpy(v.Kp,v.Err); /* Compute the proportional output */ v.Ui= v.Ui + _IQmpy(v.Ki,v.Up) + _IQmpy(v.Kc,v.SatErr); /* Compute the integral output */ v.OutPreSat= v.Up + v.Ui; /* Compute the pre-saturated output */ v.Out = _IQsat(v.OutPreSat, v.OutMax, v.OutMin); /* Saturate the output */ v.SatErr = v.Out - v.OutPreSat; /* Compute the saturate difference */ v.Up1 = v.Up; /* Update the previous proportional output */ #endif // __PIDREG3_H__ // Add the lines below if derivative output is needed following the integral update // v.Ud = _IQmpy(v.Kd,(v.Up - v.Up1)); // v.OutPreSat = v.Up + v.Ui + v.Ud; 其中没有你的 PID_REG3_MACRO(v)和PID_REG3_POS_MACRO(v) 这两个 PID_REG3_MACRO(v)是PI PID_REG3_POS_MACRO(v)是PID 你的问题2到5,pid_reg3.pdf的这两页可以接到,你看下推导下就明白了 应该是位置式的PID |
|
|
|
|
|
|
|
|
我第一次看这个代码的时候也有和你一样的疑问, 主观上理解PID控制器的输出,不就是比例 加 积分 加微分嘛 但是你看这个代码里: 你也提到了微分怎么和比例有关系呢? 再有你看,其实还有积分部分还涉及到了比例系数和积分系数相乘呢,更不可理解。 但是看看文档,推到下,这些也就不是疑问了 |
|
|
|
|
|
1 条评论
|
|
梓沐凡晨 发表于 2020-5-29 17:18 看个文档,这样说的位置式PI 调节器这种算法的优点是计算精度比较高,缺点是每次都要对e(k) 进行累加, 很容易出现积分饱和的情况。但现在有抗积分饱和的了。 增量式 PI 算法与位置式 PI 算法并没有本质的区别,只是增量式 PI 算法控制的是执行机构的增量 Δu(k),这种算法的优点在于:由于输出的是增量,因此 计算错误时的产生的影响较小,这种算法的缺点在于:每次计算 Δu(k)再与前次 的计算结果u(k −1) 相加得到本次的控制输出,这就使得 Δu(k)的截断误差被逐次的累加起来,输出的误差加大。 只是照书上说的。你考虑下 |
|
|
|
|
|
|
|
梓沐凡晨 发表于 2020-5-29 17:18 这是知乎上面的一个帖子 写的很好 你仔细看下这个帖子 再去理解下TI的位置式PID_REG3和北京航空航天大学出版社出版的《电动机的DSP控制——TI公司》这本书里提到的增量式PID 知乎的这个帖子即从理论上又从编程实现上对比了两种算法的区别 feng shi的解释书本化 百度上搜的很多博客也是这么写的;bad提到的位置式具有一定的炕扰性,增量式反应比较快,我不清楚从原理上怎么体现出这些区别 知乎的这个解释还是挺好的 建议jin chao yang看下 |
|
|
|
|
|
|
|
|
我总结了下 写到我的个人微信公众号了 你可以看看 https://mp.weixin.qq.com/s?__biz=MzI2NDE4NTQ5NA==&mid=2657808641&idx=1&sn=101fa7ce554e4d51d9a02a26571470c5&chksm=f12e22f8c659abee54a93b934c5f8992adc5752513137c12a133c7a762e7331b091c199fe921&scene=0&key=c81d77271180a0e62461a725234a604d1a20a51c8d71a59a86241577191211e1d6133de18ee3732ec69b7f671b62652d5093c46b27b1b4fb85c6aff4a42ba7ff6ad9e68de7df4f81389a1250d8fbc31b&ascene=7&uin=MjgwNzA5NDkzMg%3D%3D&devicetype=android-22&version=26031f30&nettype=cmnet&abtest_cookie=AQABAAgAAQAkhh4AAAA%3D&pass_ticket=mRYEiupMywwCUHbOBhzmYskXjc85k9xx643ughbLKY%2Fddboo0AZ3MHujeXyRQiPj&wx_header=1 |
|
|
|
|
|
|
|
JASONbzyhzlq 发表于 2020-5-29 18:34 谢谢张工! 学习学习! |
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
549 浏览 0 评论
1613 浏览 0 评论
2047 浏览 0 评论
为啥BQ7693003DBTR芯片在和BQ769X0盒子通讯时收不到信号?
1513 浏览 0 评论
DSP 28027F 开发板 XDS100v2调试探针诊断日志显示了 Error -150 (SC_ERR_FTDI_FAIL)如何解决
1337 浏览 0 评论
AT32F407在USART2 DMA发送数据时,接包接到了要发送的数据,程序还是处于等待传输完成的标识判断中,为什么?
1756浏览 29评论
2781浏览 23评论
请问下tpa3220实际测试引脚功能和官方资料不符,哪位大佬可以帮忙解答下
1723浏览 20评论
请教下关于TAS5825PEVM评估模块原理图中不太明白的地方,寻求答疑
1634浏览 14评论
两个TMP117传感器一个可以正常读取温度值,一个读取的值一直是0,为什么?
1645浏览 13评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-1 23:56 , Processed in 1.079450 second(s), Total 80, Slave 73 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
10389