搜索
bottom↓
回复: 17

飞思卡尔智能车 电机PID

[复制链接]

出0入0汤圆

发表于 2014-9-4 13:50:09 | 显示全部楼层 |阅读模式
提到小车的控制必然想到的PID控制,这也是各技术报告都不会漏掉的名词,在飞思卡尔XS128系列(二)PWM模块中已经提到了一些电机控制方面的东西,主要讲了用PID和BANG-BANG控制相结合的方式来控制电机,就是由BANG-BANG来控制力度,用PID来控制精度,下面就具体来讲讲。

  先说控制,所谓控制首先由闭环控制和开环控制之分,就是所谓的有反馈和无反馈,当然PID显然是有反馈的控制。所谓的闭环控制就是要根据被控制量的实际情况参与运算来决定操作量的大小或者方向。因为在单回路控制系统中,由于扰动的作用使被控参数偏离给定值,从而产生偏差,而自动控制系统的调节单元将来自变送器的测量值与给定值相比较后产生的偏差进行比例、积分和微分运算,并输出统一标准信号,去控制执行机构的动作,以实现对温度、压力、流量和速度等的自动控制。

  然而牵扯到高级PID,像有自适应控制、模糊控制、预测控制、神经网络控制、专家智能控制等等,里面也就模糊控制搞过一定时间,其它我也不懂,就不瞎扯了。





      比例、积分和微分的线性组合,构成控制量u(t),称为:比例(Proportional)、积分(Integrating)和微分(Differentiation)控制,简称PID控制。比例作用P只与偏差成正比,积分作用I是偏差对时间的累积,而微分作用D是偏差的变化率。

  用一句形象的比喻,比例P代表着现在,积分I代表着过去,而微分D则代表着未来。





公式如图:

  具体于比例、积分和微分,网上有很多这方面的资料,我就不多说了。

  下面是关于参数的调整,比例系数、积分系数和微分系数的合理调整时整个PID系统可以正常温度工作的关键。

  而最好的寻找PID参数的办法是从系统的数学模型出发,从想要的反应来计算参数。很多时候一个详细的数学描述是不存在的,这时候就需要从实际出发去调整PID参数了。



Ziegler——Nichols方法



  Ziegler——Nichols方法是基于系统稳定性分析的PID整定方法,在设计过程中无需要考虑任何特性要求,整定方法简单。





Tyreus——Luyben的整定值即减少了震荡的作用,而且增强了系统的稳定性。

理论上的就不多说了,我自己都懒得多看。

复制代码
    /****************************************************************
    Code Warrior 5.0
    Target : MC9S12XS128
    Crystal: 16.000Mhz  
    by:庞辉
    芜湖联大飞思卡尔项目组   
    ******************************************************************/  
      
    sint16 ideal_speed; //车的理想速度  
      
    //拨码开关选择脉冲  
    const sint16 speed_arr1[253] = {  
         37,37,37,85,85,85,37,37,37     
            
    };  
    const sint16 speed_arr2[253] = {  
         38,38,38,90,90,90,38,38,38   
    };  
      
      
    const sint16 speed_arr3[253] = {  
         40,40,40,95,95,95,40,40,40   
    };  
      
    const sint16 speed_arr4[253] = {  
         45,45,45,95,95,95,45,45,45  
    };  
      
    const sint16 speed_arr5[253] = {  
         50,50,50,95,95,95,50,50,50   
    };  
      
    const sint16 speed_arr6[253] = {  
         37,37,37,100,100,100,37,37,37  
            
    };  
      
    const sint16 speed_arr7[10] =   
    {  
        40,40,40,100,100,100,40,40,40  
    };  
      
      
    void Motor_Change(void)  
    {   
         
         
         
        if(PORTA_PA0 == 0)  
        {  
            ideal_speed = speed_arr1[pos_ + 4];  
        }  
        else if(PORTA_PA1 == 0)  
        {  
            ideal_speed = speed_arr2[pos_ + 4];  
        }                                                
        else if(PORTA_PA2 == 0)  
        {  
            ideal_speed = speed_arr3[pos_ + 4];  
        }  
         else if(PORTA_PA3 == 0)  
        {  
            ideal_speed = speed_arr4[pos_ + 4];  
        }  
        else  if(PORTA_PA4 == 0)  
        {  
            ideal_speed = speed_arr5[pos_ + 4];  
        }  
        else if(PORTA_PA5 == 0)  
        {  
            ideal_speed = speed_arr6[pos_ + 4];  
        }  
        else if(PORTA_PA6 == 0)  
        {  
            ideal_speed = speed_arr7[pos_ + 4];  
        }  
        else   
        {  
            ideal_speed = speed_arr1[pos_ + 4];  
        }  
         
        //ideal_speed = speed_arr7[pos_ + 4];  
         
         speed_error = ideal_speed - pulse_count;  
         
        if(speed_error >= 10) //情况1,全加速  
        {  
            Set_PWM01(10000, 10000);  
        }  
         
        else if(speed_error > -10) //情况2,用PID减速  
        {  
            pid();  
        }  
        else  
        {  
            Set_PWM01(0,10000);   
        }         
            
    }  
