关于无人机上层控制的PID算法的思考

2024-01-04 21:44

本文主要是介绍关于无人机上层控制的PID算法的思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

背景介绍:PID虽然出现了很多年,但是目前工业界还是把PID作为主流的控制算法(尽管学术界有很多非常时尚的控制算法,包括鲁邦控制,神经网络控制等等),PID的算法在于其不需要对系统进行复杂的建模,就可以完成比较好的控制效果。
PID算法的优势在于其非常简单,很多时候算法好不好取决于对参数的设置,所以很多时候,PID算法其实是一个体力活,主要精力都在于寻找最优参数去了。当然,对于开环系统就不用说这种PID算法了
PID算法只适合于闭合系统。对于非线性系统,时滞比较严重的系统个人也不建议使用PID,这种情况控制效果不怎么好。

二、算法介绍

  • 开环控制系统
    在这里插入图片描述
    在开环控制系统中,系统输出只受输入的控制,控制精度和抑制干扰的特性都比较差。就没有什么误差控制输入的说法,就不谈什么PID了

  • 闭环控制系统
    在这里插入图片描述

PID简介:PID控制应该算是应用非常广泛的控制算法了。小到控制一个元件的温度,大到控制无人机的飞行姿态和飞行速度等等,都可以使用PID控制。这里我们从原理上来理解PID控制。
PID(proportion integration differentiation)其实就是指比例,积分,微分控制。
在这里插入图片描述
公式描述如下:
在这里插入图片描述
其中U(t)是PID控制器的输出,PID控制器的输出是执行器的输入,如果我们知道执行器的模型,就可以实行精确控制。
这里我们引用知乎上的作者例子知乎网址为了简单说明情况和好理解,知乎这边文章里面把控制器和执行器进行了等价,就是控制器输出等于执行器输出。

2.1、P控制算法

  我们先说PID中最简单的比例控制,抛开其他两个不谈。还是用一个经典的例子吧。假设我有一个水缸,最终的控制目的是要保证水缸里的水位永远的维持在1米的高度。假设初始时刻,水缸里的水位是0.2米,那么当前时刻的水位和目标水位之间是存在一个误差的error,且error为0.8.这个时候,假设旁边站着一个人,这个人通过往缸里加水的方式来控制水位。如果单纯的用比例控制算法,就是指加入的水量u和误差error是成正比的。即
  u=kp*error  设kp=0.5
  那么t=1时(表示第1次加水,也就是第一次对系统施加控制),那么u=0.50.8=0.4,所以这一次加入的水量会使水位在0.2的基础上上升0.4,达到0.6.
  接着,t=2时刻(第2次施加控制),当前水位是0.6,所以error是0.4。u=0.5
0.4=0.2,会使水位再次上升0.2,达到0.8.
如此这么循环下去,就是比例控制算法的运行方法。
可以看到,最终水位会达到我们需要的1米。(无限下去数学上面就是一个逼近1m的求和级数,但是是永远达不到准确的1m的)
  但是,单单的比例控制存在着一些不足,其中一点就是 –稳态误差。
像上述的例子,根据kp取值不同,系统最后都会达到1米,只不过kp大了到达的快,kp小了到达的慢一些。不会有稳态误差。但是,考虑另外一种情况,假设这个水缸在加水的过程中,存在漏水的情况,假设每次加水的过程,都会漏掉0.1米高度的水。仍然假设kp取0.5,那么会存在着某种情况,假设经过几次加水,水缸中的水位到0.8时,水位将不会再变换!!!因为,水位为0.8,则误差error=0.2. 所以每次往水缸中加水的量为u=0.5*0.2=0.1.同时,每次加水,缸里又会流出去0.1米的水!!!加入的水和流出的水相抵消,水位将不再变化!!
也就是说,我的目标是1米,但是最后系统达到0.8米的水位就不再变化了,且系统已经达到稳定。由此产生的误差就是稳态误差了。
(上诉例子是一个增量PID控制算法的解释,具体什么是增量控制算法,后续会说,先有个基本概念)

