Apm飞控学习笔记之-电机解锁和故障保护-Cxm

2023-05-16

前言

CSDNicon-default.png?t=M4ADhttps://mp.csdn.net/mp_blog/creation/editor/122115245

这边说的解锁是指的非自动解锁和地面站解锁

常规解锁流程=安全开关->内八解锁

这一篇会介绍整个解锁流程以及飞控内部解锁包含了那些内容


目录

是否允许使用舵面解锁

判断油门是否关闭

获取舵量.航向

 主体内容

 主题内容中关注的函数

1.motors->armed()   

2.arming.arm(AP_Arming::Method::RUDDER)

打开libraries\AP_Arming\AP_Arming.cpp文件中的arm函数

((!do_arming_checks && mandatory_checks(true)) || (pre_arm_checks(true)&& arm_checks(method)))

pre_arm_checks(true)


ArduCopter\motors.cpp

飞控的解锁的文件就在这里

命名为arm_motors_check()函数

内容包含非常多 所以就不一一列出了 我按顺序讲

可以看到这个函数在主文件里开辟了进程

然后我们直接来看这个函数的流程

是否允许使用舵面解锁

AP_Arming::RudderArming arming_rudder = arming.get_rudder_arming_type();

if (arming_rudder == AP_Arming::RudderArming::IS_DISABLED) {

return; }

判断油门是否关闭

    if (channel_throttle->get_control_in() > 0) {
        arming_counter = 0;
        return;
    }

获取舵量.航向

int16_t yaw_in = channel_yaw->get_control_in();

 主体内容

if (yaw_in > 4000) {

        // increase the arming counter to a maximum of 1 beyond the auto trim counter
        //最大值1 如果小于就等于1
        if (arming_counter <= AUTO_TRIM_DELAY) {
            arming_counter++;
        }
        // arm the motors and configure for flight
        //准备发动机准备起飞
        if (arming_counter == ARM_DELAY && !motors->armed()) {
            // reset arming counter if arming fail
            //解除失败就重新解除
            //关键解锁函数arming.arm(AP_Arming::Method::RUDDER)
            if (!arming.arm(AP_Arming::Method::RUDDER)) {
                arming_counter = 0;
            }
        }

        // arm the motors and configure for flight
        //启动发动机,准备起飞 
        if (arming_counter == AUTO_TRIM_DELAY && motors->armed() && control_mode == Mode::Number::STABILIZE) {
            auto_trim_counter = 250;
            // ensure auto-disarm doesn't trigger immediately
            //确保不会第一时间
            auto_disarm_begin = millis();
        }

    // full left and rudder disarming is enabled
    //左满舵解除武装
    } else if ((yaw_in < -4000) && (arming_rudder == AP_Arming::RudderArming::ARMDISARM)) {

        if (!flightmode->has_manual_throttle() && !ap.land_complete) {
            arming_counter = 0;
            return;
        }

        // increase the counter to a maximum of 1 beyond the disarm delay
        if (arming_counter <= DISARM_DELAY) {
            arming_counter++;
        }

        // disarm the motors
        //解除引擎
        if (arming_counter == DISARM_DELAY && motors->armed()) {
            //解锁函数
            arming.disarm();
        }

    // Yaw is centered so reset arming counter
    } else {
        arming_counter = 0;
    }
}

 主题内容中关注的函数

arming.arm(AP_Arming::Method::RUDDER)

注意这里要关注的函数是ArduCopter\motors.cpp中的:

arming.arm(AP_Arming::Method::RUDDER)

而这个函数是在同目录下的ArduCopter\AP_Arming.cpp文件中

这里一定要注意千万不要弄混了

我们跳转到这个函数里面,注意这个函数是在同目录下的ArduCopter\AP_Arming.cpp文件中

