MATLAB - 四旋翼飞行器动力学方程

系列文章目录


前言

本例演示了如何使用 Symbolic Math Toolbox™(符号数学工具箱)推导四旋翼飞行器的连续时间非线性模型。具体来说,本例讨论了 getQuadrotorDynamicsAndJacobian 脚本,该脚本可生成四旋翼状态函数及其雅各布函数。这些函数将在使用非线性模型预测控制(模型预测控制工具箱)控制四旋翼飞行器的示例中使用。

四旋翼飞行器又称四旋翼直升机,是一种拥有四个旋翼的直升机。从四旋翼飞行器的质量中心出发,旋翼呈等距离的正方形排列。四旋翼的运动是通过调整四个旋翼的角速度来控制的,而四个旋翼是由电动马达带动旋转的。四旋翼飞行器动力学数学模型可从牛顿-欧拉方程和欧拉-拉格朗日方程中导出 [1]。


一、定义状态变量和参数

如图所示,四旋翼飞行器有六个自由度(三个线性坐标和三个角度坐标),四个控制输入。

四旋翼飞行器的 12 个状态是

\left(x,y,z,\phi\,,\theta,\psi,\dot{x},\dot{y},\dot{\ z},\dot{\phi},\dot{\theta},\dot{\psi}\right)^{T},

其中

\xi=(x,y,z)^{\mathrm{T}} 表示线性位置。

\eta=\left(\phi\,,\theta,\psi\right)^{\mathrm{T}} 分别表示滚转角、俯仰角和偏航角。

\left(\dot{x},\dot{y},\dot{z},\dot{\phi},\dot{\theta},\dot{\psi}\right)^{T} 表示线速度和角速度,或线性位置和角度位置的时间导数。

四旋翼飞行器的运动参数为

(u_1,u_2,u_3,u_4)=\left(\omega_{1}^{2},\omega_{2}^{2},\omega_{3}^{2},\omega_{4}^{2}\right) 代表四个旋翼的角速度平方。

(I_{​{xx}},I_{​{yy}},I_{​{zz}}) 代表机身坐标系中转动惯量矩阵的对角元素。

(k,l,m,b,g)代表升力常数、转子与质量中心的距离、四旋翼质量、阻力常数和重力。

前四个参数 (u_1,u_2,u_3,u_4) 是控制输入或控制四旋翼飞行器轨迹的操纵变量。其余参数固定为给定值。

二、定义变换矩阵和科里奥利矩阵

定义惯性坐标系和主体坐标系之间的变换矩阵。需要这些变换矩阵来描述四旋翼飞行器在两个坐标系中的运动。四旋翼飞行器的 12 个状态在惯性系中定义,旋转惯性矩阵在机身系中定义。

创建符号函数来表示随时间变化的角度。在按照 [1] 进行的数学推导中,需要这种明确的时间依赖性来评估时间导数。定义矩阵 Wη 以将角速度从惯性系转换到体坐标系。定义旋转矩阵 R,使用局部函数部分定义的 rotationMatrixEulerZYX 函数将线性力从机身坐标系转换到惯性坐标系。创建符号矩阵来表示这些变换矩阵。

% Create symbolic functions for time-dependent angles
% phi: roll angle
% theta: pitch angle
% psi: yaw angle
syms phi(t) theta(t) psi(t)% Transformation matrix for angular velocities from inertial frame
% to body frame
W = [ 1,  0,        -sin(theta);0,  cos(phi),  cos(theta)*sin(phi);0, -sin(phi),  cos(theta)*cos(phi) ];% Rotation matrix R_ZYX from body frame to inertial frame
R = rotationMatrixEulerZYX(phi,theta,psi);

 求用于表示惯性系中旋转能量的雅各布矩阵 J=W_{\eta}^{T}\,I\,W_{\eta}

% Create symbolic variables for diagonal elements of inertia matrix
syms Ixx Iyy Izz% Jacobian that relates body frame to inertial frame velocities
I = [Ixx, 0, 0; 0, Iyy, 0; 0, 0, Izz];
J = W.'*I*W;

接下来,找出科里奥利矩阵 C(\eta,\dot{\eta})=\frac{\mathrm{d}}{\mathrm{d}t}J-\frac{1}{2}\frac{\partial}{\partial\eta}\left(\dot{\eta}^{\Upsilon}J\right),它包含角欧拉-拉格朗日方程中的陀螺项和向心项。使用符号 diff 和 jacobian 函数进行微分运算。为了简化微分后科里奥利矩阵的符号,可以用 C(\eta,{\dot{\eta}})中的显式时间相关项替换为符号变量(代表特定时间的某些值)。这种简化的符号使这里的结果更容易与 [1] 中的推导进行比较。 

