首页 上一页 1 2 下一页 尾页

请教有关pid控制 点击:1331 | 回复:28



章于

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:8帖 | 16回
  • 年度积分:0
  • 历史总积分:40
  • 注册:2006年3月31日
发表于:2006-04-03 10:16:00
楼主
新手请问!
  我的系统是一个单轴系统,主要控制衡梁的上下移动位置,采用的是交流伺服电机,反馈的位置信号是编码器采集,我想对横梁进行位置闭环,打算采用pid控制。
  有个问题不是很明白,我通过编码器读回来的是一个位置参数,与期望值之间形成一个位置误差e,然后通过pid算法之后得到的是一个与位置有关的数值PID(e),可是输入电机的值必须是一个速度值,对应一个电机频率,这个位置有关的数值PID(e)如何转化为一个电机频率啊?  请各位高手指点,不会是用这个 PID(e)除以采样时间吧。。
   



刘岩利

  • [版主]
  • 精华:2帖
  • 求助:0帖
  • 帖子:16帖 | 8239回
  • 年度积分:397
  • 历史总积分:28760
  • 注册:2005年3月09日
发表于:2006-04-03 18:22:00
1楼
为什么你的 PID(e) 不是速度?

章于

  • 精华:0帖
  • 求助:0帖
  • 帖子:8帖 | 16回
  • 年度积分:0
  • 历史总积分:40
  • 注册:2006年3月31日
发表于:2006-04-04 17:54:00
2楼
多谢刘老师:
    我的编码器读回来只能是一个位置数,我不知道如何将其转换成速度,所以每次的误差都是个位置误差,经过PID之后得到PID(e)能对应成速度吗,是不是有当量换算? 请刘老师指教,多谢多谢!

刘岩利

  • [版主]
  • 精华:2帖
  • 求助:0帖
  • 帖子:16帖 | 8239回
  • 年度积分:397
  • 历史总积分:28760
  • 注册:2005年3月09日
发表于:2006-04-04 19:46:00
3楼
e是位置,PID(e)为什么就是位置?随便你去看什么控制器,输出量与反馈量会是一致的量纲吗?

hawkeast

  • 精华:0帖
  • 求助:0帖
  • 帖子:13帖 | 33回
  • 年度积分:0
  • 历史总积分:79
  • 注册:2004年5月08日
发表于:2006-04-04 20:18:00
4楼
你是用控制卡还是自己的DSP啊?我先前在自己的控制卡的基础上编过一个小程序,把e直接赋值给DAC去了(当然可以做一些调整),DAC直接接的是驱动器,不过由于速度上不去就没再尝试过。

章于

  • 精华:0帖
  • 求助:0帖
  • 帖子:8帖 | 16回
  • 年度积分:0
  • 历史总积分:40
  • 注册:2006年3月31日
发表于:2006-04-04 22:17:00
5楼
多谢各位, 我用的是控制卡 ,老师开发的, 由于我这是第一次尝试用闭环,毕业设计要做出来的, 现在刚开始摸索,有些东西不是很明白,多谢刘老师提示,能不能再告诉我一下,PID(e)是不是也可能直接可以去驱动电机呢?要是想搞明白,我现在是不是应该先看看控制器?  谢

刘岩利

  • [版主]
  • 精华:2帖
  • 求助:0帖
  • 帖子:16帖 | 8239回
  • 年度积分:397
  • 历史总积分:28760
  • 注册:2005年3月09日
发表于:2006-04-05 22:05:00
6楼
PID(e)是不是也可能直接可以去驱动电机呢?
理论可行,但是,你所谓“直接驱动”的意思是什么?不要电机放大器吗?你的板卡能输出功率吗?

章于

  • 精华:0帖
  • 求助:0帖
  • 帖子:8帖 | 16回
  • 年度积分:0
  • 历史总积分:40
  • 注册:2006年3月31日
发表于:2006-04-05 23:17:00
7楼
我的电机是松下交流伺服的,具体的我也不太清楚,下层硬件我涉及不到,我主要就是用vc作个交互软件,驱动电机就是只有一个自带的函数setmotionspeed(n),然后给n一个频率数就行,就根据这个n的大小控制电机转速,实际过程中这个n等于100乘以横梁运动速度,我现在就是迷惑这个PID(e)能不能直接付值给n,还是应该进行怎么转化?
多谢!

