开源飞控PX4姿态控制代码解析

2023-05-16

本篇文章首发于公众号:无人机系统技术。更多无人机技术相关文章请关注此公众号,有问题也可在公众号回复“加群”进入技术交流群进行交流。

本公众号将于9月11号联合电子工业出版社送出15本价值98元的《多旋翼飞行器设计与控制》书籍,敬请期待。关注:无人机系统技术,了解详情!!!

引言

上一讲PX4姿态控制算法详解我们对PX4姿态控制的算法进行了详细解析,还没看过的朋友先打开第三条内容仔细阅读后再来继续浏览吧。本讲内容主要是摘取PX4中关于姿态控制律实现的代码进行逐行分析,让各位朋友在代码实践中感受控制算法的魅力。姿态控制器的代码在文件Firmware\src\modules\mc_att_control\AttitudeControl\AttitudeControl.cpp的update函数中,我们先把代码贴上来,然后再进行逐行解读:

matrix::Vector3f AttitudeControl::update(matrix::Quatf q, matrix::Quatf qd, float yawspeed_feedforward)
{
  // ensure input quaternions are exactly normalized because acosf(1.00001) == NaN
  q.normalize();
  qd.normalize();

  // calculate reduced desired attitude neglecting vehicle's yaw to prioritize roll and pitch
  const Vector3f e_z = q.dcm_z();
  const Vector3f e_z_d = qd.dcm_z();
  Quatf qd_red(e_z, e_z_d);

  if (fabsf(qd_red(1)) > (1.f - 1e-5f) || fabsf(qd_red(2)) > (1.f - 1e-5f)) {
    // In the infinitesimal corner case where the vehicle and thrust have the completely opposite direction,
    // full attitude control anyways generates no yaw input and directly takes the combination of
    // roll and pitch leading to the correct desired yaw. Ignoring this case would still be totally safe and stable.
    qd_red = qd;

  } else {
    // transform rotation from current to desired thrust vector into a world frame reduced desired attitude
    qd_red *= q;
  }

  // mix full and reduced desired attitude
  Quatf q_mix = qd_red.inversed() * qd;
  q_mix *= math::signNoZero(q_mix(0));
  // catch numerical problems with the domain of acosf and asinf
  q_mix(0) = math::constrain(q_mix(0), -1.f, 1.f);
  q_mix(3) = math::constrain(q_mix(3), -1.f, 1.f);
  qd = qd_red * Quatf(cosf(_yaw_w * acosf(q_mix(0))), 0, 0, sinf(_yaw_w * asinf(q_mix(3))));

  // quaternion attitude control law, qe is rotation from q to qd
  const Quatf qe = q.inversed() * qd;

  // using sin(alpha/2) scaled rotation axis as attitude error (see quaternion definition by axis angle)
  // also taking care of the antipodal unit quaternion ambiguity
  const Vector3f eq = 2.f * math::signNoZero(qe(0)) * qe.imag();

  // calculate angular rates setpoint
  matrix::Vector3f rate_setpoint = eq.emult(_proportional_gain);

  // Feed forward the yaw setpoint rate.
  // yaw_sp_move_rate is the feed forward commanded rotation around the world z-axis,
  // but we need to apply it in the body frame (because _rates_sp is expressed in the body frame).
  // Therefore we infer the world z-axis (expressed in the body frame) by taking the last column of R.transposed (== q.inversed)
  // and multiply it by the yaw setpoint rate (yaw_sp_move_rate).
  // This yields a vector representing the commanded rotatation around the world z-axis expressed in the body frame
  // such that it can be added to the rates setpoint.
  rate_setpoint += q.inversed().dcm_z() * yawspeed_feedforward;

  // limit rates
  for (int i = 0; i < 3; i++) {
    rate_setpoint(i) = math::constrain(rate_setpoint(i), -_rate_limit(i), _rate_limit(i));
  }

  return rate_setpoint;
}

代码解读

为方便大家阅读,代码中原有的英文注释给大家保存,每一行代码的注释我们放在代码上方。