% Coriolis matrix
dJ_dt = diff(J);
h_dot_J = [diff(phi,t), diff(theta,t), diff(psi,t)]*J;
grad_temp_h = transpose(jacobian(h_dot_J,[phi theta psi]));
C = dJ_dt - 1/2*grad_temp_h;
C = subsStateVars(C,t);

三、证明科里奥利矩阵定义是一致的

科里奥利矩阵 C(\eta,{\dot{\eta}}) 很容易用上一节的符号工作流程推导出来。然而,这里的 C(\eta,{\dot{\eta}}) 定义与 [1] 中的不同,后者使用克里斯托弗符号推导科里奥利矩阵。由于 C(\eta,{\dot{\eta}}) 并非唯一,因此可以有多种定义方法。但是,欧拉-拉格朗日方程中使用的 C(\eta,\dot{\eta})\;\dot{\eta} 项必须是唯一的。本节将证明 C(\eta,{\dot{\eta}}) 的符号定义与 [1] 中的定义是一致的,即 C(\eta,\dot{\eta})\;\dot{\eta}项在两个定义中在数学上是相等的。

利用上一节中得出的 C(\eta,{\dot{\eta}}) 的符号定义来评估 C(\eta,\dot{\eta})\;\dot{\eta} 项。

% Evaluate C times etadot using symbolic definition
phidot   = subsStateVars(diff(phi,t),t);
thetadot = subsStateVars(diff(theta,t),t);
psidot   = subsStateVars(diff(psi,t),t);
Csym_etadot = C*[phidot; thetadot; psidot];

使用 [1] 中得出的 C(\eta,{\dot{\eta}}) 的定义,对 C(\eta,\dot{\eta})\;\dot{\eta} 项进行评估。

% Evaluate C times etadot using reference paper definition
C11 = 0;
C12 = (Iyy - Izz)*(thetadot*cos(phi)*sin(phi) + psidot*sin(phi)^2*cos(theta)) ...+ (Izz - Iyy)*(psidot*cos(phi)^2*cos(theta)) - Ixx*psidot*cos(theta);
C13 = (Izz - Iyy)*psidot*cos(phi)*sin(phi)*cos(theta)^2;
C21 = (Izz - Iyy)*(thetadot*cos(phi)*sin(phi) + psidot*sin(phi)^2*cos(theta)) ...+ (Iyy - Izz)*psidot*cos(phi)^2*cos(theta) + Ixx*psidot*cos(theta);
C22 = (Izz - Iyy)*phidot*cos(phi)*sin(phi);
C23 = - Ixx*psidot*sin(theta)*cos(theta) + Iyy*psidot*sin(phi)^2*sin(theta)*cos(theta) ...+ Izz*psidot*cos(phi)^2*sin(theta)*cos(theta);
C31 = (Iyy - Izz)*psidot*cos(theta)^2*sin(phi)*cos(phi) - Ixx*thetadot*cos(theta);
C32 = (Izz - Iyy)*(thetadot*cos(phi)*sin(phi)*sin(theta) + phidot*sin(phi)^2*cos(theta)) ...+ (Iyy - Izz)*phidot*cos(phi)^2*cos(theta) + Ixx*psidot*sin(theta)*cos(theta) ...- Iyy*psidot*sin(phi)^2*sin(theta)*cos(theta) - Izz*psidot*cos(phi)^2*sin(theta)*cos(theta);
C33 = (Iyy - Izz)*phidot*cos(phi)*sin(phi)*cos(theta)^2 ...- Iyy*thetadot*sin(phi)^2*cos(theta)*sin(theta) ...- Izz*thetadot*cos(phi)^2*cos(theta)*sin(theta) + Ixx*thetadot*cos(theta)*sin(theta);
Cpaper = [C11, C12, C13; C21, C22, C23; C31 C32 C33];
Cpaper_etadot = Cpaper*[phidot; thetadot; psidot];
Cpaper_etadot = subsStateVars(Cpaper_etadot,t);

证明这两个定义对 C(\eta,\dot{\eta})\;\dot{\eta} 项给出了相同的结果。

tf_Cdefinition = isAlways(Cpaper_etadot == Csym_etadot)
tf_Cdefinition = 3x1 logical array111

四、查找运动方程

求出 12 个状态的运动方程。

根据 [1],求出扭矩 τ B 在滚转、俯仰和偏航角方向上的扭矩:

  • 通过降低第 2 个转子的速度和提高第 4 个转子的速度来设定滚转运动。
  • 通过降低第 1 个转子的速度和提高第 3 个转子的速度来设置俯仰运动。
  • 偏航运动是通过增大两个相对旋翼的速度和减小另外两个旋翼的速度来实现的。

