搜索
bottom↓
回复: 23

研究 模糊控制+电机伺服控制 的进来看看!!

[复制链接]

出0入0汤圆

发表于 2011-10-24 11:53:26 | 显示全部楼层 |阅读模式
最近做点电机的伺服控制,先使用积分分离的PID算法,感觉控制效果很差,参数及其不好调试,所以就放弃了!现在正研究模糊PID的控制算法,希望做过的朋友,提供点意见和资料!不胜感激啊!
在网上找了一片模糊控制的代码,控制效果好,控制精度不行,后来在此代码的基础上加上PID控制,控制效果还可以,大概思路是先用模糊控制将误差整定到一个小的区间,然后在使用PID!但是在两种模式切换的时候,容易震荡,希望大家帮忙想想办法!!

下面是控制代码:
/**********************************************************/

/*输入量P语言值特征点*/          

const   s16   PFF[4]={0,30,60,90};           //偏差输入值范围

/*输入量D语言值特征点*/

const   s16   DFF[4]={0,15,30,45};          //偏差微分输入范围

/*输出量U语言值特征点*/

const   s16   UFF[7]={0,15,30,45,60,75,90};           //输出范围

/*采用了调整因子的规则表,大误差时偏重误差,小误差时偏重误差变化*/
/*a0=0.3,a1=0.55,a2=0.74,a3=0.89   */
const s16 rule[7][7]={
//误差变化率   -3,-2,-1, 0, 1, 2, 3      // 误差

                          {-6,-6,-6,-5,-5,-5,-4,},   //   -3

                          {-5,-4,-4,-3,-2,-2,-1,},   //   -2

                          {-4,-3,-2,-1, 0, 1, 2,},   //   -1

                          {-4,-3,-1, 0, 1, 3, 4,},   //    0

                          {-2,-1, 0, 1, 2, 3, 4,},   //    1

                          { 1, 2, 2, 3, 4, 4, 5,},   //    2

                          { 4, 5, 5, 5, 6, 6, 6}};   //    3

/**********************************************************/
s16   FuzzyCale(s16 P,s16 D)   /*模糊运算引擎,输入偏差和偏差微分*/

