匿名飞控底层PID代码解析

2023-05-16

大半年就快过去了。
大二上学期转瞬即逝,离上一次博客也有一段时间了,没错,庆幸的是我又回来了,其实本来第二篇博客是想着写一下两轮平衡车来着,代码早就写好了,但是硬件不给力,分着用还挺好,一整合起来,不是电驱烧就是板子烧,所以没调试也就没脸写博客了。
那么今天回归,写一篇博客是解析飞控底层PID代码的,仅仅解析最底层的PID函数代码部分,串级PID的解析什么的等有空下一篇再写吧。
偷得浮生半日闲。写完就去复习电路了。
先贴上代码。

float PID_calculate(
          float dT_s,            //周期(单位:秒)
          float in_ff,    //前馈值
          float expect,    //期望值(设定值)
          float feedback,   //反馈值()
          _PID_arg_st *pid_arg, //PID参数结构体
          _PID_val_st *pid_val, //PID数据结构体
          float inte_d_lim,//积分误差限幅
          float inte_lim   //integration limit,积分限幅         
          )
 {
 float differential,hz;
 hz = safe_div(1.0f,dT_s,0);
 pid_val->exp_d = (expect - pid_val->exp_old) *hz;
 
 if(pid_arg->fb_d_mode == 0)
 {
  pid_val->fb_d = (feedback - pid_val->feedback_old) *hz;
 }
 else
 {
  pid_val->fb_d = pid_val->fb_d_ex;
 } 
 differential = (pid_arg->kd_ex *pid_val->exp_d - pid_arg->kd_fb *pid_val->fb_d);
 
 pid_val->err = (expect - feedback);
  pid_val->err_i += pid_arg->ki *LIMIT((pid_val->err ),-inte_d_lim,inte_d_lim )*dT_s;//)*T;//+ differential/pid_arg->kp
 //pid_val->err_i += pid_arg->ki *(pid_val->err )*T;//)*T;//+ pid_arg->k_pre_d *pid_val->feedback_d
 pid_val->err_i = LIMIT(pid_val->err_i,-inte_lim,inte_lim);
 pid_val->out = pid_arg->k_ff *in_ff 
     + pid_arg->kp *pid_val->err  
   + differential
//     + pid_arg->k_inc_d_norm *pid_val->err_d_lpf + (1.0f-pid_arg->k_inc_d_norm) *differential
     + pid_val->err_i;
  pid_val->feedback_old = feedback;
 pid_val->exp_old = expect;
 
 return (pid_val->out);
}

首先,简化代码,即用自己的话理解别人的代码,因为别人写的代码总是不如自己写的容易理解。
我先贴上我的理解。
1     hz=1.0f/dT_s
2    exp_d=(期望值-前期望值)*hz
3    fb_d=(反馈值-前反馈值)*hz
4    differential=微分系数*exp_d-微分先行系数*fb_d
5    err=期望值-反馈值
6    err_i+=积分系数*err*dT_s
7    err_i=err_i(限幅)
8    out=前馈+kp*err+differential+err_i
9    feedback_old=feedback
10    exp_old=expect
11    return(out)

均省略了结构体前标,我也省事。

解释一下这个代码

先贴一张PID公式

