Skip to content

Commit 3778dbe

Browse files
committed
Added support for statistics
1 parent f9170e9 commit 3778dbe

7 files changed

+215
-1
lines changed

CHANGELOG

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
* Compensate inductance for motor saliency in observer.
4545
* Added MTPA mode based on measured current.
4646
* Faster overvoltage protection.
47+
* Added statistics counters.
4748

4849
=== FW 5.02 ===
4950
* IMU calibration improvement.

commands.c

+39
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,45 @@ void commands_process_packet(unsigned char *data, unsigned int len,
14911491
comm_can_io_board_set_output_digital(id, channel, on);
14921492
} break;
14931493

1494+
case COMM_GET_STATS: {
1495+
int32_t ind = 0;
1496+
uint32_t mask = buffer_get_uint16(data, &ind);
1497+
1498+
ind = 0;
1499+
uint8_t send_buffer[60];
1500+
send_buffer[ind++] = packet_id;
1501+
buffer_append_uint32(send_buffer, mask, &ind);
1502+
1503+
if (mask & ((uint32_t)1 << 0)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_speed_avg(), &ind); }
1504+
if (mask & ((uint32_t)1 << 1)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_speed_max(), &ind); }
1505+
if (mask & ((uint32_t)1 << 2)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_power_avg(), &ind); }
1506+
if (mask & ((uint32_t)1 << 3)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_power_max(), &ind); }
1507+
if (mask & ((uint32_t)1 << 4)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_current_avg(), &ind); }
1508+
if (mask & ((uint32_t)1 << 5)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_current_max(), &ind); }
1509+
if (mask & ((uint32_t)1 << 6)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_temp_mosfet_avg(), &ind); }
1510+
if (mask & ((uint32_t)1 << 7)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_temp_mosfet_max(), &ind); }
1511+
if (mask & ((uint32_t)1 << 8)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_temp_motor_avg(), &ind); }
1512+
if (mask & ((uint32_t)1 << 9)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_temp_motor_max(), &ind); }
1513+
if (mask & ((uint32_t)1 << 10)) { buffer_append_float32_auto(send_buffer, mc_interface_stat_count_time(), &ind); }
1514+
1515+
reply_func(send_buffer, ind);
1516+
} break;
1517+
1518+
case COMM_RESET_STATS: {
1519+
bool ack = false;
1520+
1521+
if (len > 0) {
1522+
ack = data[0];
1523+
}
1524+
1525+
if (ack) {
1526+
int32_t ind = 0;
1527+
uint8_t send_buffer[50];
1528+
send_buffer[ind++] = packet_id;
1529+
reply_func(send_buffer, ind);
1530+
}
1531+
} break;
1532+
14941533
// Blocking commands. Only one of them runs at any given time, in their
14951534
// own thread. If other blocking commands come before the previous one has
14961535
// finished, they are discarded.

conf_general.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#define FW_VERSION_MAJOR 5
2525
#define FW_VERSION_MINOR 03
2626
// Set to 0 for building a release and iterate during beta test builds
27-
#define FW_TEST_VERSION_NUMBER 63
27+
#define FW_TEST_VERSION_NUMBER 64
2828

2929
#include "datatypes.h"
3030

datatypes.h

+17
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,8 @@ typedef enum {
10571057
COMM_BM_MEM_WRITE,
10581058
COMM_BMS_BLNC_SELFTEST,
10591059
COMM_GET_EXT_HUM_TMP,
1060+
COMM_GET_STATS,
1061+
COMM_RESET_STATS,
10601062
} COMM_PACKET_ID;
10611063

10621064
// CAN commands
@@ -1302,6 +1304,21 @@ typedef struct {
13021304
uint8_t num_vescs;
13031305
} setup_values;
13041306

1307+
typedef struct {
1308+
systime_t time_start;
1309+
double samples;
1310+
double speed_sum;
1311+
float max_speed;
1312+
double power_sum;
1313+
float max_power;
1314+
double temp_motor_sum;
1315+
float max_temp_motor;
1316+
double temp_mos_sum;
1317+
float max_temp_mos;
1318+
double current_sum;
1319+
float max_current;
1320+
} setup_stats;
1321+
13051322
#define BACKUP_VAR_INIT_CODE 92891934
13061323

