LCOV - code coverage report
Current view: top level - home/pbarker/rc/ardupilot/Rover - mode_smart_rtl.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 43 73 58.9 %
Date: 2026-09-09 11:02:08 Functions: 5 6 83.3 %

          Line data    Source code
       1             : #include "Rover.h"
       2             : 
       3             : // Return true if this mode is enabled, used by MAVLink available mode
       4       12529 : bool ModeSmartRTL::enabled() const
       5             : {
       6             :     // Smart RTL mode requires smart RTL lib
       7       12529 :     return g2.smart_rtl.enabled();
       8             : }
       9             : 
      10           3 : bool ModeSmartRTL::_enter()
      11             : {
      12             :     // SmartRTL requires EKF (not DCM)
      13           3 :     Location ekf_origin;
      14           3 :     if (!ahrs.get_origin(ekf_origin)) {
      15           0 :         return false;
      16             :     }
      17             : 
      18             :     // refuse to enter SmartRTL if smart RTL's home has not been set
      19           3 :     if (!enabled() || !g2.smart_rtl.is_active()) {
      20           0 :         return false;
      21             :     }
      22             : 
      23             :     // initialise waypoint navigation library
      24           3 :     g2.wp_nav.init(MAX(0, g2.rtl_speed));
      25             : 
      26             :     // set desired location to reasonable stopping point
      27           3 :     if (!g2.wp_nav.set_desired_location_to_stopping_location()) {
      28           0 :         return false;
      29             :     }
      30             : 
      31             :     // init state
      32           3 :     smart_rtl_state = SmartRTLState::WaitForPathCleanup;
      33           3 :     _loitering = false;
      34             : 
      35           3 :     return true;
      36             : }
      37             : 
      38        2054 : void ModeSmartRTL::update()
      39             : {
      40        2054 :     switch (smart_rtl_state) {
      41           6 :         case SmartRTLState::WaitForPathCleanup:
      42             :             // check if return path is computed and if yes, begin journey home
      43           6 :             if (g2.smart_rtl.request_thorough_cleanup()) {
      44           3 :                 smart_rtl_state = SmartRTLState::PathFollow;
      45           3 :                 _load_point = true;
      46             :             }
      47             :             // Note: this may lead to an unnecessary 20ms slow down of the vehicle (but it is unlikely)
      48           6 :             stop_vehicle();
      49           6 :             break;
      50             : 
      51        2048 :         case SmartRTLState::PathFollow:
      52             :             // load point if required
      53        2048 :             if (_load_point) {
      54           7 :                 Vector3p dest_NED;
      55           7 :                 if (!g2.smart_rtl.pop_point(dest_NED)) {
      56             :                     // if not more points, we have reached home
      57           0 :                     GCS_SEND_TEXT(MAV_SEVERITY_INFO, "Reached destination");
      58           0 :                     smart_rtl_state = SmartRTLState::StopAtHome;
      59           0 :                     break;
      60             :                 } else {
      61             :                     // peek at the next point.  this can fail if the IO task currently has the path semaphore
      62           7 :                     Vector3p next_dest_NED;
      63           7 :                     if (g2.smart_rtl.peek_point(next_dest_NED)) {
      64           5 :                         if (!g2.wp_nav.set_desired_location_NED(dest_NED.tofloat(), next_dest_NED.tofloat())) {
      65             :                             // this should never happen because the EKF origin should already be set
      66           0 :                             GCS_SEND_TEXT(MAV_SEVERITY_INFO, "SmartRTL: failed to set destination");
      67           0 :                             smart_rtl_state = SmartRTLState::Failure;
      68           0 :                             INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);
      69             :                         }
      70             :                     } else {
      71             :                         // no next point so add only immediate point
      72           2 :                         if (!g2.wp_nav.set_desired_location_NED(dest_NED.tofloat())) {
      73             :                             // this should never happen because the EKF origin should already be set
      74           0 :                             GCS_SEND_TEXT(MAV_SEVERITY_INFO, "SmartRTL: failed to set destination");
      75           0 :                             smart_rtl_state = SmartRTLState::Failure;
      76           0 :                             INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);
      77             :                         }
      78             :                     }
      79             :                 }
      80           7 :                 _load_point = false;
      81             :             }
      82             :             // update navigation controller
      83        2048 :             navigate_to_waypoint();
      84             : 
      85             :             // check if we've reached the next point
      86        2048 :             if (g2.wp_nav.reached_destination()) {
      87           4 :                 _load_point = true;
      88             :             }
      89        2048 :             break;
      90             : 
      91           0 :         case SmartRTLState::StopAtHome:
      92             :         case SmartRTLState::Failure:
      93           0 :             _reached_destination = true;
      94             :             // we have reached the destination
      95             :             // boats loiters, rovers stop
      96           0 :             if (!rover.is_boat()) {
      97           0 :                stop_vehicle();
      98             :             } else {
      99             :                 // if not loitering yet, start loitering
     100           0 :                 if (!_loitering) {
     101           0 :                     _loitering = rover.mode_loiter.enter();
     102             :                 }
     103           0 :                 if (_loitering) {
     104           0 :                     rover.mode_loiter.update();
     105             :                 } else {
     106           0 :                     stop_vehicle();
     107             :                }
     108             :             }
     109           0 :             break;
     110             :     }
     111        2054 : }
     112             : 
     113             : // get desired location
     114         408 : bool ModeSmartRTL::get_desired_location(Location& destination) const
     115             : {
     116         408 :     switch (smart_rtl_state) {
     117           0 :     case SmartRTLState::WaitForPathCleanup:
     118           0 :         return false;
     119         408 :     case SmartRTLState::PathFollow:
     120         408 :         if (g2.wp_nav.is_destination_valid()) {
     121         408 :             destination = g2.wp_nav.get_destination();
     122         408 :             return true;
     123             :         }
     124           0 :         return false;
     125           0 :     case SmartRTLState::StopAtHome:
     126             :     case SmartRTLState::Failure:
     127           0 :         return false;
     128             :     }
     129             :     // should never reach here but just in case
     130           0 :     return false;
     131             : }
     132             : 
     133             : // set desired speed in m/s
     134           0 : bool ModeSmartRTL::set_desired_speed(float speed_ms)
     135             : {
     136           0 :     return g2.wp_nav.set_speed_max(speed_ms);
     137             : }
     138             : 
     139             : // save current position for use by the smart_rtl flight mode
     140       39175 : void ModeSmartRTL::save_position()
     141             : {
     142       39175 :     const bool save_pos = (rover.control_mode != &rover.mode_smartrtl);
     143       39175 :     g2.smart_rtl.update(true, save_pos);
     144       39175 : }

Generated by: LCOV version 1.14