bool AP_Arming_Copter::arm(const AP_Arming::Method method, const bool do_arming_checks)
{

    static bool in_arm_motors = false;
    // exit immediately if already in this function
    //如果已经在函数中
    if (in_arm_motors) {
        return false;
    }
    in_arm_motors = true;

    // return true if already armed
    //如果已经启动
    if (copter.motors->armed()) {
        in_arm_motors = false;
        return true;
    }


    //AP_Arming::arm 是整个飞机的模式和防护 如果成功返回t
    //这个很重要 这里面包括了里面的检查项目 包含了pre_arm_checks(true)
    if (!AP_Arming::arm(method, do_arming_checks)) {
        AP_Notify::events.arming_failed = true;
        in_arm_motors = false;
        return false;
    }
    


    // let logger know that we're armed (it may open logs e.g.)
    AP::logger().set_vehicle_armed(true);

    // disable cpu failsafe because initialising everything takes a while
    copter.failsafe_disable();

    // notify that arming will occur (we do this early to give plenty of warning)
    AP_Notify::flags.armed = true;
    // call notify update a few times to ensure the message gets out
    for (uint8_t i=0; i<=10; i++) {
        AP::notify().update();
    }

#if HIL_MODE != HIL_MODE_DISABLED || CONFIG_HAL_BOARD == HAL_BOARD_SITL
    gcs().send_text(MAV_SEVERITY_INFO, "Arming motors");
#endif

    // Remember Orientation
    // --------------------
    copter.init_simple_bearing();

    AP_AHRS_NavEKF &ahrs = AP::ahrs_navekf();

    copter.initial_armed_bearing = ahrs.yaw_sensor;

    if (!ahrs.home_is_set()) {
        // Reset EKF altitude if home hasn't been set yet (we use EKF altitude as substitute for alt above home)
        //home 点设置
        ahrs.resetHeightDatum();
        AP::logger().Write_Event(DATA_EKF_ALT_RESET);

        // we have reset height, so arming height is zero
        copter.arming_altitude_m = 0;
    } else if (!ahrs.home_is_locked()) {
        // Reset home position if it has already been set before (but not locked)
        //重置初始位置(如果之前已设置)(但未锁定)
        if (!copter.set_home_to_current_location(false)) {
            // ignore failure
        }

        // remember the height when we armed
        //记住我们武装时的高度
        copter.arming_altitude_m = copter.inertial_nav.get_altitude() * 0.01;
    }
    更新超级简单轴承-根据位置调整简单轴承
    //应在home_轴承更新后调用
    copter.update_super_simple_bearing(false);

    // Reset SmartRTL return location. If activated, SmartRTL will ultimately try to land at this point
#if MODE_SMARTRTL_ENABLED == ENABLED
    copter.g2.smart_rtl.set_home(copter.position_ok());
#endif

    // enable gps velocity based centrefugal force compensation
    ahrs.set_correct_centrifugal(true);
    hal.util->set_soft_armed(true);

#if SPRAYER_ENABLED == ENABLED
    // turn off sprayer's test if on
    copter.sprayer.test_pump(false);
#endif

    // enable output to motors
    //启用电机的输出
    copter.enable_motor_output();

    // finally actually arm the motors
    //启动发动机
    copter.motors->armed(true);

    AP::logger().Write_Event(DATA_ARMED);

    // log flight mode in case it was changed while vehicle was disarmed
    AP::logger().Write_Mode((uint8_t)copter.control_mode, copter.control_mode_reason);

    // re-enable failsafe
    copter.failsafe_enable();

    // perf monitor ignores delay due to arming
    AP::scheduler().perf_info.ignore_this_loop();

    // flag exiting this function
    in_arm_motors = false;

    // Log time stamp of arming event
    copter.arm_time_ms = millis();

    // Start the arming delay
    copter.ap.in_arming_delay = true;

    // assumed armed without a arming, switch. Overridden in switches.cpp
    copter.ap.armed_with_switch = false;

    // return success
    return true;
}

1.motors->armed()   

检查当前是否解锁 bool类型 1解锁 0未解锁 注意这个函数是个重载函数里面是可以包含值

    if (copter.motors->armed()) {
        in_arm_motors = false;
        return true;
    }

2.arming.arm(AP_Arming::Method::RUDDER)

这个是重点关注的函数 也就是解锁的函数 他很重要,在libraries\AP_Arming\AP_Arming.cpp里面定义了一个一样函数名的函数 这点要注意两个函数的功能不同

接下来不重要的部分我直接吧作用放在注释里

    //如果已经在函数中
    if (in_arm_motors) {
        return false;
    }
  //如果已经启动
    if (copter.motors->armed()) {
        in_arm_motors = false;
        return true;
    }

注意这里到了前面说的嵌套AP_Arming::arm(method, do_arming_checks)

这个函数的主题在libraries\AP_Arming\AP_Arming.cpp文件中

    if (!AP_Arming::arm(method, do_arming_checks)) {
        AP_Notify::events.arming_failed = true;
        in_arm_motors = false;
        return false;
    }

注意在这里我们跳转到 libraries\AP_Arming\AP_Arming.cpp中的

bool AP_Arming::arm(AP_Arming::Method method, const bool do_arming_checks)

前一个同名函数是为了解锁

后者则是为了检查当前飞机的状态然后更改电机启动标志位

打开libraries\AP_Arming\AP_Arming.cpp文件中的arm函数