求转子 T 在机身 Z 轴方向上的总推力。

% Define fixed parameters and control input
% k: lift constant
% l: distance between rotor and center of mass
% m: quadrotor mass
% b: drag constant
% g: gravity
% ui: squared angular velocity of rotor i as control input
syms k l m b g u1 u2 u3 u4% Torques in the direction of phi, theta, psi
tau_beta = [l*k*(-u2+u4); l*k*(-u1+u3); b*(-u1+u2-u3+u4)];% Total thrust
T = k*(u1+u2+u3+u4);

接下来,创建符号函数来表示随时间变化的位置。为线性位置、角度及其时间导数定义 12 个状态 \left[\xi;\eta;\;{\dot{\xi}};\;{\dot{\eta}}\right]。定义好状态后,用显式时间项代替,以简化符号。

% Create symbolic functions for time-dependent positions
syms x(t) y(t) z(t)% Create state variables consisting of positions, angles,
% and their derivatives
state = [x; y; z; phi; theta; psi; diff(x,t); diff(y,t); ...diff(z,t); diff(phi,t); diff(theta,t); diff(psi,t)];
state = subsStateVars(state,t);

建立描述 12 个状态 f=\left[\,\dot{\xi};\,\dot{\eta}\,;\,\ddot{\xi}\,;\,\ddot{\eta}\,\right] 的时间导数的 12 个运动方程。线性加速度的微分方程为 \ddot{\xi}\,=-(0,0,g)^{\Gamma}+R(0,0,T)^{\Gamma}/m.,角加速度的微分方程为 \ddot{\eta}=J^{-1}\bigl(\tau B-C(\eta,\dot{\eta})\,\dot{\eta}\,\bigr)\,.。代入明确的时间相关项,以简化符号。

f = [ % Set time-derivative of the positions and anglesstate(7:12);% Equations for linear accelerations of the center of mass-g*[0;0;1] + R*[0;0;T]/m;% Euler–Lagrange equations for angular dynamicsinv(J)*(tau_beta - C*state(10:12))
];f = subsStateVars(f,t);

在前面的步骤中,固定参数被定义为符号变量,以紧跟文献 [1] 的推导。接下来,用给定值替换固定参数。这些值用于设计四旋翼飞行器特定配置的轨迹跟踪控制器。替换固定参数后,使用简化对运动方程进行代数简化。

% Replace fixed parameters with given values here
IxxVal = 1.2;
IyyVal = 1.2;
IzzVal = 2.3;
kVal = 1;
lVal = 0.25;
mVal = 2;
bVal = 0.2;
gVal = 9.81;f = subs(f, [Ixx Iyy Izz k l m b g], ...[IxxVal IyyVal IzzVal kVal lVal mVal bVal gVal]);
f = simplify(f);

五、为非线性模型预测控制查找雅各布因子并生成文件

最后,使用符号数学工具箱查找非线性模型函数的解析雅各布因子并生成 MATLAB® 文件。这一步骤对于提高使用模型预测控制工具箱™ 解决轨迹跟踪非线性模型时的计算效率非常重要。更多信息,请参阅 nlmpc(模型预测控制工具箱)和 Specify Prediction Model for Nonlinear MPC(模型预测控制工具箱)。

查找状态函数相对于状态变量和控制输入的雅各布。

% Calculate Jacobians for nonlinear prediction model
A = jacobian(f,state);
control = [u1; u2; u3; u4];
B = jacobian(f,control);

生成状态函数和状态函数 Jacobians 的 MATLAB 文件。这些文件可用于设计轨迹跟踪控制器,详见《使用非线性模型预测控制(模型预测控制工具箱)控制四旋翼飞行器》。

% Create QuadrotorStateFcn.m with current state and control
% vectors as inputs and the state time-derivative as outputs
matlabFunction(f,'File','QuadrotorStateFcn', ...'Vars',{state,control});% Create QuadrotorStateJacobianFcn.m with current state and control
% vectors as inputs and the Jacobians of the state time-derivative
% as outputs
matlabFunction(A,B,'File','QuadrotorStateJacobianFcn', ...'Vars',{state,control});

您可以在 getQuadrotorDynamicsAndJacobian.m 文件中访问该脚本中的代码。

六、函数