1    hz就是dt的倒数也就是PID图中Kd后面的分母
234   就是Kd控制,不过采取了一个新颖的点(微分先行)相对于传统的PID,先记下来,稍后讲
5    比例也就是Kp的那一项参数不详细解释了这些最基础的不懂的百度CSDN都可查到
6    积分控制dT_s也就是图中第二项的dt也没啥好说的
7   比较重要的限幅这里讲一下
积分抗饱和
积分控制在实际应用的时候要非常小心。举个例子,假设我们给一个姿态角30度的目标值,但是你人为的让飞机还是保持水平,那这时候,控制器里面的积分会不断的累加这个误差,时间越长,这个积分项的数值越大。前面我们讲过,最终控制器的输出是要由执行机构执行的,我们这里指的是电机。假设电机PWM波的行程最大范围接收到1000,那你控制器的输出,由于积分的累加,假设到了2000,自然是没办法执行的。所以,一般对控制器的输出还会有限幅,保护执行机构,具体数值根据实际情况去定。当然,这个还不是最可怕的。假设你这时候松开飞机,让它去执行这个30度的命令,那这个时候积分项还是从2000开始计算的,实际上你到了30度以后,它还会往这个方向继续执行,出现越界,这时候出现反方向的误差,理论上积分开始慢慢的退,但是由于你之前累加的过长,导致这个退到正确方向太慢了,所以可能飞机早就翻掉了。
8    这里使用了前馈加反馈的控制,这里也记一下也稍后讲
910  就是将此次的值储存为下一次的计算做准备,期望值反馈值赋值前期望值前反馈值
11   不用说了

代码部分其实和传统PID相似度还是比较高的,所做的改进也有,这里详细讲一下,一是微分先行

微分先行PID控制是只对输出量进行微分,而对给定指令不起微分作用,因此它适合于给定指令频繁升降的场合,可以避免指令的改变导致超调过大。
想要详细理解请看这篇博客
PID控制器开发笔记之七:微分先行PID控制器的实现
简单点说其实微分先行就是期望值与前期望值的差的Kd系数和反馈值与前反馈值的差的Kd系数不一样,如果两者的系数相等了,那就是传统PID的微分项了。

二是前馈
见此博客
简单点说
前馈控制属于开环控制,反馈控制属于负反馈的闭环控制
一般定值控制系统是按照测量值与给定值比较得到的偏差进行调节,属于闭环负反馈调节。其特点是在被控变量出现偏差后才进行调节;如果干扰已经发生而没有产生偏差,调节器不会进行工作。因此反馈控制方式的调节作用落后于干扰作用。
前馈调节是按照干扰作用来进行调节的。前馈控制将干扰测量出来并直接引入调节装置,对于干扰的克服比反馈控制及时。
前馈控制系统中测量干扰量,反馈控制系统中测量被控变量
在单纯的前馈控制系统中,不测量被控变量,而单纯的反馈控制系统中不测量干扰量。
3、前馈控制需要专用调节器,反馈控制一般采用通用PID调节器
反馈调节符合PID调节规律,常用通用PID调节器、DCS等或PLC控制系统实现。前馈调节使用的调节器是是根据被控对象的特点来确定调节规律的前馈调节器。
4、前馈控制只能克服所测量的干扰,反馈控制则可克服所有干扰
前馈控制系统中若干扰量不可测量,前馈就不可能加以克服。而反馈控制系统中,任何干扰,只要它影响到被控变量,都能在一定程度上加以克服。
5、前馈控制理论上可以无差,反馈控制必定有差
反馈调节使系统达到动态稳定,让被调参数稳定在给定值附近动态变化,却不能使被调参数稳定在给定值上不动。
前馈调节在理论上可以实现无差调节。
6、前馈控制的局限性
A、在生产应用中各种环节的特性是随负荷变化的,对象动态特性形式多样性难以精确测量,容易造成过补偿或欠补偿。为了补偿前馈调节的不准确,通常将前馈和反馈控制系统结合起来组成前馈反馈控制系统。
B、工业对象存在多个扰动,若均设置前馈控制器,那设备投资高,工作量大。
C、很多前馈补偿结果在现有技术条件下没有检测手段。
D、前馈控制受到前馈控制模型精度限制。
E、前馈控制算法,往往做近似处理。
这里搬运过来了,可以去看看原文章更容易理解

然后
完。
期待更新。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