老柴夫

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 195回
  • 年度积分:0
  • 历史总积分:196
  • 注册:2006年3月02日
发表于:2006-04-06 16:32:00
8楼
实际过程中这个n等于100乘以横梁运动速度,我现在就是迷惑这个PID(e)能不能直接付值给n。
佬大……你的答案就在问题中。
我也不知道行不行,只是你有了想法,就去试一试。

刘岩利

  • [版主]
  • 精华:2帖
  • 求助:0帖
  • 帖子:16帖 | 8239回
  • 年度积分:397
  • 历史总积分:28760
  • 注册:2005年3月09日
发表于:2006-04-06 18:26:00
9楼
能不能直接赋,先把你的PID详细算法列出来看了再说,谁知道你都是怎么算的。

favnihao

  • 精华:0帖
  • 求助:0帖
  • 帖子:3帖 | 57回
  • 年度积分:0
  • 历史总积分:127
  • 注册:2006年4月06日
发表于:2006-04-07 04:05:00
10楼
你应该好好的补习一下自动控制原理,认真地想一想,前面几位老师都是在引导你,不愿直接给你答案,我这里可怜你一下,告诉你了。外环控制器的输出就是内环的输入,即位置控制器(你用的是PID)的输出就是速度环的输入,不用考虑量纲问题,如果考虑到机械系统所能承受的最大转速,你可以对该PID(e)做个限制,是他小于系统允许的最大n值。但是这是又有了一个新的问题,位置PID控制器需要设置合适的饱和值,否则当有大的位置偏差输入时,系统的超调会增大,这是因为机械系统速度饱和而未知控制器仍然积分造成的。再细致就是直接把程序写给你了,我看不必了吧。

Jena

  • 精华:0帖
  • 求助:0帖
  • 帖子:64帖 | 1469回
  • 年度积分:0
  • 历史总积分:2165
  • 注册:2006年2月28日
发表于:2006-04-07 11:03:00
11楼
伺服就有这个功能啊,何必多此一举呢?
这样搞下来,不等于自己开发了一套伺服吗?

favnihao

  • 精华:0帖
  • 求助:0帖
  • 帖子:3帖 | 57回
  • 年度积分:0
  • 历史总积分:127
  • 注册:2006年4月06日
发表于:2006-04-07 12:07:00
12楼
我就是自己开发伺服的哦:),多指教呵。

hawkeast

  • 精华:0帖
  • 求助:0帖
  • 帖子:13帖 | 33回
  • 年度积分:0
  • 历史总积分:79
  • 注册:2004年5月08日
发表于:2006-04-07 14:54:00
13楼
favnihao,能留个联系方式吗,有些问题想请教,
我的email:zhangsheng10◎hotmail.com

章于

  • 精华:0帖
  • 求助:0帖
  • 帖子:8帖 | 16回
  • 年度积分:0
  • 历史总积分:40
  • 注册:2006年3月31日
发表于:2006-04-07 23:24:00
14楼
多谢 刘岩利 favnihao  老柴夫 ,今天按照你们指点的方法试了一下,初步感觉还行,能控制横梁的运动,虽然质量还不尽人易,但起码有进展,感觉以后调参数肯定还是个大问题.明天把我的代码给你们看看,指教一下,多谢!

章于

  • 精华:0帖
  • 求助:0帖
  • 帖子:8帖 | 16回
  • 年度积分:0
  • 历史总积分:40
  • 注册:2006年3月31日
发表于:2006-04-13 10:45:00
15楼
程序如下: (采样时间我用的是多媒体定时器,一般定时我设定在15ms - 30ms之间 , 写一下主要部分。麻烦大家帮我看一下)

         double Point;   //实际横梁位置
double PID;
Point=GetFeedbackSignal();//得到实际横梁位置 
         PID=PIDControl();         //经过pid算法后的值
m_currentpos=Point;       //显示当前位置

*********** 采用普通 PID 算法  *************
double dTimeInterval;//采样间隔为dTimeInterval秒
 
