PID控制算法(六)

news2024/11/17 15:37:48
#include <stdio.h>
#include <stdlib.h>

// 定义PID结构体
typedef struct
{
    float SetSpeed;
    float ActualSpeed;
    float err;
    float integral;
    float vo_out;           //控制器输出
    float err_last;
    float Kp;
    float Ki;
    float Kd;

    float limit_min; // 输出限制最小值
    float limit_max; // 输出限制最大值
    float windup_guard;     // 积分饱和保护值

    float derivative_filter; // 微分项的滤波系数
    float err_pre_last;

} PID;

// 函数声明
void PID_init(PID *pid);
float PID_realize(PID *pid, float Setparameter);

// 函数定义
/*
void PID_init(PID *pid,float Kp, float Ki, float Kd,
                        float vo_out_limit_min, float vo_out_limit_max)
*/
void PID_init(PID *pid)
{
    // 初始化PID参数
    pid->Kp = 0.1;
    pid->Ki = 0.1;
    pid->Kd = 0.1;

    pid->SetSpeed = 0.0;
    pid->ActualSpeed = 0.0;

    pid->vo_out = 0.0;
    pid->integral = 0.0;
    pid->err = 0.0;
    pid->err_last = 0.0;

    pid->limit_min = -100;//积分保护最小设置
    pid->limit_max =  600;//积分保护最大设置
    pid->windup_guard = (pid->limit_max - pid->limit_min) * 0.1; // 设置积分饱和保护值

    pid->err_pre_last = 0.0;
    //微分项的滤波器系数设置
    pid->derivative_filter = 0.05f;

}

// 积分饱和处理:
//积分环节处理:
//积分分离、积分限制、反计算饱和
void PID_IntegralWindup(PID *pid)
{
    //将两个参数在结构体中提前定义好:
    //积分限制,反计算饱和
    double vo_out_limit_min; // 输出限制最小值
    double vo_out_limit_max; // 输出限制最大值
    if (pid->vo_out >= pid->limit_max) //当输出达到积分保护最大值时
    {
        if (pid->err > 0)
        {
            pid->integral += pid->err;//积分误差累计正偏差
        }
    }
    else if (pid->vo_out <= pid->limit_min)//当输出小于积分保护最小值时
    {
        if (pid->err < 0)
        {
            pid->integral += pid->err;//积分误差累计正偏差
        }
    }
    else //此时输出值在设置的最大和最小值区间内
    {
        pid->integral += pid->err;//正常计算积分误差
    }
}


float PID_realize(PID *pid, float Setparameter)
{
    int index;//标志位,在index = 1时执行积分的稳态误差积累
    pid->SetSpeed = Setparameter;
    pid->err = pid->SetSpeed - pid->ActualSpeed;

    PID_IntegralWindup(pid);      //反计算抗饱和处理
    //积分分离,设置误差阈值
    //当误差较大时,放弃积分项的运算,当误差较小,计算积分误差积累

    //设置积分阈值需根据实际情况调整,
    //当阈值过大时对达不到阈值的数值进行计算的过程中,
    //就会出现小数点后一位的精度不准问题。
    if(abs(pid->err) > 100)
    {
        index = 0;
        //当误差的绝对值大于所设置的阈值时,标志位置零,但积分项仍然会进行误差累计
    }
    else
    {
         index = 1;
         pid->integral = pid->integral + pid->err ; // 积分误差积累
         //不需要在此时进行积分误差积累的抵消效果?
    }

    // 不完全微分:
    //测微分变化趋势,减小对噪声高频信号噪声的放大程度:
    float derivative = (pid->err - pid->err_last) - (pid->err_last - pid->err_pre_last);

    float filtered_derivative = pid->derivative_filter * derivative +
          (1 - pid->derivative_filter) *
          (pid->err - 2 * pid->err_last + pid->err_pre_last);

    //pid->integral = pid->integral + pid->err; // 积分误差积累

    //PID输出计算
//    pid->vo_out = pid->Kp * pid->err + pid->Ki * pid->integral +
//                  pid->Kd * (pid->err - pid->err_last);

    pid->vo_out = pid->Kp * pid->err + pid->Ki * pid->integral +
                  pid->Kd * filtered_derivative;

    //积分饱和处理:计算PID控制器的输出
    if (pid->vo_out > pid->limit_max)
    {
        pid->vo_out = pid->limit_max; // 限制输出最大值
    }
    else if (pid->vo_out < pid->limit_min)
    {
        pid->vo_out = pid->limit_min; // 限制输出最小值
    }

    pid->err_last = pid->err;          // 本次误差更新
    pid->err_pre_last = pid->err_last; // 上一次的误差更新

    //float浮点数--数据类型
    pid->ActualSpeed = pid->vo_out * 2.0; // 将输出值赋给实际值,此前是1.0,现在设置为2.0做补偿;
    return pid->ActualSpeed;
}


