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

2020-02-21 21:13发布

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

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

实际上 , 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[8] = {43,26,12,6,-6,-12,-26,-43}; //MAX:28

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

unsigned char SignalBit[8];

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);

}         
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
26条回答
dongyanbo
1楼-- · 2020-02-24 16:58
大学时自动控制原理没学好,学习一下代码
jiang887786
2楼-- · 2020-02-24 17:09
 精彩回答 2  元偷偷看……
chenguanghua
3楼-- · 2020-02-24 21:51
PID+模糊控制烧水器,好几年前做的一个课题,现在也忘的差不多了
wbxjtu
4楼-- · 2020-02-24 23:19
口诀不错
wycox
5楼-- · 2020-02-25 02:16
老师傅的经验值得好好学习。
彼岸花开@
6楼-- · 2020-02-25 05:00
收藏   研究一下。。

一周热门 更多>