关于无人机上层控制的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

相关文章

Python实现局域网远程控制电脑

《Python实现局域网远程控制电脑》这篇文章主要为大家详细介绍了如何利用Python编写一个工具,可以实现远程控制局域网电脑关机,重启,注销等功能,感兴趣的小伙伴可以参考一下... 目录1.简介2. 运行效果3. 1.0版本相关源码服务端server.py客户端client.py4. 2.0版本相关源码1

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int