// check we have required terrain data bool AP_Arming_Copter::pre_arm_terrain_check(bool display_failure) { #if AP_TERRAIN_AVAILABLE && AC_TERRAIN // succeed if not using terrain data if (!copter.terrain_use()) { return true; } // check if terrain following is enabled, using a range finder but RTL_ALT is higher than rangefinder's max range // To-Do: modify RTL return path to fly at or above the RTL_ALT and remove this check if (copter.rangefinder_state.enabled && (copter.g.rtl_altitude > copter.rangefinder.max_distance_cm_orient(ROTATION_PITCH_270))) { check_failed(ARMING_CHECK_PARAMETERS, display_failure, "RTL_ALT above rangefinder max range"); return false; } // show terrain statistics uint16_t terr_pending, terr_loaded; copter.terrain.get_statistics(terr_pending, terr_loaded); bool have_all_data = (terr_pending <= 0); if (!have_all_data) { check_failed(ARMING_CHECK_PARAMETERS, display_failure, "Waiting for Terrain data"); } return have_all_data; #else return true; #endif }
// check nothing is too close to vehicle bool AP_Arming_Copter::pre_arm_proximity_check(bool display_failure) { #if PROXIMITY_ENABLED == ENABLED // return true immediately if no sensor present if (copter.g2.proximity.get_status() == AP_Proximity::Proximity_NotConnected) { return true; } // return false if proximity sensor unhealthy if (copter.g2.proximity.get_status() < AP_Proximity::Proximity_Good) { check_failed(ARMING_CHECK_PARAMETERS, display_failure, "check proximity sensor"); return false; } // get closest object if we might use it for avoidance #if AC_AVOID_ENABLED == ENABLED float angle_deg, distance; if (copter.avoid.proximity_avoidance_enabled() && copter.g2.proximity.get_closest_object(angle_deg, distance)) { // display error if something is within 60cm if (distance <= 0.6f) { check_failed(ARMING_CHECK_PARAMETERS, display_failure, "Proximity %d deg, %4.2fm", (int)angle_deg, (double)distance); return false; } } #endif #endif return true; }
// perform pre-arm checks // return true if the checks pass successfully bool AP_Arming_Copter::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(ARMING_CHECK_NONE, 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(ARMING_CHECK_NONE, display_failure, "Motor Interlock Enabled"); } // succeed if pre arm checks are disabled if (checks_to_perform == ARMING_CHECK_NONE) { return true; } return fence_checks(display_failure) & parameter_checks(display_failure) & motor_checks(display_failure) & pilot_throttle_checks(display_failure) & AP_Arming::pre_arm_checks(display_failure); }
bool AP_Arming::servo_checks(bool report) const { bool check_passed = true; for (uint8_t i = 0; i < NUM_SERVO_CHANNELS; i++) { const SRV_Channel *c = SRV_Channels::srv_channel(i); if (c == nullptr || c->get_function() == SRV_Channel::k_none) { continue; } const uint16_t trim = c->get_trim(); if (c->get_output_min() > trim) { check_failed(ARMING_CHECK_NONE, report, "SERVO%d minimum is greater than trim", i + 1); check_passed = false; } if (c->get_output_max() < trim) { check_failed(ARMING_CHECK_NONE, report, "SERVO%d maximum is less than trim", i + 1); check_passed = false; } } #if HAL_WITH_IO_MCU if (!iomcu.healthy()) { check_failed(ARMING_CHECK_NONE, report, "IOMCU is unhealthy"); check_passed = false; } #endif return check_passed; }
// performs pre_arm gps related checks and returns true if passed bool AP_Arming_Rover::gps_checks(bool display_failure) { if (!rover.control_mode->requires_position() && !rover.control_mode->requires_velocity()) { // we don't care! return true; } // check for ekf failsafe if (rover.failsafe.ekf) { check_failed(ARMING_CHECK_NONE, display_failure, "EKF failsafe"); return false; } // ensure position esetimate is ok if (!rover.ekf_position_ok()) { const char *reason = AP::ahrs().prearm_failure_reason(); if (reason == nullptr) { reason = "Need Position Estimate"; } check_failed(ARMING_CHECK_NONE, display_failure, "%s", reason); return false; } // call parent gps checks return AP_Arming::gps_checks(display_failure); }
bool AP_Arming::board_voltage_checks(bool report) { // check board voltage if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_VOLTAGE)) { #if HAL_HAVE_BOARD_VOLTAGE const float bus_voltage = hal.analogin->board_voltage(); const float vbus_min = AP_BoardConfig::get_minimum_board_voltage(); if(((bus_voltage < vbus_min) || (bus_voltage > AP_ARMING_BOARD_VOLTAGE_MAX))) { check_failed(ARMING_CHECK_VOLTAGE, report, "Board (%1.1fv) out of range %1.1f-%1.1fv", (double)bus_voltage, (double)vbus_min, (double)AP_ARMING_BOARD_VOLTAGE_MAX); return false; } #endif // HAL_HAVE_BOARD_VOLTAGE #if HAL_HAVE_SERVO_VOLTAGE const float vservo_min = AP_BoardConfig::get_minimum_servo_voltage(); if (is_positive(vservo_min)) { const float servo_voltage = hal.analogin->servorail_voltage(); if (servo_voltage < vservo_min) { check_failed(ARMING_CHECK_VOLTAGE, report, "Servo voltage to low (%1.2fv < %1.2fv)", (double)servo_voltage, (double)vservo_min); return false; } } #endif // HAL_HAVE_SERVO_VOLTAGE } return true; }
bool AP_Arming::rc_calibration_checks(bool report) { bool check_passed = true; const uint8_t num_channels = RC_Channels::get_valid_channel_count(); for (uint8_t i = 0; i < NUM_RC_CHANNELS; i++) { const RC_Channel *c = rc().channel(i); if (c == nullptr) { continue; } if (i >= num_channels && !(c->has_override())) { continue; } const uint16_t trim = c->get_radio_trim(); if (c->get_radio_min() > trim) { check_failed(ARMING_CHECK_RC, report, "RC%d minimum is greater than trim", i + 1); check_passed = false; } if (c->get_radio_max() < trim) { check_failed(ARMING_CHECK_RC, report, "RC%d maximum is less than trim", i + 1); check_passed = false; } } return check_passed; }
bool AP_Arming::gps_checks(bool report) { const AP_GPS &gps = AP::gps(); if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_GPS)) { //GPS OK? if (!AP::ahrs().home_is_set() || gps.status() < AP_GPS::GPS_OK_FIX_3D) { check_failed(ARMING_CHECK_GPS, report, "Bad GPS Position"); return false; } //GPS update rate acceptable if (!gps.is_healthy()) { check_failed(ARMING_CHECK_GPS, report, "GPS is not healthy"); return false; } // check GPSs are within 50m of each other and that blending is healthy float distance_m; if (!gps.all_consistent(distance_m)) { check_failed(ARMING_CHECK_GPS, report, "GPS positions differ by %4.1fm", (double)distance_m); return false; } if (!gps.blend_health_check()) { check_failed(ARMING_CHECK_GPS, report, "GPS blending unhealthy"); return false; } // check AHRS and GPS are within 10m of each other Location gps_loc = gps.location(); Location ahrs_loc; if (AP::ahrs().get_position(ahrs_loc)) { const float distance = location_diff(gps_loc, ahrs_loc).length(); if (distance > AP_ARMING_AHRS_GPS_ERROR_MAX) { if (report) { gcs().send_text(MAV_SEVERITY_CRITICAL, "PreArm: GPS and AHRS differ by %4.1fm", (double)distance); } return false; } } } if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_GPS_CONFIG)) { uint8_t first_unconfigured = gps.first_unconfigured_gps(); if (first_unconfigured != AP_GPS::GPS_ALL_CONFIGURED) { if (report) { gcs().send_text(MAV_SEVERITY_CRITICAL, "PreArm: GPS %d failing configuration checks", first_unconfigured + 1); gps.broadcast_first_configuration_failure_reason(); } return false; } } return true; }
void brk_test() { void *oldbrk1, *oldbrk2; const void *brk_failed = (void *) - 1; int len; unsigned int *tmp; unsigned int ii; (void) printf("-- brk test start\n"); /* A length which is not a page multiple, yet a multiple of 8. */ len = 8192 * 5 + 128; /* Try allocating some memory. */ oldbrk1 = sbrk(len); if (oldbrk1 == brk_failed) { check_failed("sbrk alloc"); } /* Try writing to the memory. */ printf("writing to memory at %p\n", oldbrk1); tmp = (unsigned int *) oldbrk1; for (ii = 0; ii < (len / sizeof(int)); ii++) *tmp++ = ii; /* Try verifying what we wrote. */ printf("verifying memory\n"); tmp = (unsigned int *) oldbrk1; for (ii = 0; ii < (len / sizeof(int)); ii++) { if (*tmp++ != ii) { (void) printf("verify failed at 0x%lx\n", (unsigned long) tmp); exit(1); } } /* Try freeing the memory. */ printf("freeing memory\n"); oldbrk2 = sbrk(-len); if (oldbrk2 == brk_failed) { check_failed("sbrk dealloc"); } /* oldbrk2 should be at least "len" greater than oldbrk1. */ if ((unsigned long) oldbrk2 < ((unsigned long) oldbrk1 + len)) { (void) printf("sbrk didn't return old brk??\n"); exit(1); } (void) printf("-- brk test passed\n"); }
bool AP_Arming::mission_checks(bool report) { if (((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_MISSION)) && _required_mission_items) { AP_Mission *mission = AP::mission(); if (mission == nullptr) { check_failed(ARMING_CHECK_MISSION, report, "No mission library present"); #if CONFIG_HAL_BOARD == HAL_BOARD_SITL AP_HAL::panic("Mission checks requested, but no mission was allocated"); #endif // CONFIG_HAL_BOARD == HAL_BOARD_SITL return false; } AP_Rally *rally = AP::rally(); if (rally == nullptr) { check_failed(ARMING_CHECK_MISSION, report, "No rally library present"); #if CONFIG_HAL_BOARD == HAL_BOARD_SITL AP_HAL::panic("Mission checks requested, but no rally was allocated"); #endif // CONFIG_HAL_BOARD == HAL_BOARD_SITL return false; } const struct MisItemTable { MIS_ITEM_CHECK check; MAV_CMD mis_item_type; const char *type; } misChecks[5] = { {MIS_ITEM_CHECK_LAND, MAV_CMD_NAV_LAND, "land"}, {MIS_ITEM_CHECK_VTOL_LAND, MAV_CMD_NAV_VTOL_LAND, "vtol land"}, {MIS_ITEM_CHECK_DO_LAND_START, MAV_CMD_DO_LAND_START, "do land start"}, {MIS_ITEM_CHECK_TAKEOFF, MAV_CMD_NAV_TAKEOFF, "takeoff"}, {MIS_ITEM_CHECK_VTOL_TAKEOFF, MAV_CMD_NAV_VTOL_TAKEOFF, "vtol takeoff"}, }; for (uint8_t i = 0; i < ARRAY_SIZE(misChecks); i++) { if (_required_mission_items & misChecks[i].check) { if (!mission->contains_item(misChecks[i].mis_item_type)) { check_failed(ARMING_CHECK_MISSION, report, "Missing mission item: %s", misChecks[i].type); return false; } } } if (_required_mission_items & MIS_ITEM_CHECK_RALLY) { Location ahrs_loc; if (!AP::ahrs().get_position(ahrs_loc)) { check_failed(ARMING_CHECK_MISSION, report, "Can't check rally without position"); return false; } RallyLocation rally_loc = {}; if (!rally->find_nearest_rally_point(ahrs_loc, rally_loc)) { check_failed(ARMING_CHECK_MISSION, report, "No sufficently close rally point located"); return false; } } } return true; }
/* check base system operations */ bool AP_Arming::system_checks(bool report) { if (check_enabled(ARMING_CHECK_SYSTEM)) { if (!hal.storage->healthy()) { check_failed(ARMING_CHECK_SYSTEM, report, "Param storage failed"); return false; } } if (AP::internalerror().errors() != 0) { check_failed(ARMING_CHECK_NONE, report, "Internal errors detected (0x%x)", AP::internalerror().errors()); return false; } return true; }
bool AP_Arming::logging_checks(bool report) { if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_LOGGING)) { if (DataFlash_Class::instance()->logging_failed()) { check_failed(ARMING_CHECK_LOGGING, report, "Logging failed"); return false; } if (!DataFlash_Class::instance()->CardInserted()) { check_failed(ARMING_CHECK_LOGGING, report, "No SD card"); return false; } } return true; }
bool AP_Arming::arm_checks(ArmingMethod method) { // ensure the GPS drivers are ready on any final changes if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_GPS_CONFIG)) { if (!AP::gps().prepare_for_arming()) { return false; } } // check system health on arm as well as prearm if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_SYSTEM)) { if (!system_checks(true)) { return false; } } // note that this will prepare DataFlash to start logging // so should be the last check to be done before arming if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_LOGGING)) { DataFlash_Class *df = DataFlash_Class::instance(); df->PrepForArming(); if (!df->logging_started()) { check_failed(ARMING_CHECK_LOGGING, true, "Logging not started"); return false; } } return true; }
bool AP_Arming::arm_checks(AP_Arming::Method method) { // ensure the GPS drivers are ready on any final changes if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_GPS_CONFIG)) { if (!AP::gps().prepare_for_arming()) { return false; } } // note that this will prepare AP_Logger to start logging // so should be the last check to be done before arming // Note also that we need to PrepForArming() regardless of whether // the arming check flag is set - disabling the arming check // should not stop logging from working. AP_Logger *logger = AP_Logger::get_singleton(); if (logger->logging_present()) { // If we're configured to log, prep it logger->PrepForArming(); if (!logger->logging_started() && ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_LOGGING))) { check_failed(ARMING_CHECK_LOGGING, true, "Logging not started"); return false; } } return true; }
// Copter and sub share the same RC input limits // Copter checks that min and max have been configured by default, Sub does not bool AP_Arming::rc_checks_copter_sub(const bool display_failure, const RC_Channel *channels[4], const bool check_min_max) const { // set rc-checks to success if RC checks are disabled if ((checks_to_perform != ARMING_CHECK_ALL) && !(checks_to_perform & ARMING_CHECK_RC)) { return true; } bool ret = true; const char *channel_names[] = { "Roll", "Pitch", "Throttle", "Yaw" }; for (uint8_t i=0; i<ARRAY_SIZE(channel_names);i++) { const RC_Channel *channel = channels[i]; const char *channel_name = channel_names[i]; // check if radio has been calibrated if (check_min_max && !channel->min_max_configured()) { check_failed(ARMING_CHECK_RC, display_failure, "RC %s not configured", channel_name); ret = false; } if (channel->get_radio_min() > 1300) { check_failed(ARMING_CHECK_RC, display_failure, "%s radio min too high", channel_name); ret = false; } if (channel->get_radio_max() < 1700) { check_failed(ARMING_CHECK_RC, display_failure, "%s radio max too low", channel_name); ret = false; } bool fail = true; if (i == 2) { // skip checking trim for throttle as older code did not check it fail = false; } if (channel->get_radio_trim() < channel->get_radio_min()) { check_failed(ARMING_CHECK_RC, display_failure, "%s radio trim below min", channel_name); if (fail) { ret = false; } } if (channel->get_radio_trim() > channel->get_radio_max()) { check_failed(ARMING_CHECK_RC, display_failure, "%s radio trim above max", channel_name); if (fail) { ret = false; } } } return ret; }
/** * test_rmvol - test that UBI rmvol ioctl rejects bad input parameters. * * This function returns %0 if the test passed and %-1 if not. */ static int test_rmvol(void) { int ret; struct ubi_mkvol_request req; const char *name = TESTNAME ":test_rmvol()"; /* Bad vol_id */ ret = ubi_rmvol(libubi, node, -1); if (check_failed(ret, EINVAL, "ubi_rmvol", "vol_id = -1")) return -1; ret = ubi_rmvol(libubi, node, dev_info.max_vol_count); if (check_failed(ret, EINVAL, "ubi_rmvol", "vol_id = %d", dev_info.max_vol_count)) return -1; /* Try to remove non-existing volume */ ret = ubi_rmvol(libubi, node, 0); if (check_failed(ret, ENODEV, "ubi_rmvol", "removed non-existing volume 0")) return -1; /* Try to remove volume twice */ req.vol_id = UBI_VOL_NUM_AUTO; req.alignment = 1; req.bytes = dev_info.avail_bytes; req.vol_type = UBI_DYNAMIC_VOLUME; req.name = name; if (ubi_mkvol(libubi, node, &req)) { failed("ubi_mkvol"); return -1; } if (ubi_rmvol(libubi, node, req.vol_id)) { failed("ubi_rmvol"); return -1; } ret = ubi_rmvol(libubi, node, req.vol_id); if (check_failed(ret, ENODEV, "ubi_rmvol", "volume %d removed twice", req.vol_id)) return -1; return 0; }
// check motor setup was successful bool AP_Arming_Copter::motor_checks(bool display_failure) { // check motors initialised correctly if (!copter.motors->initialised_ok()) { check_failed(ARMING_CHECK_NONE, display_failure, "check firmware or FRAME_CLASS"); return false; } return true; }
/* check base system operations */ bool AP_Arming::system_checks(bool report) { if (check_enabled(ARMING_CHECK_SYSTEM)) { if (!hal.storage->healthy()) { check_failed(ARMING_CHECK_SYSTEM, report, "Param storage failed"); } } return true; }
bool AP_Arming::compass_checks(bool report) { if ((checks_to_perform) & ARMING_CHECK_ALL || (checks_to_perform) & ARMING_CHECK_COMPASS) { Compass &_compass = AP::compass(); // avoid Compass::use_for_yaw(void) as it implicitly calls healthy() which can // incorrectly skip the remaining checks, pass the primary instance directly if (!_compass.use_for_yaw(_compass.get_primary())) { // compass use is disabled return true; } if (!_compass.healthy()) { check_failed(ARMING_CHECK_COMPASS, report, "Compass not healthy"); return false; } // check compass learning is on or offsets have been set if (!_compass.learn_offsets_enabled() && !_compass.configured()) { check_failed(ARMING_CHECK_COMPASS, report, "Compass not calibrated"); return false; } //check if compass is calibrating if (_compass.is_calibrating()) { check_failed(ARMING_CHECK_COMPASS, report, "Compass calibration running"); return false; } //check if compass has calibrated and requires reboot if (_compass.compass_cal_requires_reboot()) { check_failed(ARMING_CHECK_COMPASS, report, "Compass calibrated requires reboot"); return false; } // check for unreasonable compass offsets Vector3f offsets = _compass.get_offsets(); if (offsets.length() > _compass.get_offsets_max()) { check_failed(ARMING_CHECK_COMPASS, report, "Compass offsets too high"); return false; } // check for unreasonable mag field length float mag_field = _compass.get_field().length(); if (mag_field > AP_ARMING_COMPASS_MAGFIELD_MAX || mag_field < AP_ARMING_COMPASS_MAGFIELD_MIN) { check_failed(ARMING_CHECK_COMPASS, report, "Check mag field"); return false; } // check all compasses point in roughly same direction if (!_compass.consistent()) { check_failed(ARMING_CHECK_COMPASS, report, "Compasses inconsistent"); return false; } } return true; }
static int assert_u32_less(u32 val1, u32 val2, const char *name) { if (val1 >= val2) { check_failed("Assertion failed for '%s'. 0x%x >= 0x%x\n", name, (int)val1, (int)val2); //errors++; return 1; } return 0; }
static int assert_u32_noteq(u32 val, u32 wrong, const char *name) { if (val==wrong) { check_failed("Assertion failed for '%lld:%s'. should not be " "0x%x.\n", (long long)current_mft_record, name, (int)wrong); return 1; } return 0; }
bool AP_Arming::logging_checks(bool report) { if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_LOGGING)) { if (!AP::logger().logging_present()) { // Logging is disabled, so nothing to check. return true; } if (AP::logger().logging_failed()) { check_failed(ARMING_CHECK_LOGGING, report, "Logging failed"); return false; } if (!AP::logger().CardInserted()) { check_failed(ARMING_CHECK_LOGGING, report, "No SD card"); return false; } } return true; }
/** * 0 success. * 1 fail. */ static int assert_u32_equal(u32 val, u32 ok, const char *name) { if (val!=ok) { check_failed("Assertion failed for '%lld:%s'. should be 0x%x, " "was 0x%x.\n", (long long)current_mft_record, name, (int)ok, (int)val); //errors++; return 1; } return 0; }
bool AP_Arming::fence_checks(bool display_failure) { const AC_Fence *fence = AP::fence(); if (fence == nullptr) { return true; } // check fence is ready const char *fail_msg = nullptr; if (fence->pre_arm_check(fail_msg)) { return true; } if (fail_msg == nullptr) { check_failed(ARMING_CHECK_NONE, display_failure, "Check fence"); } else { check_failed(ARMING_CHECK_NONE, display_failure, "%s", fail_msg); } return false; }
bool AP_Arming_Rover::pre_arm_checks(bool report) { if (SRV_Channels::get_emergency_stop()) { check_failed(ARMING_CHECK_NONE, report, "Motors Emergency Stopped"); return false; } return (AP_Arming::pre_arm_checks(report) & rover.g2.motors.pre_arm_check(report) & fence_checks(report) & proximity_check(report)); }
bool AP_Arming::barometer_checks(bool report) { if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_BARO)) { if (!AP::baro().all_healthy()) { check_failed(ARMING_CHECK_BARO, report, "Barometer not healthy"); return false; } } return true; }
bool AP_Arming::ins_checks(bool report) { if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_INS)) { const AP_InertialSensor &ins = AP::ins(); if (!ins.get_gyro_health_all()) { check_failed(ARMING_CHECK_INS, report, "Gyros not healthy"); return false; } if (!ins.gyro_calibrated_ok_all()) { check_failed(ARMING_CHECK_INS, report, "Gyros not calibrated"); return false; } if (!ins.get_accel_health_all()) { check_failed(ARMING_CHECK_INS, report, "Accels not healthy"); return false; } if (!ins.accel_calibrated_ok_all()) { check_failed(ARMING_CHECK_INS, report, "3D Accel calibration needed"); return false; } //check if accelerometers have calibrated and require reboot if (ins.accel_cal_requires_reboot()) { check_failed(ARMING_CHECK_INS, report, "Accels calibrated requires reboot"); return false; } // check all accelerometers point in roughly same direction if (!ins_accels_consistent(ins)) { check_failed(ARMING_CHECK_INS, report, "Accels inconsistent"); return false; } // check all gyros are giving consistent readings if (!ins_gyros_consistent(ins)) { check_failed(ARMING_CHECK_INS, report, "Gyros inconsistent"); return false; } // check AHRS attitudes are consistent char failure_msg[50] = {}; if (!AP::ahrs().attitudes_consistent(failure_msg, ARRAY_SIZE(failure_msg))) { check_failed(ARMING_CHECK_INS, report, "%s", failure_msg); return false; } } return true; }
// perform pre_arm_rc_checks checks bool AP_Arming_Rover::pre_arm_rc_checks(const bool display_failure) { // set rc-checks to success if RC checks are disabled if ((checks_to_perform != ARMING_CHECK_ALL) && !(checks_to_perform & ARMING_CHECK_RC)) { return true; } const RC_Channel *channels[] = { rover.channel_steer, rover.channel_throttle, }; const char *channel_names[] = {"Steer", "Throttle"}; for (uint8_t i= 0 ; i < ARRAY_SIZE(channels); i++) { const RC_Channel *channel = channels[i]; const char *channel_name = channel_names[i]; // check if radio has been calibrated if (!channel->min_max_configured()) { check_failed(ARMING_CHECK_RC, display_failure, "RC %s not configured", channel_name); return false; } if (channel->get_radio_min() > 1300) { check_failed(ARMING_CHECK_RC, display_failure, "%s radio min too high", channel_name); return false; } if (channel->get_radio_max() < 1700) { check_failed(ARMING_CHECK_RC, display_failure, "%s radio max too low", channel_name); return false; } if (channel->get_radio_trim() < channel->get_radio_min()) { check_failed(ARMING_CHECK_RC, display_failure, "%s radio trim below min", channel_name); return false; } if (channel->get_radio_trim() > channel->get_radio_max()) { check_failed(ARMING_CHECK_RC, display_failure, "%s radio trim above max", channel_name); return false; } } return true; }
bool AP_Arming::battery_checks(bool report) { if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_BATTERY)) { char buffer[MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN+1] {}; if (!AP::battery().arming_checks(sizeof(buffer), buffer)) { check_failed(ARMING_CHECK_BATTERY, report, "%s", buffer); return false; } } return true; }
bool AP_Arming::board_voltage_checks(bool report) { #if HAL_HAVE_BOARD_VOLTAGE // check board voltage if ((checks_to_perform & ARMING_CHECK_ALL) || (checks_to_perform & ARMING_CHECK_VOLTAGE)) { if(((hal.analogin->board_voltage() < AP_ARMING_BOARD_VOLTAGE_MIN) || (hal.analogin->board_voltage() > AP_ARMING_BOARD_VOLTAGE_MAX))) { check_failed(ARMING_CHECK_VOLTAGE, report, "Check board voltage"); return false; } } #endif return true; }