野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 277929|回复: 981

STM32运用之自平衡小车的PID算法封装-求加精

  [复制链接]
发表于 2015-1-10 18:36:30 | 显示全部楼层 |阅读模式
本帖最后由 低调的华丽 于 2015-1-20 09:25 编辑

继卡尔曼封装之后推出第二个封装,PID算法,这个其实比上个简单多了下面贴出代码:
  1. /**
  2.   ******************************************************************************
  3.   * @file    PID_Control.h
  4.   * @author  willieon
  5.   * @version V0.1
  6.   * @date    January-2015
  7.   * @brief   PID控制算法头文件
  8.   *                        定义结构体类型以及声明函数
  9.   *                        #define IF_THE_INTEGRAL_SEPARATION  0/1  为积分分离标志
  10.   ******************************************************************************
  11.   **/

  12. #ifndef __PID_CONTROL_H__
  13. #define __PID_CONTROL_H__

  14. #define IF_THE_INTEGRAL_SEPARATION  0   
  15. //#define IF_THE_INTEGRAL_SEPARATION  1   //是否积分分离  0-不分离,1 -分离

  16. typedef struct
  17. {
  18.         double SetPoint; // 设定目标 Desired Value   
  19.         double Proportion; // 比例常数 Proportional Const
  20.         double Integral; // 积分常数 Integral Const
  21.         double Derivative; // 微分常数 Derivative Const   
  22.         double LastError; // Error[-1]
  23.         double PrevError; // Error[-2]
  24.         double SumError; // Sums of Errors  
  25. }PID;

  26. #if IF_THE_INTEGRAL_SEPARATION            //是否积分分离预编译开始

  27. double PIDCalc(double NextPoint ,double SepLimit, PID *pp);   //带积分分离的PID运算

  28. #else

  29. double PIDCalc( double NextPoint, PID *pp);     //不带积分分离的PID运算

  30. #endif        //是否积分分离预编译结束

  31. void PIDInit (double SetPoint, double Proportion, double Integral, double Derivative, PID *pp);

  32. #endif
复制代码
  1. /**
  2.   ******************************************************************************
  3.   * @file    PID_Control.c
  4.   * @author  willieon
  5.   * @version V0.1
  6.   * @date    January-2015
  7.   * @brief   PID控制算法函数代码
  8.   *        
  9.   *
  10.   ******************************************************************************
  11.   **/

  12. #include "PID_Control.h"
  13. #include "math.h"

  14. /*************************************************************************************
  15. *        名    称: double PIDCalc( PID *pp, double NextPoint ,double SepLimit)
  16. *        功    能: PID控制运算
  17. *        入口参数: PID *pp  - 定义的运算所需变量的结构体
  18. *                           NextPoint - 负反馈输入值
  19. *                           SepLimit  - 积分分离上限
  20. *        出口参数: 返回PID控制量
  21. *        说    明: 默认不进行积分分离,如果用户需要使用积分分离,需在PID_Control.h中
  22. *                                将 #define IF_THE_INTEGRAL_SEPARATION  0  改为
  23. *                            #define IF_THE_INTEGRAL_SEPARATION  1
  24. *        调用方法: 进行积分分离时入口参数为3个,具体方法如下:
  25. *                                PID PIDControlStruct ;   //定义PID运算结构体
  26. *                                PIDInit(50, 0.24, 0.04, 0.2, &PIDControlStruct);//结构体初始化,注意&符号不能省
  27. *                                ControlData = PIDCalc(ReadData, 200, &PIDControlStruct);   //控制量 = PIDCalc(反馈值,积分分离上限,PID运算结构体)
  28. *
  29. ***************************************************************************************
  30. */

  31. #if IF_THE_INTEGRAL_SEPARATION

  32. double PIDCalc(double NextPoint ,double SepLimit, PID *pp)
  33. {
  34.         double dError, Error,Flag;   
  35.         Error = pp->SetPoint - NextPoint;         // 偏差
  36.         if(abs(Error) > SepLimit)        //当偏差大于分离上限积分分离
  37.         {
  38.                 Flag = 0;
  39.         }
  40.         else       //当偏差小于分离上限,积分项不分离
  41.         {
  42.                 Flag = 1;
  43.                 pp->SumError += Error;         // 积分  
  44.         }
  45.         dError = pp->LastError - pp->PrevError;         // 当前微分
  46.         pp->PrevError = pp->LastError;
  47.         pp->LastError = Error;  
  48.         return (
  49.                 pp->Proportion                *                Error                 // 比例项
  50.                 + Flag * pp->Integral        *                pp->SumError         // 积分项
  51.                 + pp->Derivative                *                dError                 // 微分项
  52.                 );
  53. }

  54. #else

  55. double PIDCalc( double NextPoint, PID *pp)
  56. {  
  57.         double dError, Error;   
  58.         Error = pp->SetPoint - NextPoint;                         // 偏差
  59.         pp->SumError += Error;                                        // 积分  
  60.         dError = pp->LastError - pp->PrevError;                // 当前微分
  61.         pp->PrevError = pp->LastError;
  62.         pp->LastError = Error;  
  63.         return (pp->Proportion        *        Error                // 比例项
  64.                 + pp->Integral                *        pp->SumError         // 积分项
  65.                 + pp->Derivative        *        dError         // 微分项
  66.                 );
  67. }

  68. #endif


  69. /*************************************************************************************
  70. *        名    称: double PIDCalc( PID *pp, double NextPoint ,double SepLimit)
  71. *        功    能: PID初始化设定
  72. *        入口参数: PID *pp  - 定义的运算所需变量的结构体
  73. *                           SetPoint - 设定的目标值
  74. *                           Proportion,Integral ,Derivative - P,I,D系数
  75. *        出口参数: 无
  76. *        说    明:        
  77. *        调用方法:  PID PIDControlStruct ;   //定义PID运算结构体
  78. *                                PIDInit(50, 0.24, 0.04, 0.2, &PIDControlStruct);//结构体初始化,注意&符号不能省
  79. *                                因为函数需要传入一个指针,需要对结构体取首地址传给指针
  80. *
  81. ***************************************************************************************
  82. */


  83. void PIDInit (double SetPoint, double Proportion, double Integral, double Derivative, PID *pp)
  84. {  
  85.         pp -> SetPoint = SetPoint; // 设定目标 Desired Value   
  86.         pp -> Proportion = Proportion; // 比例常数 Proportional Const
  87.         pp -> Integral = Integral; // 积分常数 Integral Const
  88.         pp -> Derivative = Derivative; // 微分常数 Derivative Const   
  89.         pp -> LastError = 0; // Error[-1]
  90.         pp -> PrevError = 0; // Error[-2]
  91.         pp -> SumError = 0; // Sums of Errors

  92.         //memset ( pp,0,sizeof(struct PID));   //need include "string.h"
  93. }