13071324
typedef struct __attribute__((packed)) {

mc_interface.c

+122
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ volatile float ADC_curr_norm_value[6];
5454
typedef struct {
5555
volatile mc_configuration m_conf;
5656
mc_fault_code m_fault_now;
57+
setup_stats m_stats;
5758
int m_ignore_iterations;
5859
int m_drv_fault_iterations;
5960
unsigned int m_cycles_running;
@@ -124,6 +125,7 @@ static volatile bool m_fault_stop_is_second_motor;
124125
// Private functions
125126
static void update_override_limits(volatile motor_if_state_t *motor, volatile mc_configuration *conf);
126127
static void run_timer_tasks(volatile motor_if_state_t *motor);
128+
static void update_stats(volatile motor_if_state_t *motor);
127129
static volatile motor_if_state_t *motor_now(void);
128130

129131
// Function pointers
@@ -138,6 +140,8 @@ static thread_t *sample_send_tp;
138140
static THD_WORKING_AREA(fault_stop_thread_wa, 512);
139141
static THD_FUNCTION(fault_stop_thread, arg);
140142
static thread_t *fault_stop_tp;
143+
static THD_WORKING_AREA(stat_thread_wa, 512);
144+
static THD_FUNCTION(stat_thread, arg);
141145

142146
void mc_interface_init(void) {
143147
memset((void*)&m_motor_1, 0, sizeof(motor_if_state_t));
@@ -165,10 +169,13 @@ void mc_interface_init(void) {
165169
m_sample_mode_last = DEBUG_SAMPLING_OFF;
166170
m_sample_is_second_motor = false;
167171

172+
mc_interface_stat_reset();
173+
168174
// Start threads
169175
chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL);
170176
chThdCreateStatic(sample_send_thread_wa, sizeof(sample_send_thread_wa), NORMALPRIO - 1, sample_send_thread, NULL);
171177
chThdCreateStatic(fault_stop_thread_wa, sizeof(fault_stop_thread_wa), HIGHPRIO - 3, fault_stop_thread, NULL);
178+
chThdCreateStatic(stat_thread_wa, sizeof(stat_thread_wa), NORMALPRIO, stat_thread, NULL);
172179

173180
int motor_old = mc_interface_get_motor_thread();
174181
mc_interface_select_motor_thread(1);
@@ -2538,6 +2545,121 @@ static THD_FUNCTION(timer_thread, arg) {
25382545
}
25392546
}
25402547

2548+
static void update_stats(volatile motor_if_state_t *motor) {
2549+
mc_interface_select_motor_thread(motor == (&m_motor_1) ? 1 : 2);
2550+
2551+
setup_values val = mc_interface_get_setup_values();
2552+
2553+
const double power = mc_interface_get_input_voltage_filtered() * fabsf(val.current_in_tot);
2554+
const double speed = mc_interface_get_speed();
2555+
const double temp_mos = mc_interface_temp_fet_filtered();
2556+
const double temp_mot = mc_interface_temp_motor_filtered();
2557+
2558+
motor->m_stats.power_sum += power;
2559+
motor->m_stats.speed_sum += fabs(speed);
2560+
motor->m_stats.temp_mos_sum += temp_mos;
2561+
motor->m_stats.temp_motor_sum += temp_mot;
2562+
motor->m_stats.current_sum += fabs((double)(val.current_tot));
2563+
motor->m_stats.samples += (double)1.0;
2564+
2565+
if (power > (double)motor->m_stats.max_power) {
2566+
motor->m_stats.max_power = power;
2567+
}
2568+
2569+
if (fabs(speed) > (double)motor->m_stats.max_speed) {
2570+
motor->m_stats.max_speed = fabsf(speed);
2571+
}
2572+
2573+
if (temp_mos > (double)motor->m_stats.max_temp_mos) {
2574+
motor->m_stats.max_temp_mos = temp_mos;
2575+
}
2576+
2577+
if (temp_mot > (double)motor->m_stats.max_temp_motor) {
2578+
motor->m_stats.max_temp_motor = temp_mot;
2579+
}
2580+
2581+
if (fabsf(val.current_tot) > motor->m_stats.max_current) {
2582+
motor->m_stats.max_current = fabsf(val.current_tot);
2583+
}
2584+
}
2585+
2586+
float mc_interface_stat_speed_avg(void) {
2587+
volatile setup_stats *s = &motor_now()->m_stats;
2588+
double res = s->speed_sum / s->samples;
2589+
return res;
2590+
}
2591+
2592+
float mc_interface_stat_speed_max(void) {
2593+
return motor_now()->m_stats.max_speed;
2594+
}
2595+
2596+
float mc_interface_stat_power_avg(void) {
2597+
volatile setup_stats *s = &motor_now()->m_stats;
2598+
double res = s->power_sum / s->samples;
2599+
return res;
2600+
}
2601+
2602+
float mc_interface_stat_power_max(void) {
2603+
return motor_now()->m_stats.max_power;
2604+
}
2605+
2606+
float mc_interface_stat_current_avg(void) {
2607+
volatile setup_stats *s = &motor_now()->m_stats;
2608+
double res = s->current_sum / s->samples;
2609+
return res;
2610+
}
2611+
2612+
float mc_interface_stat_current_max(void) {
2613+
return motor_now()->m_stats.max_current;
2614+
}
2615+
2616+
float mc_interface_stat_temp_mosfet_avg(void) {
2617+
volatile setup_stats *s = &motor_now()->m_stats;
2618+
double res = s->temp_mos_sum / s->samples;
2619+
return res;
2620+
}
2621+
2622+
float mc_interface_stat_temp_mosfet_max(void) {
2623+
return motor_now()->m_stats.max_temp_mos;
2624+
}
2625+
2626+
float mc_interface_stat_temp_motor_avg(void) {
2627+
volatile setup_stats *s = &motor_now()->m_stats;
2628+
double res = s->temp_motor_sum / s->samples;
2629+
return res;
2630+
}
2631+
2632+
float mc_interface_stat_temp_motor_max(void) {
2633+
return motor_now()->m_stats.max_temp_motor;
2634+
}
2635+
2636+
float mc_interface_stat_count_time(void) {
2637+
return UTILS_AGE_S(motor_now()->m_stats.time_start);
2638+
}
2639+
2640+
void mc_interface_stat_reset(void) {
2641+
volatile setup_stats *s = &motor_now()->m_stats;
2642+
memset((void*)s, 0, sizeof(setup_stats));
2643+
s->time_start = chVTGetSystemTimeX();
2644+
s->max_temp_mos = -300.0;
2645+
s->max_temp_motor = -300.0;
2646+
}
2647+
2648+
static THD_FUNCTION(stat_thread, arg) {
2649+
(void)arg;
2650+
2651+
chRegSetThreadName("StatCounter");
2652+
2653+
for(;;) {
2654+
update_stats(&m_motor_1);
2655+
#ifdef HW_HAS_DUAL_MOTORS
2656+
update_stats(&m_motor_2);
2657+
#endif
2658+
2659+
chThdSleepMilliseconds(10);
2660+
}
2661+
}
2662+
25412663
static THD_FUNCTION(sample_send_thread, arg) {
25422664
(void)arg;
25432665

mc_interface.h

+14
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,20 @@ void mc_interface_ignore_input_both(int time_ms);
101101

102102
void mc_interface_set_current_off_delay(float delay_sec);
103103

104+
// Statistics
105+
float mc_interface_stat_speed_avg(void);
106+
float mc_interface_stat_speed_max(void);
107+
float mc_interface_stat_power_avg(void);
108+
float mc_interface_stat_power_max(void);
109+
float mc_interface_stat_current_avg(void);
110+
float mc_interface_stat_current_max(void);
111+
float mc_interface_stat_temp_mosfet_avg(void);
112+
float mc_interface_stat_temp_mosfet_max(void);
113+
float mc_interface_stat_temp_motor_avg(void);
114+
float mc_interface_stat_temp_motor_max(void);
115+
float mc_interface_stat_count_time(void);
116+
void mc_interface_stat_reset(void);
117+
104118
// MC implementation functions
105119
void mc_interface_fault_stop(mc_fault_code fault, bool is_second_motor, bool is_isr);
106120
int mc_interface_try_input(void);

terminal.c

+21
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,21 @@ void terminal_process_string(char *str) {
11211121
commands_printf("Invalid arguments\n");
11221122
}
11231123
}
1124+
} else if (strcmp(argv[0], "stats") == 0) {
1125+
commands_printf("Speed Avg : %.1f km/h", (double)(mc_interface_stat_speed_avg() * 3.6));
1126+
commands_printf("Speed Max : %.1f km/h", (double)(mc_interface_stat_speed_max() * 3.6));
1127+
commands_printf("Power Avg : %.1f W", (double)mc_interface_stat_power_avg());
1128+
commands_printf("Power Max : %.1f W", (double)mc_interface_stat_power_max());
1129+
commands_printf("Current Avg: %.1f A", (double)mc_interface_stat_current_avg());
1130+
commands_printf("Current Max: %.1f A", (double)mc_interface_stat_current_max());
1131+
commands_printf("T FET Avg : %.1f degC", (double)mc_interface_stat_temp_mosfet_avg());
1132+
commands_printf("T FET Max : %.1f degC", (double)mc_interface_stat_temp_mosfet_max());
1133+
commands_printf("T MOTOR Avg: %.1f degC", (double)mc_interface_stat_temp_motor_avg());
1134+
commands_printf("T MOTOR Max: %.1f degC", (double)mc_interface_stat_temp_motor_max());
1135+
commands_printf("Count Time : %.1f s\n", (double)mc_interface_stat_count_time());
1136+
} else if (strcmp(argv[0], "stats_reset") == 0) {
1137+
mc_interface_stat_reset();
1138+
commands_printf("OK\n");
11241139
}
11251140

11261141
// The help command
@@ -1269,6 +1284,12 @@ void terminal_process_string(char *str) {
12691284
commands_printf("update_pid_pos_offset [angle_now] [store]");
12701285
commands_printf(" Update position PID offset.");
12711286

1287+
commands_printf("stats");
1288+
commands_printf(" Print setup statistics.");
1289+
1290+
commands_printf("stats_reset");
1291+
commands_printf(" Reset setup statistics.");
1292+
12721293
for (int i = 0;i < callback_write;i++) {
12731294
if (callbacks[i].cbf == 0) {
12741295
continue;

0 commit comments

Comments
 (0)