function [Rz,Ry,Rx] = rotationMatrixEulerZYX(phi,theta,psi)
% Euler ZYX angles conventionRx = [ 1,           0,          0;0,           cos(phi),  -sin(phi);0,           sin(phi),   cos(phi) ];Ry = [ cos(theta),  0,          sin(theta);0,           1,          0;-sin(theta),  0,          cos(theta) ];Rz = [cos(psi),    -sin(psi),   0;sin(psi),     cos(psi),   0;0,            0,          1 ];if nargout == 3% Return rotation matrix per axesreturn;end% Return rotation matrix from body frame to inertial frameRz = Rz*Ry*Rx;
endfunction stateExpr = subsStateVars(timeExpr,var)if nargin == 1 var = sym("t");endrepDiff = @(ex) subsStateVarsDiff(ex,var);stateExpr = mapSymType(timeExpr,"diff",repDiff);repFun = @(ex) subsStateVarsFun(ex,var);stateExpr = mapSymType(stateExpr,"symfunOf",var,repFun);stateExpr = formula(stateExpr);
endfunction newVar = subsStateVarsFun(funExpr,var)name = symFunType(funExpr);name = replace(name,"_Var","");stateVar = "_" + char(var);newVar = sym(name + stateVar);
endfunction newVar = subsStateVarsDiff(diffExpr,var)if nargin == 1 var = sym("t");endc = children(diffExpr);if ~isSymType(c{1},"symfunOf",var)% not f(t)newVar = diffExpr;return;endif ~any([c{2:end}] == var)% not derivative wrt t onlynewVar = diffExpr;return;endname = symFunType(c{1});name = replace(name,"_Var","");extension = "_" + join(repelem("d",numel(c)-1),"") + "ot";stateVar = "_" + char(var);newVar = sym(name + extension + stateVar);
end

七、参考资料

[1] Raffo, Guilherme V., Manuel G. Ortega, and Francisco R. Rubio. "An integral predictive/nonlinear ℋ∞ control structure for a quadrotor helicopter". Automatica 46, no. 1 (January 2010): 29–39. https://doi.org/10.1016/j.automatica.2009.10.018.

[2] Tzorakoleftherakis, Emmanouil, and Todd D. Murphey. "Iterative sequential action control for stable, model-based control of nonlinear systems." IEEE Transactions on Automatic Control 64, no. 8 (August 2019): 3170–83. https://doi.org/10.1109/TAC.2018.2885477.

[3] Luukkonen, Teppo. "Modelling and control of quadcopter". Independent research project in applied mathematics, Aalto University, 2011.

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

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

相关文章

streamlit中文开发手册(详细版)

目录 一、安装与配置 1.1 安装 Streamlit 1.2 配置文件 1.3 运行Streamlit应用 二、streamlit显示数据 2.1 显示标题 2.2 显示文本 2.3 显示代码段 2.4 通用显示方法 2.5 显示表格 2.6 显示JSON 2.7 显示pyplot图表 2.8 显示地图 2.9 显示图像 2.10 显示视频 三…

2024年腾讯云新用户专属优惠活动及代金券活动汇总

腾讯云作为国内领先的云计算服务提供商,一直致力于为用户提供优质、高效的服务。为了更好地满足新用户的需求,腾讯云在2024年推出了一系列新用户专属优惠活动和代金券活动。本文将为大家详细介绍这些活动,帮助大家更好地了解和利用这些优惠。…

Gogs - 管理协作者

Gogs - 管理协作者 References 仓库设置 管理协作者 权限设置 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

Android 13(T) - Media框架(2)- libmedia

这一节学习有两个目标: 1 熟悉Android Media API的源码路径与调用层次 2 从MediaPlayer的创建与销毁了解与native的串接 1、源码路径 Media相关的API位于:frameworks/base/media/java/android/media,里面提供有MediaPlayer MediaCodecList M…

代币合约 ERC20 Token接口

代币合约 在以太坊上发布代币就要遵守以太坊的规则,那么以太坊有什么规则呢?以太坊的精髓就是利用代码规定如何运作,由于在以太坊上发布智能合约是不能修改和删除的,所以智能合约一旦发布,就意味着永久有效,不可篡改…

如何解决NAND系统性能问题?-- NAND接口分类

三、NAND接口 NAND闪存接口是连接主机控制器与NAND存储芯片的通信桥梁,负责命令、地址和数据的传输。典型的NAND闪存接口包括一组I/O线(通常为8条或更多)用于数据传输,以及若干控制信号线。 基本接口信号: Chip Enable…

吲哚及其衍生物:连接肠道炎症与神经健康的隐秘调节剂

谷禾健康 你敢相信吗?从粪便中提取出具有强烈粪臭味的物质,当用酒精稀释上千倍后,脱胎换骨变成了一种香味。这就是一种吲哚衍生物——3-甲基吲哚(又名粪臭素) 吲哚,是所有花香类原精的关键成分,这种物质在低剂量1-3%浓…

