一直没看的无人机定高

2023-05-16

除了定高的部分,其他没看的还有一些控制函数。

定高的原理的话,也是利用了两级pid,

按照原本的理解,从外环开始看的话,反馈高度比较容易获得,就是激光测距得到的高度。期望高度好像无法得到。内环的话,期望速度是外环的输出,实际速度不知道怎么测得的,应该是高度的微分,等下仔细看看。

说期望高度“无法得到”,是因为没有必要,或者说我们通常不这么做。

首先是因为我们通常不使用定高在某个高度这个功能(吧),而是通常利用一键起飞,飞起来后再控制无人机能够按照一定的速度,去上升和下降。

然后从控制效果的角度看,如果按照我们通常的两级pid的控制思路:期望高度是我们给定的高度,反馈高度是我们测得的高度,利用pid可以得到期望速度,再利用这个期望速度结合实际速度,可以得到我们应得的加速度,也就是电机输出量。这也许可以达到定高的目的(而且是在不考虑最初期望高度和反馈速度的巨大偏差可能带来的不稳定的情况下),但会使我们丧失对飞机运动的控制:因为我们常常需要飞机上升或者下降,通常这个需求是在控制中被作为期望速度输入。但看上述的控制过程,我们会发现期望速度会由外环给出,我们不能对它赋值以实现控制。
这种情况下想要实现飞机的上升和下降,就只能去改变飞机的期望高度,而且我们很难去控制它的速度,这当然是我们不想要看到的。

为什么角度环没有遇到这种问题?这是一个较为细微的概念,对于初学者对于控制的原理和过程不明确,就不太容易理解。原因在于,我们对无人机的控制需求大体只有转向、左右、前后、上下移动,这也是遥控器上的那两个东西所能控制的部分。

我们实现前后左右移动,也就是想要飞机达到我们期望的前后左右方向的速度,只要使飞机的pitch和roll保持固定的角度就可以,想要前进,就让pitch增大,而且想要前进的速度越大,pitch就要越大。因此在角度环,我们外环是角度,用期望速度换算成期望角度、内环是角速度,得到电机输出量,就可以实现稳定或者移动。

但上下就不同了。我们要想实现一定的上下速度,速度本身就是目标值。对应角度环的话,这个速度应该对应角速度。

那问题来了,为什么我们不直接使用一个环呢?只用速度环按道理来讲就可以实现以指定速度上下移动了吧。原因就在于。。。还不知道怎么去表述,但原因之一应该跟起飞降落有关。

接下来看代码:
对于高度控制的头文件,定义了如下函数,内容很简单:
在这里插入图片描述
高度环控制和pid初始化、高度速度环控制和pid初始化
以及自动上升下降任务

我们先看这个串级pid:
参数初始化就不说了,其实也不是很懂。

对于外环:

Auto_Take_Off_Land_Task(1000*dT_s);

先调用了自动起飞/降落任务,

fs.alt_ctrl_speed_set = fs.speed_set_h[Z] + auto_taking_off_speed;

这个 fs.alt_ctrl_speed_set速度,就是我们的实际期望速度,为什么叫实际期望速度?就是说它是由两个速度相加:
1、 fs.speed_set_h[Z]
在这里插入图片描述
这个速度是程序或者用户对飞机的控制指令,包括那三个东西相加。

2、auto_taking_off_speed

一键起飞功能给出的速度,等下详细看一键起飞这些功能。

接下来:

loc_ctrl_2.exp[Z] += fs.alt_ctrl_speed_set *dT_s;
loc_ctrl_2.exp[Z] = LIMIT(loc_ctrl_2.exp[Z],loc_ctrl_2.fb[Z]-200,loc_ctrl_2.fb[Z]+200);
loc_ctrl_2.fb[Z] = (s32)wcz_hei_fus.out;/

对期望高度和反馈高度赋值。

if(fs.alt_ctrl_speed_set != 0)
{
	flag.ct_alt_hold = 0;
}

如果此时的期望速度不为零,那么也就是说还在上升或者下降,那么这个标志为就置零,也即是说现在不是在定高状态。

else
{
	if(ABS(loc_ctrl_1.exp[Z] - loc_ctrl_1.fb[Z])<20)
	{
		flag.ct_alt_hold = 1;
	}
}

否则,期望速度位为零了,也就是说需要高度不会再变了,同时对于位置环,期望速度与实际速度差别很小了,那么就置位这个标志位。

