Pixhawk学习10.2——多旋翼位置控制

2023-05-16

10.1中介绍了目标位置点的计算逻辑,知道下一时刻的目标位置后,飞控需要根据当前位置进行计算,依次得到期望速度,期望拉力矢量,期望姿态。至此就完成了多旋翼的位置控制。

1、期望速度计算

上篇计算得到期望位置之后,根据飞机当前位置,可知道位置差矢量。在位置速度串级PID中,位置环只采用了比例,速度环采用了PID。在这里插入图片描述

	/* run position & altitude controllers, if enabled (otherwise use already computed velocity setpoints) */
				if (_run_pos_control) {
					_vel_sp(0) = (_pos_sp(0) - _pos(0)) * _params.pos_p(0);
					_vel_sp(1) = (_pos_sp(1) - _pos(1)) * _params.pos_p(1);
				}
if (_run_alt_control) {
					_vel_sp(2) = (_pos_sp(2) - _pos(2)) * _params.pos_p(2);
				}

得到期望速度之后,主要进行了以下三步操作,用来规范真正的期望速度:

#限制最大水平速度
确保水平速度矢量和大小在限制范围内,对水平两个速度进行等比例缩小;

/* make sure velocity setpoint is saturated in xy*/
				float vel_norm_xy = sqrtf(_vel_sp(0) * _vel_sp(0) +
							  _vel_sp(1) * _vel_sp(1));

				if (vel_norm_xy > _params.vel_max(0)) {
					/* note assumes vel_max(0) == vel_max(1) */
					_vel_sp(0) = _vel_sp(0) * _params.vel_max(0) / vel_norm_xy;
					_vel_sp(1) = _vel_sp(1) * _params.vel_max(1) / vel_norm_xy;
				}

#限制最大垂直速度
确保垂直速度在限制范围内,对垂向速度进行限制。

/* make sure velocity setpoint is saturated in z*/
				if (_vel_sp(2) < -1.0f * _params.vel_max_up) {
					_vel_sp(2) = -1.0f * _params.vel_max_up;
				}

				if (_vel_sp(2) >  _params.vel_max_down) {
					_vel_sp(2) = _params.vel_max_down;
				}

#限制期望速度变化量(加速度)
对当前和之前的期望速度做差,限制其变化量,即限制加速度值。

// limit total horizontal acceleration
				math::Vector<2> acc_hor;
				acc_hor(0) = (_vel_sp(0) - _vel_sp_prev(0)) / dt;
				acc_hor(1) = (_vel_sp(1) - _vel_sp_prev(1)) / dt;

				if ((acc_hor.length() > _params.acc_hor_max) & !_reset_pos_sp) {
					acc_hor.normalize();
					acc_hor *= _params.acc_hor_max;
					math::Vector<2> vel_sp_hor_prev(_vel_sp_prev(0), _vel_sp_prev(1));
					math::Vector<2> vel_sp_hor = acc_hor * dt + vel_sp_hor_prev;
					_vel_sp(0) = vel_sp_hor(0);
					_vel_sp(1) = vel_sp_hor(1);
				}

				// limit vertical acceleration

				float acc_v = (_vel_sp(2) - _vel_sp_prev(2)) / dt;

				if ((fabsf(acc_v) > 2 * _params.acc_hor_max) & !_reset_alt_sp) {
					acc_v /= fabsf(acc_v);
					_vel_sp(2) = acc_v * 2 * _params.acc_hor_max * dt + _vel_sp_prev(2);
				}

				_vel_sp_prev = _vel_sp;

				_global_vel_sp.vx = _vel_sp(0);
				_global_vel_sp.vy = _vel_sp(1);
				_global_vel_sp.vz = _vel_sp(2);

2.期望拉力矢量计算

拉力矢量由期望速度和当前速度的差进行PID计算得到。

thrust_sp = vel_err.emult(_params.vel_p) + _vel_err_d.emult(_params.vel_d) + thrust_int;

得到期望拉力矢量之后,又需要进行以下三种操作得到最终的实际期望拉力矢量:
#确保升力大于最小值
确保拉力矢量的幅值不能小于最小拉力值,不至于飞机掉下去。

	/* limit min lift */
					if (-thrust_sp(2) < thr_min) {
						thrust_sp(2) = -thr_min;
						saturation_z = true;
					}

