LCOV - code coverage report
Current view: top level - home/pbarker/rc/ardupilot/ArduSub - system.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 96 103 93.2 %
Date: 2026-09-09 11:02:08 Functions: 8 10 80.0 %

          Line data    Source code
       1             : #include "Sub.h"
       2             : 
       3             : /*****************************************************************************
       4             : *   The init_ardupilot function processes everything we need for an in - air restart
       5             : *        We will determine later if we are actually on the ground and process a
       6             : *        ground start in that case.
       7             : *
       8             : *****************************************************************************/
       9             : 
      10     6750292 : static void failsafe_check_static()
      11             : {
      12     6750292 :     sub.mainloop_failsafe_check();
      13     6750292 : }
      14             : 
      15          83 : void Sub::init_ardupilot()
      16             : {
      17             :     // initialise notify system
      18          83 :     notify.init();
      19             : 
      20             :     // initialise battery monitor
      21          83 :     battery.init();
      22             : 
      23          83 :     barometer.init();
      24             : 
      25             : #if AP_FEATURE_BOARD_DETECT
      26             :     // Detection won't work until after BoardConfig.init()
      27             :     switch (AP_BoardConfig::get_board_type()) {
      28             :     case AP_BoardConfig::PX4_BOARD_PIXHAWK2:
      29             :         AP_Param::set_default_by_name("BARO_EXT_BUS", 0);
      30             :         break;
      31             :     case AP_BoardConfig::PX4_BOARD_PIXHAWK:
      32             :         AP_Param::set_by_name("BARO_EXT_BUS", 1);
      33             :         break;
      34             :     default:
      35             :         AP_Param::set_default_by_name("BARO_EXT_BUS", 1);
      36             :         break;
      37             :     }
      38             : #elif CONFIG_HAL_BOARD != HAL_BOARD_LINUX
      39          83 :     AP_Param::set_default_by_name("BARO_EXT_BUS", 1);
      40             : #endif
      41             : 
      42             : #if AP_TEMPERATURE_SENSOR_ENABLED
      43             :     // In order to preserve Sub's previous AP_TemperatureSensor Behavior we set the Default I2C Bus Here
      44          83 :     AP_Param::set_default_by_name("TEMP1_BUS", barometer.external_bus());
      45             : #endif
      46             : 
      47             :     // setup telem slots with serial ports
      48          83 :     gcs().setup_uarts();
      49             : 
      50             :     // initialise rc channels including setting mode
      51          83 :     rc().init();
      52             : 
      53             : 
      54          83 :     init_rc_in();               // sets up rc channels from radio
      55          83 :     init_rc_out();              // sets up motors and output to escs
      56          83 :     init_joystick();            // joystick initialization
      57             : 
      58             : #if AP_RELAY_ENABLED
      59          83 :     relay.init();
      60             : #endif
      61             : 
      62             : #if OSD_ENABLED
      63          83 :     osd.init();
      64             : #endif
      65             : 
      66             :     /*
      67             :      *  setup the 'main loop is dead' check. Note that this relies on
      68             :      *  the RC library being initialised.
      69             :      */
      70          83 :     hal.scheduler->register_timer_failsafe(failsafe_check_static, 1000);
      71             : 
      72             :     // Do GPS init
      73          83 :     gps.set_log_gps_bit(MASK_LOG_GPS);
      74          83 :     gps.init();
      75             : 
      76          83 :     AP::compass().set_log_bit(MASK_LOG_COMPASS);
      77          83 :     AP::compass().init();
      78             : 
      79             : #if AP_AIRSPEED_ENABLED
      80          83 :     airspeed.set_log_bit(MASK_LOG_IMU);
      81             : #endif
      82             : 
      83             : #if AP_OPTICALFLOW_ENABLED
      84             :     // initialise optical flow sensor
      85          83 :     optflow.init(MASK_LOG_OPTFLOW);
      86             : #endif
      87             : 
      88             : #if HAL_MOUNT_ENABLED
      89             :     // initialise camera mount
      90          83 :     camera_mount.init();
      91             :     // This step is necessary so that the servo is properly initialized
      92          83 :     camera_mount.set_angle_target(0, 0, 0, false);
      93             :     // for some reason the call to set_angle_targets changes the mode to mavlink targeting!
      94          83 :     camera_mount.set_mode(MAV_MOUNT_MODE_RC_TARGETING);
      95             : #endif
      96             : 
      97             : #if AP_CAMERA_ENABLED
      98             :     // initialise camera
      99          83 :     camera.init();
     100             : #endif
     101             : 
     102             : #ifdef USERHOOK_INIT
     103             :     USERHOOK_INIT
     104             : #endif
     105             : 
     106             :     // Init baro and determine if we have external (depth) pressure sensor
     107          83 :     barometer.set_log_baro_bit(MASK_LOG_IMU);
     108          83 :     barometer.calibrate(false);
     109          82 :     barometer.update();
     110             : 
     111          82 :     for (uint8_t i = 0; i < barometer.num_instances(); i++) {
     112          82 :         if (barometer.get_type(i) == AP_Baro::BARO_TYPE_WATER) {
     113          82 :             barometer.set_primary_baro(i);
     114          82 :             depth_sensor_idx = i;
     115          82 :             ap.depth_sensor_present = true;
     116          82 :             sensor_health.depth = barometer.healthy(depth_sensor_idx); // initialize health flag
     117          82 :             break; // Go with the first one we find
     118             :         }
     119             :     }
     120             : 
     121          82 :     if (!ap.depth_sensor_present) {
     122             :         // We only have onboard baro
     123             :         // No external underwater depth sensor detected
     124           0 :         barometer.set_primary_baro(0);
     125           0 :         ahrs.set_alt_measurement_noise(10.0f);  // Readings won't correspond with rest of INS
     126             :     } else {
     127          82 :         ahrs.set_alt_measurement_noise(0.1f);
     128             :     }
     129             : 
     130          82 :     leak_detector.init();
     131             : 
     132          82 :     last_pilot_heading_rad = ahrs.get_yaw_rad();
     133             : 
     134             :     // initialise rangefinder
     135             : #if AP_RANGEFINDER_ENABLED
     136          82 :     init_rangefinder();
     137             : #endif
     138             : 
     139             :     // initialise mission library
     140          82 :     mission.init();
     141             : #if HAL_LOGGING_ENABLED
     142          82 :     mission.set_log_start_mission_item_bit(MASK_LOG_CMD);
     143             : #endif
     144             : 
     145             :     // initialise AP_Logger library
     146             : #if HAL_LOGGING_ENABLED
     147          82 :     logger.setVehicle_Startup_Writer(FUNCTOR_BIND(&sub, &Sub::Log_Write_Vehicle_Startup_Messages, void));
     148             : #endif
     149             : 
     150          82 :     startup_INS_ground();
     151             : 
     152             :     // enable CPU failsafe
     153          82 :     mainloop_failsafe_enable();
     154             : 
     155          82 :     ins.set_log_raw_bit(MASK_LOG_IMU_RAW);
     156             : 
     157             :     // PARAMETER_CONVERSION - Added: Mar-2026
     158          82 :     if (g2.param_conversion_increment < 1) {
     159           9 :         update_actuators_from_jsbuttons();
     160           9 :         update_lights_from_rcin();
     161           9 :         g2.param_conversion_increment.set_and_save(1);
     162             :     }
     163             : 
     164          82 :     g2.actuators.initialize_actuators();
     165             : 
     166             : #if LEAKDETECTOR_MAX_INSTANCES > 0
     167          82 :     update_leak_pins();
     168             : #endif
     169             : #if AP_RELAY_ENABLED
     170          82 :     update_relay_pins();
     171             : #endif
     172             :     // flag that initialisation has completed
     173          82 :     ap.initialised = true;
     174          82 : }
     175             : 
     176             : 
     177             : //******************************************************************************
     178             : //This function does all the calibrations, etc. that we need during a ground start
     179             : //******************************************************************************
     180          82 : void Sub::startup_INS_ground()
     181             : {
     182             :     // initialise ahrs (may push imu calibration into the mpu6000 if using that device).
     183          82 :     ahrs.init();
     184          82 :     ahrs.set_vehicle_class(AP_AHRS::VehicleClass::SUBMARINE);
     185          82 :     ahrs.set_fly_forward(false);
     186             : 
     187             :     // Warm up and calibrate gyro offsets
     188          82 :     ins.init(scheduler.get_loop_rate_hz());
     189             : 
     190             :     // reset ahrs including gyro bias
     191          82 :     ahrs.reset();
     192          82 : }
     193             : 
     194             : // calibrate gyros - returns true if successfully calibrated
     195             : // position_ok - returns true if the horizontal absolute position is ok and home position is set
     196       85627 : bool Sub::position_ok()
     197             : {
     198             :     // return false if ekf failsafe has triggered
     199       85627 :     if (failsafe.ekf) {
     200           0 :         return false;
     201             :     }
     202             : 
     203             :     // check ekf position estimate
     204       85627 :     return (ekf_position_ok() || optflow_position_ok());
     205             : }
     206             : 
     207             : // ekf_position_ok - returns true if the ekf claims it's horizontal absolute position estimate is ok and home position is set
     208       85627 : bool Sub::ekf_position_ok()
     209             : {
     210       85627 :     if (!ahrs.have_inertial_nav()) {
     211             :         // do not allow navigation with dcm position
     212         143 :         return false;
     213             :     }
     214             : 
     215             :     // if disarmed we accept a predicted horizontal position
     216       85484 :     if (!motors.armed()) {
     217        2293 :         if (ahrs.has_status(AP_AHRS::Status::HORIZ_POS_ABS)) {
     218         739 :             return true;
     219             :         }
     220        1554 :         if (ahrs.has_status(AP_AHRS::Status::PRED_HORIZ_POS_ABS)) {
     221           0 :             return true;
     222             :         }
     223        1554 :         return false;
     224             :     }
     225             : 
     226             :     // once armed we require a good absolute position and EKF must not be in const_pos_mode
     227       83191 :     if (ahrs.has_status(AP_AHRS::Status::CONST_POS_MODE)) {
     228        5662 :         return false;
     229             :     }
     230       77529 :     return ahrs.has_status(AP_AHRS::Status::HORIZ_POS_ABS);
     231             : }
     232             : 
     233             : // optflow_position_ok - returns true if optical flow based position estimate is ok
     234       21490 : bool Sub::optflow_position_ok()
     235             : {
     236             :     // return immediately if EKF not used
     237       21490 :     if (!ahrs.have_inertial_nav()) {
     238         143 :         return false;
     239             :     }
     240             : 
     241             :     // return immediately if neither optflow nor visual odometry is enabled
     242       21347 :     bool enabled = false;
     243             : #if AP_OPTICALFLOW_ENABLED
     244       21347 :     if (optflow.enabled()) {
     245           0 :         enabled = true;
     246             :     }
     247             : #endif
     248             : #if HAL_VISUALODOM_ENABLED
     249       21347 :     if (visual_odom.enabled()) {
     250       19785 :         enabled = true;
     251             :     }
     252             : #endif
     253       21347 :     if (!enabled) {
     254        1562 :         return false;
     255             :     }
     256             : 
     257             :     // if disarmed we accept a predicted horizontal relative position
     258       19785 :     if (!motors.armed()) {
     259          53 :         return ahrs.has_status(AP_AHRS::Status::PRED_HORIZ_POS_REL);
     260             :     }
     261             : 
     262       19732 :     if (ahrs.has_status(AP_AHRS::Status::CONST_POS_MODE)) {
     263        5601 :         return false;
     264             :     }
     265             : 
     266       14131 :     return ahrs.has_status(AP_AHRS::Status::HORIZ_POS_REL);
     267             : }
     268             : 
     269             : #if HAL_LOGGING_ENABLED
     270             : /*
     271             :   should we log a message type now?
     272             :  */
     273     3144745 : bool Sub::should_log(uint32_t mask)
     274             : {
     275     3144745 :     ap.logging_started = logger.logging_started();
     276     3144745 :     return logger.should_log(mask);
     277             : }
     278             : #endif
     279             : 
     280             : #include <AP_AdvancedFailsafe/AP_AdvancedFailsafe.h>
     281             : #include <AP_Avoidance/AP_Avoidance.h>
     282             : #include <AP_ADSB/AP_ADSB.h>
     283             : 
     284             : // dummy method to avoid linking AFS
     285             : #if AP_ADVANCEDFAILSAFE_ENABLED
     286           0 : bool AP_AdvancedFailsafe::gcs_terminate(bool should_terminate, const char *reason) { return false; }
     287           3 : AP_AdvancedFailsafe *AP::advancedfailsafe() { return nullptr; }
     288             : #endif
     289             : 
     290             : #if AP_ADSB_AVOIDANCE_ENABLED
     291             : // dummy method to avoid linking AP_Avoidance
     292           0 : AP_Avoidance *AP::ap_avoidance() { return nullptr; }
     293             : #endif  // AP_ADSB_AVOIDANCE_ENABLED

Generated by: LCOV version 1.14