匿名飞控底层PID代码解析 的相关文章

  • echarts 折线图,可滑动

    1 主要得展示 折线图 xff0c x轴可以滑动 xff0c 如图 详细代码如下 xff1a span class token operator lt span template span class token operator gt s
  • echarts x轴一个数据;y轴左边数值,右边百分比。(柱状图)

    大概样子如下 xff1a 配置代码如下 xff1a span class token keyword export span span class token keyword const span span class token func
  • vue自定义指令clickoutside

    npm install vue click outside 方法一 xff1a span class token operator lt span span v span class token operator span clickout
  • canvas四个点画矩形,中垂线,以及顶点拖拽

    场景 xff1a 已知四个点 xff0c 画出矩形 xff0c 并且计算出每个中垂线 xff0c 并加箭头 xff0c 标识符 xff0c 点击四个顶点还能拖拽进行变动 vue span class token operator lt sp
  • promise.all([]).then(() => {}).catch(() => {})异步处理

    场景 xff1a 在同一时间 xff0c 同时调用相同的接口 xff08 唯一不同 xff1a 接口传参不一样 xff09 简单写法 xff1a Promise span class token punctuation span span
  • git 修改远程仓库地址,用户名,地址

    在git上新建项目 然后讲本地原来的git clone地址更换成新建仓库的clone 地址 方法一 xff1a 1 删除本地仓库当前关联的无效远程地址 xff0c 再为本地仓库添加新的远程仓库地址 git remote span class
  • Docker Dockerfile

    什么是Dockerfile Dockerfile 是一个用来构建镜像的文本文件 xff0c 文本内容包含了一条条构建镜像所需的指令和说明 使用Dockerfile定制镜像 仅讲解如何运行Dockerfile 文件来定制一个镜像 1 定制一个
  • websocket

    在WebSocket API中 xff0c 浏览器和服务器只需要完成一次握手 xff0c 两者之间就直接可以创建持久性的连接 xff0c 并进行双向数据传输 webSocket方法 ws send 向服务器发送数据ws close 关闭连接
  • 搭建electron-vue下

    搭建electron vue下 npm install 后续问题Version 9 of Highlight js has reached EOL npm run dev 后续ReferenceError Unknown plugin 34
  • Centos 7 安装VNC步骤

    Centos7 安装 VNC 步骤 一 安装 1 以root 用户运行以下命令来安装vncserver yum install tigervnc server 2 同样运行以下命令来安装vncviewer yum install vnc 3
  • [记录]Ubuntu18.04使用桥接模式实现上网

    前言 一般在虚拟机中采用NAT模式就可以上网 其最大优势是虚拟系统接入互联网非常简单 xff0c 你不需要进行任何其他的配置 xff0c 只需要宿主机器能访问互联网即可 但是这种方式 虚拟机可以通过主机 单向访问 网络上的其他主机 xff0
  • Linux-浅谈系统调用

    我们开始研究操作系统中一个非常重要的概念 系统调用 大多数程序员在写程序时都很难离开系统调用 xff0c 与系统调用打交道的方式是通过库函数的方式 xff0c 库函数用来把系统调用给封装起来 xff0c 要理解系统调用的概念还需要一些储备知
  • 可复用软件模块的接口设计

    在上一篇博客中模块化代码的基本写法举例 青衫客36的博客 CSDN博客 xff0c 我们给出了模块化代码的基本写法 xff0c 本文我们继续探讨对menu程序进行改造 xff0c 使之成为可复用软件模块 下面先引入可重用软件的一些相关概念
  • Makefile实验

    一 准备C程序 1 input h ifndef INPUT H define INPUT H void input int int a int b endif 2 input c include lt stdio h gt include
  • CSAPPLab2- BombLab

    写在前面 xff1a 本次实验对GDB的使用提出了较高要求 xff0c 对GDB调试不了解的读者可以先移步到笔者的这篇博客 GDB调试实验 青衫客36的博客 CSDN博客 由于老师发布的压缩包中有48个bomb代码包 xff0c 根据 学号
  • 代码优化- 前端优化

    常量折叠 基本思想 xff1a 在编译期间计算表达式的值 xff08 编译时静态计算 xff09 例如 xff1a a 61 3 43 5 61 61 gt a 61 8 xff0c if true amp amp false 61 61
  • Haffman编码(算法导论)

    上次算法导论课讲到了Haffman树 xff0c 笔者惊叹于Haffman编码的压缩效果 xff0c 故想自己亲自动手尝试写一个极简的Haffman压缩程序 首先 xff0c 我们来了解一下什么是Haffman编码 Haffman编码 赫夫
  • C++ Primer- 变量声明和定义的关系

    为了允许把程序拆分成多个逻辑部分来编写 xff0c C 43 43 语言支持分离式编译 xff08 separatecompilation xff09 机制 xff0c 该机制允许将程序分割为若干个文件 xff0c 每个文件可被独立编译 如
  • Compiler Lab2- 自制极简编译器

    笔者实现的这个超级迷你版编译器 xff08 词法分析 语法分析 生成中间代码 xff08 cpp xff09 xff09 仅支持四则运算 xff0c 功能真的是非常非常简单 xff0c 不过其中的流程 xff08 词法分析 gt 语法分析
  • 贪心算法实现最佳任务调度实验

    题目描述 一个单位时间任务是恰好需要一个单位时间完成的任务 给定一个单位时间任务的有限集S 关于S 的一个时间表用于描述S 中单位时间任务的执行次序 时间表中第1 个任务从时间0 开始执行直至时间1 结束 xff0c 第2 个任务从时间1

