-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpower.c
124 lines (109 loc) · 4.22 KB
/
power.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "power.h"
#include <math.h>
#include "app_timer.h"
#include "nrf_log.h"
#include "config.h"
#define M_PI 3.14159265358979323846 /* pi */
static float v[3] = {0., 0., 0.};
static float filter_step(float x)
{
v[0] = v[1];
v[1] = (2.127896704574157583e-1 * x) + (0.57442065908516848349 * v[0]);
return (v[0] + v[1]);
}
static float filter_step_2(float x)
{
v[0] = v[1];
v[1] = v[2];
v[2] = (2.730192576740342672e-2 * x) + (-0.51147881111215798278 * v[0]) + (1.40227110804254428977 * v[1]);
return (v[0] + v[2]) + 2 * v[1];
}
static bool is_down = false;
void power_update_accel(power_compute_t *p_power_compute, imu_t *p_imu)
{
#if USE_GYRO
p_power_compute->rot_deg += p_imu->gyro_dps[GYRO_AXIS] / ACCEL_HZ;
p_power_compute->dps_sum += p_imu->gyro_dps[GYRO_AXIS];
p_power_compute->dps_cnt += 1;
if (p_power_compute->rot_deg > 360 || p_power_compute->rot_deg <= -360)
{
float dps = p_power_compute->dps_sum / p_power_compute->dps_cnt;
if (dps < 0) dps = -dps;
float revolution_time = 360 / dps;
float power_float = (2 * M_PI * p_power_compute->crank_length * 2 *
p_power_compute->force_sum / p_power_compute->force_cnt / revolution_time);
if (power_float < 0)
{
power_float = -power_float;
}
p_power_compute->page_16->instantaneous_power = (uint16_t)(power_float);
p_power_compute->page_16->accumulated_power += (uint16_t)(power_float);
p_power_compute->page_16->update_event_count++;
p_power_compute->common->instantaneous_cadence = (uint16_t)(60.0 / revolution_time);
p_power_compute->dps_cnt = 0;
p_power_compute->dps_sum = 0;
while (p_power_compute->rot_deg > 360) {
p_power_compute->rot_deg -= 360;
}
while (p_power_compute->rot_deg <= -360) {
p_power_compute->rot_deg += 360;
}
}
#else
float revolution_time;
p_power_compute->accel = filter_step_2(p_imu->accel_g[ACCEL_AXIS]);
if (p_power_compute->accel > 0.5)
{
is_down = true;
}
if (is_down && p_power_compute->accel < -0.5)
{
p_power_compute->rev_cnt++;
uint32_t rev_timer_cnt = app_timer_cnt_get();
revolution_time = (rev_timer_cnt - p_power_compute->rev_timer_cnt) / (float)APP_TIMER_TICKS(1000);
float power_float = (2 * M_PI * p_power_compute->crank_length * 2 *
p_power_compute->force_sum / p_power_compute->force_cnt / revolution_time);
if (power_float < 0)
{
power_float = -power_float;
}
p_power_compute->page_16->instantaneous_power = (uint16_t)(power_float);
p_power_compute->page_16->accumulated_power += (uint16_t)(power_float);
p_power_compute->page_16->update_event_count++;
p_power_compute->rev_timer_cnt = rev_timer_cnt;
p_power_compute->common->instantaneous_cadence = (uint16_t)(60.0 / revolution_time);
NRF_LOG_INFO("Revolution: %i rpm, %i W (%i measurements)",
(int)p_power_compute->common->instantaneous_cadence,
(int)power_float,
(int)p_power_compute->force_cnt);
p_power_compute->rev_time = revolution_time;
p_power_compute->force_sum = 0.0;
p_power_compute->force_cnt = 0;
is_down = false;
}
#endif
}
void power_update_scale(power_compute_t *p_power_compute, scale_t *p_scale)
{
p_power_compute->force_sum += p_scale->units;
p_power_compute->force_cnt++;
if (p_power_compute->page_1->auto_zero_status == ANT_BPWR_AUTO_ZERO_ON)
{
if (p_scale->units - p_power_compute->az_last_force < AUTO_ZERO_TOLERANCE &&
p_power_compute->az_last_force - p_scale->units < AUTO_ZERO_TOLERANCE)
{
p_power_compute->az_cnt++;
if (p_power_compute->az_cnt > (SCALE_HZ * AUTO_ZERO_INTERVAL) / 1000)
{
NRF_LOG_INFO("Setting auto zero.")
p_scale->offset = p_scale->raw;
p_power_compute->az_cnt = 0;
}
}
else
{
p_power_compute->az_cnt = 0;
p_power_compute->az_last_force = p_scale->units;
}
}
}