px4固定翼无人机姿态控制理解

2023-05-16

  学习px4代码也有一段时间了,所以想写一写,自己的一些学习心得吧,也算是笔记吧。

  在px4这套代码中,每一个功能都是一个模块,例如姿态控制,也就是一个应用程序,我们可以把它添加到初始话脚本里,让它自启动。需要注意的就是在一个应用程序就是处理订阅的消息,然后发布处理过后的消息。这种消息机制就是uorb消息机制,可以找资料学习它具体实现的一个过程。

  接下来,就逐步学习一下这个姿态控制的模块。

  首先就是应用程序的入口,“extern "C" __EXPORT int fw_att_control_main(int argc, char *argv[])”,在这个函数里就实现了,这个程序是否已近启动,如果没有启动就会注册函数来启动。

  task_main()这个函数就是整个姿态控制的关键,具体姿态控制的算法就是在这里面实现。刚开始就介绍说每个应用程序会订阅相应的消息,然后处理,最后发布。

所以刚开始就是一些消息的订阅:


_att_sp_sub = orb_subscribe(ORB_ID(vehicle_attitude_setpoint));//姿态设定点

_ctrl_state_sub = orb_subscribe(ORB_ID(control_state));//飞机状态

_accel_sub = orb_subscribe_multi(ORB_ID(sensor_accel), 0);//加速度值
_vcontrol_mode_sub = orb_subscribe(ORB_ID(vehicle_control_mode));//控制模式

_params_sub = orb_subscribe(ORB_ID(parameter_update));//参数更新

_manual_sub = orb_subscribe(ORB_ID(manual_control_setpoint));//手动控制的设定

_global_pos_sub = orb_subscribe(ORB_ID(vehicle_global_position));//车辆全球位置

_vehicle_status_sub = orb_subscribe(ORB_ID(vehicle_status));//飞机状态

_vehicle_land_detected_sub = orb_subscribe(ORB_ID(vehicle_land_detected));//着陆探测  

接下来就是以check的方式获取订阅消息的值:


vehicle_setpoint_poll();
vehicle_accel_poll();
vehicle_control_mode_poll();
vehicle_manual_poll();
vehicle_status_poll();
vehicle_land_detected_poll();  

接下来就是以阻塞等待方式检查参数是否更新,以及当前的飞机状态。阻塞等待这种获取订阅消息的方式,具体是怎么实现的可以查找资料进行学习。

这个if函数就是姿态控制运行的开始,如果姿态发生了改变,就运行这个if


if (fds[1].revents & POLLIN)   

那么要知道姿态是否发生改变,那么就需要知道当前的姿态,这通过获取当前姿态的消息,然后得到四元数,转化为旋转矩阵,进而求得姿态角:


 1 orb_copy(ORB_ID(control_state), _ctrl_state_sub, &_ctrl_state);
 2 
 3 
 4 /* get current rotation matrix and euler angles from control state quaternions */
 5 math::Quaternion q_att(_ctrl_state.q[0], _ctrl_state.q[1], _ctrl_state.q[2], _ctrl_state.q[3]);
 6 _R = q_att.to_dcm();
 7 
 8 math::Vector<3> euler_angles;
 9 euler_angles = _R.to_euler();
10 _roll    = euler_angles(0);
11 _pitch   = euler_angles(1);
12 _yaw     = euler_angles(2);  

由于姿态控制算法在一些模式下面是不会估算姿态设定点的,所以要确认这些标志。


_att_sp.fw_control_yaw = _att_sp.fw_control_yaw && _vcontrol_mode.flag_control_auto_enabled;//判断垂尾,用于自主起飞。  

判断是否安全故障,如果安全故障开启,就会设定降落伞。

接下来是襟翼的设定,分为手动控制和自动控制


 1             float flap_control = 0.0f;
 2 
 3             /* map flaps by default to manual if valid */
 4             if (PX4_ISFINITE(_manual.flaps) && _vcontrol_mode.flag_control_manual_enabled
 5                 && fabsf(_parameters.flaps_scale) > 0.01f) {
 6                 flap_control = 0.5f * (_manual.flaps + 1.0f) * _parameters.flaps_scale;
 7 
 8             } else if (_vcontrol_mode.flag_control_auto_enabled
 9                    && fabsf(_parameters.flaps_scale) > 0.01f) {
10                 flap_control = _att_sp.apply_flaps ? 1.0f * _parameters.flaps_scale : 0.0f;
11             }
12 
13             // move the actual control value continuous with time, full flap travel in 1sec
14             if (fabsf(_flaps_applied - flap_control) > 0.01f) {
15                 _flaps_applied += (_flaps_applied - flap_control) < 0 ? deltaT : -deltaT;
16 
17             } else {
18                 _flaps_applied = flap_control;
19             }  