#保证飞机不超过最大倾斜角
限制最大倾斜角。利用Z向的拉力值乘以最大倾斜角的正切,得到最大水平速度。并根据实际的水平和速度的幅值等比例缩小水平两个速度。

/* limit max tilt */
						if (thr_min >= 0.0f && tilt_max < M_PI_F / 2 - 0.05f) {
							/* absolute horizontal thrust */
							float thrust_sp_xy_len = math::Vector<2>(thrust_sp(0), thrust_sp(1)).length();

							if (thrust_sp_xy_len > 0.01f) {
								/* max horizontal thrust for given vertical thrust*/
								float thrust_xy_max = -thrust_sp(2) * tanf(tilt_max);

								if (thrust_sp_xy_len > thrust_xy_max) {
									float k = thrust_xy_max / thrust_sp_xy_len;
									thrust_sp(0) *= k;
									thrust_sp(1) *= k;
									saturation_xy = true;
								}
							}
						}

#限制最大推力
如果拉力矢量的幅值大于最大拉力,那么让水平期望拉力为零,Z向拉力为拉力。

		if (-thrust_sp(2) > thr_max) {
								/* thrust Z component is too large, limit it */
								thrust_sp(0) = 0.0f;
								thrust_sp(1) = 0.0f;
								thrust_sp(2) = -thr_max;
								saturation_xy = true;
								saturation_z = true;

							} else {
								/* preserve thrust Z component and lower XY, keeping altitude is more important than position */
								float thrust_xy_max = sqrtf(thr_max * thr_max - thrust_sp(2) * thrust_sp(2));
								float thrust_xy_abs = math::Vector<2>(thrust_sp(0), thrust_sp(1)).length();
								float k = thrust_xy_max / thrust_xy_abs;
								thrust_sp(0) *= k;
								thrust_sp(1) *= k;
								saturation_xy = true;
							}

3.期望姿态计算

PIX中的期望姿态由期望拉力矢量和期望航向来计算。期望航向已经在路径规划时得到。
期望拉力矢量其实是指定了机体的期望Z轴,期望航向是指定了机体的期望Z轴。
即,将拉力矢量归一化,就是往姿态矩阵 的第三列。

/* desired body_z axis = -normalize(thrust_vector) */
						math::Vector<3> body_x;
						math::Vector<3> body_y;
						math::Vector<3> body_z;

						if (thrust_abs > SIGMA) {
							body_z = -thrust_sp / thrust_abs;

						} else {
							/* no thrust, set Z axis to safe value */
							body_z.zero();
							body_z(2) = 1.0f;
						}

将期望航向角通过三角函数变换在于姿态矩阵R_sp 的第三列叉乘就能得R_sp 的第一列。

