PID算法的C语言实现
1.根据我控制算法类文章中关于PID的理论的一些描述,同时也根据网络上一些其他的PID文章,以及自己最近一个项目的实践后,总结了几套基于C语言的PID算法,由于网络中很少有人进行分享完整的PID算法实现,我这里分享下。
(1)头文件,定义pid的结构体,类的概念,包含pid的属性和方法
#ifndef __PID_H_
#define __PID_H_ #include <stdint.h> typedef struct _pid
{
int16_t set_value; // 给定值,rin(k)
int16_t actual_value; // 实际值,反馈值,rout(k)
int16_t err; // 偏差值,rin(k) - rout(k)
int16_t err_last; // 上一次偏差值,rin(k - 1) - rout(k - 1)
int16_t err_last_last; // 上一次上一次的偏差值,rin(k - 2) - rout(k - 2)
float kp; // 比例系数
float ki; // 积分系数
float kd; // 微分系数
float uk; // pid公式运算结果值
float incremental_value; // 增量值
float integral_value; // 积分值
float umax; // uk的上限值,抗积分饱和用
float umin; // uk的下限值,抗积分饱和用
int16_t err_up_value; // 偏差上限值,积分分离用
int16_t ki_k; // 积分的再次乘机系数,积分分离用 float out_value; // float(*position_type)(struct _pid *ppid); // 位置型PID算法,无积分分离、无抗积分饱和
float(*incremental_type)(struct _pid *ppid); // 增量型PID算法
float(*integral_separation_type)(struct _pid *ppid); // 积分分离PID算法
float(*int_sep_anti_sat_type)(struct _pid *ppid); // 积分分离 + 抗积分饱和PID算法
}_pid_t; _pid_t *pid_create(void); extern _pid_t *pg_pid; #endif
(2).c文件,包含头文件中4个PID算法的实现,包含位置型PID算法、增量型PID算法、积分分离PID算法、积分分离+抗饱和PID算法
#include <stdlib.h>
#include <string.h> #include "pid.h" #include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "portmacro.h"
#include "semphr.h" #include "Debug.h" /*************************************
*
* Funciton Name : pid_position_type
* Function :位置型PID算法,无积分分离、无抗积分饱和
* @note : 积分分离:能解决初期系统偏差值大,累加到积分项中,引起系统超调、振荡问题。积分是为了消除静态误差的,应在误差在小范围时引入积分
* : 抗积分饱和:能解决执行器到达极限值时,但uk还在增大,使得系统进入饱和,进入饱和区的时间越长,当系统出现反向偏差,解决这个反向偏差的时间就会越长,此时系统会像失控一样。
* :进入抗积分饱和,当uk超过上限时,积分向只累加负偏差,当uk超过下限时,积分项只累加正偏差。
*
× @param :pid
*
*
* @return : uk
*************************************/
static float pid_position_type_f(struct _pid *ppid)
{
ppid->err = ppid->set_value - ppid->actual_value; // 偏差 ppid->integral_value += ppid->err; // 积分累加 ppid->uk = ppid->kp * ppid->err + ppid->ki * ppid->integral_value + ppid->kd * (ppid->err - ppid->err_last); ppid->err_last = ppid->err; return (ppid->uk);
} /*************************************
*
* Funciton Name : pid_incremental_type_f
* Function :增量型PID算法
* @note : 相较于位置型,因为与3个偏差相关,增强了系统稳定性
*
× @param :pid
*
*
* @return : uk + 增量值
*************************************/
static float pid_incremental_type_f(struct _pid *ppid)
{
ppid->err = ppid->set_value - ppid->actual_value; // 偏差 //ppid->integral_value += ppid->err; // 积分累加 ppid->incremental_value = ppid->kp * ( ppid->err - ppid->err_last) + ppid->ki * ppid->err + ppid->kd * (ppid->err - 2 * ppid->err_last + ppid->err_last_last); ppid->uk += ppid->incremental_value; ppid->err_last_last = ppid->err_last;
ppid->err_last = ppid->err; return (ppid->uk);
} /*************************************
*
* Funciton Name : pid_integral_separation_type_f
* Function :积分分离PID算法
* @note : 能解决初期系统偏差值大,累加到积分项中,引起系统超调、振荡问题。积分是为了消除静态误差的,应在误差在小范围时引入积分
*
× @param :pid
*
*
* @return : uk
*************************************/
static float pid_integral_separation_type_f(struct _pid *ppid)
{
ppid->err = ppid->set_value - ppid->actual_value; // 偏差 // 误差过大去除积分效果
if ( abs(ppid->err) > ppid->err_up_value )
{
ppid->ki_k = 0;
}
else
{
ppid->ki_k = 1;
ppid->integral_value += ppid->err; // 积分累加
} ppid->uk = ppid->kp * ppid->err + ppid->ki_k * ppid->ki * ppid->integral_value + ppid->kd * (ppid->err - ppid->err_last); ppid->err_last = ppid->err; return (ppid->uk);
} /*************************************
*
* Funciton Name : pid_int_sep_anti_sat_type_f
* Function :积分分离 + 抗积分饱和PID算法
* @note : 能解决初期系统偏差值大,累加到积分项中,引起系统超调、振荡问题。积分是为了消除静态误差的,应在误差在小范围时引入积分
* : 抗积分饱和:能解决执行器到达极限值时,但uk还在增大,使得系统进入饱和,进入饱和区的时间越长,当系统出现反向偏差,解决这个反向偏差的时间就会越长,此时系统会像失控一样。
* :进入抗积分饱和,当uk超过上限时,积分向只累加负偏差,当uk超过下限时,积分项只累加正偏差。
*
× @param :pid
*
*
* @return : uk
*************************************/
static float pid_int_sep_anti_sat_type_f(struct _pid *ppid)
{
ppid->err = ppid->set_value - ppid->actual_value; // 偏差 Debug("ppid->err = %d\r\n", ppid->err); if ( ppid->out_value > ppid->umax ) // 抗积分饱和
{
// 误差过大去除积分效果
if ( abs(ppid->err) > ppid->err_up_value ) // 积分分离
{
ppid->ki_k = 0;
}
else
{
ppid->ki_k = 1; if ( ppid->err < 0 )
{
ppid->integral_value += ppid->err; // 积分累加
} }
}
else if ( ppid->out_value < ppid->umin ) // 抗积分饱和
{
// 误差过大去除积分效果
if ( abs(ppid->err) > ppid->err_up_value ) // 积分分离
{
ppid->ki_k = 0;
}
else
{
ppid->ki_k = 1; if ( ppid->err > 0 )
{
ppid->integral_value += ppid->err; // 积分累加
} }
}
else
{
// 误差过大去除积分效果
if ( abs(ppid->err) > ppid->err_up_value )
{
ppid->ki_k = 0;
}
else
{
ppid->ki_k = 1;
ppid->integral_value += ppid->err; // 积分累加
}
} ppid->uk = ppid->kp * ppid->err + ppid->ki_k * ppid->ki * ppid->integral_value + ppid->kd * (ppid->err - ppid->err_last); ppid->err_last = ppid->err; // if ( ppid->uk >= 0.07 && ppid->uk <= 1 )
// {
// ppid->uk = 1;
// }
//
// if ( ppid->uk <= -0.07 && ppid->uk >= -1 )
// {
// ppid->uk = -1;
// } return (ppid->uk);
} /*************************************
*
* Funciton Name : pid_init
* Function : pid实例构造
*
*
*************************************/
static void pid_init(_pid_t *ppid)
{
ppid->kp = 0.2;
ppid->ki = 0.05;
ppid->kd = 0; ppid->umax = 4000;
ppid->umin = 0; ppid->position_type = pid_position_type_f;
ppid->incremental_type = pid_incremental_type_f;
ppid->integral_separation_type = pid_integral_separation_type_f;
ppid->int_sep_anti_sat_type = pid_int_sep_anti_sat_type_f;
} /*************************************
*
* Funciton Name : pid_create
* Function : pid实例创建
* @author :
*
* @return : 返回pid实例
*
*************************************/
_pid_t *pid_create(void)
{
_pid_t *ppid = (_pid_t *)pvPortMalloc(sizeof(_pid_t)); memset(ppid, 0, sizeof(_pid_t)); pid_init(ppid); return ppid;
}
(3)PID的实现算法有了,但还是要根据实际情况进行调试选取最适合的PID算法以及修改可能存在的不恰当的位置。
PID算法的C语言实现的更多相关文章
- PID算法(c 语言)(转)
PID算法(c 语言)(来自老外) #include <stdio.h> #include<math.h> //定义PID 的结构体 struct _pid { int pv; ...
- PID算法(c 语言)(来自老外)
#include <stdio.h> #include<math.h> //定义PID 的结构体 struct _pid { int pv; // integer that c ...
- PID控制算法的C语言实现三 位置型PID的C语言实现
上一节中已经抽象出了位置性PID和增量型PID的数学表达式,这一节,重点讲解C语言代码的实现过程,算法的C语言实现过程具有一般性,通过PID算法的C语言实现,可以以此类推,设计其它算法的C语言实现. ...
- PID控制算法的C语言实现
参考: PID控制器开发笔 浅谈位置式PID 专家PID控制在快速系统中的仿真及应用(这篇了论文介绍的积分分离PID.专家PID(脚本实现和simulink实现)很详细) PID控制算法的C语言实现一 ...
- 【转】位置式、增量式PID算法C语言实现
位置式.增量式PID算法C语言实现 芯片:STM32F107VC 编译器:KEIL4 作者:SY 日期:2017-9-21 15:29:19 概述 PID 算法是一种工控领域常见的控制算法,用于闭环反 ...
- PID算法(C语言)
/************ PID算法(C语言) ************/ #include <stdio.h> #include<math.h> struct _pid { ...
- PID控制算法的C语言实现十一 模糊算法简介
在PID控制算法的C语言实现九中,文章已经对模糊PID的实质做了一个简要说明.本来打算等到完成毕业设计,工作稳定了再着力完成剩下的部分.鉴于网友的要求和信任,抽出时间来,对模糊PID做一个较为详细的论 ...
- PID控制算法的C语言实现二 PID算法的离散化
上一节中,我论述了PID算法的基本形式,并对其控制过程的实现有了一个简要的说明,通过上一节的总结,基本已经可以明白PID控制的过程.这一节中先继续上一节内容补充说明一下. 1.说明一下反馈控制的原理, ...
- PID控制算法的C语言实现一 PID算法原理
本系列是转载............. 全部的程序有一个共同点:就是我没认真去调pid的参数 在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设 ...
随机推荐
- lumen容器模仿
<?php class Container { private $bindings = []; private $instances = []; public function getClosu ...
- 如何使用 Gin 和 Gorm 搭建一个简单的 API 服务 (一)
介绍 Go 语言最近十分火热,但对于新手来说,想立马上手全新的语法和各种各样的框架还是有点难度的.即使是基础学习也很有挺有挑战性. 在这篇文章中,我想用最少的代码写出一个可用的 API 服务. ...
- 全文检索Solr集成HanLP中文分词【转】
以前发布过HanLP的Lucene插件,后来很多人跟我说其实Solr更流行(反正我是觉得既然Solr是Lucene的子项目,那么稍微改改配置就能支持Solr),于是就抽空做了个Solr插件出来,开源在 ...
- oblivious polynomial evaluation
Oblivious polynomial evaluation is a protocol involving two parties, a sender whose input is a polyn ...
- 循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中
在我们开发代码的时候,一般都喜欢进行一定程度的重构,以达到简化代码.关注点分离.提高代码可读性等等方面的考虑,本篇随笔介绍在VUE+Element 前端应用开发过程中,实现简化main.js处理代码, ...
- D. Rescue Nibel! 解析(思維、組合、離散化、差分)
Codeforce 1420 D. Rescue Nibel! 解析(思維.組合.離散化.差分) 今天我們來看看CF1420D 題目連結 題目 給你\(n\)個區間,求有幾種方法使得\(k\)個區間的 ...
- Optimal binary search trees
问题 该问题的实际应用 Suppose that we are designing a program to translate text from English to French. For ea ...
- 手把手教你使用 Prometheus 监控 MySQL 与 MariaDB.md
概述 MySQL 是常用的关系型数据库,MariaDB 作为 MySQL 的分支版本,兼容 MySQL 协议,也越来越流行.在 Kubernetes 环境中如何使用 Prometheus 来对它们进行 ...
- Learn day2 运算/循环/字符串操作
1.容器类型的强制转换 类型:str list tuple set dict var1 = "今天天气好晴朗朗"var2 = ["刘璐","王钊&qu ...
- Unity报错:xxx AnimationEvent has no function name specified!
参考:https://blog.csdn.net/register_man/article/details/54172778 在开发时出现了题目中的错误且有动画掉帧的情况,搜索后发现是在动画编辑器中我 ...