123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- #include "Sub.h"
- /*****************************************************************************
- * The init_ardupilot function processes everything we need for an in - air restart
- * We will determine later if we are actually on the ground and process a
- * ground start in that case.
- *
- *****************************************************************************/
- static void mavlink_delay_cb_static()
- {
- sub.mavlink_delay_cb();
- }
- static void failsafe_check_static()
- {
- sub.mainloop_failsafe_check();
- }
- void Sub::init_ardupilot()
- {
- // initialise serial port
- serial_manager.init_console();
- hal.console->printf("\n\nInit %s"
- "\n\nFree RAM: %u\n",
- AP::fwversion().fw_string,
- (unsigned)hal.util->available_memory());
- // load parameters from EEPROM
- load_parameters();
- BoardConfig.init();
- #if HAL_WITH_UAVCAN
- BoardConfig_CAN.init();
- #endif
- #if AP_FEATURE_BOARD_DETECT
- // Detection won't work until after BoardConfig.init()
- switch (AP_BoardConfig::get_board_type()) {
- case AP_BoardConfig::PX4_BOARD_PIXHAWK2:
- AP_Param::set_by_name("GND_EXT_BUS", 0);
- celsius.init(0);
- break;
- default:
- AP_Param::set_by_name("GND_EXT_BUS", 1);
- celsius.init(1);
- break;
- }
- #else
- AP_Param::set_default_by_name("GND_EXT_BUS", 1);
- celsius.init(1);
- #endif
- // identify ourselves correctly with the ground station
- mavlink_system.sysid = g.sysid_this_mav;
-
- // initialise serial port
- serial_manager.init();
- // setup first port early to allow BoardConfig to report errors
- gcs().setup_console();
- // init cargo gripper
- #if GRIPPER_ENABLED == ENABLED
- g2.gripper.init();
- #endif
- // initialise notify system
- notify.init();
- // initialise battery monitor
- battery.init();
- barometer.init();
- // Register the mavlink service callback. This will run
- // anytime there are more than 5ms remaining in a call to
- // hal.scheduler->delay.
- hal.scheduler->register_delay_callback(mavlink_delay_cb_static, 5);
- // setup telem slots with serial ports
- gcs().setup_uarts();
- #if LOGGING_ENABLED == ENABLED
- log_init();
- #endif
- // initialise rc channels including setting mode
- rc().init();
- init_rc_in(); // sets up rc channels from radio
- init_rc_out(); // sets up motors and output to escs
- init_joystick(); // joystick initialization
- relay.init();
- /*
- * setup the 'main loop is dead' check. Note that this relies on
- * the RC library being initialised.
- */
- hal.scheduler->register_timer_failsafe(failsafe_check_static, 1000);
- // Do GPS init
- gps.set_log_gps_bit(MASK_LOG_GPS);
- gps.init(serial_manager);
- AP::compass().set_log_bit(MASK_LOG_COMPASS);
- AP::compass().init();
- #if OPTFLOW == ENABLED
- // make optflow available to AHRS
- ahrs.set_optflow(&optflow);
- #endif
- // init Location class
- #if AP_TERRAIN_AVAILABLE && AC_TERRAIN
- Location::set_terrain(&terrain);
- wp_nav.set_terrain(&terrain);
- #endif
- pos_control.set_dt(MAIN_LOOP_SECONDS);
- // init the optical flow sensor
- #if OPTFLOW == ENABLED
- init_optflow();
- #endif
- #if MOUNT == ENABLED
- // initialise camera mount
- camera_mount.init();
- // This step ncessary so the servo is properly initialized
- camera_mount.set_angle_targets(0, 0, 0);
- // for some reason the call to set_angle_targets changes the mode to mavlink targeting!
- camera_mount.set_mode(MAV_MOUNT_MODE_RC_TARGETING);
- #endif
- #ifdef USERHOOK_INIT
- USERHOOK_INIT
- #endif
- // Init baro and determine if we have external (depth) pressure sensor
- barometer.set_log_baro_bit(MASK_LOG_IMU);
- barometer.calibrate(false);
- barometer.update();
- for (uint8_t i = 0; i < barometer.num_instances(); i++) {
- if (barometer.get_type(i) == AP_Baro::BARO_TYPE_WATER) {
- barometer.set_primary_baro(i);
- depth_sensor_idx = i;
- ap.depth_sensor_present = true;
- sensor_health.depth = barometer.healthy(depth_sensor_idx); // initialize health flag
- break; // Go with the first one we find
- }
- }
- if (!ap.depth_sensor_present) {
- // We only have onboard baro
- // No external underwater depth sensor detected
- barometer.set_primary_baro(0);
- EKF2.set_baro_alt_noise(10.0f); // Readings won't correspond with rest of INS
- EKF3.set_baro_alt_noise(10.0f);
- } else {
- EKF2.set_baro_alt_noise(0.1f);
- EKF3.set_baro_alt_noise(0.1f);
- }
- leak_detector.init();
- last_pilot_heading = ahrs.yaw_sensor;
- // initialise rangefinder
- #if RANGEFINDER_ENABLED == ENABLED
- init_rangefinder();
- #endif
- // initialise AP_RPM library
- #if RPM_ENABLED == ENABLED
- rpm_sensor.init();
- #endif
- // initialise mission library
- mission.init();
- // initialise AP_Logger library
- #if LOGGING_ENABLED == ENABLED
- logger.setVehicle_Startup_Writer(FUNCTOR_BIND(&sub, &Sub::Log_Write_Vehicle_Startup_Messages, void));
- #endif
- startup_INS_ground();
- #ifdef ENABLE_SCRIPTING
- if (!g2.scripting.init()) {
- gcs().send_text(MAV_SEVERITY_ERROR, "Scripting failed to start");
- }
- #endif // ENABLE_SCRIPTING
- // we don't want writes to the serial port to cause us to pause
- // mid-flight, so set the serial ports non-blocking once we are
- // ready to fly
- serial_manager.set_blocking_writes_all(false);
- // enable CPU failsafe
- mainloop_failsafe_enable();
- ins.set_log_raw_bit(MASK_LOG_IMU_RAW);
- // disable safety if requested
- BoardConfig.init_safety();
-
- hal.console->print("\nInit complete");
- // flag that initialisation has completed
- ap.initialised = true;
- #if AP_PARAM_KEY_DUMP
- AP_Param::show_all(hal.console, true);
- #endif
- }
- //******************************************************************************
- //This function does all the calibrations, etc. that we need during a ground start
- //******************************************************************************
- void Sub::startup_INS_ground()
- {
- // initialise ahrs (may push imu calibration into the mpu6000 if using that device).
- ahrs.init();
- ahrs.set_vehicle_class(AHRS_VEHICLE_SUBMARINE);
- // Warm up and calibrate gyro offsets
- ins.init(scheduler.get_loop_rate_hz());
- // reset ahrs including gyro bias
- ahrs.reset();
- }
- // calibrate gyros - returns true if successfully calibrated
- // position_ok - returns true if the horizontal absolute position is ok and home position is set
- bool Sub::position_ok()
- {
- // return false if ekf failsafe has triggered
- if (failsafe.ekf) {
- return false;
- }
- // check ekf position estimate
- return (ekf_position_ok() || optflow_position_ok());
- }
- // ekf_position_ok - returns true if the ekf claims it's horizontal absolute position estimate is ok and home position is set
- bool Sub::ekf_position_ok()
- {
- if (!ahrs.have_inertial_nav()) {
- // do not allow navigation with dcm position
- return false;
- }
- // with EKF use filter status and ekf check
- nav_filter_status filt_status = inertial_nav.get_filter_status();
- // if disarmed we accept a predicted horizontal position
- if (!motors.armed()) {
- return ((filt_status.flags.horiz_pos_abs || filt_status.flags.pred_horiz_pos_abs));
- }
- // once armed we require a good absolute position and EKF must not be in const_pos_mode
- return (filt_status.flags.horiz_pos_abs && !filt_status.flags.const_pos_mode);
- }
- // optflow_position_ok - returns true if optical flow based position estimate is ok
- bool Sub::optflow_position_ok()
- {
- #if OPTFLOW != ENABLED
- return false;
- #else
- // return immediately if optflow is not enabled or EKF not used
- if (!optflow.enabled() || !ahrs.have_inertial_nav()) {
- return false;
- }
- // get filter status from EKF
- nav_filter_status filt_status = inertial_nav.get_filter_status();
- // if disarmed we accept a predicted horizontal relative position
- if (!motors.armed()) {
- return (filt_status.flags.pred_horiz_pos_rel);
- }
- return (filt_status.flags.horiz_pos_rel && !filt_status.flags.const_pos_mode);
- #endif
- }
- /*
- should we log a message type now?
- */
- bool Sub::should_log(uint32_t mask)
- {
- #if LOGGING_ENABLED == ENABLED
- ap.logging_started = logger.logging_started();
- return logger.should_log(mask);
- #else
- return false;
- #endif
- }
|