int main()
{
    PID myPID; // 创建PID控制器实例

    // 初始化PID参数
    PID_init(&myPID);

    float Setparameter;//传感器获取的参数值(温、湿、气压?)

    printf("Enter the set parameter: ");
    scanf("%f", &Setparameter); // 读取用户输入的目标参数
    int count= 0 ;
    while(count<1000)
    {
    myPID.ActualSpeed = PID_realize(&myPID, Setparameter); // 调用PID控制函数

      if(count >= 1)//只显示了最后200次的计算结果
      {
        printf("count is: %d, actual_speed is: %f\n", count, myPID.ActualSpeed);
      }

    count++;
    }
    return 0;
}

在上述代码中,相比之前的PID运算过程,本次在程序中添加并实现了PID算法的不完全微分过程,通过计算本次、上次以及上上次的误差,计算三者之间的差值来计算微分系数,并自行设置了滤波器系数来消除高频噪声所带来的误差,计算结果相比之前有所提升。通过修改设置的误差阈值和滤波器系数,可以一定程度上提高PID计算结果的精度。

运行结果如下(参数分别设为了1102.39和30.9):

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2176772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于php的酒店管理系

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

毕业设计——小程序项目的完整原型设计

作品详情 完整短剧项目的需求文档&#xff0c;包括小程序项目的完整原型设计&#xff0c;数据指标体系与埋点规划&#xff0c;会员系统、剧集播放解锁、充值支付等逻辑设计。 项目文档链接&#xff1a;https://axhub.im/ax10/b224d75a2ea99a8b/#g1

校园跑腿圈子论坛社团小程序APP需要多少钱

校园跑腿圈子论坛社团小程序APP的开发费用因多种因素而异&#xff0c;包括功能需求、设计需求、开发团队规模和技术难度等。以下是对这些因素的详细分析以及大致的费用估算&#xff1a; 一、功能需求 校园跑腿小程序的基本功能可能包括用户注册登录、任务发布与接单、实时聊天…

gitee公钥设置、创建库及使用

简介 一、如何安装git 使用gitee&#xff0c;需要先安装git工具。 工具网站地址&#xff1a;https://git-scm.com/downloads 安装完成后&#xff0c;在terminal命令行输入git --version可以查看到git的版本。 二、登录gitee 我们先在 gitee上注册账号并登录。gitee官网&#x…

告别“军备竞赛”!L2进入下沉普及周期,谁在领跑本土方案市场?

随着智能驾驶普及进入20万元以下价位区间&#xff0c;“军备竞赛”模式不再成为主流。尤其是成本占比权重更加突出&#xff0c;取消激光雷达、算力降维以及高低配策略&#xff0c;成为「新常态」。 8月27日&#xff0c;小鹏MONA M03正式上市&#xff0c;22天后&#xff0c;新车…

828华为云征文|部署高性能个人博客系统 VanBlog

828华为云征文&#xff5c;部署高性能个人博客系统 VanBlog 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 VanBlog3.1 VanBlog 介绍3.2 VanBlog 部署3.3 VanBlog 使用 四…

中腾国际团餐产业集团经验谈:如何让上海央厨配送更高效、更安心

上海作为国际大都市&#xff0c;近些年对餐饮行业的效率与品质提出了更高要求。中央厨房(央厨)以其规模化、标准化生产的优势&#xff0c;成为提升餐饮供应链效率的关键一环。而央厨配送&#xff0c;作为连接央厨与消费者的重要桥梁&#xff0c;其重要性不言而喻。中腾国际团餐…

2024年双十一值得入手好物?2024年双十一必买清单!

双十一的号角已经吹响&#xff0c;你是否还在为买什么而纠结&#xff1f;快来看看这份2024年双十一必买清单&#xff01;这里汇聚了各类令人惊喜的好物&#xff0c;从科技新宠到生活必备&#xff0c;总有一款能打动你的心&#xff01; 一、真1000w配置——西圣find可视挖耳勺 …

实在智能:创业需找准“切口” 并着力做深做透