if(flag.taking_off == 1)
{
	PID_calculate( dT_s,            
					0,				
					loc_ctrl_2.exp[Z],			
					loc_ctrl_2.fb[Z],		
					&alt_arg_2, 
					&alt_val_2,	
					100,
					0								
					 );
}
else
{
	loc_ctrl_2.exp[Z] = loc_ctrl_2.fb[Z];
	alt_val_2.out = 0;		
}

如果taking_off标志位有效,那么说明飞机已经起来了,那么就执行pid,否则,认为飞机在地上,也就没有速度。期望值等于反馈值,所需速度也就为0.

对于内环:

loc_ctrl_1.exp[Z] = 0.6f *fs.alt_ctrl_speed_set + alt_val_2.out;

w_acc_z_lpf += 0.1f *(imu_data.w_acc[Z] - w_acc_z_lpf); 

loc_ctrl_1.fb[Z] = wcz_spe_fus.out + Ano_Parame.set.pid_alt_1level[KD] *w_acc_z_lpf;

反馈和期望速度赋值,注意这里的期望速度,两个值相加,应该是用于修正。

PID_calculate( dT_s,          
				0,				
				loc_ctrl_1.exp[Z],				
				loc_ctrl_1.fb[Z] ,			
				&alt_arg_1, 
				&alt_val_1,	
				100,
				(THR_INTE_LIM *10 - err_i_comp )*out_en									
				 );

pid就略了。

if(flag.taking_off == 1)
{
	LPF_1_(1.0f,dT_s,THR_START *10,err_i_comp);//err_i_comp = THR_START *10;			
}
else
{
	err_i_comp = 0;
}

如果起飞了,那么 err_i_comp就赋值这个,否则,飞机在地上,err_i_comp就为0。
这个err_i_comp应该也是修正用的。

loc_ctrl_1.out[Z] = out_en *(alt_val_1.out + err_i_comp);

loc_ctrl_1.out[Z] = LIMIT(loc_ctrl_1.out[Z],0,MAX_THR_SET *10);	

mc.ct_val_thr = loc_ctrl_1.out[Z];

飞行时out_en才为1,地上时为0.
也就是说是否把油门值输出,取决于当前taking_off状态,因为即使在地上时,没有alt_val_2.out,但仍然有fs.alt_ctrl_speed_set

接下来就是看看非常混乱的一键起飞/降落了。。。。
非常混乱,是因为这个相关的代码有好几个,不知道怎么控制的,尝试分析一下。。

先是注意到了高度控制的那个文件里,有一个自动起飞降落任务:

Auto_Take_Off_Land_Task

进去之后还有一个一键起飞降落任务:

one_key_take_off_task

先看这个一键起飞任务:

void one_key_take_off_task(u16 dt_ms)
{
	if(one_key_taof_start != 0)
	{
		one_key_taof_start += dt_ms;
		
		
		if(one_key_taof_start > 1400 && flag.motor_preparation == 1)
		{
			one_key_taof_start = 0;
				if(flag.auto_take_off_land == AUTO_TAKE_OFF_NULL)
				{
					flag.auto_take_off_land = AUTO_TAKE_OFF;

					flag.taking_off = 1;
				}
			
		}
	}
	//reset
	if(flag.unlock_sta == 0)
	{
		one_key_taof_start = 0;
	}

}

对one_key_taof_start进行判断,如果不是0,那就++,加到1400了,同时电机准备好了,就把one_key_taof_start清零。如果此时起飞降落标志位为起飞无效,那么就把状态改为起飞,taking _off=1。
如果没解锁,那么one_key_taof_start永远是0,无法累计。

也就是说,解锁之后等待1.4s,且状态为起飞无效,那么就把状态设置为起飞。

再看上一个任务:自动起飞降落任务
先执行了一键起飞任务,然后判断:

if(flag.unlock_sta)
{
	if(flag.taking_off)
	{	
		if(flag.auto_take_off_land == AUTO_TAKE_OFF_NULL)
		{
			flag.auto_take_off_land = AUTO_TAKE_OFF;		
		}
	}

}
else
{
	auto_taking_off_speed = 0;	
	flag.auto_take_off_land = AUTO_TAKE_OFF_NULL;	
}

如果解锁,且taking _off有效,那么如果起飞无效,就改成有效。
否则,没有解锁,auto_taking_off_speed恒为0,起飞设置为无效。