bool AP_Arming::arm(AP_Arming::Method method, const bool do_arming_checks)
{
    if (armed) { //already armed
        return false;
    }

    if ((!do_arming_checks && mandatory_checks(true)) || (pre_arm_checks(true) && arm_checks(method))) {
        armed = true;

        //TODO: Log motor arming
        //Can't do this from this class until there is a unified logging library

    } else {
        //解除失败日志通知
        AP::logger().arming_failure();
        armed = false;
    }

    return armed;
}

其中核心就是

((!do_arming_checks && mandatory_checks(true)) || (pre_arm_checks(true)&& arm_checks(method)))

pre_arm_checks(true)

飞行前的检查

bool AP_Arming_Copter::pre_arm_checks(bool display_failure)
{
    const bool passed = run_pre_arm_checks(display_failure);
    set_pre_arm_check(passed);
    return passed;
}

我们要重点关注的是

run_pre_arm_checks(display_failure)

bool AP_Arming_Copter::run_pre_arm_checks(bool display_failure)
{
    // exit immediately if already armed
    if (copter.motors->armed()) {
        return true;
    }


    // check if motor interlock and Emergency Stop aux switches are used
    // at the same time.  This cannot be allowed.
    if (rc().find_channel_for_option(RC_Channel::AUX_FUNC::MOTOR_INTERLOCK) &&
        rc().find_channel_for_option(RC_Channel::AUX_FUNC::MOTOR_ESTOP)){
        check_failed(display_failure, "Interlock/E-Stop Conflict");
        return false;
    }

    // check if motor interlock aux switch is in use
    // if it is, switch needs to be in disabled position to arm
    // otherwise exit immediately.  This check to be repeated,
    // as state can change at any time.
    if (copter.ap.using_interlock && copter.ap.motor_interlock_switch) {
        check_failed(display_failure, "Motor Interlock Enabled");
    }

    // if pre arm checks are disabled run only the mandatory checks
    if (checks_to_perform == 0) {
        return mandatory_checks(display_failure);
    }

    return fence_checks(display_failure)        //围栏
        & parameter_checks(display_failure)     //参数
        & motor_checks(display_failure)         //电机
        & pilot_throttle_checks(display_failure)    //油门
        & oa_checks(display_failure)
        & gcs_failsafe_check(display_failure) &     //地面站故障保护
        AP_Arming::pre_arm_checks(display_failure);
}

最重要的部分这边我都已经打上了注释如果感兴趣可以自己去查看这边关注一下油门

bool AP_Arming_Copter::pilot_throttle_checks(bool display_failure)如下:

bool AP_Arming_Copter::pilot_throttle_checks(bool display_failure)
{
    // check throttle is above failsafe throttle
    // this is near the bottom to allow other failures to be displayed before checking pilot throttle
    //检查油门是否高于故障保护油门
    //这靠近底部,以便在检查先导油门之前显示其他故障
    if ((checks_to_perform == ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_RC)) {
        if (copter.g.failsafe_throttle != FS_THR_DISABLED && copter.channel_throttle->get_radio_in() < copter.g.failsafe_throttle_value) {
            #if FRAME_CONFIG == HELI_FRAME
            const char *failmsg = "Collective below Failsafe";
            #else
            const char *failmsg = "Throttle below Failsafe";
            #endif
            check_failed(ARMING_CHECK_RC, display_failure, "%s", failmsg);
            return false;
        }
    }

    return true;
}

大概的意思就是查看标志位是否有其他故障 然后检查油门位置 这个函数会决定是否能在未开启遥控器的情况下解锁

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

Apm飞控学习笔记之-电机解锁和故障保护-Cxm 的相关文章