matrix::Vector3f AttitudeControl::update(matrix::Quatf q, matrix::Quatf qd, float yawspeed_feedforward)
{
  // ensure input quaternions are exactly normalized because acosf(1.00001) == NaN

//对当前姿态四元数进行归一化,其实四元数本来就是归一化的,但是在计算机中存储传输时1.0可能会被存储成1.000001,而后面在运算反余弦函数时就会出现acosf(1.00001) == NaN

  q.normalize();

//对期望姿态四元数进行归一化,原因同当前姿态四元数

  qd.normalize();

  // calculate reduced desired attitude neglecting vehicle's yaw to prioritize roll and pitch

//计算当前姿态四元数对应的机体坐标系Z轴单位向量,在机载NED系下表示

  const Vector3f e_z = q.dcm_z();

//计算期望姿态四元数对应的机体坐标系Z轴单位向量,在机载NED系下表示

 const Vector3f e_z_d = qd.dcm_z();

//计算去除旋转误差后仅代表倾斜误差的四元数,计算公式如下:

在这里插入图片描述

  Quatf qd_red(e_z, e_z_d);

//无旋转运动时,直接赋值为期望四元数(这个判断条件我觉得是有问题的,以后再去细究吧):

  if (fabsf(qd_red(1)) > (1.f - 1e-5f) || fabsf(qd_red(2)) > (1.f - 1e-5f)) {
    // In the infinitesimal corner case where the vehicle and thrust have the completely opposite direction,
    // full attitude control anyways generates no yaw input and directly takes the combination of
    // roll and pitch leading to the correct desired yaw. Ignoring this case would still be totally safe and stable.
    qd_red = qd;

  }

//将旋转轴从N系转换到B系:
在这里插入图片描述

//结合当前姿态,我们可以得到仅代表倾斜运动的期望四元数:
在这里插入图片描述

//所以qd_red *= q是把上面两步骤合成了一步

  else {
    // transform rotation from current to desired thrust vector into a world frame reduced desired attitude
    qd_red *= q;
  }

//根据期望四元数和倾斜期望四元数可以得到代表旋转运动的期望四元数 :
在这里插入图片描述

  // mix full and reduced desired attitude
  Quatf q_mix = qd_red.inversed() * qd;

//根据旋转运动的性质,q_mix一定可以表示为(cos(α_mix/2),0,0,sin(α_mix/2))

  q_mix *= math::signNoZero(q_mix(0));
  // catch numerical problems with the domain of acosf and asinf
  q_mix(0) = math::constrain(q_mix(0), -1.f, 1.f);
  q_mix(3) = math::constrain(q_mix(3), -1.f, 1.f);

//限制旋转误差,最后结合倾斜运动和受限制旋转运动组成新的期望四元数:
在这里插入图片描述
在这里插入图片描述

qd = qd_red * Quatf(cosf(_yaw_w * acosf(q_mix(0))), 0, 0, sinf(_yaw_w * asinf(q_mix(3))));

//根据新四元数姿态期望计算四元数误差:
在这里插入图片描述

  // quaternion attitude control law, qe is rotation from q to qd
  const Quatf qe = q.inversed() * qd;

//根据实际意义选取姿态误差为:eq=2*sign(qe(0))*qe(1:3)

  // using sin(alpha/2) scaled rotation axis as attitude error (see quaternion definition by axis angle)
  // also taking care of the antipodal unit quaternion ambiguity
  const Vector3f eq = 2.f * math::signNoZero(qe(0)) * qe.imag();

//根据姿态误差计算期望角速度:

  // calculate angular rates setpoint
  matrix::Vector3f rate_setpoint = eq.emult(_proportional_gain);

//增加偏航角速度前馈:

  // Feed forward the yaw setpoint rate.
  // yaw_sp_move_rate is the feed forward commanded rotation around the world z-axis,
  // but we need to apply it in the body frame (because _rates_sp is expressed in the body frame).
  // Therefore we infer the world z-axis (expressed in the body frame) by taking the last column of R.transposed (== q.inversed)
  // and multiply it by the yaw setpoint rate (yaw_sp_move_rate).
  // This yields a vector representing the commanded rotatation around the world z-axis expressed in the body frame
  // such that it can be added to the rates setpoint.
  rate_setpoint += q.inversed().dcm_z() * yawspeed_feedforward;

//角速度期望输出限幅

  // limit rates
  for (int i = 0; i < 3; i++) {
    rate_setpoint(i) = math::constrain(rate_setpoint(i), -_rate_limit(i), _rate_limit(i));
  }

  return rate_setpoint;
}