随机推荐

  • 在CentOS安装CMake

    你或许听过好几种 Make 工具 xff0c 例如 GNU Make xff0c QT 的 qmake xff0c 微软的 MS nmake xff0c BSD Make xff08 pmake xff09 xff0c Makepp xff
  • CSAPP Lab3- bufbomb

    实验目标 xff08 1 xff09 掌握函数调用时的栈帧结构 xff08 2 xff09 利用输入缓冲区的溢出漏洞 xff0c 将攻击代码嵌入当前程序的栈帧中 xff0c 使得程序执行我们所期望的过程 实验代码 xff08 1 xff09
  • 金蝶部署SpringBoot+vue项目总结

    金蝶部署SpringBoot 43 vue项目文章目录 文章目录 金蝶部署SpringBoot 43 vue项目文章目录前言一 金蝶部署中两个重要概念1 域2 应用基础上下文 二 部署准备1 前后台打包2 部署过程3 部署成功后的注意事项
  • Gazebo-Realsense 编译问题解决

    64 Gazebo仿真 Realsense 编译问题解决 参考 这篇文章配置 首先git clone代码到你的工作空间 git clone https github com nilseuropa realsense ros gazebo g
  • docker快捷添加用户组,远离sudo困扰

    使用docker命令时 xff0c 总是需要root权限 xff0c 同时还要验证密码 xff0c 过于麻烦便将root添加进docker分组 xff0c 远离sudo困扰 span class token comment 创建docker
  • 全注解下的SpringIoc 续4-条件装配bean

    Spring Boot默认启动时会加载bean xff0c 如果加载失败 xff0c 则应用就会启动失败 但是部分场景下 xff0c 我们希望某个bean只有满足一定的条件下 xff0c 才允许Spring Boot加载 xff0c 所以
  • 卡尔曼滤波结果和图优化的融合

    仅使用卡尔曼滤波结果作为初始值辅助NDT算法的进行 xff0c 并没有进行实际融合 论文地址 算法流程 扩展的卡尔曼滤波融合GPS 惯性测量单元IMU 编码器里程计得到融合后的定位信息 基于3D NDT配准得到激光里程计 建图优化 融合单帧
  • Kalibr工具进行相机IMU标定

    github地址 xff1a https github com ethz asl kalibrWiki文档 xff1a https github com ethz asl kalibr wiki camera imu calibration
  • 保研复试-计算机网络复习

    计算机网络是我专业课里成绩较高的课 xff0c 老师应该会问到 xff0c 面试的时候计网也是公司里爱问的科目 整理一下看到的网上的一些保研 考研复试题 xff0c 便于复习 一 计算机网络的体系结构 1 计算机网络的分类 按分布范围 xf
  • Hbase的API

    Hbase API 文章目录 Hbase API准备工作Namespace DDL1 Junit执行代码模板2 创建namespace的API3 列出所有的namespace4 列出所有namespace中的表名5 修改namespace的
  • 【Python】 matplotlib 以pdf形式保存图片

    Python matplotlib 以pdf形式保存图片 span class token keyword import span matplotlib span class token punctuation span pyplot as
  • 51单片机 | 点亮第一个LED | LED 闪烁实验 | LED流水灯实验

    文章目录 一 51单片机GPIO介绍1 GPIO概念2 GPIO 结构框图与工作原理2 1 P0端口2 2 P1端口2 3 P2端口2 4 P3端口 2 5 要点 二 LED简介三 硬件设计四 软件设计1 点亮第一个LED2 LED 闪烁实
  • matlab二维矩阵可视化几种方法

    目录 一 pcolor 二 imagesc 三 spy 四 文末彩蛋 一 pcolor 以一个100x100块对角矩阵B为例 1 xff1a 原生pcolor 可以在矩阵维度不大时进行可视化 xff0c 带小方格 矩阵比较大时画出整体为黑色
  • 【ROS入门】双系统安装和ros安装踩坑

    记录一下安装Ubuntu双系统和和ros过程中踩的坑 xff0c 防止下次再犯错 一 双系统安装与删除 双系统的安装比一开始想的说实话要简单得多 xff0c 随便用u盘制作一个系统安装盘 xff0c 或者在u盘里面放需要的Ubuntu镜像
  • 【ROS入门】TF与URDF

    一 什么是TF TF全程就是transform xff0c 就是一个坐标系的转换 在ROS中坐标的转换是一个很重要的内容 xff0c 主要还是因为机器的不灵活性 xff0c 如果是人 xff0c 完全可以灵活地控制手臂去抓取一个物体 xff
  • 树莓派3B+——系统安装及显示

    树莓派3B 43 系统安装及显示 目录 树莓派3B 43 系统安装及显示系统安装显示显示器显示3 5寸显示屏显示pc显示 树莓派3B 43 系统安装及显示 初次接触树莓派 xff0c 花了差不多一天的时间把系统的安装和显示全部搞定 xff0
  • VSLAM 相关知识点总结

    VSLAM 相关知识点 这篇文章是对VSLAM涉及的知识点进行系统性的总结和更新 xff0c 一些内容来源至VSLAM经典教材 xff0c 博客 xff0c 和开源项目 引用材料如下表 SLAM十四讲高博古月老师的技术博客崔神的github
  • Windows下CLion中文乱码最有效的解决方式

    作者开发环境 Windows 10 Clion 18 3 MinGW W64 很多人都遇到了Clion的中文乱码问题 xff0c 然后在CSDN上面寻找解决办法 比如这篇很有代表性https blog csdn net Cbk XLL ar
  • Neutron复盘及学习笔记

    前言 对于openstack neutron xff0c 曾花费很多的时间去看它的源码 xff0c 结果啥都没有看出来 openstack代码风格是 xff0c 为了实现plugin的可插拔 xff0c 运用了很多设计模式 xff0c 设计
  • 匿名飞控底层PID代码解析

    大半年就快过去了 大二上学期转瞬即逝 xff0c 离上一次博客也有一段时间了 xff0c 没错 xff0c 庆幸的是我又回来了 xff0c 其实本来第二篇博客是想着写一下两轮平衡车来着 xff0c 代码早就写好了 xff0c 但是硬件不给力