{

  #define         PMAX    100                 //偏差正最大值

  #define         PMIN   -100                 //偏差负最大值

  #define         DMAX    100                 //偏差微分正最大值

  #define         DMIN   -100                 //偏差微分负最大值


  #define   FMAX        100       /*输出语言值的满幅值*/


  s16    U;                            /*偏差,偏差微分以及输出值的精确量*/
            
  u16    PF[2],DF[2],UF[4];   /*偏差,偏差微分以及输出值的隶属度*/

  s16    Pn,Dn,Un[4];                 //分区参数

  s32    temp1,temp2;



  /*隶属度的确定*/

  /*根据P,D的指定语言值获得有效隶属度*/

  if(P>-PFF[3] && P<PFF[3])
  {

                if(P<=-PFF[2])        {Pn=-2;PF[0]=FMAX*((float)(-PFF[2]-P)/(PFF[3]-PFF[2]));} //        将误差分区域,同事求出相应的

                else if(P<=-PFF[1])   {Pn=-1;PF[0]=FMAX*((float)(-PFF[1]-P)/(PFF[2]-PFF[1]));}

                else if(P<=PFF[0])    {Pn=0; PF[0]=FMAX*((float)(-PFF[0]-P)/(PFF[1]-PFF[0]));}

                else if(P<=PFF[1])    {Pn=1; PF[0]=FMAX*((float)(PFF[1]-P)/(PFF[1]-PFF[0]));}

                else if(P<=PFF[2])    {Pn=2; PF[0]=FMAX*((float)(PFF[2]-P)/(PFF[2]-PFF[1]));}

                else if(P<=PFF[3])    {Pn=3; PF[0]=FMAX*((float)(PFF[3]-P)/(PFF[3]-PFF[2]));}

    }

  else if(P<=-PFF[3])   {Pn=-2;   PF[0]=FMAX;}

  else if(P>=PFF[3])    {Pn=3;   PF[0]=0;}

  PF[1]=FMAX-PF[0];                  //这个为低一级隶属度


  if(D>-DFF[3] && D<DFF[3])
  {

                if(D<=-DFF[2])        {Dn=-2;DF[0]=FMAX*((float)(-DFF[2]-D)/(DFF[3]-DFF[2]));}

                else if(D<=-DFF[1])   {Dn=-1;DF[0]=FMAX*((float)(-DFF[1]-D)/(DFF[2]-DFF[1]));}

                else if(D<=DFF[0])    {Dn=0; DF[0]=FMAX*((float)(-DFF[0]-D)/(DFF[1]-DFF[0]));}

                else if(D<=DFF[1])    {Dn=1; DF[0]=FMAX*((float)(DFF[1]-D)/(DFF[1]-DFF[0]));}

                else if(D<=DFF[2])    {Dn=2; DF[0]=FMAX*((float)(DFF[2]-D)/(DFF[2]-DFF[1]));}

                else if(D<=DFF[3])    {Dn=3; DF[0]=FMAX*((float)(DFF[3]-D)/(DFF[3]-DFF[2]));}

    }

  else if(D<=-DFF[3])   {Dn=-2;   DF[0]=FMAX;}

  else if(D>=DFF[3])   {Dn=3;   DF[0]=0;}

  DF[1]=FMAX-DF[0];                           //这个为低一级隶属度


  /*使用误差范围优化后的规则表rule[7][7]*/

  /*输出值使用13个隶属函数,中心值由UFF[7]指定*/

  /*一般都是四个规则有效*/

                                  
  Un[0]=rule[Pn-1+3][Dn-1+3];

  Un[1]=rule[Pn+3][Dn-1+3];
  Un[2]=rule[Pn-1+3][Dn+3];

  Un[3]=rule[Pn+3][Dn+3];


  if(PF[0]<=DF[0])UF[0]=PF[0]; else UF[0]=DF[0];

  if(PF[1]<=DF[0])UF[1]=PF[1]; else UF[1]=DF[0];

  if(PF[0]<=DF[1])UF[2]=PF[0]; else UF[2]=DF[1];

  if(PF[1]<=DF[1])UF[3]=PF[1]; else UF[3]=DF[1];


  /*同隶属函数 输出语言值求大*/

  {

          if(Un[0]==Un[1])
          {       
                          if(UF[0]>UF[1])UF[1]=0;

                        else UF[0]=0;
          }

          if(Un[0]==Un[2])
          {
                          if(UF[0]>UF[2])UF[2]=0;

                        else UF[0]=0;
          }

          if(Un[0]==Un[3])
          {
                          if(UF[0]>UF[3])UF[3]=0;

                        else UF[0]=0;
          }

          if(Un[1]==Un[2])
          {
                          if(UF[1]>UF[2])UF[2]=0;

                        else UF[1]=0;
           }

          if(Un[1]==Un[3])
          {
                          if(UF[1]>UF[3])UF[3]=0;

                        else UF[1]=0;
          }


          if(Un[2]==Un[3])
          {
                          if(UF[2]>UF[3])UF[3]=0;

                        else UF[2]=0;
          }

  }


  /*重心法反模糊*/          //加权平均算法

  {/*Un[]原值为输出隶属函数标号,转换为隶属函数值*/

          if(Un[0]>=0)Un[0]=UFF[Un[0]];else Un[0]=-UFF[-Un[0]];

          if(Un[1]>=0)Un[1]=UFF[Un[1]];else Un[1]=-UFF[-Un[1]];

          if(Un[2]>=0)Un[2]=UFF[Un[2]];else Un[2]=-UFF[-Un[2]];

          if(Un[3]>=0)Un[3]=UFF[Un[3]];else Un[3]=-UFF[-Un[3]];

  }

  temp1=UF[0]*Un[0]+UF[1]*Un[1]+UF[2]*Un[2]+UF[3]*Un[3];

  temp2=UF[0]+UF[1]+UF[2]+UF[3];

  U=temp1/temp2;


  return U;

}

s16 FuzzyControl(Fuzzy *Fuzzy,s16 NextPoint)
{

        s16 ek,eck;

        s16 temp1;

    ek         =          SetPoint - NextPoint;                          //得到误差值

        eck =         ek - Fuzzy->ek_1;                                  //得到误差变化值

        temp1 = FuzzyCale(ek,eck);

        //Fuzzy->ek_2 =  Fuzzy->ek_1;                 
        Fuzzy->ek_1 =  ek;                                            //更新两次误差值,备下次计算误差变化使用;

        return         temp1        ;


}


s16 Fuzzy_Pid(PID* pid,Fuzzy *Fuzzy,s16 NextPoint)
{
    s16  dError1,dError2, Error;
    s16 ek;         
        s16 temp1;
        s16 dU;

        ek = SetPoint -  NextPoint;

        if( ek>=-40 && ek<=40 )                   //小误差使用PID 控制        ,位置式控制
        {
               
                mark = 1;
        Error = SetPoint -  NextPoint;          // 偏差

        pid->SumError += Error;                 // 积分
                  
        dError1 = pid->ek_1 - pid->ek_2;                    // 当前微分
                  
        pid->ek_2 = pid->ek_1;  
        pid->ek_1 = Error;  

                temp1 = pid->Kp * Error                              // 比例项  
                    + pid->Ki * (pid->SumError/2)         // 积分项  
                    + pid->Kd * dError1 ;                    // 微分项

                   if ( temp1 >=  200)  temp1  = 190 ;            //限幅输出

               if ( temp1 <= -200)  temp1  = -190;

            temp1 /=2;

//                mark = 1;
//                Error = SetPoint -  NextPoint;                                  //求偏差
//
//            dError1 = Error - pid->ek_1;                                  //偏差变化值
//                dError2 = pid->ek_1 - pid->ek_2;
//
//                if((pid->LastValue >= 300 && Error > 0)||(pid->LastValue <= -300 && Error < 0))        //积分分离
//                {
//                        dU =  (  (s16)( pid->Kp * (Error -  pid->ek_1) +  pid->Kd * (dError1 - dError2)  )  )>>2;
//                }
//
//            dU =  ( (s16)(  pid->Kp * (Error -  pid->ek_1)        + pid->Ki * Error +  pid->Kd * (dError1 - dError2)  ) )>>2;
//
//        pid->ek_2 = pid->ek_1;                                            //更新误差
//        pid->ek_1 = Error;  
//
//                temp1 =  dU  +          pid->LastValue;
//                pid->LastValue = temp1;
//
//                if ( temp1 >=  200)  temp1  = 190 ;            //限幅输出
//                if ( temp1 <= -200)  temp1  = -190;
//               
//                temp1 /=2;

        }
        else                                                                                          //大误差使用模糊控制
        {
       
                mark  = 2;
                   temp1 =  FuzzyControl(Fuzzy,NextPoint);

        }

        return         temp1;

}