总结

本篇内容对PX4中实现姿态控制器的代码进行了详细解读,经过算法公式的推导,代码的逐行分析,大家应该对PX4中多旋翼飞行器的姿态控制器设计与实现有了清晰的认识,不过纸上得来终觉浅,绝知此事要躬行,光看不练无异于纸上谈兵,大家可以在matlab中做做仿真,或者在搭建的飞控开发平台上根据自己的理解来实现姿态控制,在实战中感受飞控算法的魅力。

本篇文章首发于公众号:无人机系统技术。更多无人机技术相关文章请关注此公众号,有问题也可在公众号回复“加群”进入技术交流群进行交流。
在这里插入图片描述

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

开源飞控PX4姿态控制代码解析 的相关文章

  • ROS入门之话题消息的定义与使用

    1 定义msg文件 xff1a 在catkin ws src learning topic文件下新建msg文件夹并在文件夹下新建Person msg文件 msg文件中代码如下 xff1a string name uint8 sex uint
  • git为什么会有冲突

    看了百度很多回答 xff0c 觉得和实操有点出入 xff0c 记录一下个人理解 结论 xff1a 冲突的产生就是各分支修改的文件版本不一致 xff08 远程冲突同理 xff09 例 xff1a 分支 m 和分支 d 都有一个相同文件 61
  • 视觉SLAM十四讲:运动方程

    SLAM xff1a 同时定位和建图 xff08 Simultaneous Localization and Mapping xff09 希望机器人从未知环境的未知地点出发 xff0c 在运动过程中通过重复观测到的地图特征 xff08 比如
  • NeRF简介及nerf-pytorch的使用

    NeRF全称为Neural Radiance Field 神经辐射场 是2020年发表的论文 xff0c 论文名字为 NeRF Representing Scenes as Neural Radiance Fields for View S
  • SLAM如何定位与建图

    SLAM xff1a 同时定位和建图 xff08 Simultaneous Localization and Mapping xff09 机器人从未知环境中的未知地点出发 xff0c 在运动过程中通过重复观测到的地图特征 xff08 比如
  • OpenMV——串口通信+发送中心位置

    串口通信 OpenMV本质还是一个单片机 xff0c 可以通过调用pyb中的UART使用串口通信 xff0c 注意发送的数据类型为字符串 xff0c 可以通过json dumps 进行字符串转换 span class token keywo
  • liunx下rpm包mysql安装脚本

    目录 文章目录 前言 一 mysqlshell安装脚本 二 xff0c mysql 配置文件 前言 liunx下mysql安装脚本shell脚本 采用的版本时 mysql 5 7 28 xff0c rpm安装方式 shell安装脚本 xff
  • setTimeout与setInterval的坑以及优缺点

    转自 xff1a setTimeout与setInterval的坑以及优缺点 找寻的千寻 博客园 setInterval和setTimeout的缺陷和优势分析 F ZERO F的博客 CSDN博客 settimeout缺点 说到setTim
  • 登录功能app端的建立与实现

    选择使用Android文件的一些主要包装命名搭建 1 Layout存放布局界面的地方 xff0c values是存放图片和颜色 字体等 2 manifests体现层 61 61 代码 3 执行界面打开 lt application lt 登
  • 麻将胡牌算法(遍历+剪枝)

    麻将胡牌算法 xff08 遍历 43 剪枝 xff09 简介麻将胡牌算法及代码1 方法引入2 类型定义2 1 牌定义2 2 牌特征定义 3 计算胡牌3 1 检测十三幺牌型3 2 检测七小对牌型3 3 检测普通牌型胡牌3 3 1 检测所有可能
  • 接口报错Missing grant type

    错误详情 xff1a 原因 xff1a 缺少表单参数 xff1a grant type 但如果传递了该参数依旧报错则说明传递的数据格式有误 xff0c 需要修改数据格式 解决方式 xff1a 第一步 xff1a 设置数据格式 Content
  • 如何关闭vue-element-admin中的格式化校验

    1 找到根目录下的 eslintignore文件 xff0c 如下 xff1a 2 将该文件内的内容全部替换为 xff0c 如图所示 xff1a 3 删除node modules和package lock json文件 xff0c 重新运行
  • D435i问题及解决

    提问连接 https support intelrealsense com hc en us requests new 1 使用realsense viewer时 xff0c 如果在3D模式下观看 xff0c 需要打开stereo modu
  • ubuntu磁盘空间不足解决办法

    df h后发现 目录下空间很少 点击左下角 搜索disk 点击 disk usage 看各个目录下占用的空间 xff0c 删除空间 2 在ubuntu 使用Windows的磁盘空间 发现 media liao 软件 下还有空间 xff0c
  • instant-ngp简介及NeRF的使用

    英伟达实验室开源的instant ngp全称为Instant Neural Graphics Primitives xff0c 源码地址为https github com NVlabs instant ngp xff0c 可用于快速的训练N
  • Bad owner or permissions on /home/cxhpc/.ssh/config

    实测解决方案 xff1a 进入 home cxhpc ssh sudo chmod 600 config
  • D3.js学习指北--第三章应用,冒泡排序的可视化

    D3学习指北 第三章应用 xff0c 冒泡排序的可视化 前言 本章前面已经讲了D3选择操作 xff0c 以及选择后返回的选择集的操作 那么我们应用一下 xff0c 利用d3 js写一个冒泡排序的可视化 首先第一步 xff1a 分析需求 一个
  • STM32(CubeMax)基础配置

    对于刚刚接触HAL库的小伙伴来说 xff0c 每次对于基础部分都需要查阅视频去进行操作 xff0c 本文就是通过STM32F103C8T6模块进行基础配置 xff0c 其他单片机基本与之一致 1 SYS配置如下图所示 2 RCC配置如下图所
  • (一)ROS学习之搭建realsense d435相机工作环境

    注 xff1a 本教程是在RealSense SDK和ROS Kinetic已正确安装的情况下进行的 一 realsense ros安装 1 Create a catkin workspace mkdir p realsense rosws
  • (三)ROS学习之gazebo加载异常或者加载缓慢完美解决

    1 升级gazebo版本 在终端运行以下指令 sudo sh c 39 echo 34 deb http packages osrfoundation org gazebo ubuntu stable 96 lsb release cs 9

