LCOV - code coverage report
Current view: top level - AP_Stats - AP_Stats.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 87 102 85.3 %
Date: 2026-09-09 11:02:08 Functions: 10 11 90.9 %

          Line data    Source code
       1             : #include "AP_Stats.h"
       2             : 
       3             : #include <AP_Math/AP_Math.h>
       4             : #include <AP_RTC/AP_RTC.h>
       5             : #include <AP_AHRS/AP_AHRS.h>
       6             : 
       7             : const extern AP_HAL::HAL& hal;
       8             : 
       9             : // table of user settable parameters
      10             : const AP_Param::GroupInfo AP_Stats::var_info[] = {
      11             : 
      12             :     // @Param: _BOOTCNT
      13             :     // @DisplayName: Boot Count
      14             :     // @Description: Number of times board has been booted
      15             :     // @ReadOnly: True
      16             :     // @User: Standard
      17             :     AP_GROUPINFO("_BOOTCNT",    0, AP_Stats, params.bootcount, 0),
      18             : 
      19             :     // @Param: _FLTTIME
      20             :     // @DisplayName: Total FlightTime
      21             :     // @Description: Total FlightTime (seconds)
      22             :     // @Units: s
      23             :     // @ReadOnly: True
      24             :     // @User: Standard
      25             :     AP_GROUPINFO("_FLTTIME",    1, AP_Stats, params.flttime, 0),
      26             : 
      27             :     // @Param: _RUNTIME
      28             :     // @DisplayName: Total RunTime
      29             :     // @Description: Total time autopilot has run
      30             :     // @Units: s
      31             :     // @ReadOnly: True
      32             :     // @User: Standard
      33             :     AP_GROUPINFO("_RUNTIME",    2, AP_Stats, params.runtime, 0),
      34             : 
      35             :     // @Param: _RESET
      36             :     // @DisplayName: Statistics Reset Time
      37             :     // @Description: Seconds since January 1st 2016 (Unix epoch+1451606400) since statistics reset (set to 0 to reset statistics, other set values will be ignored)
      38             :     // @Units: s
      39             :     // @ReadOnly: True
      40             :     // @User: Standard
      41             :     AP_GROUPINFO("_RESET",    3, AP_Stats, params.reset, 1),
      42             : 
      43             :     // @Param: _FLTCNT
      44             :     // @DisplayName: Total Flight Count
      45             :     // @Description: Total number of flights
      46             :     // @ReadOnly: True
      47             :     // @User: Standard
      48             :     AP_GROUPINFO("_FLTCNT",    4, AP_Stats, params.fltcount, 0),
      49             : 
      50             :     // @Param: _DISTFLWN
      51             :     // @DisplayName: Total Distance Flown
      52             :     // @Description: Estimate of total distance flown since statistics reset
      53             :     // @Units: m
      54             :     // @ReadOnly: True
      55             :     // @User: Standard
      56             :     AP_GROUPINFO("_DISTFLWN",    5, AP_Stats, params.distance_flown_m, 0),
      57             : 
      58             :     AP_GROUPEND
      59             : };
      60             : 
      61             : AP_Stats *AP_Stats::_singleton;
      62             : 
      63             : // constructor
      64        2098 : AP_Stats::AP_Stats(void)
      65             : {
      66        2098 :     AP_Param::setup_object_defaults(this, var_info);
      67        2098 :     _singleton = this;
      68        2098 : }
      69             : 
      70        2094 : void AP_Stats::copy_variables_from_parameters()
      71             : {
      72        2094 :     flttime = params.flttime;
      73        2094 :     runtime = params.runtime;
      74        2094 :     reset = params.reset;
      75        2094 :     flttime_boot = flttime;
      76        2094 :     fltcount = params.fltcount;
      77        2094 :     distance_flown_m = params.distance_flown_m;
      78        2094 : }
      79             : 
      80        2094 : void AP_Stats::init()
      81             : {
      82        2094 :     params.bootcount.set_and_save(params.bootcount+1);
      83             : 
      84             :     // initialise our variables from parameters:
      85        2094 :     copy_variables_from_parameters();
      86        2094 : }
      87             : 
      88        4990 : void AP_Stats::flush()
      89             : {
      90        4990 :     params.flttime.set_and_save_ifchanged(flttime);
      91        4990 :     params.runtime.set_and_save_ifchanged(runtime);
      92        4990 :     params.fltcount.set_and_save_ifchanged(fltcount);
      93        4990 :     params.distance_flown_m.set_and_save_ifchanged(distance_flown_m);
      94        4990 :     last_flush_ms = AP_HAL::millis();
      95        4990 : }
      96             : 
      97        4990 : void AP_Stats::update_flighttime()
      98             : {
      99        4990 :     if (_flying_ms) {
     100        3908 :         WITH_SEMAPHORE(sem);
     101        3908 :         const uint32_t now = AP_HAL::millis();
     102        3908 :         const uint32_t delta = (now - _flying_ms)/1000;
     103        3908 :         flttime += delta;
     104        3908 :         _flying_ms += delta*1000;
     105        3908 :     }
     106        4990 : }
     107             : 
     108        4990 : void AP_Stats::update_runtime()
     109             : {
     110        4990 :     const uint32_t now = AP_HAL::millis();
     111        4990 :     const uint32_t delta = (now - _last_runtime_ms)/1000;
     112        4990 :     runtime += delta;
     113        4990 :     _last_runtime_ms += delta*1000;
     114        4990 : }
     115             : 
     116      149217 : void AP_Stats::update()
     117             : {
     118      149217 :     WITH_SEMAPHORE(sem);
     119      149217 :     const uint32_t now_ms = AP_HAL::millis();
     120             : #if AP_AHRS_ENABLED
     121      149217 :     update_distance_flown();
     122             : #endif  // AP_AHRS_ENABLED
     123      149217 :     if (now_ms -  last_flush_ms > flush_interval_ms) {
     124        4114 :         update_flighttime();
     125        4114 :         update_runtime();
     126        4114 :         flush();
     127             :     }
     128      149217 :     const uint32_t params_reset = params.reset;
     129      149217 :     if (params_reset == 0) {
     130             :         // Only reset statistics if the user explicitly sets AP_STATS_RESET parameter to zero.
     131             :         // This allows users to load parameter files (in MP, MAVProxy or any other GCS) without
     132             :         // accidentally resetting the statistics, because the AP_STATS_RESET value contained in
     133             :         // the parameter file will be ignored (unless it is zero and it is usually not zero).
     134             :         // The other statistics parameters are read-only, and the GCS should be clever enough to not set those.
     135           0 :         params.bootcount.set_and_save_ifchanged(0);
     136           0 :         params.flttime.set_and_save_ifchanged(0);
     137           0 :         params.runtime.set_and_save_ifchanged(0);
     138           0 :         params.fltcount.set_and_save_ifchanged(0);
     139           0 :         params.distance_flown_m.set_and_save_ifchanged(0);
     140           0 :         uint32_t system_clock = 0; // in seconds
     141             : #if AP_RTC_ENABLED
     142             :         uint64_t rtc_clock_us;
     143           0 :         if (AP::rtc().get_utc_usec(rtc_clock_us)) {
     144           0 :             system_clock = rtc_clock_us / 1000000;
     145             :             // can't store Unix seconds in a 32-bit float.  Change the
     146             :             // time base to Jan 1st 2016:
     147           0 :             system_clock -= 1451606400;
     148             :         }
     149             : #endif
     150           0 :         params.reset.set_and_save_ifchanged(system_clock);
     151           0 :         copy_variables_from_parameters();
     152             :         // Reset distance tracking state
     153           0 :         _last_position_valid = false;
     154             :     }
     155      149217 : }
     156             : 
     157      294970 : void AP_Stats::set_flying(const bool is_flying)
     158             : {
     159      294970 :     if (is_flying) {
     160      205347 :         if (!_flying_ms) {
     161         927 :             fltcount += 1;
     162         927 :             _flying_ms = AP_HAL::millis();
     163             :         }
     164             :     } else {
     165       89623 :         if (_flying_ms) {
     166         876 :             update_flighttime();
     167         876 :             update_runtime();
     168         876 :             update_distance_flown();
     169         876 :             flush();
     170             :         }
     171       89623 :         _flying_ms = 0;
     172             :     }
     173      294970 : }
     174             : 
     175             : #if AP_AHRS_ENABLED
     176      150093 : void AP_Stats::update_distance_flown()
     177             : {
     178      150093 :     if (!_flying_ms) {
     179             :         // Dont count unless flying
     180       55421 :         _last_position_valid = false;
     181       69453 :         return;
     182             :     }
     183             : 
     184             :     // Run at 1Hz to reduce how much GPS variance is counted as distance
     185       94672 :     const uint32_t now_ms = AP_HAL::millis();
     186       94672 :     if (now_ms - _last_distance_update_ms < 1000) {
     187       13061 :         return;
     188             :     }
     189       81611 :     _last_distance_update_ms = now_ms;
     190             : 
     191       81611 :     const AP_AHRS &ahrs = AP::ahrs();
     192       81611 :     if (!ahrs.healthy()) {
     193         377 :         _last_position_valid = false;
     194         377 :         return;
     195             :     }
     196             : 
     197       81234 :     Location current_loc;
     198       81234 :     if (!ahrs.get_location(current_loc)) {
     199         594 :         _last_position_valid = false;
     200         594 :         return;
     201             :     }
     202             : 
     203       80640 :     if (_last_position_valid) {
     204       79715 :         float delta_m = _last_position.get_distance_NED(current_loc).length();
     205             : 
     206             :         // Avoid counting small distances that are probably error
     207       79715 :         if (delta_m >= 0.5) {
     208             :             // Dont blindly add large distances that are likely just gross error / spoofing
     209             :             // Assumes vehicle traveling below mach ~0.9
     210       59399 :             if (delta_m > 300.0f) {
     211          41 :                 delta_m = 300.0f;
     212             :             }
     213       59399 :             distance_flown_m += delta_m;
     214             :         }
     215             :     }
     216             : 
     217       80640 :     _last_position = current_loc;
     218       80640 :     _last_position_valid = true;
     219             : }
     220             : #endif  // AP_AHRS_ENABLED
     221             : 
     222             : /*
     223             :   get time in flight since boot
     224             :  */
     225           0 : uint32_t AP_Stats::get_flight_time_s(void)
     226             : {
     227           0 :     update_flighttime();
     228           0 :     return flttime - flttime_boot;
     229             : }
     230             : 
     231      294970 : AP_Stats *AP::stats(void)
     232             : {
     233      294970 :     return AP_Stats::get_singleton();
     234             : }

Generated by: LCOV version 1.14