随机推荐

  • nuScenes数据集详细介绍

    本文为博主原创文章 xff0c 未经博主允许不得转载 本文为专栏 python三维点云从基础到深度学习 系列文章 xff0c 地址为 https blog csdn net suiyingy article details 12401771
  • fegin调用的时候数据格式转换为linkedhashmap

    在spring cloud项目开发中 xff0c 使用fegin进行远程调用 1 接口服务方返回类型为Map String Object 类型 2 接口调用方返回值类型也是Map String Object 3 通过fegin调用之后返回的
  • 一个字符串截取函数c语言

    刚开始学习c语言 xff0c 标准库中总是有很多函数没有 xff0c string h中的字符串处理函数好像不是很多 xff0c 在做栈的例子用需要用到一个字符串按位置截取的函数 xff0c 就自己写一个 xff0c 超简单 char su
  • RAF_DB数据集分类_3

    混淆矩阵 这里ECANet太长了 xff0c 我这里直接利用resnet代替一下 xff0c 你可以直接替换 xff0c 然后把权重对应好即可 xff0c 这只是一个简单的混淆矩阵生成 xff0c 没有太多美化 span class tok
  • docker镜像的创建

    目录 基于现有镜像创建 首先启动一个镜像 xff0c 在容器里做修改 然后将修改后的容器提交为新的镜像 xff0c 需要使用该容器的ID号创建新镜像 基于本地模板创建 导入镜像 基于Dockerfile创建 联合文件系统 xff08 Uni
  • ROS源码分析--子话题-catkin

    catkin简介 catkin简介 packagexml 格式1格式2 CMakeListtxtmeta package典型ROS应用添加自定义message文件 修改packagexml修改CMakeListtxt find packag
  • vnc安装和开机自启设置

    一 安装VNC 键入以下命令以在 Ubuntu 服务器上安装 TigerVNC xff1a sudo apt install tigervnc standalone server tigervnc common 现在安装了 VNC 服务器
  • 【Linux】线程安全篇Ⅰ

    文章目录 0 概述1 线程不安全举例1 1 前提知识铺垫1 2 场景模拟1 3 代码模拟 2 互斥2 1 什么是互斥2 2 互斥锁的原理 amp amp 特性2 3 互斥锁的计数器如何保证原子性2 4 互斥锁的接口2 4 1 初始化接口2
  • PX4/APM/飞控的学习笔记前言-Cxm

    开始了 开始了 终于有时间可以学习飞控了 此文章是用来当目录 我会持续更新我的学习之旅 希望能对各位有所帮助 如果有错误的地方还请各位前辈指点 此帖持续更新后续内容 其实从21年的一月就开始学习飞控一开始是从PX4开始学习 但是因为对liu
  • kubernetes 中文版

    这个文档非常好用 xff0c 建议收藏 无水印版 https pan baidu com s 1LSI46GBENd90Z06FnuaKmw lukb
  • SimpleBGC三轴云台用户手册

    SimpleBGC三轴云台用户手册 V1 00 硬件平台 xff1a STorM BGC V1 31 软件框架 xff1a SimpleBGC V1 00 本方案是采用俄版STorM BGC硬件平台 xff0c 软件采用SimpleBGC架
  • typedef和define有什么区别

    typedef和define都是替一个对象取一个别名 xff0c 以此增强程序的可读性 xff0c 区别如下 xff1a xff08 1 xff09 原理不同 define是C语言中定义的语法 xff0c 是预处理指令 xff0c 在预处理
  • 接口返回报错 resource notfound,plrase check path

    1 报错原因 post请求的content type application x www form urlencoded 但是请求体中设置的是json数据 34 date 34 34 2022 01 01 34 34 inclTransfe
  • Java中枚举的线程安全性及序列化问题

    一 枚举是如何保证线程安全的 要想看源码 xff0c 首先得有一个类吧 xff0c 那么枚举类型到底是什么类呢 xff1f 是enum吗 xff1f 答案很明显不是 xff0c enum就和class一样 xff0c 只是一个关键字 xff
  • Vscode配置Git

    vscode安装git 首先我们要确保我们下载了vscode和git xff0c 接下来就是给vscode配置git的步骤 xff1a 配置git环境变量 xff08 path值为git安装位置的cmd文件夹 xff09 xff0c 如图
  • SLAM-6视觉里程计里面特征点计算的缺点所做的改进

    缺点的改进方法 xff1a 由于之前的视觉里程计要计算关键点和描述子 xff0c 花费大量的时间 xff0c 有两种办法可以避免 1 只计算关键点 xff0c 通过光流法追踪关键点的运动 xff0c 可以得到同一个关键点在不同时刻图片的位置
  • SLAM8-后端的其他方法,BA与图优化,Pose Graph优化的理论与公式详解、因子图优化

    1 BA方法 Bundle Adjustment翻译过来是 光束调整 xff0c 意思是每个特征反射的光束 xff0c 通过调整它们的空间位置和相机姿态 xff0c 使它们都汇聚到相机光心 xff0c 这个过程叫BA 假定世界坐标系下的点p
  • 【动手学深度学习】 2预备知识

    李沫 动手学习深度学习 课程学习 需要预备的知识原因重点线性代数处理表格数据矩阵运算微积分决定以何种方式调整参数 损失函数 xff08 loss function xff09 衡量 模型有多糟糕 这个问题的分数 梯度 xff08 gradi
  • JDK源码之-java.lang.Object

    JDK源码之 java lang Object public final native Class lt gt getClass public native int hashCode public boolean equals Object
  • Apm飞控学习笔记之-电机解锁和故障保护-Cxm

    前言 CSDN https mp csdn net mp blog creation editor 122115245 这边说的解锁是指的非自动解锁和地面站解锁 常规解锁流程 61 安全开关 gt 内八解锁 这一篇会介绍整个解锁流程以及飞控