OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3703|回复: 7

请教一个PID算法的问题!

[复制链接]

53

主题

113

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
433
金钱
433
注册时间
2013-4-10
在线时间
83 小时
发表于 2016-8-31 21:58:45 | 显示全部楼层 |阅读模式
如题,请教PID算法的问题
//数据结构
typedef struct PID
{
int SetPoint; //设定目标 Desired Value
long SumError; //误差累计
double Proportion; //比例常数 Proportional Const
double Integral; //积分常数 Integral Const
double Derivative; //微分常数 Derivative Const
int LastError; //Error[-1]
int PrevError; //Error[-2]
} PID;

static PID sPID;
static PID *sptr = &sPID;
//PID参数初始化
void IncPIDInit(void)
{
sptr->SumError = 0;
sptr->LastError = 0; //Error[-1]
sptr->PrevError = 0; //Error[-2]
sptr->Proportion = 0; //比例常数 Proportional Const
sptr->Integral = 0; //积分常数Integral Const
sptr->Derivative = 0; //微分常数 Derivative Const
sptr->SetPoint = 0;
}
//增量式PID控制设计
int IncPIDCalc(int NextPoint)
{
register int iError, iIncpid;
//当前误差
iError = sptr->SetPoint - NextPoint;
//增量计算
iIncpid = sptr->Proportion * iError //E[k]项
- sptr->Integral * sptr->LastError //E[k-1]项
+ sptr->Derivative * sptr->PrevError; //E[k-2]项
//存储误差,用于下次计算
sptr->PrevError = sptr->LastError;
sptr->LastError = iError;
//返回增量值
return(iIncpid);
}

如上代码:int IncPIDCalc(int NextPoint) 返回值的范围是多少,如果我要设置输出的上下限应该怎么处理呢,假设输出范围在【-1000-1000】。
另外:输入的参数是反馈的量,对这个参数有什么要求,比如说范围应该在什么区间。
我的应用是恒张力控制,控制目标是伺服电机的转速,反馈的量是张力值。
先谢谢大家了。

打铁还需自身硬@ing
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

53

主题

113

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
433
金钱
433
注册时间
2013-4-10
在线时间
83 小时
 楼主| 发表于 2016-9-1 12:41:47 | 显示全部楼层
为什么有人看没人回复呢!自己顶一个,希望懂的人帮帮忙!谢谢
回复 支持 反对

使用道具 举报

38

主题

527

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1424
金钱
1424
注册时间
2011-11-27
在线时间
122 小时
发表于 2016-9-1 13:09:01 | 显示全部楼层
你的应用是恒张力控制,而且反馈也是张力值,你的pid控制目标量应该是张力,不是电机转速
回复 支持 反对

使用道具 举报

53

主题

113

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
433
金钱
433
注册时间
2013-4-10
在线时间
83 小时
 楼主| 发表于 2016-9-1 21:47:01 | 显示全部楼层
科科1987 发表于 2016-9-1 13:09
你的应用是恒张力控制,而且反馈也是张力值,你的pid控制目标量应该是张力,不是电机转速

你说的也对,就是控制电机转速,这样间接控制张力了吧!具体上下限范围应该怎么做?
打铁还需自身硬@ing
回复 支持 反对

使用道具 举报

4

主题

290

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1130
金钱
1130
注册时间
2015-8-4
在线时间
107 小时
发表于 2016-9-2 09:37:28 | 显示全部楼层
上下限就是你的目标值,PID一般来说会设定一个目标值,而不是一个区间。如果要求在-1000到1000之间震荡,那你可以在PID内部计算误差时判断。比如iError=sptr->SetPoint-NextPoint;这句后面添加 if(fabs(iError)<1000)return 0;表示误差在范围内,不做控制。
回复 支持 反对

使用道具 举报

38

主题

527

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1424
金钱
1424
注册时间
2011-11-27
在线时间
122 小时
发表于 2016-9-2 13:53:38 | 显示全部楼层
gaoxiaohu110 发表于 2016-9-1 21:47
你说的也对,就是控制电机转速,这样间接控制张力了吧!具体上下限范围应该怎么做?

//增量计算
iIncpid = sptr->Proportion * iError //E[k]项
- sptr->Integral * sptr->LastError //E[k-1]项
+ sptr->Derivative * sptr->PrevError; //E[k-2]项

/*接下来做一个ilncpid的限幅,通常在积分环节也要做一个限幅*/
永远保持一颗学习的心态。
回复 支持 反对

使用道具 举报

53

主题

113

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
433
金钱
433
注册时间
2013-4-10
在线时间
83 小时
 楼主| 发表于 2016-9-2 13:58:24 | 显示全部楼层
科科1987 发表于 2016-9-2 13:53
//增量计算
iIncpid = sptr->Proportion * iError //E[k]项
- sptr->Integral * sptr->LastError //E[k ...

这个限幅应该怎么做呢!简单的比较应该是不合理的吧!
打铁还需自身硬@ing
回复 支持 反对

使用道具 举报

38

主题

527

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1424
金钱
1424
注册时间
2011-11-27
在线时间
122 小时
发表于 2016-9-3 13:15:47 | 显示全部楼层
gaoxiaohu110 发表于 2016-9-2 13:58
这个限幅应该怎么做呢!简单的比较应该是不合理的吧!

首先不能超过速度调节的最大范围,然后根据你的张力控制实际需要确定
永远保持一颗学习的心态。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-26 10:26

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表