然后是襟副翼的设定,分为手动控制和自动控制


 1 if (PX4_ISFINITE(_manual.aux2) && _vcontrol_mode.flag_control_manual_enabled
 2                 && fabsf(_parameters.flaperon_scale) > 0.01f) {
 3                 flaperon_control = 0.5f * (_manual.aux2 + 1.0f) * _parameters.flaperon_scale;
 4 
 5             } else if (_vcontrol_mode.flag_control_auto_enabled
 6                    && fabsf(_parameters.flaperon_scale) > 0.01f) {
 7                 flaperon_control = _att_sp.apply_flaps ? 1.0f * _parameters.flaperon_scale : 0.0f;
 8             }
 9 
10             // move the actual control value continuous with time, full flap travel in 1sec
11             if (fabsf(_flaperons_applied - flaperon_control) > 0.01f) {
12                 _flaperons_applied += (_flaperons_applied - flaperon_control) < 0 ? deltaT : -deltaT;
13 
14             } else {
15                 _flaperons_applied = flaperon_control;
16             }  

接下来就是通过订阅的消息来判断是否能够控制姿态

也就是这一行代码:


1 if (_vcontrol_mode.flag_control_attitude_enabled)  

在这个if语句里面执行的主要有判断空速是否有效,如果无效设定空速为参数设定,如果有效设定空速为测量或者计算的空速。

通过vehicle_global_position来计算飞机的地面速度。

如果自问模式下面,我们需要通过遥控器来产生姿态设定点;

计算机体坐标系下飞机的速度;

准备姿态控制器运行需要的参数;


 1                 control_input.roll = _roll;
 2                 control_input.pitch = _pitch;
 3                 control_input.yaw = _yaw;
 4                 control_input.roll_rate = _ctrl_state.roll_rate;
 5                 control_input.pitch_rate = _ctrl_state.pitch_rate;
 6                 control_input.yaw_rate = _ctrl_state.yaw_rate;
 7                 control_input.speed_body_u = speed_body_u;
 8                 control_input.speed_body_v = speed_body_v;
 9                 control_input.speed_body_w = speed_body_w;
10                 control_input.acc_body_x = _accel.x;
11                 control_input.acc_body_y = _accel.y;
12                 control_input.acc_body_z = _accel.z;
13                 control_input.roll_setpoint = roll_sp;
14                 control_input.pitch_setpoint = pitch_sp;
15                 control_input.yaw_setpoint = yaw_sp;
16                 control_input.airspeed_min = _parameters.airspeed_min;
17                 control_input.airspeed_max = _parameters.airspeed_max;
18                 control_input.airspeed = airspeed;
19                 control_input.scaler = airspeed_scaling;
20                 control_input.lock_integrator = lock_integrator;
21                 control_input.groundspeed = groundspeed;
22                 control_input.groundspeed_scaler = groundspeed_scaler;  

前面的判断就是为运行姿态控制器所准备的。


1 _roll_ctrl.control_attitude(control_input);
2 _pitch_ctrl.control_attitude(control_input);
3 _yaw_ctrl.control_attitude(control_input);
4 _wheel_ctrl.control_attitude(control_input);  

上面就是计算目标与当前姿态的角度误差值,对于roll和pitch是计算角度误差,然后算出角速率,对于yaw速率的计算是,假设在没有侧向力的情况下,通过计算可以得到相应的yaw速率:

就是通过如下计算公式得到:

以及:

                                                                                                                                                                                                                                                             、

计算得到相应的yaw速率;

由于滚转,俯仰和偏航速率是在地面坐标系下,因此,要通过坐标转换转换到机体坐标系下,也就是:

                                                                                                                                                                           通过上述转换就把角速率转换到机体坐标系下了,接下来是通过误差,运用pid来控制姿态,下面的还需要研究一下。先这样吧。

      以上内容均属自己理解,有错误之处见谅,共同讨论。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

 

转载于:https://www.cnblogs.com/laokingshine/p/7236942.html

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

