@@ -19,6 +19,7 @@ void Sensor::update() {
19
19
/* * get current angular velocity (rad/s) */
20
20
float Sensor::getVelocity () {
21
21
// calculate sample time
22
+ // if timestamps were unsigned, we could get rid of this section, unsigned overflow handles it correctly
22
23
float Ts = (angle_prev_ts - vel_angle_prev_ts)*1e-6f ;
23
24
if (Ts < 0 .0f ) { // handle micros() overflow - we need to reset vel_angle_prev_ts
24
25
vel_angle_prev = angle_prev;
@@ -28,10 +29,28 @@ float Sensor::getVelocity() {
28
29
}
29
30
if (Ts < min_elapsed_time) return velocity; // don't update velocity if deltaT is too small
30
31
31
- velocity = ( (float )(full_rotations - vel_full_rotations)*_2PI + (angle_prev - vel_angle_prev) ) / Ts;
32
- vel_angle_prev = angle_prev;
33
- vel_full_rotations = full_rotations;
34
- vel_angle_prev_ts = angle_prev_ts;
32
+ float current_angle = 0 .0f ;
33
+ float prev_angle = 0 .0f ;
34
+ // Avoid floating point precision loss for large full_rotations
35
+ // this is likely optional
36
+ if (full_rotations == vel_full_rotations) {
37
+ current_angle = angle_prev;
38
+ prev_angle = vel_angle_prev;
39
+ } else {
40
+ current_angle = (float ) full_rotations * _2PI + angle_prev;
41
+ prev_angle = (float ) vel_full_rotations * _2PI + vel_angle_prev;
42
+ }
43
+ const float delta_angle = current_angle - prev_angle;
44
+
45
+ // floating point equality checks are bad, so instead we check that the angle change is very small
46
+ if (fabsf (delta_angle) > 1e-8f ) {
47
+ velocity = delta_angle / Ts;
48
+
49
+ vel_angle_prev = angle_prev;
50
+ vel_full_rotations = full_rotations;
51
+ vel_angle_prev_ts = angle_prev_ts;
52
+ }
53
+
35
54
return velocity;
36
55
}
37
56
0 commit comments