复制代码



回复

使用道具 举报

 楼主| 发表于 2015-1-10 18:39:54 | 显示全部楼层
本帖最后由 低调的华丽 于 2015-1-20 09:24 编辑

复制代码
回复

使用道具 举报

 楼主| 发表于 2015-1-10 18:41:41 | 显示全部楼层
将前篇  卡尔曼  和本次的 PID放在一起,在VS2010平台中调试 代码如下  
  1. #include "kalman.h"

  2. #include "stdio.h"
  3. #include "stdlib.h"
  4. #include "PID_Control.h"

  5. void main(void)

  6. {
  7.         KalmanCountData k;
  8.         PID PIDControlStruct;
  9.         Kalman_Filter_Init(&k);
  10.         PIDInit(50, 1, 0.04, 0.2, &PIDControlStruct);
  11.         int m,n;

  12.         double out;

  13.         for(int a = 0;a<80;a++)
  14.         {
  15.                 m = 1+ rand() %100;
  16.                 n = 1+ rand() %100;
  17.                 Kalman_Filter((float)m,(float)n,&k);
  18.                 out = PIDCalc(k.Angle_Final, &PIDControlStruct);
  19.                 printf("%3d and %3d is %6f -pid- %6f\r\n",m,n,k.Angle_Final,out);

  20.         }
  21. }
复制代码
回复 支持 2 反对 0

使用道具 举报

 楼主| 发表于 2015-1-10 18:44:20 | 显示全部楼层
如果觉得double类型对CPU负载太大,就改为float吧,有时候控制量范围不大,float完全能满足!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-10 18:45:40 | 显示全部楼层
看本帖的反响,如果支持高,我会把手头自平衡小车的代码用标准的库格式封装改写。逐步放出来
回复 支持 1 反对 0

使用道具 举报

发表于 2015-1-10 20:33:38 | 显示全部楼层
好东西。。。。
回复

使用道具 举报

发表于 2015-1-10 22:27:54 | 显示全部楼层
看过 来支持下!!!!!
回复 支持 1 反对 0

使用道具 举报

发表于 2015-1-11 09:28:53 | 显示全部楼层
实现的情况如何呢,稳定不
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-11 16:51:49 | 显示全部楼层
yy2816157676 发表于 2015-1-11 09:28
实现的情况如何呢,稳定不

稳定不稳定不是主要看代码,而是看整定啊
回复 支持 反对

使用道具 举报

发表于 2015-1-11 22:49:18 | 显示全部楼层
低调的华丽 发表于 2015-1-10 18:45
看本帖的反响,如果支持高,我会把手头自平衡小车的代码用标准的库格式封装改写。逐步放出来

在精神和灵魂上支持你
回复 支持 反对

使用道具 举报

发表于 2015-1-11 22:57:49 | 显示全部楼层
这种算法实际应用中很有用,大家顶起来,版主加油!!!
回复 支持 反对

使用道具 举报

发表于 2015-1-20 18:11:37 | 显示全部楼层
学习一下
回复

使用道具 举报

发表于 2015-1-20 22:02:48 | 显示全部楼层
学习啦。。。。。
回复

使用道具 举报

发表于 2015-1-22 19:23:59 | 显示全部楼层
一直想学习PID怎么搞,正好学习一下
回复 支持 反对