if(flag.auto_take_off_land ==AUTO_TAKE_OFF)
{

	s16 max_take_off_vel = LIMIT(Ano_Parame.set.auto_take_off_speed,20,200);
	take_off_ok_cnt += dT_ms;
	auto_taking_off_speed = AUTO_TAKE_OFF_KP *(Ano_Parame.set.auto_take_off_height - wcz_hei_fus.out);

	auto_taking_off_speed = LIMIT(auto_taking_off_speed,0,max_take_off_vel);
	

	if(take_off_ok_cnt>=5000 || (Ano_Parame.set.auto_take_off_height - loc_ctrl_2.exp[Z] <2))
	{
		flag.auto_take_off_land = AUTO_TAKE_OFF_FINISH;			
	}

	if(take_off_ok_cnt >2000 && ABS(fs.speed_set_h_norm[Z])>0.1f)
	{
		flag.auto_take_off_land = AUTO_TAKE_OFF_FINISH;
	}

}

如果自动起飞有效了,那么设置自动起飞速度。自动起飞流程有两个退出条件:
1、自动起飞流程运行的时间大于5s,或者满足高度。
2、自动起飞流程运行的时间大于2s,且用户在控制油门。
满足这两个条件之一,都认为自动起飞已经完成。

else 
{
	take_off_ok_cnt = 0;		
	if(flag.auto_take_off_land ==AUTO_TAKE_OFF_FINISH)
	{
		auto_taking_off_speed = 0;			
	}		
}

否则,自动起飞无效(还没飞或者已经会玩),就不计数。
如果已经飞完,那么把自动速度设为零。

如果状态是自动下降,就给一个自动下降速度。

if(flag.auto_take_off_land == AUTO_LAND)
{
	auto_taking_off_speed = -(s16)LIMIT(Ano_Parame.set.auto_landing_speed,20,200);
}

除此之外还有一个一键起飞函数:

one_key_take_off()

内容比较短:

void one_key_take_off()
{
	if(flag.unlock_err == 0)
	{	
		if(flag.auto_take_off_land == AUTO_TAKE_OFF_NULL && one_key_taof_start == 0)
		{
			one_key_taof_start = 1;
			flag.unlock_cmd = 1;
		}
	}
}

上述这三个有控制关系,一般来讲,只要调用函数one_key_take_off(),且已经解锁了,一键就可以起飞。

嗯,飞行就讲到这里,还有一个问题就是,期望高度如何去设定,等看看遥控器程序再回来解答。接下来的任务就是如何编写控制函数了。。。orz会不会太难了啊唉

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

