Ardusub源码分析(1)——AP_Arming_Sub

[复制链接]
发表于 2025-12-15 15:23:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
代码

AP_Arming_Sub.h
  1. #pragma once
  2. #include <AP_Arming/AP_Arming.h>
  3. class AP_Arming_Sub : public AP_Arming {
  4. public:
  5.     AP_Arming_Sub() : AP_Arming() { }
  6.     /* Do not allow copies */
  7.     CLASS_NO_COPY(AP_Arming_Sub);
  8.     bool rc_calibration_checks(bool display_failure) override;
  9.     bool pre_arm_checks(bool display_failure) override;
  10.     bool has_disarm_function() const;
  11.     bool disarm(AP_Arming::Method method, bool do_disarm_checks=true) override;
  12.     bool arm(AP_Arming::Method method, bool do_arming_checks=true) override;
  13. protected:
  14.     bool ins_checks(bool display_failure) override;
  15. };
复制代码
AP_Arming_Sub.cpp
  1. #include "AP_Arming_Sub.h"
  2. #include "Sub.h"
  3. bool AP_Arming_Sub::rc_calibration_checks(bool display_failure)
  4. {
  5.     const RC_Channel *channels[] = {
  6.         sub.channel_roll,
  7.         sub.channel_pitch,
  8.         sub.channel_throttle,
  9.         sub.channel_yaw
  10.     };
  11.     return rc_checks_copter_sub(display_failure, channels);
  12. }
  13. bool AP_Arming_Sub::has_disarm_function() const {
  14.     bool has_shift_function = false;
  15.     // make sure the craft has a disarm button assigned before it is armed
  16.     // check all the standard btn functions
  17.     for (uint8_t i = 0; i < 16; i++) {
  18.         switch (sub.get_button(i)->function(false)) {
  19.             case JSButton::k_shift :
  20.                 has_shift_function = true;
  21.                 break;
  22.             case JSButton::k_arm_toggle :
  23.                 return true;
  24.             case JSButton::k_disarm :
  25.                 return true;
  26.         }
  27.     }
  28.     // check all the shift functions if there's shift assigned
  29.     if (has_shift_function) {
  30.         for (uint8_t i = 0; i < 16; i++) {
  31.             switch (sub.get_button(i)->function(true)) {
  32.                 case JSButton::k_arm_toggle :
  33.                 case JSButton::k_disarm :
  34.                     return true;
  35.             }
  36.         }
  37.     }
  38.     return false;
  39. }
  40. bool AP_Arming_Sub::pre_arm_checks(bool display_failure)
  41. {
  42.     if (armed) {
  43.         return true;
  44.     }
  45.     // don't allow arming unless there is a disarm button configured
  46.     if (!has_disarm_function()) {
  47.         check_failed(display_failure, "Must assign a disarm or arm_toggle button");
  48.         return false;
  49.     }
  50.     return AP_Arming::pre_arm_checks(display_failure);
  51. }
  52. bool AP_Arming_Sub::ins_checks(bool display_failure)
  53. {
  54.     // call parent class checks
  55.     if (!AP_Arming::ins_checks(display_failure)) {
  56.         return false;
  57.     }
  58.     // additional sub-specific checks
  59.     if (check_enabled(ARMING_CHECK_INS)) {
  60.         char failure_msg[50] = {};
  61.         if (!AP::ahrs().pre_arm_check(false, failure_msg, sizeof(failure_msg))) {
  62.             check_failed(ARMING_CHECK_INS, display_failure, "AHRS: %s", failure_msg);
  63.             return false;
  64.         }
  65.     }
  66.     return true;
  67. }
  68. bool AP_Arming_Sub::arm(AP_Arming::Method method, bool do_arming_checks)
  69. {
  70.     static bool in_arm_motors = false;
  71.     // exit immediately if already in this function
  72.     if (in_arm_motors) {
  73.         return false;
  74.     }
  75.     in_arm_motors = true;
  76.     if (!AP_Arming::arm(method, do_arming_checks)) {
  77.         AP_Notify::events.arming_failed = true;
  78.         in_arm_motors = false;
  79.         return false;
  80.     }
  81. #if HAL_LOGGING_ENABLED
  82.     // let logger know that we're armed (it may open logs e.g.)
  83.     AP::logger().set_vehicle_armed(true);
  84. #endif
  85.     // disable cpu failsafe because initialising everything takes a while
  86.     sub.mainloop_failsafe_disable();
  87.     // notify that arming will occur (we do this early to give plenty of warning)
  88.     AP_Notify::flags.armed = true;
  89.     // call notify update a few times to ensure the message gets out
  90.     for (uint8_t i=0; i<=10; i++) {
  91.         AP::notify().update();
  92.     }
  93. #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
  94.     send_arm_disarm_statustext("Arming motors");
  95. #endif
  96.     AP_AHRS &ahrs = AP::ahrs();
  97.     sub.initial_armed_bearing = ahrs.yaw_sensor;
  98.     if (!ahrs.home_is_set()) {
  99.         // Reset EKF altitude if home hasn't been set yet (we use EKF altitude as substitute for alt above home)
  100.         // Always use absolute altitude for ROV
  101.         // ahrs.resetHeightDatum();
  102.         // AP::logger().Write_Event(LogEvent::EKF_ALT_RESET);
  103.     } else if (!ahrs.home_is_locked()) {
  104.         // Reset home position if it has already been set before (but not locked)
  105.         if (!sub.set_home_to_current_location(false)) {
  106.             // ignore this failure
  107.         }
  108.     }
  109.     hal.util->set_soft_armed(true);
  110.     // enable output to motors
  111.     sub.enable_motor_output();
  112.     // finally actually arm the motors
  113.     sub.motors.armed(true);
  114. #if HAL_LOGGING_ENABLED
  115.     // log flight mode in case it was changed while vehicle was disarmed
  116.     AP::logger().Write_Mode((uint8_t)sub.control_mode, sub.control_mode_reason);
  117. #endif
  118.     // reenable failsafe
  119.     sub.mainloop_failsafe_enable();
  120.     // perf monitor ignores delay due to arming
  121.     AP::scheduler().perf_info.ignore_this_loop();
  122.     // flag exiting this function
  123.     in_arm_motors = false;
  124.     // if we do not have an ekf origin then we can't use the WMM tables
  125.     if (!sub.ensure_ekf_origin()) {
  126.         gcs().send_text(MAV_SEVERITY_WARNING, "Compass performance degraded");
  127.         if (check_enabled(ARMING_CHECK_PARAMETERS)) {
  128.             check_failed(ARMING_CHECK_PARAMETERS, true, "No world position, check ORIGIN_* parameters");
  129.             return false;
  130.         }
  131.     }
  132.     // return success
  133.     return true;
  134. }
  135. bool AP_Arming_Sub::disarm(const AP_Arming::Method method, bool do_disarm_checks)
  136. {
  137.     // return immediately if we are already disarmed
  138.     if (!sub.motors.armed()) {
  139.         return false;
  140.     }
  141.     if (!AP_Arming::disarm(method, do_disarm_checks)) {
  142.         return false;
  143.     }
  144. #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
  145.     send_arm_disarm_statustext("Disarming motors");
  146. #endif
  147.     auto &ahrs = AP::ahrs();
  148.     // save compass offsets learned by the EKF if enabled
  149.     if (ahrs.use_compass() && AP::compass().get_learn_type() == Compass::LEARN_EKF) {
  150.         for (uint8_t i=0; i<COMPASS_MAX_INSTANCES; i++) {
  151.             Vector3f magOffsets;
  152.             if (ahrs.getMagOffsets(i, magOffsets)) {
  153.                 AP::compass().set_and_save_offsets(i, magOffsets);
  154.             }
  155.         }
  156.     }
  157.     // send disarm command to motors
  158.     sub.motors.armed(false);
  159.     // reset the mission
  160.     sub.mission.reset();
  161. #if HAL_LOGGING_ENABLED
  162.     AP::logger().set_vehicle_armed(false);
  163. #endif
  164.     hal.util->set_soft_armed(false);
  165.     // clear input holds
  166.     sub.clear_input_hold();
  167.     return true;
  168. }