如何利用RPA做UI自动化测试对传统自动化的降维打击

写在前面 RPA软件一开始的目的并不是自动化测试,而是要把电脑上面几十个、上百个常用的软件,通过机器人流程自动化来打通,通过一个软件来控制几十个、上百个软件。而这个过程,其实覆盖了软件自动化测试。 所谓降维打击&#xff0c…

【第二课课后作业】书生·浦语大模型实战营-轻松玩转书生·浦语大模型趣味Demo

目录 轻松玩转书生浦语大模型趣味Demo课后作业1. 基础作业1.1 使用 InternLM-Chat-7B 模型生成 300 字的小故事:1.2 熟悉 hugging face 下载功能,使用 huggingface_hub python 包,下载 InternLM-20B 的 config.json 文件到本地 2. 进阶作业2.…

强化学习应用(三):基于Q-learning的无人机物流路径规划研究(提供Python代码)

一、Q-learning简介 Q-learning是一种强化学习算法,用于解决基于马尔可夫决策过程(MDP)的问题。它通过学习一个价值函数来指导智能体在环境中做出决策,以最大化累积奖励。 Q-learning算法的核心思想是通过不断更新一个称为Q值的…

【Docker】数据卷挂载以及宿主机目录挂载的使用

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《Docker实战》。🎯🎯 &…

[JVM] Java类的加载过程

Java类的加载过程 在Java中,类的加载是指在程序运行时将类的二进制数据加载到内存中,并转化为可以被JVM执行的形式的过程。类的加载过程主要包括以下几个步骤: 加载(Loading):通过类的全限定名,…

P1042 [NOIP2003 普及组] 乒乓球————C++

目录 [NOIP2003 普及组] 乒乓球题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 解题思路Code运行结果 [NOIP2003 普及组] 乒乓球 题目背景 国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。其中 …

HTML 链接 图片引入

文章目录 链接图片引入 链接 准备工作 新建一个名为link.html和suc.html suc.html <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>显示结果</title></head><body>注册成功...&l…

电子学会C/C++编程等级考试2020年12月(三级)真题解析

C/C++编程(1~8级)全部真题・点这里 第1题:完美立方 形如 a^3= b^3 + c^3 + d^3的等式被称为完美立方等式。例如 12^3= 6^3 + 8^3 + 10^3 。 编写一个程序,对任给的正整数 N (N≤100),寻找所有的四元组 (a, b, c, d),使得 a^3= b^3 + c^3 + d^3 ,其中 a,b,c,d均大于 11, …

人工智能:我的学习之旅与认知探索(第1版)

&#x1f31f;&#x1f30c; 欢迎来到知识与创意的殿堂 — 远见阁小民的世界&#xff01;&#x1f680; &#x1f31f;&#x1f9ed; 在这里&#xff0c;我们一起探索技术的奥秘&#xff0c;一起在知识的海洋中遨游。 &#x1f31f;&#x1f9ed; 在这里&#xff0c;每个错误都…

UE5 实现RPG游戏操作控制

在UE5以后&#xff0c;epic抛弃了之前的那一套操作输入系统&#xff0c;使用了一套新的增强输入作为替代&#xff0c;目的主要是解决经常切换操作时的问题&#xff08;操作人物上车以后&#xff0c;可以直接切换成操作汽车的一套输入&#xff09;接下来&#xff0c;将实现如何使…

K8s:Pod生命周期

我们一般将pod对象从创建至终的这段时间范围称为pod的生命周期&#xff0c;它主要包含下面的过程&#xff1a; pod创建过程 运行初始化容器&#xff08;init container&#xff09;过程 运行主容器&#xff08;main container&#xff09; 容器启动后钩子&#xff08;post st…

Django框架完成读者浏览书籍,图书详情页,借阅管理

前情回顾&#xff1a; 使用Django框架实现简单的图书借阅系统——完成图书信息管理 文章目录 1.完成展示图书信息功能1.1django 静态资源管理问题1.2编写图书展示模板HTML 2.完成图书详情页功能2.1从后端获取图书详情信息2.2详情页面展示图书数据 3.完成借阅管理功能3.1管理员…

Qt QListWidget列表框控件

文章目录 1 属性和方法1.1 外观1.2 添加条目1.3 删除条目1.4 信号和槽 2 实例2.1 布局2.2 代码实现 Qt中的列表框控件&#xff0c;对应的类是QListWidget 它用于显示多个列表项&#xff0c;列表项对应的类是QListWidgetitem 1 属性和方法 QListWidget有很多属性和方法&#xf…