Skip to content

Commit fef9782

Browse files
committed
sensor precision fix, part 2, sensor changes
1 parent a767b31 commit fef9782

File tree

8 files changed

+65
-102
lines changed

8 files changed

+65
-102
lines changed

src/sensors/Encoder.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,25 @@ void Encoder::handleIndex() {
102102
Shaft angle calculation
103103
*/
104104
float Encoder::getAngle(){
105+
return _2PI * (pulse_counter % (int)cpr);
106+
}
107+
108+
float Encoder::getPosition(){
105109
return _2PI * (pulse_counter) / ((float)cpr);
106110
}
111+
double Encoder::getPrecisePosition(){
112+
return _2PI * (pulse_counter) / ((double)cpr);
113+
}
114+
int32_t Encoder::getFullRotations(){
115+
return pulse_counter / (int)cpr;
116+
}
117+
float Encoder::getShaftAngle(){
118+
return getAngle();
119+
}
120+
121+
122+
123+
107124
/*
108125
Shaft velocity calculation
109126
function using mixed time and frequency measurement technique

src/sensors/Encoder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,14 @@ class Encoder: public Sensor{
6060

6161
// Abstract functions of the Sensor class implementation
6262
/** get current angle (rad) */
63+
float getShaftAngle() override;
6364
float getAngle() override;
6465
/** get current angular velocity (rad/s) */
6566
float getVelocity() override;
67+
float getPosition() override;
68+
double getPrecisePosition() override;
69+
int32_t getFullRotations() override;
70+
6671
/**
6772
* returns 0 if it does need search for absolute zero
6873
* 0 - encoder without index

src/sensors/HallSensor.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,47 @@ void HallSensor::attachSectorCallback(void (*_onSectorChange)(int sector)) {
9696
Shaft angle calculation
9797
*/
9898
float HallSensor::getAngle() {
99-
return ((electric_rotations * 6 + electric_sector) / cpr) * _2PI ;
99+
return getShaftAngle();
100100
}
101101

102102
/*
103103
Shaft velocity calculation
104104
function using mixed time and frequency measurement technique
105105
*/
106106
float HallSensor::getVelocity(){
107-
if (pulse_diff == 0 || ((_micros() - pulse_timestamp) > pulse_diff) ) { // last velocity isn't accurate if too old
107+
if (pulse_diff == 0 || ((long)(_micros() - pulse_timestamp) > pulse_diff) ) { // last velocity isn't accurate if too old
108108
return 0;
109109
} else {
110-
return direction * (_2PI / cpr) / (pulse_diff / 1000000.0);
110+
return direction * (_2PI / (float)cpr) / (pulse_diff / 1000000.0);
111111
}
112112

113113
}
114114

115+
116+
117+
float HallSensor::getShaftAngle() {
118+
return (float)((electric_rotations * 6 + electric_sector) % cpr) * _2PI ;
119+
}
120+
121+
122+
float HallSensor::getPosition() {
123+
return ((float)(electric_rotations * 6 + electric_sector) / (float)cpr) * _2PI ;
124+
}
125+
126+
127+
double HallSensor::getPrecisePosition() {
128+
return ((double)(electric_rotations * 6 + electric_sector) / (double)cpr) * (double)_2PI ;
129+
}
130+
131+
132+
int32_t HallSensor::getFullRotations() {
133+
return (int32_t)((electric_rotations * 6 + electric_sector) / cpr);
134+
}
135+
136+
137+
138+
139+
115140
// HallSensor initialisation of the hardware pins
116141
// and calculation variables
117142
void HallSensor::init(){
@@ -149,4 +174,3 @@ void HallSensor::enableInterrupts(void (*doA)(), void(*doB)(), void(*doC)()){
149174
if(doB != nullptr) attachInterrupt(digitalPinToInterrupt(pinB), doB, CHANGE);
150175
if(doC != nullptr) attachInterrupt(digitalPinToInterrupt(pinC), doC, CHANGE);
151176
}
152-

src/sensors/HallSensor.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,17 @@ class HallSensor: public Sensor{
5050

5151
// HallSensor configuration
5252
Pullup pullup; //!< Configuration parameter internal or external pullups
53-
float cpr;//!< HallSensor cpr number
53+
int cpr;//!< HallSensor cpr number
5454

5555
// Abstract functions of the Sensor class implementation
5656
/** get current angle (rad) */
57+
float getShaftAngle() override;
5758
float getAngle() override;
5859
/** get current angular velocity (rad/s) */
5960
float getVelocity() override;
61+
float getPosition() override;
62+
double getPrecisePosition() override;
63+
int32_t getFullRotations() override;
6064

6165
// whether last step was CW (+1) or CCW (-1).
6266
Direction direction;
@@ -77,7 +81,7 @@ class HallSensor: public Sensor{
7781
Direction decodeDirection(int oldState, int newState);
7882
void updateState();
7983

80-
volatile long pulse_timestamp;//!< last impulse timestamp in us
84+
volatile unsigned long pulse_timestamp;//!< last impulse timestamp in us
8185
volatile int A_active; //!< current active states of A channel
8286
volatile int B_active; //!< current active states of B channel
8387
volatile int C_active; //!< current active states of C channel

src/sensors/MagneticSensorAnalog.cpp

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,47 +23,15 @@ MagneticSensorAnalog::MagneticSensorAnalog(uint8_t _pinAnalog, int _min_raw_coun
2323

2424

2525
void MagneticSensorAnalog::init(){
26-
27-
// velocity calculation init
28-
angle_prev = 0;
29-
velocity_calc_timestamp = _micros();
30-
31-
// full rotations tracking number
32-
full_rotation_offset = 0;
33-
raw_count_prev = getRawCount();
26+
raw_count = getRawCount();
3427
}
3528

3629
// Shaft angle calculation
3730
// angle is in radians [rad]
38-
float MagneticSensorAnalog::getAngle(){
31+
float MagneticSensorAnalog::getShaftAngle(){
3932
// raw data from the sensor
40-
raw_count = getRawCount();
41-
42-
int delta = raw_count - raw_count_prev;
43-
// if overflow happened track it as full rotation
44-
if(abs(delta) > (0.8*cpr) ) full_rotation_offset += delta > 0 ? -_2PI : _2PI;
45-
46-
float angle = full_rotation_offset + ( (float) (raw_count) / (float)cpr) * _2PI;
47-
48-
// calculate velocity here
49-
long now = _micros();
50-
float Ts = ( now - velocity_calc_timestamp)*1e-6;
51-
// quick fix for strange cases (micros overflow)
52-
if(Ts <= 0 || Ts > 0.5) Ts = 1e-3;
53-
velocity = (angle - angle_prev)/Ts;
54-
55-
// save variables for future pass
56-
raw_count_prev = raw_count;
57-
angle_prev = angle;
58-
velocity_calc_timestamp = now;
59-
60-
return angle;
61-
}
62-
63-
// Shaft velocity calculation
64-
float MagneticSensorAnalog::getVelocity(){
65-
// TODO: Refactor?: to avoid angle being called twice, velocity is pre-calculted during getAngle
66-
return velocity;
33+
raw_count = getRawCount();
34+
return ( (float) (raw_count) / (float)cpr) * _2PI;
6735
}
6836

6937
// function reading the raw counter of the magnetic sensor

src/sensors/MagneticSensorAnalog.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ class MagneticSensorAnalog: public Sensor{
2929

3030
// implementation of abstract functions of the Sensor class
3131
/** get current angle (rad) */
32-
float getAngle() override;
33-
/** get current angular velocity (rad/s) **/
34-
float getVelocity() override;
35-
32+
float getShaftAngle() override;
3633
/** raw count (typically in range of 0-1023), useful for debugging resolution issues */
3734
int raw_count;
3835

@@ -48,16 +45,6 @@ class MagneticSensorAnalog: public Sensor{
4845
*/
4946
int getRawCount();
5047

51-
// total angle tracking variables
52-
float full_rotation_offset; //!<number of full rotations made
53-
int raw_count_prev; //!< angle in previous position calculation step
54-
55-
// velocity calculation variables
56-
float angle_prev; //!< angle in previous velocity calculation step
57-
long velocity_calc_timestamp; //!< last velocity calculation timestamp
58-
float velocity;
59-
60-
6148
};
6249

6350

src/sensors/MagneticSensorPWM.cpp

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,47 +26,16 @@ void MagneticSensorPWM::init(){
2626

2727
// initial hardware
2828
pinMode(pinPWM, INPUT);
29-
30-
// velocity calculation init
31-
angle_prev = 0;
32-
velocity_calc_timestamp = _micros();
33-
34-
// full rotations tracking number
35-
full_rotation_offset = 0;
36-
raw_count_prev = getRawCount();
29+
raw_count = getRawCount();
3730
}
3831

3932
// get current angle (rad)
40-
float MagneticSensorPWM::getAngle(){
41-
33+
float MagneticSensorPWM::getShaftAngle(){
4234
// raw data from sensor
4335
raw_count = getRawCount();
44-
45-
int delta = raw_count - raw_count_prev;
46-
// if overflow happened track it as full rotation
47-
if(abs(delta) > (0.8*cpr) ) full_rotation_offset += delta > 0 ? -_2PI : _2PI;
48-
49-
float angle = full_rotation_offset + ( (float) (raw_count) / (float)cpr) * _2PI;
50-
51-
// calculate velocity here
52-
long now = _micros();
53-
float Ts = (now - velocity_calc_timestamp)*1e-6;
54-
// quick fix for strange cases (micros overflow)
55-
if(Ts <= 0 || Ts > 0.5) Ts = 1e-3;
56-
velocity = (angle - angle_prev)/Ts;
57-
58-
// save variables for future pass
59-
raw_count_prev = raw_count;
60-
angle_prev = angle;
61-
velocity_calc_timestamp = now;
62-
63-
return angle;
36+
return( (float) (raw_count) / (float)cpr) * _2PI;
6437
}
6538

66-
// get velocity (rad/s)
67-
float MagneticSensorPWM::getVelocity(){
68-
return velocity;
69-
}
7039

7140
// read the raw counter of the magnetic sensor
7241
int MagneticSensorPWM::getRawCount(){

src/sensors/MagneticSensorPWM.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ class MagneticSensorPWM: public Sensor{
2323
int pinPWM;
2424

2525
// get current angle (rad)
26-
float getAngle() override;
27-
// get current angular velocity (rad/s)
28-
float getVelocity() override;
26+
float getShaftAngle() override;
2927

3028
// pwm handler
3129
void handlePWM();
@@ -50,15 +48,6 @@ class MagneticSensorPWM: public Sensor{
5048
*/
5149
int getRawCount();
5250

53-
// total angle tracking variables
54-
float full_rotation_offset; //!<number of full rotations made
55-
int raw_count_prev; //!< angle in previous position calculation step
56-
57-
// velocity calculation variables
58-
float angle_prev; //!< angle in previous velocity calculation step
59-
long velocity_calc_timestamp; //!< last velocity calculation timestamp
60-
float velocity;
61-
6251
// time tracking variables
6352
unsigned long last_call_us;
6453
// unsigned long pulse_length_us;

0 commit comments

Comments
 (0)