为了方便查看 上传源码
ourdev_688086TEYCVO.txt(文件大小:37K) (原文件名:main.txt)

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2011-10-24 11:57:24 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2011-10-24 12:38:40 | 显示全部楼层
说说意见吧! 模糊自适应的PID算法谁做过啊?能给点资料吗?

出0入0汤圆

 楼主| 发表于 2011-10-24 12:42:51 | 显示全部楼层
大家都不怎么喜欢说话?

出0入0汤圆

 楼主| 发表于 2011-10-24 21:11:08 | 显示全部楼层
都不研究电机的算法啊?

出0入0汤圆

发表于 2011-10-24 22:10:46 | 显示全部楼层
终于大侠研究模糊控制了

出0入0汤圆

发表于 2011-10-24 22:34:27 | 显示全部楼层
玩过一两天,感觉模糊控制到最后就是查表,  通过输入的变量在数组里找到对应的输出, 当时玩到后面都省去了前面那些模糊化、推理和解模糊, 直接按照感觉改表里的数据了。。。。。

出0入0汤圆

 楼主| 发表于 2011-10-24 22:47:38 | 显示全部楼层
有没有比较好的参考资料和代码啊?
感觉模糊控制经验要求较多!!

出0入0汤圆

发表于 2011-10-25 00:14:54 | 显示全部楼层
你的做法是对的,直线加速到某个速度,再PID。这个速度稍微选一个,要注意惯性,因为惯性和负载有关系。根据负载和精度的不一样,反复调好的,就和我们调程序一样。

PS:我的BLDC,最高1000转,我可以控制在10转以内,再高精度也没时间去调了,没准这个算法不合适。

出0入0汤圆

发表于 2011-10-25 08:20:34 | 显示全部楼层
进来学习学习--对模糊控制不是很懂-

出0入0汤圆

发表于 2011-10-25 08:27:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-25 08:31:53 | 显示全部楼层
算法这个东西只能是学习,特别是模糊算法。PID还能用用,模糊没用过。

出0入0汤圆

发表于 2011-10-25 12:47:16 | 显示全部楼层
主要是存在很大的主观性,  里面的很多东西都是按照人的主观意愿来设定的,其实到后面也就是查表了,  虽然我只懂点皮毛。

出0入0汤圆

 楼主| 发表于 2011-10-25 12:59:59 | 显示全部楼层
回复【8楼】kinsno
-----------------------------------------------------------------------

但是在两种控制的 切换的时候怎么处理啊? 如果控制量就在PID和模糊控制的零界点波动,那就会出现一会进行模糊控制,以后进入PID控制区域,这样的话不是很难稳定??我在实际中也遇到了这样的问题,还没找打解决的办法呢
??

出0入0汤圆

发表于 2011-10-25 13:24:44 | 显示全部楼层
查表控制起来比较好。

出0入0汤圆

发表于 2013-9-7 00:00:51 | 显示全部楼层
学习了

出0入0汤圆

发表于 2013-9-7 06:28:36 | 显示全部楼层
学习了,我也用的是这个程序,为我提供了新的思路,谢谢了呀!!!能加QQ交流吗???447230995

出0入0汤圆

发表于 2013-9-8 22:16:02 | 显示全部楼层
mark一下,感觉很有用的

出0入0汤圆

发表于 2014-3-2 22:38:10 | 显示全部楼层
是不是要调节积分微分项

出0入0汤圆

发表于 2014-3-31 14:41:59 | 显示全部楼层
正研究着,碰到个量化因子,和隶属的计算问题

出0入0汤圆

发表于 2014-3-31 15:27:06 | 显示全部楼层
正研究着,碰到个量化因子,和隶属的计算问题

出0入0汤圆

发表于 2014-7-13 09:48:31 | 显示全部楼层
MARK            

出0入0汤圆

发表于 2016-1-20 12:21:55 | 显示全部楼层
兄弟 现在这个研究的怎么样了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 23:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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