一直没看的无人机定高 的相关文章

  • LoRa关键参数 1、扩频因子(SF) 2、编码率(CR) 3、信号带宽(BW) 4、LoRa信号带宽BW、符号速率Rs和数据速率DR的关系 5、

    LoRa 学习 xff1a LoRa 关键参数 xff08 扩频因子 xff0c 编码率 xff0c 带宽 xff09 的设定及解释 1 扩频因子 xff08 SF xff09 2 编码率 xff08 CR xff09 3 信号带宽 xff
  • MarkDown的语法

    使用MarkDoown时应该注意些什么呢 目录 一 添加标题 二 引用代码块 三 嵌入图片 1 本地图片 2 互联网图片 四 快捷键使用 五 分界线的使用 一 添加标题 在文字前加入相应数量的 一级标题 二级标题 三级标题 四级标题 五级标
  • python试爬李毅吧贴子标题,爬虫最初级

    注 xff1a 以下所有python代码均运行于2 7 0 最近想抓点数据存起来 xff0c 开始捣鼓python 爬虫技术以前没接触过 xff0c 这一回就当练手 xff0c 从零开始 xff0c 从最原始的方式开始 先定个小目标 xff
  • Activity的生命周期

    图来自百度百科 onCreate 启动activity时被调用 xff0c 用于进行初始化操作 xff08 加载布局 绑定事件等 xff09 xff0c 不应在onCreate 中做过多的不必要操作 xff0c 避免造成打开activity
  • Activity的启动模式

    以下为读书笔记 xff1a 实际项目中 xff0c 我们要通过特定的需求 xff0c 为每个活动指定恰当的启动模式 Android一共有4种启动模式 xff1a standard singleTop singleTask singleIns
  • PID参数 Ziegler-Nichols基于时域响应曲线的整定 反应曲线法

    PID控制器是工业过程控制中广泛采用的一种控制器 xff0c 其中 xff0c P I D分别为比例 xff08 Proportion xff09 积分 xff08 Integral xff09 微分 xff08 Differential
  • 郑学坚《微型计算机原理及应用》考点精讲 36讲

    链接 xff1a https pan baidu com s 12 vGBRrjOd UtO8P4e9bow 提取码 xff1a tqmp 当初考研时买的网课 xff0c 现在也用不着了 xff0c 赠与有缘人 书籍记录着别人多年时光总结出
  • 几种常用排序算法

    排序算法代码如下 xff1a void Sort Algorithm Bubble Sort int amp nums const int len bool haschange 61 true for int i 61 0 i lt len
  • 四旋翼姿态解算

    代码思路如下 xff1a 姿态解算 void IMU update float dT imu state st state float gyr VEC XYZ s32 acc VEC XYZ s16 mag val VEC XYZ imu
  • 树莓派4B-基于MCP2515的CAN通信过程记录篇

    本文主要记录使用树莓派4B xff0c 通过外接MCP2515模块来实现CAN通信 xff0c 使用基于Can utils实现CAN消息的收发 准备工作 xff1a 树莓派MCP2515模块杜邦线若干 知乎上一篇较为详细的参考 xff0c
  • nuxt踩坑集

    目录结构 assets 资源文件 用于组织未编译的静态资源如 LESS SASS或 JavaScript components 组件 layouts page 模板页面 xff0c 默认为 default vue可以在这个目录下创建全局页面
  • 记录个人在安装D435i驱动时出现的问题及解决方案

    目录 1 驱动安装 xff1a 2 启动Intel RealSense Viewer后报错No Frames Recevied 3 Record时报错Error opening file 1 驱动安装 xff1a 参考这篇博客 xff1a
  • 深度学习常见的优化算法

    文章目录 1 梯度下降算法 xff08 batch gradient descent BGD 2 随机梯度下降法 xff08 Stochastic gradient descent SGD 3 小批量梯度下降 Mini batch grad
  • vscode如何链接github

    1 首先安装配置好vscode xff1a https code visualstudio com download 然后下载git xff1a https git scm com download 根据自己的电脑选择相应的版本的下载就好了
  • 串口(uart)开发流程

    UART概述 UART全称 xff0c Universal Asynchronous Receiver and Transmitter UART xff0c 一般是每个单片机或开发板必备的一个功能模块 xff0c 可以用来调试 xff0c
  • *33.硬中断和软中断是什么?区别?

    1 硬中断 硬件中断 像磁盘 xff0c 网卡 xff0c 键盘 xff0c 时钟等 2 软中断 软件中断 进程产生 区别 xff1a xff08 产生机制 处理顺序 可否屏蔽 中断信号由来 xff09 1 软中断的发生的时间是由程序控制的
  • gazebo学习时遇到的问题(PX4篇)

    最近在研究如何使用UAV xff0c 由于是初学者 xff0c 不好直接上手实体无人机 xff0c 因此考虑通过在gazebo中模拟的方式进行一下无人机的简单使用模拟 xff0c 于是了解到了PX4这个东西 xff0c 他不仅支持固件写入
  • 阿里云服务器的搭建和部署(小白教程)

    阿里云服务器的搭建和部署 xff08 小白教程 xff09 一 购买服务器二 管理云服务器三 环境配置1 JDK的配置与下载2 tomcat的配置与下载3 MySQL的安装与配置 四 外网访问服务器 个人推荐阿里云 因为里面有一个大学生的云
  • 一篇带你搞懂Python3 中的 def __init__

    在学习python 100 days时 xff0c 在面向对象编程基础的那一块 xff0c 封装一个class时 xff0c 突然出现def init 的方法 xff0c 刚开始时 xff0c 对他的理解很模糊 xff0c 为什么定义一个类