/* vector of desired yaw direction in XY plane, rotated by PI/2 */
						math::Vector<3> y_C(-sinf(_att_sp.yaw_body), cosf(_att_sp.yaw_body), 0.0f);

						if (fabsf(body_z(2)) > SIGMA) {
							/* desired body_x axis, orthogonal to body_z */
							body_x = y_C % body_z;

							/* keep nose to front while inverted upside down */
							if (body_z(2) < 0.0f) {
								body_x = -body_x;
							}

							body_x.normalize();

再通过叉乘R_sp 的第三列和第一列,就能得到完整的姿态矩阵。

		/* desired body_y axis */
						body_y = body_z % body_x;

						/* fill rotation matrix */
						for (int i = 0; i < 3; i++) {
							R(i, 0) = body_x(i);
							R(i, 1) = body_y(i);
							R(i, 2) = body_z(i);
						}

至此,就得到了期望的姿态矩阵,可将R转换为四元数,或者直接求解水平期望姿态角。

/* copy quaternion setpoint to attitude setpoint topic */
						matrix::Quatf q_sp = R;
						memcpy(&_att_sp.q_d[0], q_sp.data(), sizeof(_att_sp.q_d));
						_att_sp.q_d_valid = true;

						/* calculate euler angles, for logging only, must not be used for control */
						matrix::Eulerf euler = R;
						_att_sp.roll_body = euler(0);
						_att_sp.pitch_body = euler(1);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pixhawk学习10.2——多旋翼位置控制 的相关文章

  • Lua性能优化—Lua内存优化

    原文链接https blog uwa4d com archives usparkle luaperformance html 这是侑虎科技第236篇原创文章 xff0c 感谢作者舒航供稿 xff0c 欢迎转发分享 xff0c 未经作者授权请
  • Jetson Xavier NX(emmc)烧录系统时可能遇到的问题(避坑)

    目录 Ununtu18虚拟机无法联网 当NX接上电源后 xff0c 指示灯没有亮 xff08 不工作 xff09 在登陆SDK时 xff0c 可能会出现卡在初始界面的情况 在烧录镜像时 xff0c 可能会卡在该处没有变化 Ununtu18虚
  • 互斥量、条件变量与pthread_cond_wait()函数的使用,详解(一)

    1 首先pthread cond wait 的定义是这样的 The pthread cond wait and pthread cond timedwait functions are used to block on a conditio
  • STAR法则写简历

    STAR 法则是在面试 xff0c 求职 xff0c 写简历时候的常用利器 虽然常用 xff0c 但是我想知道的人一定很少很少 xff0c 不然为什么那么多人面试的时候犯那么低级的错误呢 xff1f STAR法则无法帮你提高你的实力 xff
  • 论文发表为什么不可以一稿多投呢

    论文发表为什么不可以一稿多投呢 很多作者在担心投一家杂志会被拒稿 xff0c 就会选择一篇稿件投多家期刊的方法 xff0c 大家应该或多或少都听过不能一稿多投 xff0c 但具体原因是什么大家知道吗 一稿多投会有什么后果 一稿多投是自稿件发
  • ROS下视频消息发布与订阅

    https download csdn net download v7xyy 10869743 下下来后 1 发布视频消息 rosrun video transport tutorial video publisher xff08 节点 c
  • ros中标志位设计(4)

    由于需要涉及控制权的交接事件 xff0c 需要通过标志位的方式进行设计 首先需要自定一个标志位的信息在ros中用于标志位信息的发布 下面是用于标志位的头文件Flag h Generated by gencpp from file xx ms
  • 全球最贵域名Sex.com将再度出售

    金融时报消息称 xff0c Sex com域名曾位居全球最贵域名前例 xff0c 四年前 xff0c 它以1400万美元成交 xff0c 不过 xff0c 买下此域名的公司面临破产 xff0c 因此Sex com将再度拿来出售 Sex co
  • 微信消息推送消息加解密(golang)

    本篇介绍如何使用golang对微信消息推送进行加解密 xff0c 后续会补充 xff0c 目前先写个原理 xff0c 大概自己看一下 xff0c 其他的自己应该也能写 老套路 xff0c 分为三步 xff0c 为啥写 xff0c 教程 xf
  • C++数据可视化MathGL使用简示

    C 43 43 数据可视化 MathGL 使用指南 效果演示 搭建环境与依赖项 Windows10 64位 VS2017 Zlib1 2 11 xff08 已编译好的可用版本已集成在我后面的项目链接里 xff09 libpng1 6 37
  • 飞思卡尔智能车——舵机及PID控制

    本篇博客已迁移至 xff1a 飞思卡尔智能车 舵机及PID控制 请帮个忙 xff0c 去新地址访问 xff1a xff09 舵机 xff1a 小车转向的控制 机构 也就是控制小车的转向 它的特点是结构紧凑 易安装调试 控制简单 大扭力 成本
  • Github Actions + Docker实现HTML静态前端页面CICD部署

    使用 Github Actions 可以实现 CICD 自动构建部署 简单来说就是你只需要执行 git push 命令 xff0c 你服务器上的网页就可以自动部署更新 xff0c 无需你执行编译指令 前置环境 服务器一台 xff0c 我的是
  • Ubuntu显示“submodule(s) are missing“或“子模块未对路径注册“解决方案

    最近测试openMVG的三维重建效果 xff0c 于是在github下克隆openMVG的库 xff0c git clone过程成功进行 xff0c 但是在build文件夹下cmake的时候error occured 错误显示 34 sub
  • 互斥量、条件变量与pthread_cond_wait()函数的使用,详解(二)

    1 Linux 线程 进程与线程之间是有区别的 xff0c 不过Linux内核只提供了轻量进程的支持 xff0c 未实现线程模型 Linux是一种 多进程单线程 的操作系统 Linux本身只有进程的概念 xff0c 而其所谓的 线程 本质上
  • 网易视频云:流媒体服务器原理和架构解析

    网易视频云 是网易公司旗下的视频云服务产品 xff0c 以Paas服务模式 xff0c 向开发者提供音视频编解码SDK和开放API xff0c 助力APP接入音视频功能 今天 xff0c 网易视频云的技术专家给大家分享一篇流媒体技术性文章
  • MATLAB语言中int函数

    在MATLAB语言中 xff0c 求符号函数的定积分是使用int函数 xff0c 其调用格式如下 xff1a int F x a b a表示定积分的下限 xff1b b表示定积分的上限 xff1b 上式表示 xff0c 被积函数F在区间 a
  • matlab中的subs函数用法

    matlab中subs 是符号计算函数 xff0c 表示将符号表达式中的某些符号变量替换为指定的新的变量 xff0c 常用调用方式为 xff1a subs S OLD NEW 表示将符号表达式S中的符号变量OLD替换为新的值NEW 下面具体
  • Android配置临时ipv6地址

    Google公网DNS 2001 4860 4860 64642001 4860 4860 64 ifconfig wlan0 inet6 add IPV6ADDR ifconfig wlan0 inet6 add 2001 4860 48
  • MFC:pic控件的矩形的left、right、top、bottom 坐标位置

    CRect rect 然后 获取矩形控件 那么这个矩形控件的左上 和右下 分别对应 xff0c left xff0c top xff1b right xff0c bottom left xff0c top为左上角的点坐标 right xff
  • ubuntu下对sd卡 分区和格式化 挂载sd卡

    一 sd卡分区和格式化 1 查看自己的设备号 命令 xff1a mount 可以看到 最后一行即为sd卡的挂载目录 2 umount 由于sd卡插上之后会自动mount xff0c 所以需要unmout 命令 xff1a umount 路径

随机推荐

  • linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁

    Linux下提供了多种方式来处理线程同步 xff0c 最常用的是互斥锁 条件变量 信号量和读写锁 下面是思维导图 xff1a 一 互斥锁 xff08 mutex xff09 锁机制是同一时刻只允许一个线程执行一个关键部分的代码 1 初始化锁
  • IMX头部详细解析之一 头部组成

    镜像组成 完整的imx镜像由以下四部分组成 xff1a Image Vector Table xff08 映像向量表 xff09 Boot Data xff08 启动数据 xff09 Device Configuration Data xf
  • IMX头部详细解析之二 头部生成工具

    前言 在之前的文章中 xff0c 介绍了imx的头部组成部分 xff0c 本文将介绍u boot如何通过mkimage工具构建imx的头部 正文 在imx6平台上进行裸机程序开发时 xff0c 通常需要添加imx头部信息 xff0c 才能使
  • Linux命令查询工具 O-LinuxCmd

    Linux命令查询工具 O linuxCmd 前言 一直以来 xff0c 遇到不熟悉的Linux命令都会直接百度 xff0c 找到一些命令查询网站再进行查询 xff0c 比如这个man linuxde net网站就很不错 虽然加入收藏夹就能
  • 嵌入式Linux利用ppp实现4G模块联网

    之前做项目时需要用到SIM7100模块 xff0c 便快速了解下ppp拨号 xff0c 实现了功能 xff0c 但是功能虽然实现了 xff0c 却依然有许多疑问 xff0c 这段时间有点时间 xff0c 打算更加详细的研究下 编译ppp2
  • O-ComTool V2.0.0串口调试工具

    O ComTool V2 1 0更新 xff0c 点击访问 O ComTool V2 0 0 简介 本次更新带来了 船新 的串口助手 xff0c 相较于V1 0 0版本 xff0c 代码重构 xff0c 添加了更多实用功能 xff0c 如
  • Marvell交换芯片88E6321/88E6320驱动总结-硬件篇

    芯片特性 Marvell 88E6321 88E6320 是一个7 Port千兆以太网交换芯片 支持最新的IEEEE802 1 Audio Video Bridging标准 芯片包含两个10 100 1000三速以太网收发器 xff08 P
  • Marvell交换芯片88E6321/88E6320驱动总结-寄存器篇

    由于我在项目中将该芯片作为PHY和SERDES使用 xff0c 因此本文内容主要还是围绕PHY和SERDES的相关功能 xff0c 至于其他功能则没有进行深入研究 工作模式 在之前的硬件篇中有提到 xff0c 该芯片有两种寻址模式 xff1
  • 更新 O-ComTool V2.1.0 串口调试助手

    FBI再次WARNING 测试时间较短 xff0c 有问题留言反馈哟 xff01 本次更新如下 实现更加人性化的暂停显示 上一版本中 xff0c 点击暂停显示时间过久 xff0c 就会出现卡顿的现象 xff0c 现在舍弃原来的方法 xff0
  • 什么是PN结

    FBI WARNING xff1a 本文是个人对PN结的理解 xff0c 若有错误 xff0c 望不吝赐教 xff0c 谢谢 xff01 二极管 三极管作为电路中的常见元件 xff0c 了解其工作原理是非常必要的 xff0c 但是在此之前
  • struct termios结构体详解

    一 数据成员 termios 函数族提供了一个常规的终端接口 xff0c 用于控制非同步通信端口 这个结构包含了至少下列成员 xff1a tcflag t c iflag 输入模式 tcflag t c oflag 输出模式 tcflag
  • PISSTV 树莓派慢扫描电视

    连接硬件 硬件 xff1a 树莓派 有驱动的摄像头 调试时需要usb wifi 配置树莓派 配置树莓派时要开启树莓派摄像头的支持 因为需要安装软件 xff0c 将树莓派连接到外网 测试摄像头拍照 使用raspistill命令进行拍照 ras
  • PID控制参数整定(调节方法)原理+图示+MATLAB调试

    序 首先最重要的是了解每个参数调节了系统响应的那些属性 xff0c 通过观察响应从而调节参数改变属性 PID的作用概述 xff1a 1 P产生响应速度和力度 xff0c 过小响应慢 xff0c 过大会产生振荡 xff0c 是I和D的基础 2
  • 关于VSCODE的插件 一

    官方API文档 1 要学好TypeScript 官方教程 1 1TypeScript是一门弱类型语言 强类型和弱类型主要是站在变量类型处理的角度进行分类的 这些概念未经过严格定义 xff0c 它们并不是属于语言本身固有的属性 xff0c 而
  • Pixhawk学习1——CMakeList.txt的解析

    在PX4的工程文件中 xff0c src modules下是具体的飞控代码 里面主要包含了传感器采集 姿态结算 姿态控制 xff0c 位置结算 位置控制等程序模块 在进行二次开发时 xff0c 需要添加的模块也是在这个文件夹里 每个文件夹里
  • Pixhawk学习2——uORB微对象请求代理及规则

    在Pixhawk中 xff0c 所有的功能被独立以进程模块为单位进行实现并工作 而每个进程模块都有一个 xff08 或多个 xff1f xff09 主题信息topic xff08 topic可以在Firmware msg里查看到所有的可使用
  • Pixhawk学习4——Commander相关分析

    Commander文件夹中的内容的作用主要为Pixhawk飞行模式的切换 该段程序会根据遥控器上的开关状态以及飞机飞行状态和各传感器性能状态进行判断 xff0c 最终实现飞行模式的切换 飞行模式切换主要涉及到以下几个文件 xff1a src
  • Pixhawk学习7——位置解算

    Pixhawk的位置解算分为两部分 xff0c 第一部分主要为传感器的数据获取 xff0c 而该部分最主要的就是GPS数据的提取 第二部分为与惯性器件之间的组合导航 组合导航的好处我就不用多说了 Pixhawk代码中目前主要有两处组合导航的
  • Pixhawk学习9——固定翼位置控制(L1控制+TECS总能量控制)

    本篇博客本来没有在之前的计划中 但由于最近项目上遇到了固定翼轨迹控制的一些问题 xff0c 所以就结合pix的程序学习总结了一下 不同于旋翼 xff0c 固定翼要实现位置变化必须得有一个轨迹变化过程 xff0c 因为它不像旋翼那样可以直接调
  • Pixhawk学习10.2——多旋翼位置控制

    10 1中介绍了目标位置点的计算逻辑 xff0c 知道下一时刻的目标位置后 xff0c 飞控需要根据当前位置进行计算 xff0c 依次得到期望速度 xff0c 期望拉力矢量 xff0c 期望姿态 至此就完成了多旋翼的位置控制 1 期望速度计