2.2 I控制算法

  还是用上面的例子,如果仅仅用比例,可以发现存在暂态误差,最后的水位就卡在0.8了。于是,在控制中,我们再引入一个分量,该分量和误差的积分是正比关系。所以,比例+积分控制算法为:
  u=kp*error+ ki∗∫ error
还是用上面的例子来说明,第一次的误差error是0.8,第二次的误差是0.4,至此,误差的积分(离散情况下积分其实就是做累加),∫error=0.8+0.4=1.2. 这个时候的控制量,除了比例的那一部分,还有一部分就是一个系数ki乘以这个积分项。由于这个积分项会将前面若干次的误差进行累计,所以可以很好的消除稳态误差(假设在仅有比例项的情况下,系统卡在稳态误差了,即上例中的0.8,由于加入了积分项的存在,会让输入增大,从而使得水缸的水位可以大于0.8,渐渐到达目标的1.0.)这就是积分项的作用。

2.3 D控制算法

  换一个另外的例子,考虑刹车情况。平稳的驾驶车辆,当发现前面有红灯时,为了使得行车平稳,基本上提前几十米就放松油门并踩刹车了。当车辆离停车线非常近的时候,则使劲踩刹车,使车辆停下来。整个过程可以看做一个加入微分的控制策略。
微分,说白了在离散情况下,就是error的差值,就是t时刻和t-1时刻error的差,即u=kd*(error(t)-error(t-1)),其中的kd是一个系数项。可以看到,在刹车过程中,因为error是越来越小的,所以这个微分控制项一定是负数,在控制中加入一个负数项,他存在的作用就是为了防止汽车由于刹车不及时而闯过了线。从常识上可以理解,越是靠近停车线,越是应该注意踩刹车,不能让车过线,所以这个微分项的作用,就可以理解为刹车,当车离停车线很近并且车速还很快时,这个微分项的绝对值(实际上是一个负数)就会很大,从而表示应该用力踩刹车才能让车停下来。
切换到上面给水缸加水的例子,就是当发现水缸里的水快要接近1的时候,加入微分项,可以防止给水缸里的水加到超过1米的高度,说白了就是减少控制过程中的震荡。

3、PID控制算法的变形

3.1连续PID

在这里插入图片描述

虽然在教程和文献中有各种时间常数,比如TI TD这种,但是由于其本质也是一个参数,所以很多人为了方便,最后统一成了Kp,KI,Kd
在这里插入图片描述
在这里插入图片描述

3.2(位置型)数字PID

在这里插入图片描述
数字也是一样,可以简化为,
在这里插入图片描述
在这里插入图片描述
C++代码

#include <iostream>class PositionPID {
private:double kp;  // 比例增益double ki;  // 积分增益double kd;  // 微分增益double prevError;  // 上一次误差double integral;   // 积分项累加值public:PositionPID(double kp, double ki, double kd) : kp(kp), ki(ki), kd(kd), prevError(0), integral(0) {}double calculate(double setpoint, double current) {double error = setpoint - current;integral += error;double output = kp * error + ki * integral + kd * (error - prevError);prevError = error;return output;}
};int main() {// 示例使用double setpoint = 50.0;  // 目标值double current = 0.0;   // 当前值PositionPID positionPID(0.1, 0.01, 0.05);  // 用具体的参数值初始化PID控制器for (int i = 0; i < 100; ++i) {double output = positionPID.calculate(setpoint, current);// 在实际系统中应用输出值,更新当前值 current// 这里仅简单输出控制器的输出值std::cout << "Iteration " << i << ": Output = " << output << std::endl;}return 0;
}

3.2增量型数字PID

在这里插入图片描述

C++代码