如今&#xff0c;随着人工智能产业的爆发&#xff0c;大量专注于这一领域的初创企业不断涌现。尽管这种多元化的创新生态为产业发展注入了新的活力&#xff0c;但也不可避免的为初创企业带来了诸多压力和挑战。 浙江实在智能科技有限公司(以下简称“实在智能”)作为一家成立6年…

大模型开发 - 一文搞懂Fine-tuning(大模型微调)

本文将从Fine-tuning的本质、Fine-tuning的原理Fine-tuning的应用三个方面&#xff0c;带您一文搞懂大模型微调&#xff1a;Fine-tuning Fine-tuning&#xff08;微调&#xff09;&#xff1a;通过特定领域数据对预训练模型进行针对性优化&#xff0c;以提升其在特定任务上的性…

别人做谷歌seo凭什么比你好?

谷歌SEO的竞争激烈&#xff0c;做得好的才能占据排名。但为什么有些人做SEO就是比你好&#xff1f;其中一个关键因素就是资源投入。SEO的核心包括技术优化、内容质量和外链建设等。这些方面都需要专业知识和时间投入&#xff0c;但如果资源有限&#xff0c;你的优化效果就会受到…

NVM:nvm list available命令执行异常

一、异常图片 二、解决 在nvm的安装位置找到文件settings.txt&#xff0c;修改镜像地址 node_mirror: https://npmmirror.com/mirrors/node/ npm_mirror: https://npmmirror.com/mirrors/npm/ 再次执行 三、相关知识 3.1 nvm简介 NVM&#xff08;Node Version Manager&#…

huggingface使用国内镜像站下载

huggingface使用国内镜像站下载 huggingface开源的模型托管仓库&#xff0c;预训练模型的数量已超过30万个&#xff0c;并且任何模型在下载之前都可以使用huggingface提供的spaces空间去测试效果 huggingface的国内镜像站HF-Mirror的地址&#xff1a;https://hf-mirror.com/ …

聊聊JIT是如何影响JVM性能的!

文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 我们知道Java虚拟机栈是线程…

pwn练习(1)

[BJDCTF 2020]babystack2.0 p.sendline(-1): 通过之前建立的连接&#xff0c;向服务器发送字符串"-1"和一个换行符。这可能是为了触发某个特定的行为或条件。 from pwn import* premote(node4.anna.nssctf.cn,28575) p.sendline(-1) payloadbA*(0X108)p64(0x40072A) …

基于SSM的“实习支教中小学学校信息管理系统”的设计与实现(源码+数据库+文档)

基于SSM的“实习支教中小学学校信息管理系统”的设计与实现&#xff08;源码数据库文档) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 主页 注册页面 师资力量界面 个…

十个最好看的桌面屏保 最好用的桌面屏保软件推荐

屏保是指在计算机长时间空闲时自动启动的一种程序&#xff0c;屏保作用可以保护你的屏幕隐私&#xff0c;屏保还可以起到美化作用。今天小编给大家带来最酷最好看的十个桌面电脑屏保&#xff1a;芝麻时钟&#xff08;下载地址&#xff1a;https://clock.zhimasoft.cn/?bili &a…

汽车总线之---- LIN总线

Introduction LIN总线的简介&#xff0c;对于传统的这种点对点的连接方式&#xff0c;我们可以看到ECU相关的传感器和执行器是直接连接到ECU的&#xff0c;当传感器和执行器的数量较少时&#xff0c;这样的连接方式是能满足要求的&#xff0c;但是随着汽车电控功能数量的不断增…

linux 内核代码学习(十)--Linux内核启动和文件系统

前面第九章介绍了linux内核文件系统从软盘启动的几种方式&#xff1a;1、从软盘直接启动的linux&#xff0c;软盘上包括内核及简单文件系统&#xff1b;2、从软盘直接启动的linux&#xff0c;将内核与文件系统分别放置在一张软盘上&#xff1b;3、Grub做为引导程序&#xff0c;…

【软件类】OPPO 2024届校招正式批笔试题-研发通用(C卷)

昨天做了一场OPPO的&#xff0c;BC两题都速切了&#xff0c;其中B为语法题&#xff0c;C为思维题&#xff0c;想明白mid的范围即可&#xff0c;但A题真给我搞汗流浃背了&#xff0c;倒不是A题难&#xff0c;而是数据卡的很死。从下午一直调到了晚上还是TLE了&#xff0c;最后出…