@@ -19,6 +19,7 @@ void Sensor::update() {
1919 /* * get current angular velocity (rad/s) */
2020float Sensor::getVelocity () {
2121 // calculate sample time
22+ // if timestamps were unsigned, we could get rid of this section, unsigned overflow handles it correctly
2223 float Ts = (angle_prev_ts - vel_angle_prev_ts)*1e-6f ;
2324 if (Ts < 0 .0f ) { // handle micros() overflow - we need to reset vel_angle_prev_ts
2425 vel_angle_prev = angle_prev;
@@ -28,10 +29,28 @@ float Sensor::getVelocity() {
2829 }
2930 if (Ts < min_elapsed_time) return velocity; // don't update velocity if deltaT is too small
3031
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 ;
33+ float prev_angle = 0 ;
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+
3554 return velocity;
3655}
3756
0 commit comments