Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
#include "Utils/Stats.h"
#include "Hal/FastCode.hpp"
#include "Hal/Time.hpp"
#include <algorithm>
#include <cstddef>
namespace Espfc::Utils {
Stats::Stats(): _loop_last(0), _loop_time(0)
{
for (size_t i = 0; i < COUNTER_COUNT; i++)
{
_start[i] = 0;
_avg[i] = 0;
_sum[i] = 0;
_count[i] = 0;
_freq[i] = 0;
}
}
void FAST_CODE_ATTR Stats::start(StatCounter c)
{
_start[c] = micros();
}
void FAST_CODE_ATTR Stats::end(StatCounter c)
{
uint32_t diff = micros() - _start[c];
_sum[c] += diff;
_count[c]++;
}
void Stats::loopTick()
{
uint32_t now = micros();
uint32_t diff = now - _loop_last;
//_loop_time = diff;
_loop_time += (((int32_t)diff - _loop_time + 4) >> 3);
_loop_last = now;
}
uint32_t Stats::loopTime() const
{
return _loop_time;
}
void Stats::update()
{
if (!timer.check()) return;
for (size_t i = 0; i < COUNTER_COUNT; i++)
{
_avg[i] = (float)(_sum[i] + (_count[i] >> 1)) / timer.delta;
_freq[i] = (float)_count[i] * 1e6 / timer.delta;
_real[i] = _count[i] > 0 ? ((float)(_sum[i] + (_count[i] >> 1)) / _count[i]) : 0.0f;
_sum[i] = 0;
_count[i] = 0;
}
}
float Stats::getLoad(StatCounter c) const
{
return _avg[c] * 100.f;
}
/**
* @brief Get the Time of counter normalized to 1 ms
*/
float Stats::getTime(StatCounter c) const
{
return _avg[c] * 1000.0f;
}
float Stats::getReal(StatCounter c) const
{
return _real[c];
}
float Stats::getFreq(StatCounter c) const
{
return _freq[c];
}
float Stats::getTotalLoad() const
{
float ret = 0;
for (size_t i = 0; i < COUNTER_COUNT; i++)
{
if (i == COUNTER_CPU_0 || i == COUNTER_CPU_1) continue;
ret += getLoad((StatCounter)i);
}
return ret;
}
float Stats::getTotalTime() const
{
float ret = 0;
for (size_t i = 0; i < COUNTER_COUNT; i++)
{
if (i == COUNTER_CPU_0 || i == COUNTER_CPU_1) continue;
ret += getTime((StatCounter)i);
}
return ret;
}
float Stats::getCpuLoad() const
{
float cpu0 = getLoad(COUNTER_CPU_0);
float cpu1 = getLoad(COUNTER_CPU_1);
float maxLoad = std::max(cpu0, cpu1);
float minLoad = std::min(cpu0, cpu1);
float alpha = maxLoad / (minLoad + maxLoad);
return alpha * maxLoad + (1.f - alpha) * minLoad;
}
float Stats::getCpuTime() const
{
return getTime(COUNTER_CPU_0) + getTime(COUNTER_CPU_1);
}
const char* Stats::getName(StatCounter c) const
{
// clang-format off
switch (c)
{
case COUNTER_GYRO_READ: return "gyro_r";
case COUNTER_GYRO_FILTER: return "gyro_f";
case COUNTER_GYRO_FFT: return "gyro_a";
case COUNTER_RPM_UPDATE: return " rpm_u";
case COUNTER_ACCEL_READ: return " acc_r";
case COUNTER_ACCEL_FILTER: return " acc_f";
case COUNTER_MAG_READ: return " mag_r";
case COUNTER_MAG_FILTER: return " mag_f";
case COUNTER_BARO: return "baro_p";
case COUNTER_GPS_READ: return " gps_r";
case COUNTER_IMU_FUSION: return " imu_p";
case COUNTER_IMU_FUSION2: return " imu_c";
case COUNTER_OUTER_PID: return " pid_o";
case COUNTER_INNER_PID: return " pid_i";
case COUNTER_MIXER: return " mix_p";
case COUNTER_MIXER_WRITE: return " mix_w";
case COUNTER_MIXER_READ: return " mix_r";
case COUNTER_BLACKBOX: return " bblog";
case COUNTER_INPUT_READ: return " rx_r";
case COUNTER_INPUT_FILTER: return " rx_f";
case COUNTER_FAILSAFE: return " rx_s";
case COUNTER_ACTUATOR: return " rx_a";
case COUNTER_SERIAL: return "serial";
case COUNTER_WIFI: return " wifi";
case COUNTER_BATTERY: return " bat";
case COUNTER_TELEMETRY: return " tlm";
case COUNTER_CPU_0: return " cpu_0";
case COUNTER_CPU_1: return " cpu_1";
default: return "unknwn";
}
// clang-format on
}
} // namespace Espfc::Utils
f27e468caThis file is pinned to the selected release. Download the original to open it in your design tool.