double CMotionControlDlg::PIDControl()
{

    double dOutSignal;            //PID控制的输出
    double dError;
    double dDemandSignal=GetDemandSignal();//给定期望位置
    double dFeedbackSignal=GetFeedbackSignal();//反馈位置
    dError = dDemandSignal-dFeedbackSignal;  //位置误差

    dvalue0=Kp*dError;    //比例
    dvalue1=dvalue1+Ki*dError*dTimeInterval;//积分
    dvalue2=Kd*(dError-dOldError)/dTimeInterval;//微分
    dOutSignal=dvalue0+dvalue1+dvalue2;//输出

    dOldError=dError;
    return dOutSignal;
}
******在多媒体时间函数中写如下控制运动代码*******

if (fabs(dError) >0.00005) //如果横梁运动位置误差
{                          //大于0.00005则采用如下控制

double st=8000;  //设定一个速度上限
if(PID>st)         
{
 SetMotionSpeed(8000);  //给定运动速度
 StartMotion(3);        //规定电机正转
}
else if(PID<=st&&PID>0)  //如果经过pid算法之后的值在范围内
{                        //就直接将pid值直接输入电机???
  SetMotionSpeed(PID);  
  StartMotion(3);   
}
else if(PID<=0)        //如果pid为负,代表横梁超过规定位置
{                      //使电机反转,将pid值直接输入电机
SetMotionSpeed(-PID);  
StartMotion(2);        //使电机反转
}
else
  StartMotion(0);    // 误差小于0.0005则 电机停止运动

刘岩利

  • [版主]
  • 精华:2帖
  • 求助:0帖
  • 帖子:16帖 | 8239回
  • 年度积分:397
  • 历史总积分:28760
  • 注册:2005年3月09日
发表于:2006-04-13 22:44:00
16楼
没有细看,只是看到了“误差小于0.0005则 电机停止运动”,这种做法有没有危险?此时电机虽然不动,但是积分运算还在进行,如果持续一段时间,PID(e)的结果可能很大,当电机需要动的时候,会飞的。

章于

  • 精华:0帖
  • 求助:0帖
  • 帖子:8帖 | 16回
  • 年度积分:0
  • 历史总积分:40
  • 注册:2006年3月31日
发表于:2006-04-13 23:52:00
17楼
如果我不限制的话,那么考虑到误差之内的情况,PID(e)最终很难真正的为零,不知还有没有其他更好的方法?
ps: 还有一个问题,我的程序运行当中,当PID(e)很小的时候电机会突然停止几秒钟,然后在运转,这是为什么?每次停止时PID(e)的数字会跟采用时间,还有kp ki kd都有点关系

学习数控

  • 精华:0帖
  • 求助:0帖
  • 帖子:4帖 | 167回
  • 年度积分:0
  • 历史总积分:221
  • 注册:2003年2月06日
发表于:2006-04-14 01:21:00
18楼
----"PID(e)最终很难真正的为零"

PID(e)是否为零,并不重要,重要的是误差要趋于零.

SetMotionSpeed 应该可以接受变量为负值,故无需StartMotion(2).     

当误差小于0.0005,无需停止电机.

章于

  • 精华:0帖
  • 求助:0帖
  • 帖子:8帖 | 16回
  • 年度积分:0
  • 历史总积分:40
  • 注册:2006年3月31日
发表于:2006-04-14 09:38:00
19楼
多谢关注!我的程序中SetMotionSpeed 与 StartMotion  这都是下层自带的函数,规定是这么用的。

刘岩利

  • [版主]
  • 精华:2帖
  • 求助:0帖
  • 帖子:16帖 | 8239回
  • 年度积分:397
  • 历史总积分:28760
  • 注册:2005年3月09日
发表于:2006-04-14 23:04:00
20楼
“ ----"PID(e)最终很难真正的为零"
PID(e)是否为零,并不重要,重要的是误差要趋于零.”

对于闭环控制,一般来说,就是一个动态平衡的的过程,确实不需要关心 PID(e)是否为零。

“不知还有没有其他更好的方法?”
如果你确实需要这样的功能(通常被称做“定位后不晃动”),那么就把PID中的积分运算也停下来。



热门招聘
相关主题

官方公众号

智造工程师
    首页 上一页 1 2 下一页 尾页