LCOV - code coverage report
Current view: top level - home/pbarker/rc/ardupilot/ArduCopter - mode_autorotate.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 42 48 87.5 %
Date: 2026-09-09 11:02:08 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* -----------------------------------------------------------------------------------------
       2             :     This is currently a SITL only function until the project is complete.
       3             :     To trial this in SITL you will need to use Real Flight 8.
       4             :     Instructions for how to set this up in SITL can be found here:
       5             :     https://discuss.ardupilot.club/t/autonomous-autorotation-gsoc-project-blog/42139
       6             :  -----------------------------------------------------------------------------------------*/
       7             : 
       8             : #include "Copter.h"
       9             : #include <AC_Autorotation/AC_Autorotation.h>
      10             : #include "mode.h"
      11             : 
      12             : #if MODE_AUTOROTATE_ENABLED
      13             : 
      14           1 : bool ModeAutorotate::init(bool ignore_checks)
      15             : {
      16             : #if FRAME_CONFIG != HELI_FRAME
      17             :     // Only allow trad heli to use autorotation mode
      18             :     return false;
      19             : #endif
      20             : 
      21             :     // Check that mode is enabled, make sure this is the first check as this is the most
      22             :     // important thing for users to fix if they are planning to use autorotation mode
      23           1 :     if (!g2.arot.enabled()) {
      24           0 :         GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "AROT: Mode not enabled");
      25           0 :         return false;
      26             :     }
      27             : 
      28             :     // Must be armed to use mode, prevent triggering state machine on the ground
      29           1 :     if (!motors->armed() || copter.ap.land_complete || copter.ap.land_complete_maybe) {
      30           0 :         GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "AROT: Must be armed and flying");
      31           0 :         return false;
      32             :     }
      33             : 
      34             :     // Initialise controller
      35           1 :     g2.arot.init();
      36             : 
      37             :     // Setting default starting state
      38           1 :     current_phase = Phase::ENTRY_INIT;
      39             : 
      40             :     // Set entry timer
      41           1 :     _entry_time_start_ms = millis();
      42             : 
      43             :     // reset logging timer
      44           1 :     _last_logged_ms = 0;
      45             : 
      46           1 :     return true;
      47             : }
      48             : 
      49       14401 : void ModeAutorotate::run()
      50             : {
      51             :     // Current time
      52       14401 :     const uint32_t now_ms = millis();
      53             : 
      54             :     // Set dt in library
      55       14401 :     float const last_loop_time_s = AP::scheduler().get_last_loop_time_s();
      56       14401 :     g2.arot.set_dt(last_loop_time_s);
      57             : 
      58             :     //----------------------------------------------------------------
      59             :     //                  State machine logic
      60             :     //----------------------------------------------------------------
      61             :     // State machine progresses through the autorotation phases as you read down through the if statements.
      62             :     // More urgent phases (the ones closer to the ground) take precedence later in the if statements.
      63             : 
      64       14401 :     if (current_phase < Phase::GLIDE_INIT && ((now_ms - _entry_time_start_ms) > g2.arot.entry_time_ms)) {
      65             :         // Flight phase can be progressed to steady state glide
      66           1 :         current_phase = Phase::GLIDE_INIT;
      67             :     }
      68             : 
      69             :     // Check if we believe we have landed. We need the landed state to zero all
      70             :     // controls and make sure that the copter landing detector will trip
      71       14401 :     if (current_phase < Phase::LANDED && g2.arot.check_landed()) {
      72           1 :         current_phase = Phase::LANDED_INIT;
      73             :     }
      74             : 
      75             :     // Check if we are bailing out and need to re-set the spool state
      76       14401 :     if (motors->autorotation_bailout()) {
      77         960 :         motors->set_desired_spool_state(AP_Motors::DesiredSpoolState::THROTTLE_UNLIMITED);
      78             :     }
      79             : 
      80             :     // Get norm input from yaw channel
      81       14401 :     const float pilot_norm_input = channel_yaw->norm_input_dz();
      82             : 
      83             :     //----------------------------------------------------------------
      84             :     //                  State machine actions
      85             :     //----------------------------------------------------------------
      86       14401 :     switch (current_phase) {
      87             : 
      88           1 :         case Phase::ENTRY_INIT:
      89             :             // Entry phase functions to be run only once
      90           1 :             g2.arot.init_entry();
      91           1 :             current_phase = Phase::ENTRY;
      92             :             FALLTHROUGH;
      93             : 
      94         800 :         case Phase::ENTRY:
      95             :             // Smoothly transition the collective to enter autorotation regime and begin forward speed control
      96         800 :             g2.arot.run_entry(pilot_norm_input);
      97         800 :             break;
      98             : 
      99           1 :         case Phase::GLIDE_INIT:
     100             :             // Glide phase functions to be run only once
     101           1 :             g2.arot.init_glide();
     102           1 :             current_phase = Phase::GLIDE;
     103             :             FALLTHROUGH;
     104             : 
     105        5920 :         case Phase::GLIDE:
     106             :             // Maintain head speed and forward speed as we glide to the ground
     107        5920 :             g2.arot.run_glide(pilot_norm_input);
     108        5920 :             break;
     109             : 
     110           0 :         case Phase::FLARE_INIT:
     111             :         case Phase::FLARE:
     112             :         case Phase::TOUCH_DOWN_INIT:
     113             :         case Phase::TOUCH_DOWN:
     114           0 :             break;
     115             : 
     116           1 :         case Phase::LANDED_INIT:
     117             :             // Landed phase functions to be run only once
     118           1 :             GCS_SEND_TEXT(MAV_SEVERITY_INFO, "AROT: Landed");
     119           1 :             current_phase = Phase::LANDED;
     120             :             FALLTHROUGH;
     121             : 
     122        7681 :         case Phase::LANDED:
     123             :             // Don't allow controller to continually ask for more pitch to build speed when we are on the ground, decay to zero smoothly
     124        7681 :             g2.arot.run_landed();
     125        7681 :             break;
     126             :     }
     127             : 
     128             :     // Slow rate (25 Hz) logging for the mode
     129       14401 :     if (now_ms - _last_logged_ms > 40U) {
     130         848 :         g2.arot.log_write_autorotation();
     131         848 :         _last_logged_ms = now_ms;
     132             :     }
     133             : 
     134       14401 : } // End function run()
     135             : 
     136             : #endif

Generated by: LCOV version 1.14