nnimo 发表于 2014-5-6 22:44:05

【经验分享】初步解析飞思卡尔控制电机PID算法代码 .

本帖最后由 FSL_TICS_ZJJ 于 2014-5-7 11:08 编辑

PID实指“比例proportional”、“积分integral”、“微分derivative” , 这三项构成PID基本要素。每一项完成不同任务对系统功能产生不同的影响。 搞软件的往往对硬件不屑 ,却忘了软件再牛B也是为硬件服务的 , PID的数字化算法就完全是为硬件而生的 , 这是控制电机算法的一个难点 , 没有一定的对软硬件的理解 , 就连调试装定PID参数都会很为难 ! 飞思卡尔智能车项目里面就会用到PID算法 , 比如车爬坡和平地连续拐弯时 , 代码里面没有PID算法 , 控制和驱动起来就会很拙急 , 对不对 ? 不过 ,搞清楚问题还是有个前提的 , 那就是懂点微积分 , 不会微积分嘛 , 下面的内容无需关注 {:smile:}

实际上 , PID算法的应用基础始于对PCB板上的运放的PID参数进行调校 , P对应于运放增益; I 就是运放输入和输出端之间接一个电容引入反馈 , 就是控制器的输出与输入误差会积累起来影响输出 ;D 就是运放输入端串接一个电容 ,起的微分作用是阻止输出与输入误差的变化 .结合示波器来观察控制电机的PID参数设定的话 , 网上有一首诗 , 它就代表我的心声了 :

参数整定找最佳,从小到大顺序查
先是比例后积分,最后再把微分加
曲线振荡很频繁,比例度盘要放大
曲线漂浮绕大湾,比例度盘往小扳
曲线偏离回复慢,积分时间往下降
曲线波动周期长,积分时间再加长
曲线振荡频率快,先把微分降下来
动差大来波动慢,微分时间应加长
理想曲线两个波,前高后低四比一
一看二调多分析,调节质量不会低 !

下面贴段代码 (真的是仅供参考):
#include <mc9s12dg128.h> /* derivative information */

/*

***********************************************************************************

* 宏定义

**********************************************************************************/

#define STABMAX 50

#define SENSORNUM 8

#define SAMPLETIMES 5

/*

***********************************************************************************

* FUNCTION PROTOTYPES

**********************************************************************************/

int CalculateP(void);

float CalculatePID(void);

/********************************** PID控制程序 ********************************/

struct CARSTATE

{

int E0;

int E1;

int E2;

int E3;

float Integral;

}CarState;

/*

***********************************************************************************

* 初始化PID参数

**********************************************************************************/

void Init_PID()

{

CarState.E0 = 0;

CarState.E1 = 0;

CarState.E2 = 0;

CarState.E3 = 0;

CarState.Integral = 0;

}

/*

**********************************************************************************

* 信号处理函数

*

* 程序描述: 对传感器采集过来的数据进行处理,得到一些基本的计算参数

*

**********************************************************************************/

int SignalProcess( unsigned int signal )

{

const int BitValue = {43,26,12,6,-6,-12,-26,-43}; //MAX:28

int i,CurrPoint=0,LastPoint=0,BitNum=0;

unsigned char SignalBit;

for(i=0;i<8;i++)

{

SignalBit = signal & 0x0001;

BitNum += SignalBit;

signal >>= 1;

}

switch(BitNum)

{

case 1:

for(i=0;i<8;i++)

if(SignalBit != 0)

CurrPoint += BitValue;

CarState.E0 = CurrPoint;

break;

case 2:

for(i=0;i<8;i++)

if(SignalBit != 0)

CurrPoint += BitValue;

CurrPoint >>= 1;

CarState.E0 = CurrPoint;

break;

default:

CarState.E0 = CarState.E1;

break;

}

return CalculateP()*100;

}

/*

**********************************************************************************

*

* PID计算函数

*

* 程序描述: 计算P参数

*

**********************************************************************************/

