电子发烧友App

硬声App

0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示
电子发烧友网>电子资料下载>嵌入式开发>STM32运用之自平衡小车的PID算法封装-求加精

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

2017-11-27 | rar | 1.3 MB | 次下载 | 免费

资料介绍

继卡尔曼封装之后推出第二个封装,PID算法,这个其实比上个简单多了下面贴出代码
/**
  ******************************************************************************
  * @file    PID_Control.h
  * @author  willieon
  * @version V0.1
  * @date    January-2015
  * @brief   PID控制算法头文件
  *                        定义结构体类型以及声明函数
  *                        #define IF_THE_INTEGRAL_SEPARATION  0/1  为积分分离标志
  ******************************************************************************
  **/
 
#ifndef __PID_CONTROL_H__
#define __PID_CONTROL_H__
 
#define IF_THE_INTEGRAL_SEPARATION  0    
//#define IF_THE_INTEGRAL_SEPARATION  1   //是否积分分离  0-不分离,1 -分离
 
typedef struct
{
        double SetPoint; // 设定目标 Desired Value   
        double Proportion; // 比例常数 Proportional Const
        double Integral; // 积分常数 Integral Const
        double Derivative; // 微分常数 Derivative Const   
        double LastError; // Error[-1]
        double PrevError; // Error[-2]
        double SumError; // Sums of Errors  
}PID;
 
#if IF_THE_INTEGRAL_SEPARATION            //是否积分分离预编译开始
 
double PIDCalc(double NextPoint ,double SepLimit, PID *pp);   //带积分分离的PID运算
 
#else
 
double PIDCalc( double NextPoint, PID *pp);     //不带积分分离的PID运算
 
#endif        //是否积分分离预编译结束
 
void PIDInit (double SetPoint, double Proportion, double Integral, double Derivative, PID *pp);
 
#endif
/**
  ******************************************************************************
  * @file    PID_Control.c
  * @author  willieon
  * @version V0.1
  * @date    January-2015
  * @brief   PID控制算法函数代码
  *        
  *
  ******************************************************************************
  **/
 
#include "PID_Control.h"
#include "math.h"
 
/*************************************************************************************
*        名    称: double PIDCalc( PID *pp, double NextPoint ,double SepLimit)
*        功    能: PID控制运算
*        入口参数: PID *pp  - 定义的运算所需变量的结构体
*                           NextPoint - 负反馈输入值
*                           SepLimit  - 积分分离上限
*        出口参数: 返回PID控制量
*        说    明: 默认不进行积分分离,如果用户需要使用积分分离,需在PID_Control.h中
*                                将 #define IF_THE_INTEGRAL_SEPARATION  0  改为
*                            #define IF_THE_INTEGRAL_SEPARATION  1
*        调用方法: 进行积分分离时入口参数为3个,具体方法如下:
*                                PID PIDControlStruct ;   //定义PID运算结构体
*                                PIDInit(50, 0.24, 0.04, 0.2, &PIDControlStruct);//结构体初始化,注意&符号不能省
*                                ControlData = PIDCalc(ReadData, 200, &PIDControlStruct);   //控制量 = PIDCalc(反馈值,积分分离上限,PID运算结构体)
*
***************************************************************************************
*/
 
#if IF_THE_INTEGRAL_SEPARATION
 
double PIDCalc(double NextPoint ,double SepLimit, PID *pp)
{
        double dError, Error,Flag;   
        Error = pp->SetPoint - NextPoint;         // 偏差
        if(abs(Error) > SepLimit)        //当偏差大于分离上限积分分离
        {
                Flag = 0;
        }
        else       //当偏差小于分离上限,积分项不分离
        {
                Flag = 1;
                pp->SumError += Error;         // 积分  
        }
        dError = pp->LastError - pp->PrevError;         // 当前微分
        pp->PrevError = pp->LastError;
        pp->LastError = Error;  
        return (
                pp->Proportion                *                Error                 // 比例项
                + Flag * pp->Integral        *                pp->SumError         // 积分项
                + pp->Derivative                *                dError                 // 微分项
                );
}
 
#else
 
double PIDCalc( double NextPoint, PID *pp)
{  
        double dError, Error;   
        Error = pp->SetPoint - NextPoint;                         // 偏差
        pp->SumError += Error;                                        // 积分  
        dError = pp->LastError - pp->PrevError;                // 当前微分
        pp->PrevError = pp->LastError;
        pp->LastError = Error;  
        return (pp->Proportion        *        Error                // 比例项
                + pp->Integral                *        pp->SumError         // 积分项
                + pp->Derivative        *        dError         // 微分项
                );
}
 
