详解APM的开方控制器sqrt_controller

2023-05-16

前言

前面说过,sqrt_controller是对P项进行整定用途的,目的就是让P项的控制响应“软”下来,实际上就是一个经过改进的P控制器。读懂了sqrt_controller,那么你对APM的P控制器就了解得差不多了。

仅讨论P控制器,sqrt_controller的作用就是设定一个量linear_dist,以这个量的正负值为分界线划分出一个线性区域范围,在这个范围内表示误差量还很小,遵循Kp*error计算方式输出控制量。

超过linear_dist后,表明误差较大,此时不能由着误差单纯按照线性方式乘以Kp输出控制量,需要按照开方形式,使用另外的方式计算出实际控制量,此处后面补充。


在开始讲解源码之前,先来补充个前提:

了解飞控的应该都清楚,一般是使用串级PID来进行姿态等的控制。在APM中,外环角度环就是接收期望与实际的角度误差,然后输入到P控制器中得到期望的角速率。也就是说,这个控制过程可以表示为:
w = K p ∗ e r r o r θ w=K_p*error_θ w=Kperrorθ

而我们同样知道,假定小角度内速率恒定,那么可知 w = e r r o r θ / d t w=error_θ/dt w=errorθ/dt,而由此可直接定义
K p = 1 / d t Kp=1/dt Kp=1/dt

而实际上APM中广泛采用了这个方式,因此,后续过程中我们谈论到Kp表明的都是时间的倒数。

 

源码阅读

数学公式的原理放在后面讲解,这边先放源码

// Proportional controller with piecewise sqrt sections to constrain second derivative
// 翻译:具有分段sqrt截面以约束二阶导数的比例控制器
// error:输入参数,误差量
// p:输入参数,Kp值
// second_ord_lim:输入参数,二阶限制,对Kp进行二次限制,通常是加速度最大值输入
// dt:输入参数,时间
float AC_AttitudeControl::sqrt_controller(float error, float p, float second_ord_lim, float dt)
{
    float correction_rate;	// 最后需要返回的期望速率
    if (is_negative(second_ord_lim) || is_zero(second_ord_lim)) {
        // 二阶限制是否为负或者零
		// 是的话表明开方控制器不起作用,按照正常方式计算Kp*error
        correction_rate = error * p;
    } else if (is_zero(p)) {
        // Kp=0但是我们开启了二阶限制则采用如下计算方式
        if (is_positive(error)) {
            correction_rate = safe_sqrt(2.0f * second_ord_lim * (error));
        } else if (is_negative(error)) {
            correction_rate = -safe_sqrt(2.0f * second_ord_lim * (-error));
        } else {
            correction_rate = 0.0f;
        }
    } else {
        // 如果同时定义了Kp和二阶限制
		// 一般我们用了sqrt_controller都是进的这个函数
		// 计算获取分界点linear_dist
		// 根据error与linear_dist的相对大小采用不同公式
        float linear_dist = second_ord_lim / sq(p);
        if (error > linear_dist) {
            correction_rate = safe_sqrt(2.0f * second_ord_lim * (error - (linear_dist / 2.0f)));
        } else if (error < -linear_dist) {
            correction_rate = -safe_sqrt(2.0f * second_ord_lim * (-error - (linear_dist / 2.0f)));
        } else {
            correction_rate = error * p;
        }
    }
    if (!is_zero(dt)) {
        // 这样可以确保在最后一个时间步过分校正错误不会使我们产生小的振荡。
        return constrain_float(correction_rate, -fabsf(error) / dt, fabsf(error) / dt);
    } else {
        return correction_rate;
    }
}

 

数学原理

初看这部分程序容易看的云里雾里的,没事,这边带大家重头开始梳理。

后续过程中,我们定义参数p为Kp,second_ord_lim为加速度最大值 a m a x a_{max} amax;后面部分用error表明位移量的误差,v表示速度进行推导。

首先,我们来带大家回顾一下高中知识,还记得高中小车问题里面,位移、速度、加速度和时间中如果已知其中几个量怎么求另外几个吗,我这边直接给出:
x = v 0 t + 1 2 a t 2 x=v_0t+\frac{1}{2}at^2 x=v0t+21at2 2 a x = v t 2 − v 0 2 2ax=v_t^2-v_0^2 2ax=vt2v02


那么回到我们的源程序中,我将直接从同时定义了Kp和二阶限制的else部分开始讲。

首先是这部分函数

