LCOV - code coverage report
Current view: top level - home/pbarker/rc/ardupilot/ArduSub - surface_bottom_detector.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 41 47 87.2 %
Date: 2026-09-09 11:02:08 Functions: 3 3 100.0 %

          Line data    Source code
       1             : // Jacob Walser: [email protected]
       2             : 
       3             : #include "Sub.h"
       4             : 
       5             : // counter to verify contact with bottom
       6             : static uint32_t bottom_detector_count = 0;
       7             : static uint32_t surface_detector_count = 0;
       8             : static float current_depth = 0;
       9             : 
      10             : // checks if we have hit bottom or surface and updates the ap.at_bottom and ap.at_surface flags
      11             : // called at MAIN_LOOP_RATE
      12             : // ToDo: doesn't need to be called this fast
      13     2180683 : void Sub::update_surface_and_bottom_detector()
      14             : {
      15     2180683 :     if (!motors.armed()) { // only update when armed
      16      944196 :         set_surfaced(false);
      17      944196 :         set_bottomed(false);
      18      944196 :         return;
      19             :     }
      20             : 
      21     1236487 :     Vector3f velocity;
      22     1236487 :     UNUSED_RESULT(ahrs.get_velocity_NED(velocity));
      23             : 
      24             :     // check that we are not moving up or down
      25     1236487 :     bool vel_stationary = velocity.z > -0.05 && velocity.z < 0.05;
      26             : 
      27     1236487 :     if (ap.depth_sensor_present && sensor_health.depth) { // we can use the external pressure sensor for a very accurate and current measure of our z axis position
      28     1214771 :         current_depth = barometer.get_altitude(); // cm
      29             : 
      30             : 
      31     1214771 :         if (ap.at_surface) {
      32      144416 :             set_surfaced(current_depth > g.surface_depth*0.01 - 0.05); // add a 5cm buffer so it doesn't trigger too often
      33             :         } else {
      34     1070355 :             set_surfaced(current_depth > g.surface_depth*0.01); // If we are above surface depth, we are surfaced
      35             :         }
      36             : 
      37             : 
      38     1214771 :         if (motors.limit.throttle_lower && vel_stationary) {
      39             :             // bottom criteria met - increment the counter and check if we've triggered
      40        6375 :             if (bottom_detector_count < ((float)BOTTOM_DETECTOR_TRIGGER_SEC)*MAIN_LOOP_RATE) {
      41        6372 :                 bottom_detector_count++;
      42             :             } else {
      43           3 :                 set_bottomed(true);
      44             :             }
      45             : 
      46             :         } else {
      47     1208396 :             set_bottomed(false);
      48             :         }
      49             : 
      50             :         // with no external baro, the only thing we have to go by is a vertical velocity estimate
      51       21716 :     } else if (vel_stationary) {
      52         650 :         if (motors.limit.throttle_upper) {
      53             : 
      54             :             // surface criteria met, increment counter and see if we've triggered
      55           0 :             if (surface_detector_count < ((float)SURFACE_DETECTOR_TRIGGER_SEC)*MAIN_LOOP_RATE) {
      56           0 :                 surface_detector_count++;
      57             :             } else {
      58           0 :                 set_surfaced(true);
      59             :             }
      60             : 
      61         650 :         } else if (motors.limit.throttle_lower) {
      62             :             // bottom criteria met, increment counter and see if we've triggered
      63           0 :             if (bottom_detector_count < ((float)BOTTOM_DETECTOR_TRIGGER_SEC)*MAIN_LOOP_RATE) {
      64           0 :                 bottom_detector_count++;
      65             :             } else {
      66           0 :                 set_bottomed(true);
      67             :             }
      68             : 
      69             :         } else { // we're not at the limits of throttle, so reset both detectors
      70         650 :             set_surfaced(false);
      71         650 :             set_bottomed(false);
      72             :         }
      73             : 
      74             :     } else { // we're moving up or down, so reset both detectors
      75       21066 :         set_surfaced(false);
      76       21066 :         set_bottomed(false);
      77             :     }
      78             : }
      79             : 
      80     2180683 : void Sub::set_surfaced(bool at_surface)
      81             : {
      82             : 
      83             : 
      84     2180683 :     if (ap.at_surface == at_surface) { // do nothing if state unchanged
      85     2180613 :         return;
      86             :     }
      87             : 
      88          70 :     ap.at_surface = at_surface;
      89             : 
      90          70 :     surface_detector_count = 0;
      91             : 
      92          70 :     if (ap.at_surface) {
      93          35 :         LOGGER_WRITE_EVENT(LogEvent::SURFACED);
      94             :     } else {
      95          35 :         LOGGER_WRITE_EVENT(LogEvent::NOT_SURFACED);
      96             :     }
      97             : }
      98             : 
      99     2174311 : void Sub::set_bottomed(bool at_bottom)
     100             : {
     101             : 
     102     2174311 :     if (ap.at_bottom == at_bottom) { // do nothing if state unchanged
     103     2174305 :         return;
     104             :     }
     105             : 
     106           6 :     ap.at_bottom = at_bottom;
     107             : 
     108           6 :     bottom_detector_count = 0;
     109             : 
     110           6 :     if (ap.at_bottom) {
     111           3 :         LOGGER_WRITE_EVENT(LogEvent::BOTTOMED);
     112             :     } else {
     113           3 :         LOGGER_WRITE_EVENT(LogEvent::NOT_BOTTOMED);
     114             :     }
     115             : }

Generated by: LCOV version 1.14