#endif
 
 
/*************************************************************************************
*        名    称: double PIDCalc( PID *pp, double NextPoint ,double SepLimit)
*        功    能: PID初始化设定
*        入口参数: PID *pp  - 定义的运算所需变量的结构体
*                           SetPoint - 设定的目标值
*                           Proportion,Integral ,Derivative - P,I,D系数
*        出口参数: 无
*        说    明:        
*        调用方法:  PID PIDControlStruct ;   //定义PID运算结构体
*                                PIDInit(50, 0.24, 0.04, 0.2, &PIDControlStruct);//结构体初始化,注意&符号不能省
*                                因为函数需要传入一个指针,需要对结构体取首地址传给指针
*
***************************************************************************************
*/
 
 
void PIDInit (double SetPoint, double Proportion, double Integral, double Derivative, PID *pp)
{  
        pp -> SetPoint = SetPoint; // 设定目标 Desired Value   
        pp -> Proportion = Proportion; // 比例常数 Proportional Const
        pp -> Integral = Integral; // 积分常数 Integral Const
        pp -> Derivative = Derivative; // 微分常数 Derivative Const   
        pp -> LastError = 0; // Error[-1]
        pp -> PrevError = 0; // Error[-2]
        pp -> SumError = 0; // Sums of Errors
 
        //memset ( pp,0,sizeof(struct PID));   //need include "string.h"
}
  将前篇 卡尔曼 和本次的 PID放在一起,在VS2010平台中调试 代码如下
#include "kalman.h"
 
#include "stdio.h"
#include "stdlib.h"
#include "PID_Control.h"
 
void main(void)
 
{
        KalmanCountData k;
        PID PIDControlStruct;
        Kalman_Filter_Init(&k);
        PIDInit(50, 1, 0.04, 0.2, &PIDControlStruct);
        int m,n;
 
        double out;
 
        for(int a = 0;a<80;a++)
        {
                m = 1+ rand() %100;
                n = 1+ rand() %100;
                Kalman_Filter((float)m,(float)n,&k);
                out = PIDCalc(k.Angle_Final, &PIDControlStruct);
                printf("%3d and %3d is %6f -pid- %6f\r\n",m,n,k.Angle_Final,out);
 
        }
}
 
下载该资料的人也在下载 下载该资料的人还在阅读
更多 >

评论

查看更多

下载排行

本周

  1. 1TC358743XBG评估板参考手册
  2. 1.36 MB  |  330次下载  |  免费
  3. 2开关电源基础知识
  4. 5.73 MB  |  6次下载  |  免费
  5. 3100W短波放大电路图
  6. 0.05 MB  |  4次下载  |  3 积分
  7. 4嵌入式linux-聊天程序设计
  8. 0.60 MB  |  3次下载  |  免费
  9. 5基于FPGA的光纤通信系统的设计与实现
  10. 0.61 MB  |  2次下载  |  免费
  11. 6基于FPGA的C8051F单片机开发板设计
  12. 0.70 MB  |  2次下载  |  免费
  13. 751单片机窗帘控制器仿真程序
  14. 1.93 MB  |  2次下载  |  免费
  15. 8基于51单片机的RGB调色灯程序仿真
  16. 0.86 MB  |  2次下载  |  免费

本月

  1. 1OrCAD10.5下载OrCAD10.5中文版软件
  2. 0.00 MB  |  234315次下载  |  免费
  3. 2555集成电路应用800例(新编版)
  4. 0.00 MB  |  33564次下载  |  免费
  5. 3接口电路图大全
  6. 未知  |  30323次下载  |  免费
  7. 4开关电源设计实例指南
  8. 未知  |  21548次下载  |  免费
  9. 5电气工程师手册免费下载(新编第二版pdf电子书)
  10. 0.00 MB  |  15349次下载  |  免费
  11. 6数字电路基础pdf(下载)
  12. 未知  |  13750次下载  |  免费
  13. 7电子制作实例集锦 下载
  14. 未知  |  8113次下载  |  免费
  15. 8《LED驱动电路设计》 温德尔著
  16. 0.00 MB  |  6653次下载  |  免费

总榜

  1. 1matlab软件下载入口
  2. 未知  |  935054次下载  |  免费
  3. 2protel99se软件下载(可英文版转中文版)
  4. 78.1 MB  |  537796次下载  |  免费
  5. 3MATLAB 7.1 下载 (含软件介绍)
  6. 未知  |  420026次下载  |  免费
  7. 4OrCAD10.5下载OrCAD10.5中文版软件
  8. 0.00 MB  |  234315次下载  |  免费
  9. 5Altium DXP2002下载入口
  10. 未知  |  233046次下载  |  免费
  11. 6电路仿真软件multisim 10.0免费下载
  12. 340992  |  191185次下载  |  免费
  13. 7十天学会AVR单片机与C语言视频教程 下载
  14. 158M  |  183278次下载  |  免费
  15. 8proe5.0野火版下载(中文版免费下载)
  16. 未知  |  138040次下载  |  免费