float linear_dist = second_ord_lim / sq(p);

如前所述, K p = 1 / d t K_p=1/dt Kp=1/dt,那么下面这段程序可以解释为如下(后面把 d t dt dt简化表示为 t t t
l i n e a r _ d i s t = a m a x K p 2 = a m a x t 2 {linear\_dist}=\frac{a_{max}}{K_p^2}=a_{max}t^2 linear_dist=Kp2amax=amaxt2

那么由此也可以推算下面这行代码表示的公式

correction_rate = safe_sqrt(2.0f * second_ord_lim * (error - (linear_dist / 2.0f)));

c o r r e c t i o n _ r a t e = 2 a m a x ( e r r o r − ( l i n e a r _ d i s t 2 ) ) = 2 a m a x ( e r r o r − a m a x t 2 2 ) correction\_rate=\sqrt{2a_{max}(error-(\frac{linear\_dist}{2}))}=\sqrt{2a_{max}(error-\frac{a_{max}t^2}{2}}) correction_rate=2amax(error(2linear_dist)) =2amax(error2amaxt2 )

假定初始速度 v 0 v_0 v0为0,那么由 2 a x = v t 2 2ax=v_t^2 2ax=vt2 x = 1 2 a t 2 x=\frac{1}{2}at^2 x=21at2 可进一步推算上面的公式
c o r r e c t i o n _ r a t e = 2 a m a x ( e r r o r − x ′ ) = 2 ∗ a m a x ∗ △ x = v correction\_rate=\sqrt{2a_{max}(error-x')}=\sqrt{2*a_{max}*△x}=v correction_rate=2amax(errorx) =2amaxx =v

如果 e r r o r error error表示的是角度误差,角速度用 w w w表示的话,那么同样的 c o r r e c t i o n _ r a t e correction\_rate correction_rate计算出来的即是期望的角速率,实际上姿态控制器中就是如此的计算。

那么如果没有定义Kp仅定义了二阶限制的这部分函数我想你肯定也已经能够看懂了,我就不多做解释了

correction_rate = safe_sqrt(2.0f * second_ord_lim * (error));

由此,sqrt_controller的内容想必大家应该就能完全理解了。

 

MATLAB绘制曲线

这边用MATLAB绘制了一下sqrt_controller的控制曲线。可以很明显看到在一段区域内是以线性方式进行递增,而当误差过大,达到一定值的时候,则是按照开方函数曲线进行递增。

在这里插入图片描述

函数给出如下(太久没用Matlab了,原谅我写的简陋):

sqrt_controller函数:

function correction_rate = sqrt_controller(error,p,sencond_ord_lim,dt)

if sencond_ord_lim<0 || sencond_ord_lim==0
    rate = p.*error;
elseif p==0
    if error>0
        rate = sqrt(2.*sencond_ord_lim.*error);
    elseif error<0
        rate = -sqrt(2.*sencond_ord_lim.*(-error));
    else
        rate = 0;
    end
else
    linear_dist = sencond_ord_lim/(p.*p);
    if error>linear_dist
        rate = sqrt(2.*sencond_ord_lim.*(error-(linear_dist./2)));
    elseif error<-linear_dist
        rate = -sqrt(2.*sencond_ord_lim.*(-error-(linear_dist./2)));
    else
        rate = p.*error;
    end
end

if dt~=0
    if rate < -abs(error)/dt
        correction_rate = -abs(error)./dt;
    elseif rate > abs(error)/dt
        correction_rate = abs(error)./dt;
    else
        correction_rate = rate;
    end
else
    correction_rate = rate;
end

end

绘图程序:

Kp = 4.5;
sencond_ord_lim = 1.4;
dt = 1;
R = zeros(1,401);
i = 1;

for error = -20:0.1:20
    rate = sqrt_controller(error,Kp,sencond_ord_lim,dt);
    R(1,i)=rate;
    i = i+1;
end

plot(-20:0.1:20,R);
grid on
ylabel("期望角速率")
xlabel("angle error")

 

参考资料:
[算法] 刹车距离 get_stopping_point 和开方控制器 sqrt_controller
[飞控]姿态控制-开方控制器和倾斜角转加速度函数

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

详解APM的开方控制器sqrt_controller 的相关文章

  • 使用Ajax以及CSS+DIV高仿谷歌搜索(附源码下载)

    在使用 Google 搜索或者是 Baidu 搜索的时候 xff0c 在输入搜索关键字的同时 xff0c 会自动弹出匹配的其他关键字的提示 xff0c 全心全意为人民服务的精神在这里崭露无遗 这种利用 Ajax 技术实现输入提示和自动完成的
  • 导致索引失效的可能情况

    如下是可能导致索引失效的情况 xff1a 1 xff0e 隐式转换导致索引失效 这一点应当引起重视 也是开发中经常会犯的错误 由于表的字段tu mdn定义为varchar2 20 但在查询时把该字段作为number类型以where条件传给O
  • 二叉搜索树的增删查

    今天把搜索二叉树的思路又理了一遍 xff0c 把代码又从头到尾敲了一遍 xff0c 各位看客就不要在意代码粗糙和内存溢出了 xff0c 主要把插入和删除的过程理了一遍 xff0c 其中比较复杂的地方就是搜索二叉树的删除 xff0c 涉及了很
  • 中缀表达式转前缀和后缀表达式

    之前笔试中国电信IT研发中心的时候 xff0c 遇到了几个前 中 后缀表达式的相互转换 xff0c 当时忘得差不多了 xff0c 今天好好把该方面的知识好好复习 xff0c 并把相关代码和思路自己缕了一遍 xff1a 将中缀表达式转换为前缀
  • java prometheus 自定义exporter开发,以及实现多个接口返回metrics

    普罗 自定义exporter开发 exporter的作用是采集需要监控的数据 xff0c 并将采集到的数据转换成prometheus所需要的数据格式 xff0c 将这些转换后的数据返回 xff0c 供给prometheus 使用 java
  • 双系统重装Ubuntu经验分享

    真的很喜欢ubuntu 但又没有恒心把它学通透 xff0c 毕竟不是相关专业 第一次重装是因为没多少经验 xff0c 安装qqforlinux的时候多了两个东西 xff0c 还自己生成了快捷方式 xff0c 就想点开看看是啥 xff0c 结
  • 还在迷茫不知Dashboard是什么?答案在文中揭晓

    Dashboard的中文翻译是 仪表盘 xff0c 与汽车的仪表盘相同 一种反映车辆各系统工作状况的装置 xff0c 有车速里程表 转速表 燃油表等 司机可以很方便地从汽车仪表盘中获得汽车整体状况 而Dashboard沿袭了汽车仪表盘理念
  • 问题:UPDATE 失败,因为下列 SET 选项的设置不正确: 'ARITHABORT'。

    解决方案 1 你可以在TSQL前Set ARITHABORT ON 代码如下 Set ARITHABORT ON GO INSERT INTO ta 2 在ADO NET中 你可以这样来写 C 代码 MyConnection Execute
  • 智能制造:三体智能革命

    赵敏 宁振波 郭朝晖是走向智能研究院资深专家 xff0c 三体智能革命 编委会中三位重要作者 他们从去年5月起多次参加了中国工程院主持的 中国智能制造发展战略研究报告 的研讨 评审与修订工作 xff0c 对该报告的形成过程 研究主旨和详细内
  • 小觅相机SDK samples安装Link error: cannot find -lvtkproj4

    Link error cannot find lvtkproj4 error ld returned 1 exit status 找不到相关动态库文件 设置软链接 xff1a ln s usr lib x86 64 linux gnu li
  • 年度回忆录(2011.12----2012.09)

    前几天刚刚参加了提高班十期的开学典礼 xff0c 最近师院的新生也陆 陆续 续的开始报道了 每年到这个时候都会感慨 年年岁岁花相似 xff0c 年年岁岁人不同 啊 对于提高班来说每年都有新的血液注入进来 xff0c 提高班的队伍在不断的扩大
  • python函数(变量,参数)

    函数的变量 1 xff0c 全局变量 定义在最外层的变量 xff0c 对于所有的内函数都能调用 2 xff0c 局部变量 定义在函数内的变量叫做局部变量 xff0c 在函数外是不能访问局部变量 注 xff1a 全局变量不能直接在函数内部进行
  • 程序员读书和练习的方法(个人观点)

    lt 传送门 gt 针对本文的交流探讨 gt 总宗旨 xff1a 打好计算机通用理论基础 通用实战能力 xff0c 便于需要时对各领域的无障碍深钻 时间宝贵 xff0c 不要为了学习而学习 计算机通用理论基础 xff1a 计算机各领域理论基
  • 从零开始的Ubuntu 16.04下PX4编译环境的搭建

    近来入手了一块pixhawk xff0c 想进行一些基于已有代码的二次加工 xff0c 于是到官网https dev px4 io 上看教程 官网上的教程是分为中文 英文以及韩文的版本 很多人肯定第一反应就是看中文的版本 但是这样做弊端真的
  • 驱动程序开发:SPI设备驱动

    目录 Linux下SPI驱动简介SPI架构概述SPI适配器 xff08 控制器 xff09 SPI设备驱动spi driver注册示例SPI 设备和驱动匹配过程编写imc20608六轴传感器SPI驱动设备树编写操作具体的imc20608驱动
  • 操作系统知识点(二)

    文章目录 内存管理程序执行过程内存保护 连续分配非连续分配基本分页存储管理方式基本分段存储管理方式段页式存储管理方式 虚拟内存局部性原理请求分页存储管理 内存管理 内存管理 Memory Management 是操作系统设计中最重要和最复杂
  • VR行业发展的前景和现状?

    标题 VR行业发展的前景和现状 xff1f 1 一个新事物的产生 xff0c 总是伴随着看好和唱衰两种声音 这两种态度自然有其可以理解的地方 xff0c 因为摆在我们面前的是未知 xff0c 而坐在餐桌前的两拨人 xff0c 站在不同的角度
  • 头文件与库的区别

    昨天突然问了一下什么是头文件 xff0c 我一听就傻了 xff0c 虽然上课的时候老师在讲编译的四个过程的时候说了一下 xff0c 但是还是不太理解 xff0c 我们知道编译过程中的预处理阶段会进行头文件展开 xff0c 宏替换以及条件编译
  • 进程、线程

    线程 xff08 thread xff09 线程其实是操作系统能够进行运算调度的最小单位 它是被包含在进程之中的 xff0c 是进程中的实际运作单位 一条线程指的是进程中一个单一顺序的控制流 xff0c 一个进程中可以并发多个线程 xff0
  • 基于Zynq7020双千兆以太网的数字信号处理板设计

    一 背景 背景 Xilinx公司在2010年发布了可扩展的处理器平台Zynq7000系列 xff0c 它采用了28nm工艺 xff0c 将FPGA与ARM cortex A9集成在一颗芯片上 xff0c 实现了高性能 高集成度 低功耗 Zy

随机推荐

  • 深入理解JS中的变量作用域

    在 JS 当中一个变量的作用域 xff08 scope xff09 是程序中定义这个变量的区域 变量分为两类 xff1a 全局 xff08 global xff09 的和局部的 其中全局变量的作用域是全局性的 xff0c 即在 JavaSc
  • 硬件工程师,从零开始无人机开发。

    毕业已经五年了 xff0c 一直在杭州某大厂 xff0c 做无人机硬件开发 无人机这块 xff0c 我进去的时候大厂刚开始 做 xff0c 有幸参与到整个无人机的硬件开发 我这个刚毕业的技术小白 xff0c 在这五年间成长了很多 无奈 今年
  • 个人总结:板球控制系统之串级PID整定方法,速度环与位置环,40S任务10S完成

    其实单环我们先出了所有题目 xff0c 但是效果显然没有串级PID的效果好 xff0c 有人需要的话可以把程序包发出来 xff0c 板球运行视屏也有 另外 xff1a 天下舵机参差不齐 xff08 哪怕型号相同 xff09 xff0c 想要
  • 树莓派3B+踩坑记录:一、安装Ubuntu Mate

    树莓派3B 43 踩坑记录 xff1a 一 安装Ubuntu Mate 树莓派 xff0c Ubuntu xff0c ROS硬件准备软件准备系统烧录安装Ubuntu Mate更换国内源网络配置开启ssh远程其他彩虹屏解决方案XShell和X
  • PointNet代码详解

    PointNet代码详解 最近在做点云深度学习的机器人抓取 xff0c 这篇博客主要是把近期学习PointNet的一些总结的知识点汇总一下 PointNet概述详见以下网址和博客 xff0c 这里也就不再赘述了 三维深度学习之pointne
  • 卡尔曼滤波通俗易懂的解释

    关于卡尔曼滤波 xff0c 网上的资料很多 xff0c 但是有很大一部分都是不断堆叠公式 xff0c 然后用各种晦涩难懂的专业术语进行解释 xff0c 说实话我刚开始看的时候也是云里雾里 xff0c 因此写下这篇博客是为了照顾和我一样的萌新
  • STM32通过PWM控制ESC30C电调

    最近在搞一个水下推进器 xff0c 这东西的控制其实跟四旋翼的螺旋桨控制差不多 但我也是第一次用STM32板子来控制电调驱动桨叶旋转 xff0c 因此踩了很多坑 网上找了很多资料 xff0c 但是很多都写的不是很清楚 xff0c 这边稍微记
  • STM32F7同一定时器多路输出PWM波通道之间相互影响问题

    2020 8 12更新 这次用Cube直接生成PWM控制代码 xff0c 然后再RT Thread Studio上编写程序 xff0c 发现可实现TIM1和TIM8的8路PWM波调控 xff0c 因此上面论述的问题可能是自己在写底层时有某些
  • Ardusub源码解析学习(一)——Ardusub主程序

    APM Sub源码解析学习 xff08 一 xff09 Ardusub主程序 前言一 准备工作二 Ardusub cpp解析2 1 scheduler table2 2 schedulerget scheduler tasks setup
  • Ardusub源码解析学习(二)——电机库

    Ardusub源码解析学习 xff08 二 xff09 电机库学习 一 RC输入与输出1 1 RC Input1 2 RC Output 二 电机库学习2 1 setup motors 2 2 add motor raw 6dof 2 3
  • Ardusub源码解析学习(三)——车辆类型

    APM Sub源码解析学习 xff08 三 xff09 车辆类型 一 前言二 class AP HAL HAL三 class AP Vehicle3 1 h3 2 cpp 四 class Sub4 1 h4 2 cpp 五 总结 一 前言
  • 年度回忆录(2012.10----2013.01)

    寒假结束了 xff0c 年也过完了 xff0c 提前回来一天就开始着手补上这迟到的年终总结 xff0c 写了一个多星期还觉得有些东西没有写出来 xff0c 无奈 xff0c 点到为止吧 2012 年的后半年经历了很多 xff0c 收获了很多
  • Ardusub学习——飞行模式

    参考资料 xff1a Ardusb官方手册 Sub Rework joystick input and pilot input in general Flight Modes Ardusub支持多种飞行模式 xff0c 但是其中一部分需要有
  • Ardusub源码解析学习(五)——从manual model开始

    Ardusub源码解析学习 xff08 五 xff09 从manual model开始 manual init manual run 从本篇开始 xff0c 将会陆续对Ardusub中各种模式进行介绍 xff0c stabilize mod
  • 重读Ardupilot中stabilize model+MAVLINK解包过程

    APM源码和MAVLINK解析学习 重读stabilize stabilize modelinit run handle attitude MAVLINK消息包姿态信息传输过程 之前写的模式都是基于master版本的 xff0c 这次重读s
  • QGC添加自定义组件和发送自定义MAVLINK消息

    QGC添加自定义组件和发送自定义MAVLINK消息 一 添加自定义组件1 1 在飞行界面添加组件1 2 实现组件事件1 3 在MOCK模拟链接中实现验证1 4 验证 二 自定义MAVLINK消息的一些预备知识三 QGC自定义MAVLINK消
  • MAVLINK消息在Ardupilot中的接收和发送过程

    MAVLINK消息在Ardupilot中的接收和发送过程 SCHED TASKupdate receive update send 由于现在网上很多的都是APM旧版本的解释 xff0c 因此把自己的一些学习所得记录下来 截至写博客日期 xf
  • Ardupilot姿态控制器 PID控制流程

    Ardupilot姿态控制器 PID控制流程 一 PID姿态控制器1 1 Copter姿态控制官方原图1 2 ArduCopter V4 X STABILIZE 二 姿态控制器类实现2 1 类成员解析2 1 1 类成员变量2 1 2 类成员
  • APM姿态旋转理论基础

    APM姿态旋转理论基础 一 坐标系1 1 NED坐标系1 2 机体坐标系 二 欧拉角姿态变化率与机体角速度的关系 三 旋转矩阵3 1 基本公式3 2 矩阵作差3 3 旋转矩阵与变换矩阵的区别 四 DCM五 轴角法5 1 基本概念5 2 与旋
  • 详解APM的开方控制器sqrt_controller

    前言 前面说过 xff0c sqrt controller是对P项进行整定用途的 xff0c 目的就是让P项的控制响应 软 下来 xff0c 实际上就是一个经过改进的P控制器 读懂了sqrt controller xff0c 那么你对APM