2016-12-06 19:34:58 -04:00
// Jacob Walser: jacob@bluerobotics.com
2016-02-24 18:18:48 -04:00
# include "Sub.h"
// counter to verify contact with bottom
static uint32_t bottom_detector_count = 0 ;
static uint32_t surface_detector_count = 0 ;
static float current_depth = 0 ;
2023-06-18 09:59:21 -03:00
// checks if we have hit bottom or surface and updates the ap.at_bottom and ap.at_surface flags
2016-02-24 18:18:48 -04:00
// called at MAIN_LOOP_RATE
2016-06-23 11:59:51 -03:00
// ToDo: doesn't need to be called this fast
2016-02-24 18:18:48 -04:00
void Sub : : update_surface_and_bottom_detector ( )
{
2017-02-03 17:33:27 -04:00
if ( ! motors . armed ( ) ) { // only update when armed
set_surfaced ( false ) ;
set_bottomed ( false ) ;
return ;
}
Vector3f velocity ;
2022-01-29 19:23:06 -04:00
UNUSED_RESULT ( ahrs . get_velocity_NED ( velocity ) ) ;
2017-02-03 17:33:27 -04:00
// check that we are not moving up or down
bool vel_stationary = velocity . z > - 0.05 & & velocity . z < 0.05 ;
2017-05-03 19:13:06 -03:00
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
2017-02-03 17:33:27 -04:00
current_depth = barometer . get_altitude ( ) ; // cm
if ( ap . at_surface ) {
set_surfaced ( current_depth > g . surface_depth / 100.0 - 0.05 ) ; // add a 5cm buffer so it doesn't trigger too often
} else {
set_surfaced ( current_depth > g . surface_depth / 100.0 ) ; // If we are above surface depth, we are surfaced
}
if ( motors . limit . throttle_lower & & vel_stationary ) {
// bottom criteria met - increment the counter and check if we've triggered
if ( bottom_detector_count < ( ( float ) BOTTOM_DETECTOR_TRIGGER_SEC ) * MAIN_LOOP_RATE ) {
bottom_detector_count + + ;
} else {
set_bottomed ( true ) ;
}
} else {
set_bottomed ( false ) ;
}
// with no external baro, the only thing we have to go by is a vertical velocity estimate
} else if ( vel_stationary ) {
if ( motors . limit . throttle_upper ) {
// surface criteria met, increment counter and see if we've triggered
if ( surface_detector_count < ( ( float ) SURFACE_DETECTOR_TRIGGER_SEC ) * MAIN_LOOP_RATE ) {
surface_detector_count + + ;
} else {
set_surfaced ( true ) ;
}
} else if ( motors . limit . throttle_lower ) {
// bottom criteria met, increment counter and see if we've triggered
if ( bottom_detector_count < ( ( float ) BOTTOM_DETECTOR_TRIGGER_SEC ) * MAIN_LOOP_RATE ) {
bottom_detector_count + + ;
} else {
set_bottomed ( true ) ;
}
} else { // we're not at the limits of throttle, so reset both detectors
set_surfaced ( false ) ;
set_bottomed ( false ) ;
}
} else { // we're moving up or down, so reset both detectors
set_surfaced ( false ) ;
set_bottomed ( false ) ;
}
2016-02-24 18:18:48 -04:00
}
2017-02-03 17:33:27 -04:00
void Sub : : set_surfaced ( bool at_surface )
{
2016-06-23 11:59:51 -03:00
2017-02-03 17:33:27 -04:00
if ( ap . at_surface = = at_surface ) { // do nothing if state unchanged
return ;
}
2016-02-24 18:18:48 -04:00
2017-02-03 17:33:27 -04:00
ap . at_surface = at_surface ;
2016-02-24 18:18:48 -04:00
2017-02-03 17:33:27 -04:00
surface_detector_count = 0 ;
2016-12-06 19:34:58 -04:00
2017-02-03 17:33:27 -04:00
if ( ap . at_surface ) {
2024-01-10 00:34:30 -04:00
LOGGER_WRITE_EVENT ( LogEvent : : SURFACED ) ;
2017-02-03 17:33:27 -04:00
} else {
2024-01-10 00:34:30 -04:00
LOGGER_WRITE_EVENT ( LogEvent : : NOT_SURFACED ) ;
2017-02-03 17:33:27 -04:00
}
2016-02-24 18:18:48 -04:00
}
2017-02-03 17:33:27 -04:00
void Sub : : set_bottomed ( bool at_bottom )
{
2016-06-23 11:59:51 -03:00
2017-02-03 17:33:27 -04:00
if ( ap . at_bottom = = at_bottom ) { // do nothing if state unchanged
return ;
}
2016-02-24 18:18:48 -04:00
2017-02-03 17:33:27 -04:00
ap . at_bottom = at_bottom ;
2016-02-24 18:18:48 -04:00
2017-02-03 17:33:27 -04:00
bottom_detector_count = 0 ;
2016-12-06 19:34:58 -04:00
2017-02-03 17:33:27 -04:00
if ( ap . at_bottom ) {
2024-01-10 00:34:30 -04:00
LOGGER_WRITE_EVENT ( LogEvent : : BOTTOMED ) ;
2017-02-03 17:33:27 -04:00
} else {
2024-01-10 00:34:30 -04:00
LOGGER_WRITE_EVENT ( LogEvent : : NOT_BOTTOMED ) ;
2017-02-03 17:33:27 -04:00
}
2016-02-24 18:18:48 -04:00
}