复制代码
分析

头文件

.h代码界说了一个名为 AP_Arming_Sub 的 C++ 类,它继续自 AP_Arming 类。此类提供了一个子类化 AP_Arming 的例子,此中添加了一些基类的方法。以下是详细表明:
  1. #pragma once
复制代码

  • #pragma once
    是一个预处置处罚器指令,用于防止文件被多次包罗。当编译器看到这个指令时,它会确保该文件在一个编译过程中只被包罗一次,纵然它被多次 #include。
  1. #include <AP_Arming/AP_Arming.h>
复制代码

  • 这行代码包罗了 AP_Arming 类界说的头文件。AP_Arming 是一个库负责处置处罚无人机启动和关闭相干的逻辑。
  1. class AP_Arming_Sub : public AP_Arming {
复制代码

  • 这里界说了一个新的类 AP_Arming_Sub,它继续自 AP_Arming 类。public 关键字表现 AP_Arming 是一个公共基类。
  1. public:
  2.     AP_Arming_Sub() : AP_Arming() { }
复制代码

  • 这部分界说了一个公共构造函数 AP_Arming_Sub。构造函数利用成员初始化列表语法 : AP_Arming() 来调用基类 AP_Arming 的构造函数。
  1.     /* Do not allow copies */
  2.     CLASS_NO_COPY(AP_Arming_Sub);
复制代码

  • 这一行是一个表明,阐明确不盼望这个类被复制。固然 CLASS_NO_COPY 宏在这里没有被界说,但它通常用于在类界说中禁用复制构造函数和赋值利用符,以防止类的偶然复制。
  1.     bool rc_calibration_checks(bool display_failure) override;
  2.     bool pre_arm_checks(bool display_failure) override;
  3.     bool has_disarm_function() const;
复制代码

  • 这些是 AP_Arming_Sub 类的公共成员函数声明。它们覆盖了基类 AP_Arming 中的虚函数。override 关键字明确表现这些函数是覆盖基类的虚函数。

    • rc_calibration_checks:用于实行遥控器校准查抄。
    • pre_arm_checks:用于实行武器启动前的查抄。
    • has_disarm_function:用于查抄是否解锁。

  1.     bool disarm(AP_Arming::Method method, bool do_disarm_checks=true) override;
  2.     bool arm(AP_Arming::Method method, bool do_arming_checks=true) override;
复制代码

  • 这些函数覆盖了基类中的武器排除和武器启动功能,允许子类自界说这些活动。Method 是一个属于 AP_Arming 类的摆列范例,用于指定排除或启动武器的方法。
  1. protected:
  2.     bool ins_checks(bool display_failure) override;
复制代码

  • 这部分声明确一个受掩护的成员函数 ins_checks,它覆盖了基类中的虚函数。protected 关键字表现这个函数是供派生类和基类内部利用的,但不供外部访问。这个函数用于实行惯性导航体系(INS)查抄。
源文件
  1. #include "AP_Arming_Sub.h"
  2. #include "Sub.h"
复制代码

  • 这两行包罗了须要的头文件,以便编译器知道 AP_Arming_Sub 类和 Sub 类(或结构体)的界说。
  • "AP_Arming_Sub.h" 是包罗 AP_Arming_Sub 类声明的头文件。
  • "Sub.h" 包罗一个名为 Sub 的类或结构体的界说,这个 Sub 类(以下称为“子类”)代表一个特定的无人机子体系的设置。
AP_Arming_Sub::rc_calibration_checks(bool display_failure)
  1. bool AP_Arming_Sub::rc_calibration_checks(bool display_failure)
  2. {
复制代码

  • 这里界说了 AP_Arming_Sub 类的 rc_calibration_checks 成员函数。此函数担当一个布尔参数 display_failure,它指示是否应该体现校准失败的信息。
  1.     const RC_Channel *channels[] = {
  2.         sub.channel_roll,
  3.         sub.channel_pitch,
  4.         sub.channel_throttle,
  5.         sub.channel_yaw
  6.     };
复制代码

  • 这里界说了一个 RC_Channel 范例的指针数组 channels,它包罗指向四个差别通道的指针。这些通道通常代表多旋翼或无人机的遥控器控制通道:

    • channel_roll:横滚通道,控制无人机左右倾斜。
    • channel_pitch:俯仰通道,控制无人机前后倾斜。
    • channel_throttle:油门通道,控制无人机的升力。
    • channel_yaw:偏航通道,控制无人机的旋转方向。

  • sub 是一个 Sub 范例的对象,它包罗了这些通道的引用或指针。
  1.     return rc_checks_copter_sub(display_failure, channels);
  2. }
复制代码

  • 这行代码调用了 rc_checks_copter_sub 函数(这个函数大概在当前文件或其他文件中界说),并将 display_failure 和 channels 数组作为参数通报。这个函数的目的是实行详细的遥控器校准查抄,并返回一个布尔值,指示查抄是否通过。
  • 返回值会被通报回调用 rc_calibration_checks 的地方,指示校准查抄是否乐成。
AP_Arming_Sub::has_disarm_function() const
  1. bool AP_Arming_Sub::has_disarm_function() const {
复制代码

  • has_disarm_function 是 AP_Arming_Sub 类的一个 const 成员函数,这意味着它不会修改类的任何成员变量。const 关键字用在成员函数的声明和界说中,以确保函数调用不会改变对象的状态。
  1.     bool has_shift_function = false;
复制代码

  • 界说一个布尔变量 has_shift_function,用于跟踪是否存在“shift”功能按钮。
  1.     // make sure the craft has a disarm button assigned before it is armed
  2.     // check all the standard btn functions
  3.     for (uint8_t i = 0; i < 16; i++) {
  4.         switch (sub.get_button(i)->function(false)) {
  5.             case JSButton::k_shift :
  6.                 has_shift_function = true;
  7.                 break;
  8.             case JSButton::k_arm_toggle :
  9.                 return true;
  10.             case JSButton::k_disarm :
  11.                 return true;
  12.         }
  13.     }
复制代码

  • 这段代码遍历前16个按钮(假设装备有16个按钮),查抄每个按钮的尺度功能(非“shift”功能)。
  • sub.get_button(i) 获取第 i 个按钮对象的指针。
  • function(false) 调用按钮对象的 function 方法,通报 false 表现不查抄“shift”功能。
  • 假如按钮的功能是 JSButton::k_shift,则设置 has_shift_function 为 true。
  • 假如按钮的功能是 JSButton::k_arm_toggle 或 JSButton::k_disarm,则直接返回 true,由于这表现存在排除武器功能。
  1.     // check all the shift functions if there's shift assigned
  2.     if (has_shift_function) {
  3.         for (uint8_t i = 0; i < 16; i++) {
  4.             switch (sub.get_button(i)->function(true)) {
  5.                 case JSButton::k_arm_toggle :
  6.                 case JSButton::k_disarm :
  7.                     return true;
  8.             }
  9.         }
  10.     }
复制代码

  • 假如检测到有 shift 功能按钮,则再次遍历全部按钮,这次查抄它们的“shift”功能。
  • function(true)这次通报 true 来查抄按钮的“shift”功能。
  • 假如任何一个按钮的“shift”功能是 JSButton::k_arm_toggle 或 JSButton::k_disarm,则返回 true。
  1.     return false;
  2. }
复制代码

  • 假如遍历全部按钮后没有找到排除武器功能,则返回 false。
AP_Arming_Sub::pre_arm_checks(bool display_failure)
  1. bool AP_Arming_Sub::pre_arm_checks(bool display_failure)
复制代码

  • bool: 表现这个函数返回一个布尔范例的值,即true或false。
  • AP_Arming_Sub::: 指定pre_arm_checks函数是AP_Arming_Sub类的成员函数。
  • pre_arm_checks: 函数名,意味着实行预启动查抄。
  • (bool display_failure): 函数汲取一个名为display_failure的布尔型参数,这个参数用来决定是否体现查抄失败的信息。
  1. {
  2.     if (armed) {
  3.         return true;
  4.     }
复制代码

  • 这段代码查抄一个名为armed的变量(一个成员变量,表现体系是否已经启动)。
  • 假如体系已经启动(armed为true),则函数直接返回true,不须要举行进一步的查抄。
  1.     // don't allow arming unless there is a disarm button configured
  2.     if (!has_disarm_function()) {
  3.         check_failed(display_failure, "Must assign a disarm or arm_toggle button");
  4.         return false;
  5.     }
复制代码

  • 这部分代码查抄是否存在一个设置好的解锁按钮。
  • !has_disarm_function(): 假如has_disarm_function()函数返回false(表现没有设置解锁按钮),则实行以下代码。
  • check_failed(display_failure, "Must assign a disarm or arm_toggle button"): 调用一个名为check_failed的函数,它用来记载错误信息或体现错误消息。通报的字符串阐明确错误的缘故因由。
  • return false;: 假如没有设置解锁按钮,则返回false,表现预查抄失败。
  1.     return AP_Arming::pre_arm_checks(display_failure);
  2. }
复制代码

  • 这行代码调用基类AP_Arming的pre_arm_checks函数,继续实行进一步的预启动查抄。
  • 假如这个基类的预查抄也返回true,则整个pre_arm_checks函数返回true,否则返回false。
AP_Arming_Sub::ins_checks(bool display_failure)
  1. bool AP_Arming_Sub::ins_checks(bool display_failure)
复制代码

  • bool: 表现这个函数返回一个布尔范例的值,即true或false。
  • AP_Arming_Sub::: 指定ins_checks函数是AP_Arming_Sub类的成员函数。
  • ins_checks: 函数名,意味着实行与INS相干的预启动查抄。
  • (bool display_failure): 函数汲取一个名为display_failure的布尔型参数,用来决定是否体现查抄失败的信息。
  1. {
  2.     // call parent class checks
  3.     if (!AP_Arming::ins_checks(display_failure)) {
  4.         return false;
  5.     }
复制代码

  • 这段代码调用基类AP_Arming的ins_checks函数,实行与INS相干的通用预启动查抄。
  • 假如基类的查抄返回false,表现查抄失败,那么这个函数也立刻返回false。
  1.     // additional sub-specific checks
  2.     if (check_enabled(ARMING_CHECK_INS)) {
复制代码

  • 这段代码查抄是否启用了特定的查抄项ARMING_CHECK_INS。check_enabled根据传入的参数来确定是否实行后续的查抄。
  1.         char failure_msg[50] = {};
  2.         if (!AP::ahrs().pre_arm_check(false, failure_msg, sizeof(failure_msg))) {
  3.             check_failed(ARMING_CHECK_INS, display_failure, "AHRS: %s", failure_msg);
  4.             return false;
  5.         }
  6.     }
复制代码

  • char failure_msg[50] = {};: 界说一个字符数组failure_msg,用来存储大概的错误信息,巨细为50个字符。
  • AP::ahrs().pre_arm_check(false, failure_msg, sizeof(failure_msg)): 调用AP::ahrs()对象的pre_arm_check方法。AP::ahrs()返回一个AHRS(Attitude and Heading Reference System)类的实例。pre_arm_check方法实行与AHRS相干的查抄,假如查抄失败,它将错误信息写入failure_msg数组,并返回false。
  • 假如pre_arm_check返回false,则实行以下代码:

    • check_failed(ARMING_CHECK_INS, display_failure, "AHRS: %s", failure_msg);: 调用check_failed函数,它用于记载错误信息或体现错误消息。它汲取查抄项标识符ARMING_CHECK_INS,是否体现失败的标记display_failure,以合格式化的错误信息字符串,此中%s将被failure_msg中的内容更换。
    • return false;: 假如查抄失败,则返回false。

  1.     return true;
  2. }
复制代码

  • 假如全部的查抄都通过,则函数返回true。
AP_Arming_Sub::arm(AP_Arming::Method method, bool do_arming_checks)
  1. bool AP_Arming_Sub::arm(AP_Arming::Method method, bool do_arming_checks)
  2. {
  3.     static bool in_arm_motors = false;
复制代码

  • 声明一个静态布尔变量in_arm_motors,用于防止函数重入。
  1.     // exit immediately if already in this function
  2.     if (in_arm_motors) {
  3.         return false;
  4.     }
复制代码

  • 假如in_arm_motors为true,表现函数已经在实行中,为了制止重入,直接返回false。
  1.     in_arm_motors = true;
复制代码

  • 设置in_arm_motors为true,表现当前正在实行启动过程。
  1.     if (!AP_Arming::arm(method, do_arming_checks)) {
  2.         AP_Notify::events.arming_failed = true;
  3.         in_arm_motors = false;
  4.         return false;
  5.     }
复制代码

  • 调用基类AP_Arming的arm方法实验启动。假如返回false,表现启动失败,设置关照变乱,重置in_arm_motors,并返回false。
  1. #if HAL_LOGGING_ENABLED
  2.     // let logger know that we're armed (it may open logs e.g.)
  3.     AP::logger().set_vehicle_armed(true);
  4. #endif
复制代码

  • 假如启用了日志日志记载功能,关照日志日志体系车辆已启动。
  1.     // disable cpu failsafe because initialising everything takes a while
  2.     sub.mainloop_failsafe_disable();
复制代码

  • 禁用主循环故障安全,由于在初始化过程中大概会有较长时间的耽误。
  1.     // notify that arming will occur (we do this early to give plenty of warning)
  2.     AP_Notify::flags.armed = true;
  3.     // call notify update a few times to ensure the message gets out
  4.     for (uint8_t i=0; i<=10; i++) {
  5.         AP::notify().update();
  6.     }
复制代码

  • 设置关照标记表明车辆将要启动,并通过多次调用更新函数确保关照消息被发送。
  1. #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
  2.     send_arm_disarm_statustext("Arming motors");
  3. #endif
复制代码

  • 假如设置为SITL(软件在环仿真),发送状态文本消息表明正在启动电机。
  1.     AP_AHRS &ahrs = AP::ahrs();
复制代码

  • 获取AHRS(姿态和航向参考体系)实例的引用。
  1.     sub.initial_armed_bearing = ahrs.yaw_sensor;
复制代码

  • 设置初始启动时的航向。
  1.     if (!ahrs.home_is_set()) {
  2.         // Reset EKF altitude if home hasn't been set yet (we use EKF altitude as substitute for alt above home)
  3.         // Always use absolute altitude for ROV
  4.         // ahrs.resetHeightDatum();
  5.         // AP::logger().Write_Event(LogEvent::EKF_ALT_RESET);
  6.     } else if (!ahrs.home_is_locked()) {
  7.         // Reset home position if it has already been set before (but not locked)
  8.         if (!sub.set_home_to_current_location(false)) {
  9.             // ignore this failure
  10.         }
  11.     }
复制代码

  • 假如家位置未设置,则重置EKF高度;假如家位置未锁定,则重置为当前位置。
  1.     hal.util->set_soft_armed(true);
复制代码

  • 设置软启动标记,表明体系已启动。
  1.     // enable output to motors
  2.     sub.enable_motor_output();
复制代码

  • 启用电机输出。
  1.     // finally actually arm the motors
  2.     sub.motors.armed(true);
复制代码

  • 终极启动电机。
  1. #if HAL_LOGGING_ENABLED
  2.     // log flight mode in case it was changed while vehicle was disarmed
  3.     AP::logger().Write_Mode((uint8_t)sub.control_mode, sub.control_mode_reason);
  4. #endif
复制代码

  • 假如启用了日志日志记载,记载当前的飞行模式。
  1.     // reenable failsafe
  2.     sub.mainloop_failsafe_enable();
复制代码

  • 重新启用主循环故障安全。
  1.     // perf monitor ignores delay due to arming
  2.     AP::scheduler().perf_info.ignore_this_loop();
复制代码

  • 关照性能监督器忽略由于启动导致的耽误。
  1.     // flag exiting this function
  2.     in_arm_motors = false;
复制代码

  • 标记退出此函数,将in_arm_motors重置为false。
  1.     // if we do not have an ekf origin then we can't use the WMM tables
  2.     if (!sub.ensure_ekf_origin()) {
  3.         gcs().send_text(MAV_SEVERITY_WARNING, "Compass performance degraded");
  4.         if (check_enabled(ARMING_CHECK_PARAMETERS)) {
  5.             check_failed(ARMING_CHECK_PARAMETERS, true, "No world position, check ORIGIN_* parameters");
  6.             return false;
  7.         }
  8.     }
复制代码

  • 假如EKF原点未设置,则发送告诫并查抄是否启用了参数查抄。假如启用了,则记载失败并返回false。
  1.     // return success    return true;
  2. }
复制代码

  • 假如全部步调都乐成完成,则返回true。
AP_Arming_Sub::disarm(const AP_Arming::Method method, bool do_disarm_checks)
  1. bool AP_Arming_Sub::disarm(const AP_Arming::Method method, bool do_disarm_checks)
  2. {
复制代码

  • 声明一个返回布尔值的函数disarm,它汲取两个参数:解锁方法method和一个布尔值do_disarm_checks,后者指定是否实行解锁前的查抄。
  1.     // return immediately if we are already disarmed
  2.     if (!sub.motors.armed()) {
  3.         return false;
  4.     }
复制代码

  • 假如电机已经处于未启动状态(即已解锁),则立刻返回false。
  1.     if (!AP_Arming::disarm(method, do_disarm_checks)) {
  2.         return false;
  3.     }
复制代码

  • 调用基类AP_Arming的disarm方法实验解锁。假如返回false,表现解锁失败,因此直接返回false。
  1. #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
  2.     send_arm_disarm_statustext("Disarming motors");
  3. #endif
复制代码

  • 假如设置为SITL(软件在环仿真),发送状态文本消息表明正在解锁电机。
  1.     auto &ahrs = AP::ahrs();
复制代码

  • 获取AHRS(姿态和航向参考体系)实例的引用。
  1.     // save compass offsets learned by the EKF if enabled
  2.     if (ahrs.use_compass() && AP::compass().get_learn_type() == Compass::LEARN_EKF) {
  3.         for (uint8_t i=0; i<COMPASS_MAX_INSTANCES; i++) {
  4.             Vector3f magOffsets;
  5.             if (ahrs.getMagOffsets(i, magOffsets)) {
  6.                 AP::compass().set_and_save_offsets(i, magOffsets);
  7.             }
  8.         }
  9.     }
复制代码

  • 假如启用了指南针,而且EKF学习了指南针偏移量,则生存这些偏移量。
  1.     // send disarm command to motors
  2.     sub.motors.armed(false);
复制代码

  • 向电机发送解锁下令,将电机设置为未启动状态。
  1.     // reset the mission
  2.     sub.mission.reset();
复制代码

  • 重置任务,大概是指飞行任务或一系列预定的动作。
  1. #if HAL_LOGGING_ENABLED
  2.     AP::logger().set_vehicle_armed(false);
  3. #endif
复制代码

  • 假如启用了日志记载功能,关照日志体系车辆已解锁。
  1.     hal.util->set_soft_armed(false);
复制代码

  • 更新软启动状态,表明体系已解锁。
  1.     // clear input holds
  2.     sub.clear_input_hold();
复制代码

  • 扫除输入保持状态,这大概是为了确保在解锁后不会有任何悬挂的输入下令影响体系。
  1.     return true;
  2. }
复制代码

  • 假如解锁过程乐成完成,则返回true。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表