AP_Arming_Sub.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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(ARMING_CHECK_NONE, 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 ((checks_to_perform & ARMING_CHECK_ALL) ||
  60. (checks_to_perform & ARMING_CHECK_INS)) {
  61. if (!AP::ahrs().prearm_healthy()) {
  62. const char *reason = AP::ahrs().prearm_failure_reason();
  63. if (reason == nullptr) {
  64. reason = "AHRS not healthy";
  65. }
  66. check_failed(ARMING_CHECK_INS, display_failure, "%s", reason);
  67. return false;
  68. }
  69. }
  70. return true;
  71. }
  72. bool AP_Arming_Sub::arm(AP_Arming::Method method, bool do_arming_checks)
  73. {
  74. static bool in_arm_motors = false;
  75. // exit immediately if already in this function
  76. if (in_arm_motors) {
  77. return false;
  78. }
  79. in_arm_motors = true;
  80. if (!AP_Arming::arm(method, do_arming_checks)) {
  81. AP_Notify::events.arming_failed = true;
  82. in_arm_motors = false;
  83. return false;
  84. }
  85. // let logger know that we're armed (it may open logs e.g.)
  86. AP::logger().set_vehicle_armed(true);
  87. // disable cpu failsafe because initialising everything takes a while
  88. sub.mainloop_failsafe_disable();
  89. // notify that arming will occur (we do this early to give plenty of warning)
  90. AP_Notify::flags.armed = true;
  91. // call notify update a few times to ensure the message gets out
  92. for (uint8_t i=0; i<=10; i++) {
  93. AP::notify().update();
  94. }
  95. #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
  96. gcs().send_text(MAV_SEVERITY_INFO, "Arming motors");
  97. #endif
  98. AP_AHRS &ahrs = AP::ahrs();
  99. sub.initial_armed_bearing = ahrs.yaw_sensor;
  100. if (!ahrs.home_is_set()) {
  101. // Reset EKF altitude if home hasn't been set yet (we use EKF altitude as substitute for alt above home)
  102. // Always use absolute altitude for ROV
  103. // ahrs.resetHeightDatum();
  104. // Log_Write_Event(DATA_EKF_ALT_RESET);
  105. } else if (ahrs.home_is_set() && !ahrs.home_is_locked()) {
  106. // Reset home position if it has already been set before (but not locked)
  107. if (!sub.set_home_to_current_location(false)) {
  108. // ignore this failure
  109. }
  110. }
  111. // enable gps velocity based centrefugal force compensation
  112. ahrs.set_correct_centrifugal(true);
  113. hal.util->set_soft_armed(true);
  114. // enable output to motors
  115. sub.enable_motor_output();
  116. // finally actually arm the motors
  117. sub.motors.armed(true);
  118. AP::logger().Write_Event(DATA_ARMED);
  119. // log flight mode in case it was changed while vehicle was disarmed
  120. AP::logger().Write_Mode(sub.control_mode, sub.control_mode_reason);
  121. // reenable failsafe
  122. sub.mainloop_failsafe_enable();
  123. // perf monitor ignores delay due to arming
  124. AP::scheduler().perf_info.ignore_this_loop();
  125. // flag exiting this function
  126. in_arm_motors = false;
  127. // return success
  128. return true;
  129. }
  130. bool AP_Arming_Sub::disarm()
  131. {
  132. // return immediately if we are already disarmed
  133. if (!sub.motors.armed()) {
  134. return false;
  135. }
  136. if (!AP_Arming::disarm()) {
  137. return false;
  138. }
  139. #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
  140. gcs().send_text(MAV_SEVERITY_INFO, "Disarming motors");
  141. #endif
  142. AP_AHRS_NavEKF &ahrs = AP::ahrs_navekf();
  143. // save compass offsets learned by the EKF if enabled
  144. if (ahrs.use_compass() && AP::compass().get_learn_type() == Compass::LEARN_EKF) {
  145. for (uint8_t i=0; i<COMPASS_MAX_INSTANCES; i++) {
  146. Vector3f magOffsets;
  147. if (ahrs.getMagOffsets(i, magOffsets)) {
  148. AP::compass().set_and_save_offsets(i, magOffsets);
  149. }
  150. }
  151. }
  152. AP::logger().Write_Event(DATA_DISARMED);
  153. // send disarm command to motors
  154. sub.motors.armed(false);
  155. // reset the mission
  156. sub.mission.reset();
  157. AP::logger().set_vehicle_armed(false);
  158. // disable gps velocity based centrefugal force compensation
  159. ahrs.set_correct_centrifugal(false);
  160. hal.util->set_soft_armed(false);
  161. // clear input holds
  162. sub.clear_input_hold();
  163. return true;
  164. }