2016-10-13 03:30:04 -03:00
# include "AP_Stats.h"
2016-10-13 21:59:06 -03:00
# include <AP_Math/AP_Math.h>
2018-04-10 08:29:03 -03:00
# include <AP_RTC/AP_RTC.h>
2016-10-13 21:59:06 -03:00
const extern AP_HAL : : HAL & hal ;
2016-10-13 03:30:04 -03:00
// table of user settable parameters
const AP_Param : : GroupInfo AP_Stats : : var_info [ ] = {
// @Param: _BOOTCNT
// @DisplayName: Boot Count
// @Description: Number of times board has been booted
2017-06-07 07:04:05 -03:00
// @ReadOnly: True
2016-10-13 03:30:04 -03:00
// @User: Standard
AP_GROUPINFO ( " _BOOTCNT " , 0 , AP_Stats , params . bootcount , 0 ) ,
2016-10-13 07:44:30 -03:00
// @Param: _FLTTIME
// @DisplayName: Total FlightTime
// @Description: Total FlightTime (seconds)
2017-05-02 10:48:30 -03:00
// @Units: s
2017-06-07 07:04:05 -03:00
// @ReadOnly: True
2016-10-13 07:44:30 -03:00
// @User: Standard
AP_GROUPINFO ( " _FLTTIME " , 1 , AP_Stats , params . flttime , 0 ) ,
2016-10-13 21:08:17 -03:00
// @Param: _RUNTIME
// @DisplayName: Total RunTime
// @Description: Total time autopilot has run
2017-05-02 10:48:30 -03:00
// @Units: s
2017-06-07 07:04:05 -03:00
// @ReadOnly: True
2016-10-13 21:08:17 -03:00
// @User: Standard
AP_GROUPINFO ( " _RUNTIME " , 2 , AP_Stats , params . runtime , 0 ) ,
2016-10-13 21:59:06 -03:00
// @Param: _RESET
2017-06-08 05:26:19 -03:00
// @DisplayName: Statistics Reset Time
2017-06-08 05:26:19 -03:00
// @Description: Seconds since January 1st 2016 (Unix epoch+1451606400) since statistics reset (set to 0 to reset statistics, other set values will be ignored)
2017-05-02 10:48:30 -03:00
// @Units: s
2017-06-07 07:04:05 -03:00
// @ReadOnly: True
2016-10-13 21:59:06 -03:00
// @User: Standard
AP_GROUPINFO ( " _RESET " , 3 , AP_Stats , params . reset , 1 ) ,
2016-10-13 03:30:04 -03:00
AP_GROUPEND
} ;
2018-07-20 17:24:52 -03:00
AP_Stats * AP_Stats : : _singleton ;
// constructor
AP_Stats : : AP_Stats ( void )
{
2023-11-22 20:17:53 -04:00
AP_Param : : setup_object_defaults ( this , var_info ) ;
2018-07-20 17:24:52 -03:00
_singleton = this ;
}
2016-10-13 21:59:06 -03:00
void AP_Stats : : copy_variables_from_parameters ( )
{
flttime = params . flttime ;
runtime = params . runtime ;
reset = params . reset ;
2018-07-20 17:24:52 -03:00
flttime_boot = flttime ;
2016-10-13 21:59:06 -03:00
}
2016-10-13 03:30:04 -03:00
void AP_Stats : : init ( )
{
params . bootcount . set_and_save ( params . bootcount + 1 ) ;
2016-10-13 07:44:30 -03:00
// initialise our variables from parameters:
2016-10-13 21:59:06 -03:00
copy_variables_from_parameters ( ) ;
2016-10-13 03:30:04 -03:00
}
2016-10-13 06:39:06 -03:00
2016-10-13 21:08:17 -03:00
2016-10-13 06:39:06 -03:00
void AP_Stats : : flush ( )
{
2018-08-06 01:43:58 -03:00
params . flttime . set_and_save_ifchanged ( flttime ) ;
params . runtime . set_and_save_ifchanged ( runtime ) ;
2023-12-17 21:42:05 -04:00
last_flush_ms = AP_HAL : : millis ( ) ;
2016-10-13 07:44:30 -03:00
}
void AP_Stats : : update_flighttime ( )
{
if ( _flying_ms ) {
2019-12-02 06:16:01 -04:00
WITH_SEMAPHORE ( sem ) ;
2016-10-13 07:44:30 -03:00
const uint32_t now = AP_HAL : : millis ( ) ;
const uint32_t delta = ( now - _flying_ms ) / 1000 ;
flttime + = delta ;
_flying_ms + = delta * 1000 ;
}
2016-10-13 06:39:06 -03:00
}
2016-10-13 21:08:17 -03:00
void AP_Stats : : update_runtime ( )
{
const uint32_t now = AP_HAL : : millis ( ) ;
const uint32_t delta = ( now - _last_runtime_ms ) / 1000 ;
runtime + = delta ;
_last_runtime_ms + = delta * 1000 ;
}
2016-10-13 06:39:06 -03:00
void AP_Stats : : update ( )
{
2019-12-02 06:16:01 -04:00
WITH_SEMAPHORE ( sem ) ;
2016-10-13 06:39:06 -03:00
const uint32_t now_ms = AP_HAL : : millis ( ) ;
if ( now_ms - last_flush_ms > flush_interval_ms ) {
2016-10-13 07:44:30 -03:00
update_flighttime ( ) ;
2016-10-13 21:08:17 -03:00
update_runtime ( ) ;
2016-10-13 06:39:06 -03:00
flush ( ) ;
}
2016-10-13 21:59:06 -03:00
const uint32_t params_reset = params . reset ;
2017-06-08 05:26:19 -03:00
if ( params_reset = = 0 ) {
// Only reset statistics if the user explicitly sets AP_STATS_RESET parameter to zero.
// This allows users to load parameter files (in MP, MAVProxy or any other GCS) without
// accidentally reseting the statistics, because the AP_STATS_RESET value contained in
// the parameter file will be ignored (unless it is zero and it is usually not zero).
// The other statistics parameters are read-only, and the GCS should be clever enough to not set those.
params . bootcount . set_and_save_ifchanged ( 0 ) ;
2018-08-06 01:43:58 -03:00
params . flttime . set_and_save_ifchanged ( 0 ) ;
params . runtime . set_and_save_ifchanged ( 0 ) ;
2018-04-10 08:29:03 -03:00
uint32_t system_clock = 0 ; // in seconds
2023-10-04 04:03:33 -03:00
# if AP_RTC_ENABLED
2018-04-10 08:29:03 -03:00
uint64_t rtc_clock_us ;
if ( AP : : rtc ( ) . get_utc_usec ( rtc_clock_us ) ) {
system_clock = rtc_clock_us / 1000000 ;
// can't store Unix seconds in a 32-bit float. Change the
// time base to Jan 1st 2016:
system_clock - = 1451606400 ;
}
2023-10-04 04:03:33 -03:00
# endif
2018-08-06 01:43:58 -03:00
params . reset . set_and_save_ifchanged ( system_clock ) ;
2016-10-13 21:59:06 -03:00
copy_variables_from_parameters ( ) ;
}
2016-10-13 06:39:06 -03:00
}
2016-10-13 07:44:30 -03:00
void AP_Stats : : set_flying ( const bool is_flying )
{
if ( is_flying ) {
if ( ! _flying_ms ) {
_flying_ms = AP_HAL : : millis ( ) ;
}
} else {
2023-12-17 21:42:05 -04:00
if ( _flying_ms ) {
update_flighttime ( ) ;
update_runtime ( ) ;
flush ( ) ;
}
2016-10-13 07:44:30 -03:00
_flying_ms = 0 ;
}
}
2018-07-20 17:24:52 -03:00
/*
get time in flight since boot
*/
uint32_t AP_Stats : : get_flight_time_s ( void )
{
update_flighttime ( ) ;
return flttime - flttime_boot ;
}
AP_Stats * AP : : stats ( void )
{
return AP_Stats : : get_singleton ( ) ;
}