RflySim | 滤波器设计实验一
滤波器设计实验一
一. 无人机滤波器简介
无人机在飞行时会使用滤波器来处理传感器数据、控制飞行和稳定飞行,以及实现导航和定位等功能。卡尔曼滤波器是无人机领域中常见滤波器类型之一,也称为线性二次型估计,能够从一系列不完全且包含噪声不确定性的观测量中,估计系统的未知状态其估计精度往往比单纯地基于单一观测量的方法更高。这种滤波器以它的发明者鲁道夫·卡尔曼(Rudolf E. Kalman)命名。
卡尔曼滤波器要求噪声误差满足高斯分布假设,在这个特定情况下能够产生精确的条件概率估计,卡尔曼滤波器算法主要分为两步处理。在预测步骤中,卡尔曼滤波器产生当前状态变量的预测估计,这些估计量包含不确定性,一旦出现下一个观测量(伴随着一定的误差以及随机噪声),之前的估计量会以加权平均的方式更新,其权重值会随着估计的确定性而变化,确定性越大,其权重值越大。卡尔曼滤波器是一种实时的递归滤波器,仅仅利用当前观测量和先验估计量及不确定性矩阵,而不需要增加多余的历史信息。
二. 测量原理
三轴加速度计固连在多旋翼机体,其三轴与机体坐标系一致。因此,低频的俯仰角和滚转角观测量可以由加速度计测量值近似得到:

其中

表示加速度计测量值。
同时还有两点需要注意:
1)为了得到更加精确的角度信息,需要消除加速度计的慢时变漂移。
2)如果机体振动很大,则 αxbm,αybm将被噪声严重污染,这样将进一步影响角度θm,φm 的估计。因此机体的减振很重要。另外姿态变化率 θ·,φ·,ψ·和角速度bω有如下关系:

由此可知,俯仰角和横滚角可以由加速度计测量得到,漂移小,但噪声大。另一方面,姿态角也可以通过角速度积分得到,噪声小,但是漂移大。
三、线性互补滤波器设计
下面我们着重以俯仰角为例,详细推导下线性互补滤波,俯仰角的拉氏变换可以表示为:

为了估计俯仰角,以上式子的 需要用传感器信息替代。
同时,加速度计测量的俯仰角无漂移但噪声大,我们可以将测量到的俯仰角建模为θm =θ+nθ,其中nθ 表示高频噪声,θ表示俯仰角真值。
陀螺仪的角速度测量会有漂移但噪声小,我们可以建模为:

线性互补滤波的标准形式以传递函数方式表示为:

为了计算机算法实现,需要对其进行离散化

通过一阶向后差分法,将s表示为:

进一步表示为:

再把上式化为差分方程可以得到:

具体推导过程请见文献[1]第8章和文献[2]第8章内容。
互补滤波器的MATLAB程序可见如下。
其中,“theta_am”和“phi_am”分别代表由加速度计计算出的俯仰角和滚转角;theta_cf”和“phi_cf”分别代表由互补滤波计算出来的俯仰角和滚转角。
function [ phi_cf, theta_cf ] = Attitude_cf(dt, z, phi_cf_k, theta_cf_k, tao)
%函数描述:
% 互补滤波姿态结算。
%输入:
% dt: 时间间隔,单位:s
% z: 三轴角陀螺仪和三轴加速度计测量值,[gx, gy, gz, ax, ay, az]',
% 单位:rad/s, m/s2
% phi_cf_k, theta_cf_k: 上一时刻的角度值,单位:rad
% tao: 滤波器系数
%输出:
% phi_cf, theta_cf: 解算的姿态角,单位:rad
gx = z(1); gy = z(2);
ax = z(4); ay = z(5); az = z(6);
%使用加速度计测量值计算姿态角
g = sqrt(ax*ax + ay*ay + az*az);
theta_am = asin(ax/g);
phi_am = -asin(ay/(g*cos(theta_am)));
%互补滤波
theta_cf = tao/(tao + dt)*(theta_cf_k + gy*dt) + dt/(tao + dt)*theta_am;
phi_cf = tao/(tao + dt)*(phi_cf_k + gx*dt) + dt/(tao + dt)*phi_am;
end
> 可以得到结论:
1)直接对陀螺仪测量的角速度进行积分得到的姿态角有很大的累积误差,并且还有可能发散;2)根据来自加速度计的原始数据,计算得到的姿态角不会发散,但噪声最大且有明显的尖峰,尤其是使用实际飞行中的数据时;3)使用互补滤波器估计的姿态角是平滑的并且没有累积误差。

滤波器设计实验2
四、线性互补滤波器参数分析
基于上一讲中得出的滤波器公式:

对其参数т值进行改变,对所给的数据进行滤波,即可分析该参数对滤波效果的影响。可在MATLAB中编写如下程序:
%参数tao对滤波效果的影响
clear;
load logdata
n = length(ax); %采集数据个数
Ts = zeros(1,n); %时间间隔
Ts(1) = 0.004;
for k =1:n-1
Ts(k+1) = (timestamp(k + 1) - timestamp(k))*0.000001;
end
theta_cf = zeros(1, n); %互补滤波得到的滚转角(对应theta)
phi_cf = zeros(1, n); %互补滤波得到的俯仰角(对应phi)
tao = 0.001;
for i = 1 : 3
tao = tao*10;
for k = 2 : n
g = sqrt(ax(k)*ax(k) + ay(k)*ay(k) + az(k)*az(k));
theta_am = asin(ax(k)/g);
phi_am = -asin(ay(k)/(g*cos(theta_am)));
theta_cf(i, k) = tao/(tao + Ts(k))*(theta_cf(i, k - 1) + gy(k)*Ts(k)) + Ts(k)/(tao + Ts(k))*theta_am;
phi_cf(i,k) = tao/(tao + Ts(k))*(phi_cf(i, k- 1) + gx(k)*Ts(k)) + Ts(k)/(tao + Ts(k))*phi_am;
end
end
改变该程序中的 т值分别为0.01,0.1,1时的滤波效果。

可以看到参数т越大,对高频噪声的滤波作用越明显。当т很大时:

互补滤波器变为:

相当于加速度计不起作用,只使用陀螺仪的积分值。因此,要合理选择参数т的值。
注:本实验对应demo文件对于RflySim v3.0以下版本地址为:*\PX4PSP\RflySimAPIs\Exp02_FlightControl\e4-FilterDesign\e4.1;
对于RflySim v3.0及以上版本地址为:*\PX4PSP\RflySimAPIs\5.RflySimFlyCtrl\1.BasicExps\e4-FilterDesign\e4.1
参考文献:
[1] 全权,杜光勋,赵峙尧,戴训华,任锦瑞,邓恒译.多旋翼飞行器设计与控制[M],电子工业出版社,2018.
[2] 全权,戴训华,王帅.多旋翼飞行器设计与控制实践[M],电子工业出版社,2020.
相关文章:
RflySim | 滤波器设计实验一
滤波器设计实验一 一. 无人机滤波器简介 无人机在飞行时会使用滤波器来处理传感器数据、控制飞行和稳定飞行,以及实现导航和定位等功能。卡尔曼滤波器是无人机领域中常见滤波器类型之一,也称为线性二次型估计,能够从一系列不完全且包含噪声不…...
设计模式——责任链模式(Chain of Responsibility Pattern)+ Spring相关源码
文章目录 一、责任链模式定义二、例子2.1 菜鸟教程2.1.1 定义一个抽象日志类2.1.2 定义日志类的具体实现类ConsoleLogger 、ErrorLogger 、FileLogger2.1.3 将日志类串起来,并使用 2.2 JDK源码——Filter2.3 Spring源码——HandlerInterceptor 三、其他设计模式 一、…...
游戏中的随机抽样算法
相关题目: 382. 链表随机节点 384. 打乱数组 398. 随机数索引 文章详解: 游戏中的随机抽样算法 class ListNode:def __init__(self, val0, nextNone):self.val valself.next nextclass RandListNode:"""382. 链表随机节点https://lee…...
【Qt之QtXlsx模块】安装及使用
1. 安装Perl,编译QtXlsx源码用 可以通过命令行进行查看是否已安装Perl。 下载及安装传送门:链接: https://blog.csdn.net/MrHHHHHH/article/details/134233707?spm1001.2014.3001.5502 1.1 未安装 命令:perl --version 显示以上是未安装…...
如何在 TFRecord 文件上训练 Keras 模型实现黑色素瘤分类器
简介 + 设置 TFRecords 存储一系列二进制记录,线性读取。它们是存储数据的有用格式,因为它们可以有效地读取。在此处了解有关 TFRecords 的更多信息 。 我们将探索如何轻松加载黑色素瘤分类器的 TFRecords。 import tensorflow as tf from functools import partial import…...
C++ 复制控制之复制构造函数
C类用三个特殊的成员函数:复制构造函数、赋值操作符和析构函数 来决定类对象之间的初始化或赋值时发生什么。所谓的“复制控制”即通过这三个成员函数控制对象复制的过程 复制构造函数首先是一个构造函数,它同所有其他的构造函数一样与类同名࿰…...
Windows ObjectType Hook 之 ParseProcedure
1、背景 Object Type Hook 是基于 Object Type的一种深入的 Hook,比起常用的 SSDT Hook 更为深入。 有关 Object Type 的分析见文章 《Windows驱动开发学习记录-ObjectType Hook之ObjectType结构相关分析》。 这里进行的 Hook 为 其中之一的 ParseProcedure。文章实…...
下载树莓派对应的64位Ubuntu系统步骤
说点废话:因为ros2需要安装在64位Ubuntu上面,所以安装64位最合适; 第一步打开https://cn.ubuntu.com/ 网站;选择下载--->iot----> 选择这个镜像文件下载。我觉得镜像文件是img格式的,跟iso文件区别是ÿ…...
网络运维Day03
文章目录 基本命令使用查看文本文件内容-cat命令分页查看文本文件-less命令查看CPU信息-lscpu命令查看系统内核版本-uname命令查看机修改主机名-hostname命令查看IP地址-ifconfig命令创建目录-mkdir命令创建空文件-touch命令查看文件前几行-head命令查看文件后几行-tail命令快速…...
LangChain+LLM实战---ChatGPT的工作原理
一个词一个词的输出 ChatGPT能够自动生成类似于人类书写的文本,这是非常了不起和出乎意料的。但它是如何做到的?为什么会有效果呢?我的目的在于大致概述ChatGPT内部发生了什么,然后探讨它为什么能够很好地生成我们认为有意义的文…...
Appium知多少
Appium我想大家都不陌生,这是主流的移动自动化工具,但你对它真的了解么?为什么很多同学搭建环境时碰到各种问题也而不知该如何解决。 appium为什么英语词典查不到中文含义? appium是一个合成词,分别取自“applicatio…...
【实战Flask API项目指南】之五 RESTful API设计
实战Flask API项目指南之 RESTful API设计 本系列文章将带你深入探索实战Flask API项目指南,通过跟随小菜的学习之旅,你将逐步掌握 Flask 在实际项目中的应用。让我们一起踏上这个精彩的学习之旅吧! 前言 当小菜踏入Flask后端开发的世界时…...
尚硅谷大数据项目《在线教育之实时数仓》笔记005
视频地址:尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 第9章 数仓开发之DWD层 P031 P032 P033 P034 P035 P036 P037 P038 P039 P040 第9章 数仓开发之DWD层 P031 DWD层设计要点: (1)DWD层的设计依…...
算法通过村第十八关-回溯|青铜笔记|什么叫回溯(中篇)
文章目录 前言回溯的核心问题撤销操作解释总结 前言 提示:阳光好的时候,会感觉还可以活很久,甚至可以活出喜悦。 --余秀华 回溯是非常重要的算法思想之一,主要解决一些暴力枚举也搞不定的问题(这里埋个坑💣…...
generate by chatgpt:应用上线前的checkList(部分是我自己的回答)
prompt 1 想象你是一名高级测试工程师,在应用上线前你需要提供一份checklist,请写出来: 作为一名高级测试工程师,以下是我在应用上线前的检查清单: 功能性测试: 检查所有要素和功能是否正常工作。确保满足了所有用户故事/需求。…...
Redis实战 | 使用Redis 的有序集合(Sorted Set)实现排行榜功能,和Spring Boot集成
专栏集锦,大佬们可以收藏以备不时之需 Spring Cloud实战专栏:https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏:https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏:https:/…...
基于信号功率谱特征和GRNN广义回归神经网络的信号调制类型识别算法matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ................................................................ %调制识别 len1 func_f…...
matplotlib从起点出发(10)_Tutorial_10_Layout
使用受约束的绘图干净整洁地将图形合适排列。 受约束的布局会自动调整子图,以便刻度标签、图例和颜色条等装饰不会重叠,同时仍保留用户请求的逻辑布局。 受约束布局类似于“紧密布局”,但它要更灵活。它处理放置在多个轴上的Axes(放置颜色条…...
HTTP头部信息解释分析(详细整理)(转载)
这篇文章为大家介绍了HTTP头部信息,中英文对比分析,还是比较全面的,若大家在使用过程中遇到不了解的,可以适当参考下 HTTP 头部解释 1. Accept: 告诉WEB服务器自己接受什么介质类型,/ 表示任何类型&#…...
集线器、交换机、网桥、路由器、网关
目录 集线器(HUB)交换机(SWITCH)网桥(BRIDGE)路由器(ROUTER)网关(GATEWAY)交换机和路由器的区别参考 集线器(HUB) 功能 集线器对数据的传输起到同步、放大和整形的作用 属于物理层设备 工作机制 使用集线器互连而成的以太网被称为共享式以太网。当某个主机要给另一个主机发送单…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...