px4固定翼无人机姿态控制理解 的相关文章

  • 如何用c语言串口通讯,串口通信入门

    在讲解本章的内容之前请大家先反复阅读 手把手教你学51单片机 文档的第11章内容 xff0c 很多概念文档都已详细讲解有 1 波特率 串口通信就是单片机与电脑端 xff0c 单片机与单片机 xff0c 单片机与模块器件之间互发信息进行通信
  • php和js区别

    php和js区别 两者在语法上类似 xff0c 楼上说的对 xff0c js 61 javascript是工作在浏览器端的脚本语言 xff0c 他所提交的数据是交给浏览器来处理的 但是现在的Ajax技术已经可以把js提交的数据交付到浏览器来
  • web前端利用turf.js生成等值线、等值面

    样例如下 xff1a lt DOCTYPE html gt lt html xmlns 61 34 http www w3 org 1999 xhtml 34 gt lt head gt lt meta http equiv 61 34 C
  • python模块名和文件名冲突解决

    对于python初学者 xff0c 很容易练习到一个随机数生成的程序 xff0c 代码如下 xff1a 1 usr bin python 2 import random 3 print random randint 12 20 这个小程序最
  • python3 logging 'ascii' codec can't encode characters

    环境 xff1a mac 10 12 python3 django 1 10 问题发现 最近刚从arch 换到 mac下搬砖 xff0c 发现在arch跑的好好的代码 xff0c 在mac下 终端老是报错 还是编码错误 code try i
  • Hutool之文件工具——FileUtil

    为什么80 的码农都做不了架构师 xff1f gt gt gt 简介 我想在Java工具中 xff0c 文件操作应该也是使用相当频繁的 xff0c 但是Java对文件的操作由于牵涉到流 xff0c 所以较为繁琐 xff0c 各种Stream
  • java中数字与ASCII码的相互转换

    2019独角兽企业重金招聘Python工程师标准 gt gt gt code 测试demo public static void main String args int a 61 91151561 for byte b String va
  • IDEA怎么查看现在的项目使用的JDK版本? 2016年4月19日22:51

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 右键单击项目 xff0c 选择 或者直接使用F4 转载于 https my oschina net sprouting blog 670222
  • 什么是北向接口和南向接口

    Northbound Interface Southbound Interface 南向接口 xff1a 管理其他厂家网管或设备的接口 xff0c 即向下提供的接口 北向接口 xff1a 提供给其他厂家或运营商进行接入和管理的接口 xff0
  • 官网下载mysql源码

    官网下载mysql源码 xff0c 如下为具体步骤 xff1a 1 进入官网点击download页https www mysql com downloads 2 点击MySQL Community Edition进入mysql社区版下载页面
  • Vue设置button的disable属性

    表单元素有一个disable属性 xff0c 用来控制该元素是否可用 1 这个属性在HTML里只有1个值 xff0c 用法就是 lt button disable 61 34 disable 34 gt 点击 lt button gt 经实
  • 用C++进行简单的文件I/O操作

    序论 我曾发表过文件输入输出的文章 xff0c 现在觉得有必要再写一点 文件 I O 在C 43 43 中比烤蛋糕简单多了 在这篇文章里 xff0c 我会详细解释ASCII和二进制文件的输入输出的每个细节 xff0c 值得注意的是 xff0
  • VC++鼠标画圈

    int r 61 100 int x0 61 gameRect left 43 pt x int y0 61 gameRect top 43 pt y int x y double n 61 0 MoveTo x0 y0 while n l
  • matlab练习程序(求向量间的旋转矩阵与四元数)

    问题是这样 xff0c 如果我们知道两个向量v1和v2 xff0c 计算从v1转到v2的旋转矩阵和四元数 xff0c 由于旋转矩阵和四元数可以互转 xff0c 所以我们先计算四元数 我们可以认为v1绕着向量u旋转 角度到v2 xff0c u
  • 用lighttpd搭建一个简易的http服务器

    1 安装lighttpd 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 cd wget http download lighttpd net lighttpd releases
  • 结构体(对齐规则及举例)

    概念 一种数据结构 xff1b C语言中聚合数据类型的一类 xff1b 可以被声明为变量 数组 指针等 xff0c 用以实现比较复杂的数据结构 xff1b 是一系列元素的集合 xff0c 这些元素被称为结构体成员 xff1b 结构体成员需要
  • C++解析头文件-Qt自动生成信号定义

    目录 一 概述二 实现思路三 代码讲解 1 类图2 QtCppDescription3 测试四 源代码 一 概述 上一篇文章C 43 43 解析头文件 Qt自动生成信号声明我们主要讲解了怎么去解析C 43 43 头文件 xff0c 然后在指
  • VC++6.0与VS2010的区别

    区别1 字符串的表达 void CMy123Dlg OnBnClickedButton1 MessageBox 34 你好 34 以前VC6 0写法 现在用不了 老版本用的多字节字符集 MessageBox L 34 你好 34 L 是 u
  • 存储过程出现ORA-06508错误

    一个存储过程平时执行正常 xff0c 刚才执行出ORA 06508错误 百思不得其解 xff0c 好像没有什么不正常的地方啊 xff01 后来找到了答案 重现这个错误如下 xff1a 执行一个存储过程 xff0c 其运行时间比较长 刚开始运
  • 从零构建TCP/IP协议

    从零构建TCP IP协议 这次叫PCT协议 这篇博客是读完 图解TCP IP协议 和 TCP IP协议详解卷一 xff1a 协议 之后的总结 我从0构建了一个可靠的双工的有序的基于流的协议 xff0c 叫做PCT协议 OSI七层模型和TCP

随机推荐