int CalculateP(void)

{

CarState.E1 = CarState.E0;

return((int)CarState.E0);

}



/*

***********************************************************************************

* PID计算函数

*

* 程序描述: 对传感器采集过来的数据进行处理,得到一些基本的计算参数

*
******************************************************************* ***************/

float CalculatePID(void)

{

float P, I = 0, D;

/* parameter const */

float Kp = 1.0, Ki = -0.0002, Kd = -0.0002;

/* P parameter */

P = CarState.E0 * Kp;

/* I parameter */

if(P+I<2)

{

CarState.Integral += Ki * CarState.E0;

I = CarState.Integral;

}

/* D parameter */

D = Kd * ( CarState.E0 + 3*CarState.E1 - 3*CarState.E2 - CarState.E3 )/6.0;

CarState.E3 = CarState.E2;

CarState.E2 = CarState.E1;

CarState.E1 = CarState.E0;

return (P+I+D);

}         

rootxie 发表于 2014-5-7 08:17:16

淫得一首好湿。。。弱弱的请教一下,各种PID应用不同的区别在哪儿?在于系数不同?

wangqun 发表于 2014-5-7 08:26:29

没有说明啊,看得好累

tsb0574 发表于 2014-5-7 08:31:04

婬诗是关键!

r166 发表于 2014-5-7 08:37:52

楼主原创吗,厉害。

zhinengyibiao 发表于 2014-5-7 08:51:32

pid,一直搞不懂怎么做,先看看楼主的方案

cn_x 发表于 2014-5-7 10:12:16

研究一下,现在正在做步进控制方案

fengyunyu 发表于 2014-5-7 10:16:33

有分析,有代码,不错!

cmheia 发表于 2014-5-7 10:17:51

{:lol:}楼主能不能编辑一下,用代码格式贴代码,现在这样看着真不方便

coleyao 发表于 2014-5-7 10:20:15

本帖最后由 coleyao 于 2014-5-7 10:34 编辑

坐等整数的算法,实数的确实有点太占资源了!

Feeling_MCU 发表于 2014-5-7 10:25:26

能不能用整形变量来做呢?float变量总感觉会占用太多资源和时间。

vampirejing 发表于 2014-6-4 10:07:37

{:sweat:}一口气看完累死我了,发表时适当加换行和注释吗{:sleepy:}

kaderpan 发表于 2014-6-7 15:15:44

有点看不懂

kaderpan 发表于 2014-6-7 18:16:52

谢谢了,学习了

zndz410 发表于 2014-6-8 10:54:08

楼主励害, 学习学习.

laotui 发表于 2014-8-26 23:44:18

有用的经验,pid参数不好调。

zjk 发表于 2014-8-27 08:49:27

吸取点经验

cn_x 发表于 2014-8-27 09:14:31

PID只调过运动控制器,没有自己写过
看着运动控制器上一堆子参数
感觉要自己写就头皮发麻

weiwei4 发表于 2014-8-27 15:03:59

PID在电机控制方面很有用,不过有点复杂,没用过

dongyanbo 发表于 2014-8-27 15:17:12

大学时自动控制原理没学好,学习一下代码

jiang887786 发表于 2014-9-1 13:41:30

学校根本没学过,只能自己摸索,顶楼主,学习了。

chenguanghua 发表于 2014-9-1 13:48:25

PID+模糊控制烧水器,好几年前做的一个课题,现在也忘的差不多了

wbxjtu 发表于 2014-9-1 14:20:41

口诀不错

wycox 发表于 2014-9-1 14:26:33

老师傅的经验值得好好学习。

彼岸花开@ 发表于 2014-9-1 15:14:04

收藏   研究一下。。

kenson 发表于 2014-9-1 15:39:43

好资料谢谢了

浪里白条 发表于 2014-9-1 15:59:00

感谢露珠分享,虽然看不懂
页: [1]
查看完整版本: 【经验分享】初步解析飞思卡尔控制电机PID算法代码 .