#include <iostream>class IncrementalPID {
private:double kp;  // 比例增益double ki;  // 积分增益double kd;  // 微分增益double prevOutput;  // 上一次的输出double prevError;   // 上一次误差public:IncrementalPID(double kp, double ki, double kd) : kp(kp), ki(ki), kd(kd), prevOutput(0), prevError(0) {}double calculate(double setpoint, double current) {double error = setpoint - current;double pTerm = kp * error;double iTerm = ki * (error + prevError);double dTerm = kd * (error - prevError);double output = prevOutput + pTerm + iTerm + dTerm;prevOutput = output;prevError = error;return output;}
};int main() {// 示例使用double setpoint = 50.0;  // 目标值double current = 0.0;   // 当前值IncrementalPID incrementalPID(0.1, 0.01, 0.05);  // 用具体的参数值初始化PID控制器for (int i = 0; i < 100; ++i) {double output = incrementalPID.calculate(setpoint, current);// 在实际系统中应用输出值,更新当前值 current// 这里仅简单输出控制器的输出值std::cout << "Iteration " << i << ": Output = " << output << std::endl;}return 0;
}

个人总结

在无人机项目中,我为了迫使无人机姿态一直处于目标中央,通过调整无人机yaw角度来使用水平方向使得识别的目标一直处于无人机中央,但是给出的代码确实直接假设了控制输出等于执行器输入这里绝对是错误的,PID控制器的输出是图像目标中心位置640,但是不能简单的将这个输出等价于偏航角。


Command_Now.Reference_State.yaw_ref =incrementalPID.calculate(set_target_x , now_target_x); ;//PID角度控制


实际情况是对控制器的输出的目标位置量与角度调整量进行建模,而不是将二者简单相等。
在这里插入图片描述

这篇关于关于无人机上层控制的PID算法的思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/570690

相关文章

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Spring如何使用注解@DependsOn控制Bean加载顺序

《Spring如何使用注解@DependsOn控制Bean加载顺序》:本文主要介绍Spring如何使用注解@DependsOn控制Bean加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录1.javascript 前言2. 代码实现总结1. 前言默认情况下,Spring加载Bean的顺

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

Python远程控制MySQL的完整指南

《Python远程控制MySQL的完整指南》MySQL是最流行的关系型数据库之一,Python通过多种方式可以与MySQL进行交互,下面小编就为大家详细介绍一下Python操作MySQL的常用方法和最... 目录1. 准备工作2. 连接mysql数据库使用mysql-connector使用PyMySQL3.

如何搭建并配置HTTPD文件服务及访问权限控制

《如何搭建并配置HTTPD文件服务及访问权限控制》:本文主要介绍如何搭建并配置HTTPD文件服务及访问权限控制的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、安装HTTPD服务二、HTTPD服务目录结构三、配置修改四、服务启动五、基于用户访问权限控制六、

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

MySQL精准控制Binlog日志数量的三种方案

《MySQL精准控制Binlog日志数量的三种方案》作为数据库管理员,你是否经常为服务器磁盘爆满而抓狂?Binlog就像数据库的“黑匣子”,默默记录着每一次数据变动,但若放任不管,几天内这些日志文件就... 目录 一招修改配置文件:永久生效的控制术1.定位my.cnf文件2.添加核心参数不重启热更新:高手应

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

SpringBoot请求参数接收控制指南分享

《SpringBoot请求参数接收控制指南分享》:本文主要介绍SpringBoot请求参数接收控制指南,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring Boot 请求参数接收控制指南1. 概述2. 有注解时参数接收方式对比3. 无注解时接收参数默认位置

Spring Security+JWT如何实现前后端分离权限控制

《SpringSecurity+JWT如何实现前后端分离权限控制》本篇将手把手教你用SpringSecurity+JWT搭建一套完整的登录认证与权限控制体系,具有很好的参考价值,希望对大家... 目录Spring Security+JWT实现前后端分离权限控制实战一、为什么要用 JWT?二、JWT 基本结构