使用道具 举报

发表于 2015-1-23 16:36:39 | 显示全部楼层
平衡车做的怎么样了?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-24 09:59:39 | 显示全部楼层
xyc2690 发表于 2015-1-23 16:36
平衡车做的怎么样了?

香蕉电机的做完了,感觉性能不行,现在在做步进电机的
回复 支持 反对

使用道具 举报

发表于 2015-1-24 10:03:34 | 显示全部楼层
看看













回复

使用道具 举报

发表于 2015-1-24 12:45:21 | 显示全部楼层
好,正需要。谢谢楼主
回复 支持 反对

使用道具 举报

发表于 2015-1-24 13:04:10 | 显示全部楼层
学习才是王道
回复 支持 反对

使用道具 举报

发表于 2015-1-24 16:28:47 | 显示全部楼层
哪里有PI算法
回复 支持 反对

使用道具 举报

发表于 2015-1-24 16:49:36 | 显示全部楼层
这些代码看不懂啊,唉
回复 支持 反对

使用道具 举报

发表于 2015-1-24 16:50:35 | 显示全部楼层
有木有简单的陀螺仪积分的代码。
回复 支持 反对

使用道具 举报

发表于 2015-1-24 18:41:50 | 显示全部楼层
路过,赞一个
回复 支持 反对

使用道具 举报

发表于 2015-1-31 17:42:57 | 显示全部楼层
快快快看。。。
回复

使用道具 举报

发表于 2015-2-1 17:42:46 | 显示全部楼层
mark!!!
回复

使用道具 举报

发表于 2015-2-4 23:08:54 | 显示全部楼层
学习学习,谢谢楼主
回复 支持 反对

使用道具 举报

发表于 2015-2-4 23:38:36 来自手机 | 显示全部楼层
顶一个,我最近也在弄自平衡,在pid算法这卡住了
回复 支持 反对

使用道具 举报

发表于 2015-2-4 23:49:33 | 显示全部楼层
楼主好叼,前来膜拜膜拜
回复 支持 反对

使用道具 举报

发表于 2015-3-22 14:45:05 | 显示全部楼层
最近想搞一个平衡小车,学学先
回复 支持 反对

使用道具 举报

发表于 2015-3-22 16:13:31 | 显示全部楼层
                                           
回复 支持 反对

使用道具 举报

发表于 2015-3-25 19:52:44 | 显示全部楼层
学习 最近做平衡车做的好烦
回复 支持 反对

使用道具 举报

发表于 2015-3-25 21:50:22 | 显示全部楼层
看看大神们的心血
回复 支持 反对

使用道具 举报

发表于 2015-3-26 10:12:14 | 显示全部楼层
在学习。。。。。。。。
回复

使用道具 举报

发表于 2015-3-26 14:31:27 | 显示全部楼层
和倒立摆控制方法类似吗?
回复 支持 反对

使用道具 举报

发表于 2015-3-26 17:01:07 | 显示全部楼层
隐藏内容是什么?
回复 支持 反对

使用道具 举报

发表于 2015-3-28 22:01:48 | 显示全部楼层
good!!!!!!!!!!!!!!!!!!!!!!!!
回复

使用道具 举报

发表于 2015-3-30 17:39:18 | 显示全部楼层
pid是什么??
回复

使用道具 举报

发表于 2015-3-30 23:27:49 | 显示全部楼层
看看,学习学习
回复 支持 反对

使用道具 举报

发表于 2015-3-31 16:21:02 | 显示全部楼层
                                                  kk
回复 支持 反对

使用道具 举报

发表于 2015-4-17 13:59:20 | 显示全部楼层
希望对我学习PID有帮助         
回复 支持 反对

使用道具 举报

发表于 2015-5-3 20:36:11 | 显示全部楼层
居然 是卡尔曼一起的
回复 支持 反对

使用道具 举报

发表于 2015-5-3 21:29:09 | 显示全部楼层
回复看看         
回复 支持 反对

使用道具 举报

发表于 2015-5-3 21:33:36 | 显示全部楼层
其实参数参数整定是很虐心的一件事、、、、
回复 支持 反对

使用道具 举报

发表于 2015-5-4 11:00:03 | 显示全部楼层
好东西,版主加油!
回复 支持 反对

使用道具 举报

发表于 2015-5-4 14:20:40 | 显示全部楼层
guolai 学习一下
回复 支持 反对

使用道具 举报

发表于 2015-5-5 09:24:52 | 显示全部楼层
牛               
回复 支持 反对

使用道具 举报

发表于 2015-5-14 11:02:43 | 显示全部楼层
楼主好样的
回复 支持 反对

使用道具 举报

发表于 2015-5-14 13:13:13 | 显示全部楼层
LZ辛苦了。
回复

使用道具 举报

发表于 2015-5-18 16:59:32 | 显示全部楼层
看看。。。。。。
回复

使用道具 举报

发表于 2015-5-20 22:08:48 | 显示全部楼层
6666666666666666666666666666666666666666
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-4-30 05:20 , Processed in 0.050226 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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