随机推荐

  • Docker 实例

    1 创建两个容器实例 xff1a docker01 和 docker02 要求 xff1a 1 xff09 docker01 运行在cpu0上 2 xff09 docker02 运行在cpu1上 3 xff09 测试docker01 和 d
  • subprocess执行命令,超时判断,数据量大被截断问题,进程中断。

    Python使用subprocess在本地 或者 其他远端机器上执行命令 防止命令执行时间过长导致一直无法退出的问题 防止命令输出内容过长 xff0c 实际拿到的数据被截断 xff0c 不全的问题 新增 进程中断 xff0c 键盘ctrl
  • 重启ubuntu报错——/dev/sda7:clean

    查看Ubuntu IP地址 打开终端中执行 xff1a ifconfig a命令即可 若无法进入终端界面 重启至这一界面时 xff1a 按e键 xff0c 进入如下界面 xff1a 找到红线部分 xff0c 在splash后面手动输入 no
  • 旋转目标检测:Exploring Complementary Strengths of Ivariant and Equivariant Representations for FSL(CVPR21)

    关键词 xff1a 小样本 xff0c 自监督 xff0c 变换不变性 xff0c 等变性 参考博客 xff1a https zhuanlan zhihu com p 354771341 论文原文下载 xff1a https arxiv o
  • 旋转目标检测:The KFIoU Loss for Rotated Object Detection(Under review in ICLR 2022)

    关键词 xff1a KFIoU 倾斜IoU SkewIoU 参考博客 xff1a https zhuanlan zhihu com p 447286823 论文原文下载 xff1a https openreview net pdf id 6
  • C++14中变量模版的使用

    C 43 43 14中的variable template 变量模版 用于定义一系列变量或静态数据成员 xff0c 语法如下 xff1a template lt parameter list gt variable declaration
  • 读书笔记——《一个人的朝圣》

    图书馆借出来的另一本宝藏 xff0c 一个人的朝圣 xff0c 带来一个人心境的平和 内容摘抄 xff1a 1 你每次都是这样 xff0c 一有人做一些你没做过的事 xff0c 你就忙不迭地说那是不可能做到的 2 他明白了 xff0c 在弥
  • python算法练习1

    题目一 xff1a 给一个乱序的整数数组 xff0c 请用冒泡排序的方式实现升序排列 函数的形参是一个数组 xff0c 函数的返回值为一个数组 输入 xff1a 5 4 3 2 1 输出 xff1a 1 2 3 4 5 span class
  • C语言——鸡兔同笼问题

    include lt stdio h gt int main int a b c d printf 34 head 34 scanf 34 d 34 amp a printf 34 feet 请输入偶数 34 scanf 34 d 34 a
  • Python 通过爬虫获取网页内容时去掉某一标签内容

    以这篇文章https finance sina com cn money smjj smdt 2020 08 12 doc iivhvpwy0527268 shtml为例 xff0c 在抓取文章内容时 xff0c 不抓取 今日直播 的模块内
  • cas单点登录(5.2)-使用cas-overlay-template搭建cas服务器

    在开始之前先介绍一下CAS 官网地址 xff1a https www apereo org Github地址 https github com apereo cas 介绍 CAS是Central Authentication Service
  • 海康ISAPI使用相关

    海康ISAPI使用相关 海康SDK对运行环境有要求 xff0c 只支持x86系统 xff0c ARM或者单片机等无法使用 可以使用海康提供的ISAPI接口协议对设备进行操控 1 接口验证使用Digest Auth 2 使用设备ip地址 43
  • 计算机网络习题(IP地址分类及CIDR划分方法)

    计算机网络习题 xff08 IP地址分类及CIDR划分方法 xff09 题目描述 xff1a 已知地址块中的一个地址是140 120 84 24 20 xff08 1 xff09 求这个地址块中的最小地址和最大地址 xff08 2 xff0
  • centos7 nvidia-smi命令很慢

    nvidia smi命令很慢 xff0c 长时间才有输出 sudo usr bin nvidia persistenced verbose 设置开机自启动 chmod 43 x etc init d rc local vim etc ini
  • PX4代码解析:振动分析

    本篇文章首发于公众号 xff1a 无人机系统技术 更多无人机技术相关文章请关注此公众号 一 前言 前面的文章主要都是一些理论知识为主 xff0c 很多读者朋友看了之后可能会有点枯燥 xff0c 里面很多公式看起来也比较晦涩 xff0c 今天
  • 如何学习飞控

    本篇文章首发于公众号 xff1a 无人机系统技术 更多无人机技术相关文章请关注此公众号 xff0c 有问题也可在公众号底部添加个人微信进行交流 无人机涉及哪些工作 自开公众号以来 xff0c 陆续有不少关注者提问怎么去学习无人机技术 xff
  • Python3中.pyd文件介绍

    pyd文件是用Python编写生成的动态链接库 xff0c 包含一个或多个Python modules xff0c 可以被其它Python代码调用 以下是 pyd的生成及调用测试 xff1a 通过conda创建虚拟环境Python Test
  • PX4姿态控制算法详解

    本篇文章首发于公众号 xff1a 无人机系统技术 更多无人机技术相关文章请关注此公众号 xff0c 有问题也可在公众号回复 加群 进入技术交流群进行交流 倾转分离 今天的内容我们来解析开源飞控软件PX4中关于多旋翼飞行器的姿态控制算法 首先
  • 我为什么不挣钱也要写公众号

    本篇文章首发于公众号 xff1a 无人机系统技术 更多无人机技术相关文章请关注此公众号 xff0c 有问题也可在公众号回复 加群 进入技术交流群进行交流 自开无人机系统技术这个公众号以来已经有半年之久了 xff0c 我是在今年一月份开的公众
  • 开源飞控PX4姿态控制代码解析

    本篇文章首发于公众号 xff1a 无人机系统技术 更多无人机技术相关文章请关注此公众号 xff0c 有问题也可在公众号回复 加群 进入技术交流群进行交流 本公众号将于9月11号联合电子工业出版社送出15本价值98元的 多旋翼飞行器设计与控制