随机推荐

  • 时间序列异常检测综述

    1 Introduction 时序异常检测几个可以运用的点 xff1a 1 欺诈检测 2 工业数据检测 简介一下 xff1a 异常检测很久之前就有了 最早可以追溯到 J Fox 1972 Outliers in Time Series Jo
  • Linux基础----Makefile(1)

    前言 刚开始学习Linux xff0c 这些那真的是新知识 xff0c 由于感觉将来FPGA的学习会越来越靠近软件的方向发展 xff0c 所以觉得有必要好好地学习一下嵌入式的东西 xff0c 因此有必要把学习的过程记录下来 xff0c 方便
  • 【OpenCV】ChArUco标定板角点的检测Detection of ChArUco Corners

    opencv3 4 15源文档链接 link ChArUco标定板角点的检测 GoalSource codeCharuco板创建ChArUco板检测ChArUco姿势估计 ArUco标记和板的快速检测和多功能性是非常有用的 然而 xff0c
  • 错误 MSB3721

    错误 MSB3721 命令 C Program Files NVIDIA GPU Computing Toolkit CUDA v10 2 bin nvcc exe gencode 61 arch 61 compute 30 code 61
  • 倒立摆状态反馈控制——分析、建模与仿真(matlab)

    倒立摆状态反馈控制 引言 倒立摆是机器人学中一个非常重要的模型 xff0c 火箭 导弹 独轮车 双足机器人 四足机器人 xff0c 基本都是倒立摆的变形 问题描述 关于倒立摆的问题描述如下 xff1a 如图所示的倒立摆系统 摆的关节连接在一
  • docker pull rabbitmq:management 怎样指定版本

    docker pull rabbitmq 3 8 1 management
  • git 命令学习

    git 命令学习 git clone https github com zhaji01 notes git 克隆远程仓库 git status 本地仓库状态 git add lt file gt 把修改 xff08 包括创建 修改 删除 解
  • 【实例记录】在ubuntu上运行python实现与单片机多线程串口通信

    文章目录 工具步骤 工具 工具 xff1a 自己电脑双系统的ubuntu18 04 单片机esp8266 一个usb转ttl模块 xff0c ubuntu上已经下载了python的3 6和pip xff0c 还需要pip install s
  • 【过程记录 】windows和ubuntu两台电脑局域网进行socket通信收发数据和传输文件

    实验图片和前期准备 xff1a ubuntu作为服务端 xff0c windows客户端传输数据和文件 xff1a windows作为服务端 xff0c ubuntu作为客户端 xff1a 实验图片和前期准备 xff1a 服务端发送和接受i
  • 过程记录 yolov3目标检测输出目标坐标和原图物体像素坐标比较

    设备 xff1a jetsonnano B01 一个usb广角摄像头 语言为python 库为opencv 框架pytorch 大家都知道yolov3的坐标变换过程比较复杂 xff0c 大概要经过图片缩放 xff0c 对数空间变换等等 xf
  • Rt-Thread学习笔记-----信号量(五)

    线程间同步 1 什么是线程间同步 xff1f 同步是指按预定的先后次序进行运行 xff0c 线程同步是指多个线程通过特定的机制来控制线程之间的执行顺序 xff0c 也可以说是在线程之间通过同步建立起执行顺序的关系 xff0c 如果没有同步
  • C++类和对象——空指针访问成员函数

    C 43 43 中空指针也是可以访问成员函数的 xff0c 但是也要注意有没有用到this指针 xff1b 如果用到this指针 xff0c 需要加以判断保证代码的健壮性 span class token macro property sp
  • nodejs实现简单的自动化部署

    如题 xff0c nodejs通过码云提供的web hooks实现简单的服务器自动部署 大致流程 xff1a 1 通过码云提供的web hooks xff0c 创建一个request通过后的回调接口 xff08 说白了就是配置一个码云审批通
  • 2022届春招实习面经(CV岗)——offer经

    已拿offer公司 xff1a 腾讯 ponyai vivo研究院 华为 字节 面了一面就没继续面了 xff1a 海康威视 虎牙 京东 本科211 xff0c 硕士985 二区在投论文 43 顶会下的top5比赛 43 小厂三个月实习经历
  • LeetCode刷题笔记 --- python

    目录 一 python交换两个变量的值1 1 使用tuple1 2 使用临时变量temp 二 python中 和 区别三 python列表的使用3 1 列表的基本操作3 2 列表实现栈操作3 3 列表实现排序3 4 列表的算法效率 四 py
  • 无人机高度控制

    这个第一次看就完全没看懂 xff0c 现在再看还是没看懂orz xff0c 而且定高还是重要的功能和考点 xff0c 详细分析一下程序吧 首先是表示高度信息的结构体 xff1a 数据结构声明 typedef struct float Z S
  • ssh_exchange_identification: Connection closed by remote host

    ssh exchange identification Connection closed by remote host 导致这个问题的原因有很多 xff0c 笔者是因为在ssh中设置了代理 xff0c 这个可以作为阅读者排查问题的一个点
  • 匿名无人机飞控代码整理5

    先跳过高度部分 xff0c 这里看location部分 可以看出来这部分也是直接与我们的循迹 追踪任务相关的 所以这部分的掌握应该很重要把 前面有很多暂时不需要看 xff0c flyctrl那个巨长 所以就先看速度环控制部分了 if swi
  • 匿名无人机飞控代码整理

    看了半天 xff0c 各部分都看得都很零散 xff0c 写的也很简略 xff0c 但目前为止还是无法对系统各部分做具体一点的整合 xff0c 今天试试看 1 先从主函数起 xff0c 进入主轮询函数 Main Task 这个主函数的调用就在
  • 一直没看的无人机定高

    除了定高的部分 xff0c 其他没看的还有一些控制函数 定高的原理的话 xff0c 也是利用了两级pid xff0c 按照原本的理解 xff0c 从外环开始看的话 xff0c 反馈高度比较容易获得 xff0c 就是激光测距得到的高度 期望高