复制代码


复制代码
    #define kp_motor 15  
    #define ki_motor 4//1  
    #define kd_motor 8//10   
      
    sint16 speed_error; //理想与实际速度偏差值  
    sint16 pre_error; //速度PID 前一次的速度误差值ideal_speed- pulse_count  
    sint16 pre_d_error; //速度PID 前一次的速度误差之差d_error-pre_d_error  
    sint16 pk; //速度PID值  
      
    void pid(void)   
    {  
        sint16 error,d_error,dd_error;  
         
        error = ideal_speed - pulse_count;  
        d_error = error - pre_error;  
        dd_error = d_error - pre_d_error;  
         
        pre_error = error; //存储当前偏差  
        pre_d_error = d_error;  
         
        pk += kp_motor * d_error + ki_motor * error + kd_motor * dd_error;  
         
        if(pk >= 10000)   
        {  
            pk = 10000;  
        }  
        else if(pk <= 0)   
        {  
            pk = 0;  
        }  
         
        Set_PWM01(pk,10000);  
    }  



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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2014-9-4 13:55:30 | 显示全部楼层
顶一下楼主

出0入0汤圆

 楼主| 发表于 2014-9-4 13:58:31 | 显示全部楼层

共同交流。

出100入101汤圆

发表于 2014-9-4 14:09:39 | 显示全部楼层
支持一下原创

出0入0汤圆

发表于 2014-12-22 18:31:19 | 显示全部楼层
用的是打表法?

出0入0汤圆

发表于 2014-12-24 13:50:10 | 显示全部楼层
芜湖联大?

出0入0汤圆

发表于 2014-12-24 14:27:36 | 显示全部楼层
也就用过p...

出0入0汤圆

发表于 2014-12-24 21:59:23 | 显示全部楼层
电机的PID算法 ,不错 ,可以收藏

出0入0汤圆

发表于 2014-12-24 22:00:06 | 显示全部楼层

只用P 怎么控制  ?

出0入0汤圆

发表于 2014-12-25 06:58:50 | 显示全部楼层
franki 发表于 2014-12-24 22:00
只用P 怎么控制  ?

pwm控制有刷电机,速度快了减少脉宽,反之加宽

出0入0汤圆

发表于 2014-12-25 15:30:23 | 显示全部楼层
swap2013 发表于 2014-12-25 06:58
pwm控制有刷电机,速度快了减少脉宽,反之加宽

哦 ,PWM 啊 ,我以为是P 比例环节

出0入0汤圆

发表于 2014-12-25 17:04:08 | 显示全部楼层
使用PID控制电机的方法还是很通用的

出0入0汤圆

发表于 2014-12-25 17:05:44 | 显示全部楼层
franki 发表于 2014-12-25 15:30
哦 ,PWM 啊 ,我以为是P 比例环节

PWM也可以实现P比例环节

出0入0汤圆

发表于 2014-12-25 17:48:05 | 显示全部楼层
swap2013 发表于 2014-12-25 17:05
PWM也可以实现P比例环节

那这个就不算PID控制了吧

出0入0汤圆

发表于 2015-2-4 11:29:09 | 显示全部楼层
顶一下   看到你的帖子接下来我又能折腾我的小车啦

出0入0汤圆

发表于 2015-2-4 11:34:22 | 显示全部楼层
涨姿势 。1

出0入0汤圆

发表于 2015-5-16 15:59:00 | 显示全部楼层
代码值得鉴戒,谢谢楼主。
这个程序怎么往51上移植

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-4-23 14:29

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

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