|
3 | 3 | // CalibratedSensor()
|
4 | 4 | // sensor - instance of original sensor object
|
5 | 5 | // n_lut - number of samples in the LUT
|
6 |
| -// lut - pointer to the LUT array |
7 |
| -CalibratedSensor::CalibratedSensor(Sensor &wrapped, int n_lut, float* lut) : _wrapped(wrapped) { |
| 6 | +CalibratedSensor::CalibratedSensor(Sensor &wrapped, int n_lut) : _wrapped(wrapped) { |
8 | 7 | this->n_lut = n_lut;
|
9 |
| - this->calibrationLut = lut; |
10 | 8 | };
|
11 | 9 |
|
12 | 10 | CalibratedSensor::~CalibratedSensor() {
|
@@ -36,7 +34,7 @@ float CalibratedSensor::getSensorAngle()
|
36 | 34 | // Calculate the resolution of the LUT in radians
|
37 | 35 | float lut_resolution = _2PI / n_lut;
|
38 | 36 | // Calculate LUT index
|
39 |
| - int lut_index = raw_angle / lut_resolution + bucket_offset; |
| 37 | + int lut_index = raw_angle / lut_resolution; |
40 | 38 |
|
41 | 39 | // Get calibration values from the LUT
|
42 | 40 | float y0 = calibrationLut[lut_index];
|
@@ -86,49 +84,59 @@ void CalibratedSensor::filter_error(float* error, float &error_mean, int n_ticks
|
86 | 84 |
|
87 | 85 | }
|
88 | 86 |
|
89 |
| -void CalibratedSensor::calibrate(FOCMotor &motor) |
| 87 | +void CalibratedSensor::calibrate(FOCMotor &motor, float* lut, float zero_electric_angle, Direction senor_direction) |
90 | 88 | {
|
91 |
| - |
92 |
| - if(this->calibrationLut != nullptr){ |
93 |
| - motor.monitor_port->println("Using existing LUT."); |
| 89 | + // if the LUT is already defined, skip the calibration |
| 90 | + if(lut != nullptr){ |
| 91 | + motor.monitor_port->println("Using the provided LUT."); |
| 92 | + motor.zero_electric_angle = zero_electric_angle; |
| 93 | + motor.sensor_direction = senor_direction; |
| 94 | + this->calibrationLut = lut; |
94 | 95 | return;
|
95 | 96 | }else{
|
96 | 97 | this->calibrationLut = new float[n_lut]();
|
97 | 98 | motor.monitor_port->println("Starting Sensor Calibration.");
|
98 | 99 | }
|
| 100 | + |
| 101 | + // Calibration variables |
99 | 102 |
|
100 | 103 | // Init inital angles
|
101 | 104 | float theta_actual = 0.0;
|
102 | 105 | float avg_elec_angle = 0.0;
|
| 106 | + // set the inital electric angle to 0 |
| 107 | + float elec_angle = 0.0; |
103 | 108 |
|
| 109 | + // Calibration parameters |
| 110 | + // The motor will take a n_pos samples per electrical cycle |
| 111 | + // which amounts to n_ticks (n_pos * motor.pole_pairs) samples per mechanical rotation |
| 112 | + // Additionally, the motor will take n2_ticks steps to reach any of the n_ticks posiitons |
| 113 | + // incrementing the electrical angle by deltaElectricalAngle each time |
104 | 114 | int n_pos = 5;
|
105 | 115 | int _NPP = motor.pole_pairs; // number of pole pairs which is user input
|
106 | 116 | const int n_ticks = n_pos * _NPP; // number of positions to be sampled per mechanical rotation. Multiple of NPP for filtering reasons (see later)
|
107 | 117 | const int n2_ticks = 5; // increments between saved samples (for smoothing motion)
|
108 | 118 | float deltaElectricalAngle = _2PI * _NPP / (n_ticks * n2_ticks); // Electrical Angle increments for calibration steps
|
109 |
| - float error[n_ticks] = {0.0}; // pointer to error array (average of forward & backward) |
110 |
| - const int window = 5; // window size for moving average filter of raw error |
111 |
| - // set the electric angle to 0 |
112 |
| - float elec_angle = 0.0; |
| 119 | + float error[n_ticks] = {0.0}; // pointer to error array (average of forward & backward) |
| 120 | + // The fileter window size is set to n_pos - one electrical cycle |
| 121 | + // important for cogging filtering !!! |
| 122 | + const int window = n_pos; // window size for moving average filter of raw error |
| 123 | + |
113 | 124 |
|
114 | 125 | // find the first guess of the motor.zero_electric_angle
|
115 | 126 | // and the sensor direction
|
116 | 127 | // updates motor.zero_electric_angle
|
117 | 128 | // updates motor.sensor_direction
|
118 |
| - bool skip_align_current_sense = false; |
119 |
| - if(motor.current_sense != nullptr){ |
120 |
| - skip_align_current_sense = motor.current_sense->skip_align; |
121 |
| - motor.current_sense->skip_align = true; |
122 |
| - } |
| 129 | + // temporarily unlink the sensor and current sense |
| 130 | + CurrentSense *current_sense = motor.current_sense; |
| 131 | + motor.current_sense = nullptr; |
123 | 132 | motor.linkSensor(&this->_wrapped);
|
124 | 133 | if(!motor.initFOC()){
|
125 | 134 | motor.monitor_port->println("Failed to align the sensor.");
|
126 | 135 | return;
|
127 | 136 | }
|
128 |
| - if(motor.current_sense != nullptr){ |
129 |
| - motor.current_sense->skip_align = skip_align_current_sense; |
130 |
| - } |
| 137 | + // link back the sensor and current sense |
131 | 138 | motor.linkSensor(this);
|
| 139 | + motor.linkCurrentSense(current_sense); |
132 | 140 |
|
133 | 141 | // Set voltage angle to zero, wait for rotor position to settle
|
134 | 142 | // keep the motor in position while getting the initial positions
|
@@ -177,8 +185,12 @@ void CalibratedSensor::calibrate(FOCMotor &motor)
|
177 | 185 | }
|
178 | 186 | zero_angle_prev = zero_angle;
|
179 | 187 | avg_elec_angle += zero_angle/n_ticks;
|
180 |
| - } |
181 | 188 |
|
| 189 | + motor.monitor_port->print(">error:"); |
| 190 | + motor.monitor_port->println(zero_angle); |
| 191 | + motor.monitor_port->print(">zero_angle:"); |
| 192 | + motor.monitor_port->println(avg_elec_angle); |
| 193 | + } |
182 | 194 | _delay(2000);
|
183 | 195 |
|
184 | 196 | /*
|
@@ -212,6 +224,11 @@ void CalibratedSensor::calibrate(FOCMotor &motor)
|
212 | 224 | }
|
213 | 225 | zero_angle_prev = zero_angle;
|
214 | 226 | avg_elec_angle += zero_angle/n_ticks;
|
| 227 | + |
| 228 | + motor.monitor_port->print(">error:"); |
| 229 | + motor.monitor_port->println(zero_angle); |
| 230 | + motor.monitor_port->print(">zero_angle:"); |
| 231 | + motor.monitor_port->println(avg_elec_angle); |
215 | 232 | }
|
216 | 233 |
|
217 | 234 | // get post calibration mechanical angle.
|
|
0 commit comments