55
66
77void Sensor::update () {
8- float val = getSensorAngle ();
8+ angle_type val = getSensorAngle ();
99 if (val<0 ) // sensor angles are strictly non-negative. Negative values are used to signal errors.
1010 return ; // TODO signal error, e.g. via a flag and counter
1111 angle_prev_ts = _micros ();
12- float d_angle = val - angle_prev;
13- // if overflow happened track it as full rotation
14- if (abs (d_angle) > (0 .8f *_2PI) ) full_rotations += ( d_angle > 0 ) ? -1 : 1 ;
15- angle_prev = val;
12+ setAngleContinuous (val);
1613}
1714
1815
1916 /* * get current angular velocity (rad/s) */
2017float Sensor::getVelocity () {
2118 // calculate sample time
2219 // if timestamps were unsigned, we could get rid of this section, unsigned overflow handles it correctly
20+ #ifdef INTEGER_ANGLE
21+ angle_type Ts = angle_prev_ts - vel_angle_prev_ts;
22+ #else
2323 float Ts = (angle_prev_ts - vel_angle_prev_ts)*1e-6f ;
24+ #endif
25+ #if 0
2426 if (Ts < 0.0f) { // handle micros() overflow - we need to reset vel_angle_prev_ts
2527 vel_angle_prev = angle_prev;
28+ #ifndef INTEGER_ANGLE
2629 vel_full_rotations = full_rotations;
30+ #endif
2731 vel_angle_prev_ts = angle_prev_ts;
2832 return velocity;
2933 }
34+ #endif
3035 if (Ts < min_elapsed_time) return velocity; // don't update velocity if deltaT is too small
3136
3237 // Calculate change in angle. Handles `full_rotations` integer wrap-arounds,
3338 // and avoids float precision loss issues by keeping numbers small.
34- float delta_angle = angle_prev - vel_angle_prev;
39+ angle_type delta_angle = angle_prev - vel_angle_prev;
40+ #ifndef INTEGER_ANGLE
3541 const int32_t delta_full_rotations = full_rotations - vel_full_rotations;
3642 if (delta_full_rotations) {
3743 delta_angle += delta_full_rotations * _2PI;
3844 }
45+ #endif
3946
47+ #ifdef INTEGER_ANGLE
48+ if (abs (delta_angle) > 0 )
49+ {
50+ velocity = delta_angle * 1000000 * _2PI / (Ts * steps_per_revolution);
51+ }
52+ else
53+ {
54+ velocity = 0 .0f ;
55+ }
56+
57+ #else
4058 // floating point equality checks are bad, so instead we check that the angle change is very small
4159 if (fabsf (delta_angle) > 1e-8f ) {
4260 velocity = delta_angle / Ts;
4361 } else {
4462 velocity = 0 .0f ;
4563 }
64+ #endif
4665
4766 // Always advance the velocity reference sample to avoid stale deltas/time windows.
4867 vel_angle_prev = angle_prev;
68+ #ifndef INTEGER_ANGLE
4969 vel_full_rotations = full_rotations;
70+ #endif
5071 vel_angle_prev_ts = angle_prev_ts;
5172
5273 return velocity;
@@ -68,30 +89,63 @@ void Sensor::init() {
6889}
6990
7091
71- float Sensor::getMechanicalAngle () {
92+ angle_type Sensor::getMechanicalAngle () {
7293 return angle_prev;
7394}
7495
7596
7697
7798float Sensor::getAngle (){
99+ #ifdef INTEGER_ANGLE
100+ return angle_prev / (float )steps_per_revolution * _2PI;
101+ #else
78102 return (float )full_rotations * _2PI + angle_prev;
103+ #endif
79104}
80105
81106
82107
83108double Sensor::getPreciseAngle () {
109+ #ifdef INTEGER_ANGLE
110+ return angle_prev / (double )steps_per_revolution * _2PI;
111+ #else
84112 return (double )full_rotations * (double )_2PI + (double )angle_prev;
113+ #endif
85114}
86115
87116
88117
89118int32_t Sensor::getFullRotations () {
119+ #ifdef INTEGER_ANGLE
120+ return angle_prev/steps_per_revolution;
121+ #else
90122 return full_rotations;
123+ #endif
91124}
92125
93126
94127
95128int Sensor::needsSearch () {
96129 return 0 ; // default false
97130}
131+
132+ void Sensor::setAngleContinuous (angle_type sensor_angle)
133+ {
134+ #ifdef INTEGER_ANGLE
135+ angle_type d_angle = sensor_angle - sensor_angle_prev;
136+ if (abs (d_angle) > (steps_per_revolution/2 ) )
137+ {
138+ d_angle += d_angle > 0 ? -steps_per_revolution : steps_per_revolution;
139+ }
140+ angle_prev += d_angle;
141+ sensor_angle_prev = sensor_angle;
142+ #else
143+ angle_type d_angle = sensor_angle - angle_prev;
144+ if (abs (d_angle) > (0 .8f *_2PI) )
145+ {
146+ full_rotations += ( d_angle > 0 ) ? -1 : 1 ;
147+ }
148+ angle_prev = sensor_angle;
149+ #endif
150+
151+ }
0 commit comments