29
29
typedef struct {
30
30
//constant variables
31
31
float Ts ; //Sample Time in s
32
- float Rs ; //Stator Resistance Phase to Neutral in Ohms
33
- float Ld ; //Inductance in d-Direction in H
34
- float Lq ; //Inductance in q-Direction in H
35
- float flux_linkage ; //Flux linkage of the permanent magnets in mWb
36
32
float J ; //Rotor/Load Inertia in Nm*s^2
37
33
int v_max_adc ; //max voltage that ADC can measure
38
34
int pole_pairs ; //number of pole pairs ( pole numbers / 2)
39
35
float km ; //constant = 1.5 * pole pairs
36
+ float ld ; //motor inductance in D axis in uHy
37
+ float lq ; //motor inductance in Q axis in uHy
40
38
41
39
//non constant variables
42
40
float id ; //Current in d-Direction in Amps
@@ -68,10 +66,10 @@ static volatile virtual_motor_t virtual_motor;
68
66
static volatile int m_curr0_offset_backup ;
69
67
static volatile int m_curr1_offset_backup ;
70
68
static volatile int m_curr2_offset_backup ;
69
+ static volatile mc_configuration * m_conf ;
71
70
72
71
//private functions
73
- static void connect_virtual_motor (float ml , float J , float Ld , float Lq ,
74
- float Rs ,float lambda ,float Vbus );
72
+ static void connect_virtual_motor (float ml , float J , float Vbus );
75
73
static void disconnect_virtual_motor (void );
76
74
static inline void run_virtual_motor_electrical (float v_alpha , float v_beta );
77
75
static inline void run_virtual_motor_mechanics (float ml );
@@ -85,7 +83,10 @@ static void terminal_cmd_disconnect_virtual_motor(int argc, const char **argv);
85
83
/**
86
84
* Virtual motor initialization
87
85
*/
88
- void virtual_motor_init (void ){
86
+ void virtual_motor_init (volatile mc_configuration * conf ){
87
+
88
+ virtual_motor_set_configuration (conf );
89
+
89
90
//virtual motor variables init
90
91
virtual_motor .connected = false; //disconnected
91
92
@@ -103,15 +104,12 @@ void virtual_motor_init(void){
103
104
virtual_motor .i_beta = 0.0 ;
104
105
virtual_motor .id_int = 0.0 ;
105
106
virtual_motor .iq = 0.0 ;
106
- const volatile mc_configuration * conf = mc_interface_get_configuration ();
107
- virtual_motor .pole_pairs = conf -> si_motor_poles / 2 ;
108
- virtual_motor .km = 1.5 * virtual_motor .pole_pairs ;
109
107
110
108
// Register terminal callbacks used for virtual motor setup
111
109
terminal_register_command_callback (
112
110
"connect_virtual_motor" ,
113
111
"connects virtual motor" ,
114
- "[ml][J][Ld][Lq][Rs][lambda][ Vbus]" ,
112
+ "[ml][J][Vbus]" ,
115
113
terminal_cmd_connect_virtual_motor );
116
114
117
115
terminal_register_command_callback (
@@ -121,6 +119,31 @@ void virtual_motor_init(void){
121
119
terminal_cmd_disconnect_virtual_motor );
122
120
}
123
121
122
+ void virtual_motor_set_configuration (volatile mc_configuration * conf ){
123
+ m_conf = conf ;
124
+
125
+ //recalculate constants that depend on m_conf
126
+ virtual_motor .pole_pairs = m_conf -> si_motor_poles / 2 ;
127
+ virtual_motor .km = 1.5 * virtual_motor .pole_pairs ;
128
+ #ifdef HW_HAS_PHASE_SHUNTS
129
+ if (m_conf -> foc_sample_v0_v7 ) {
130
+ virtual_motor .Ts = (1.0 / m_conf -> foc_f_sw ) ;
131
+ } else {
132
+ virtual_motor .Ts = (1.0 / (m_conf -> foc_f_sw / 2.0 ));
133
+ }
134
+ #else
135
+ virtual_motor .Ts = (1.0 / m_conf -> foc_f_sw ) ;
136
+ #endif
137
+
138
+ if (m_conf -> foc_motor_ld_lq_diff > 0.0 ){
139
+ virtual_motor .lq = m_conf -> foc_motor_l + m_conf -> foc_motor_ld_lq_diff /2 ;
140
+ virtual_motor .ld = m_conf -> foc_motor_l - m_conf -> foc_motor_ld_lq_diff /2 ;
141
+ }else {
142
+ virtual_motor .lq = m_conf -> foc_motor_l ;
143
+ virtual_motor .ld = m_conf -> foc_motor_l ;
144
+ }
145
+ }
146
+
124
147
/**
125
148
* Virtual motor interrupt handler
126
149
*/
@@ -151,14 +174,9 @@ float virtual_motor_get_angle_deg(void){
151
174
*
152
175
* @param ml : torque present at motor axis in Nm
153
176
* @param J: rotor inertia Nm*s^2
154
- * @param Ld: inductance at d axis in Hy
155
- * @param Lq: inductance at q axis in Hy
156
- * @param Rs: resistance in ohms
157
- * @param lambda: flux linkage in Vs/rad
158
177
* @param Vbus: Bus voltage in Volts
159
178
*/
160
- static void connect_virtual_motor (float ml , float J , float Ld , float Lq ,
161
- float Rs , float lambda , float Vbus ){
179
+ static void connect_virtual_motor (float ml , float J , float Vbus ){
162
180
if (virtual_motor .connected == false){
163
181
//first we send 0.0 current command to make system stop PWM outputs
164
182
mcpwm_foc_set_current (0.0 );
@@ -184,32 +202,40 @@ static void connect_virtual_motor(float ml , float J, float Ld, float Lq,
184
202
mcpwm_foc_set_current_offsets (2048 , 2048 , 2048 );
185
203
186
204
//sets virtual motor variables
187
- ADC_Value [ ADC_IND_VIN_SENS ] = Vbus * VOLTAGE_TO_ADC_FACTOR ;
188
205
ADC_Value [ ADC_IND_TEMP_MOS ] = 2048 ;
189
206
ADC_Value [ ADC_IND_TEMP_MOTOR ] = 2048 ;
190
- #ifdef HW_VERSION_AXIOM
191
- ADC_Value [ ADC_IND_VOUT_GATE_DRV ] = 1692 ;
192
- // 1692 gives 15.0 as Gate Driver Voltage
193
- //( 15.0 = (ADC_Value[] * 11.0 * 3.3) / 4096 )
207
+ #ifdef HW_HAS_GATE_DRIVER_SUPPLY_MONITOR
208
+ //we load 1 to get the transfer function indirectly
209
+ ADC_Value [ ADC_IND_VOUT_GATE_DRV ] = 1 ;
210
+
211
+ float tempVoltage = GET_GATE_DRIVER_SUPPLY_VOLTAGE ();
212
+ if (tempVoltage != 0.0 ){
213
+ ADC_Value [ ADC_IND_VOUT_GATE_DRV ] = ( (HW_GATE_DRIVER_SUPPLY_MAX_VOLTAGE + HW_GATE_DRIVER_SUPPLY_MIN_VOLTAGE ) / 2.0 ) /
214
+ GET_GATE_DRIVER_SUPPLY_VOLTAGE ();
215
+ }
194
216
#endif
195
- virtual_motor .phi = mcpwm_foc_get_phase () * M_PI / 180.0 ;// 0.0;//m_motor_state.phase;
217
+ virtual_motor .phi = mcpwm_foc_get_phase () * M_PI / 180.0 ;
196
218
utils_fast_sincos_better (virtual_motor .phi , (float * )& virtual_motor .sin_phi ,
197
219
(float * )& virtual_motor .cos_phi );
220
+
221
+ if (m_conf -> foc_sensor_mode == FOC_SENSOR_MODE_ENCODER ){
222
+ encoder_deinit ();
223
+ }
224
+ }
225
+
226
+ //we load 1 to get the transfer function indirectly
227
+ ADC_Value [ ADC_IND_VIN_SENS ] = 1 ;
228
+
229
+ float tempVoltage = GET_INPUT_VOLTAGE ();
230
+ if (tempVoltage != 0.0 ){
231
+ ADC_Value [ ADC_IND_VIN_SENS ] = Vbus / GET_INPUT_VOLTAGE ();
198
232
}
199
233
200
234
//initialize constants
201
- virtual_motor .Ts = mcpwm_foc_get_ts ();
202
235
virtual_motor .v_max_adc = Vbus ;
203
236
virtual_motor .J = J ;
204
- virtual_motor .Ld = Ld ;
205
- virtual_motor .Lq = Lq ;
206
- virtual_motor .flux_linkage = lambda ;
207
- virtual_motor .Rs = Rs ;
208
- virtual_motor .ml = ml ;
209
237
virtual_motor .tsj = virtual_motor .Ts / virtual_motor .J ;
210
- const volatile mc_configuration * conf = mc_interface_get_configuration ();
211
- virtual_motor .pole_pairs = conf -> si_motor_poles / 2 ;
212
- virtual_motor .km = 1.5 * virtual_motor .pole_pairs ;
238
+ virtual_motor .ml = ml ;
213
239
214
240
virtual_motor .connected = true;
215
241
}
@@ -246,6 +272,31 @@ static void disconnect_virtual_motor( void ){
246
272
ADC_InitStructure .ADC_NbrOfConversion = HW_ADC_NBR_CONV ;
247
273
248
274
ADC_Init (ADC1 , & ADC_InitStructure );
275
+
276
+ if (m_conf -> foc_sensor_mode == FOC_SENSOR_MODE_ENCODER ){
277
+ switch (m_conf -> m_sensor_port_mode ) {
278
+ case SENSOR_PORT_MODE_ABI :
279
+ encoder_init_abi (m_conf -> m_encoder_counts );
280
+ break ;
281
+
282
+ case SENSOR_PORT_MODE_AS5047_SPI :
283
+ encoder_init_as5047p_spi ();
284
+ break ;
285
+
286
+ case SENSOR_PORT_MODE_AD2S1205 :
287
+ encoder_init_ad2s1205_spi ();
288
+ break ;
289
+
290
+ case SENSOR_PORT_MODE_SINCOS :
291
+ encoder_init_sincos (m_conf -> foc_encoder_sin_gain , m_conf -> foc_encoder_sin_offset ,
292
+ m_conf -> foc_encoder_cos_gain , m_conf -> foc_encoder_cos_offset ,
293
+ m_conf -> foc_encoder_sincos_filter_constant );
294
+ break ;
295
+
296
+ default :
297
+ break ;
298
+ }
299
+ }
249
300
}
250
301
}
251
302
@@ -271,46 +322,41 @@ static inline void run_virtual_motor(float v_alpha, float v_beta, float ml){
271
322
*/
272
323
static inline void run_virtual_motor_electrical (float v_alpha , float v_beta ){
273
324
274
- utils_fast_sincos_better ( virtual_motor .phi , (float * )& virtual_motor .sin_phi ,
275
- (float * )& virtual_motor .cos_phi );
276
-
277
325
virtual_motor .vd = virtual_motor .cos_phi * v_alpha + virtual_motor .sin_phi * v_beta ;
278
326
virtual_motor .vq = virtual_motor .cos_phi * v_beta - virtual_motor .sin_phi * v_alpha ;
279
327
280
328
// d axis current
281
329
virtual_motor .id_int += ((virtual_motor .vd +
282
330
virtual_motor .we *
283
331
virtual_motor .pole_pairs *
284
- virtual_motor .Lq * virtual_motor .iq -
285
- virtual_motor . Rs * virtual_motor .id )
286
- * virtual_motor .Ts ) / virtual_motor .Ld ;
287
- virtual_motor .id = virtual_motor .id_int - virtual_motor . flux_linkage / virtual_motor .Ld ;
332
+ virtual_motor .lq * virtual_motor .iq -
333
+ m_conf -> foc_motor_r * virtual_motor .id )
334
+ * virtual_motor .Ts ) / virtual_motor .ld ;
335
+ virtual_motor .id = virtual_motor .id_int - m_conf -> foc_motor_flux_linkage / virtual_motor .ld ;
288
336
289
337
// q axis current
290
338
virtual_motor .iq += (virtual_motor .vq -
291
339
virtual_motor .we *
292
340
virtual_motor .pole_pairs *
293
- (virtual_motor .Ld * virtual_motor .id + virtual_motor .flux_linkage ) -
294
- virtual_motor .Rs * virtual_motor .iq )
295
- * virtual_motor .Ts / virtual_motor .Lq ;
341
+ (virtual_motor .ld * virtual_motor .id + m_conf -> foc_motor_flux_linkage ) -
342
+ m_conf -> foc_motor_r * virtual_motor .iq )
343
+ * virtual_motor .Ts / virtual_motor .lq ;
344
+
345
+ // // limit current maximum values
346
+ utils_truncate_number_abs ((float * ) & (virtual_motor .iq ) , (2048 * FAC_CURRENT ) );
347
+ utils_truncate_number_abs ((float * ) & (virtual_motor .id ) , (2048 * FAC_CURRENT ) );
296
348
}
297
349
298
350
/**
299
351
* Run mechanical side of the machine
300
352
* @param ml externally applied load torque in Nm
301
353
*/
302
354
static inline void run_virtual_motor_mechanics (float ml ){
303
- virtual_motor .me = virtual_motor .km * (virtual_motor . flux_linkage +
304
- (virtual_motor .Ld - virtual_motor .Lq ) *
355
+ virtual_motor .me = virtual_motor .km * (m_conf -> foc_motor_flux_linkage +
356
+ (virtual_motor .ld - virtual_motor .lq ) *
305
357
virtual_motor .id ) * virtual_motor .iq ;
306
358
// omega
307
- float w_aux = virtual_motor .we + virtual_motor .tsj * (virtual_motor .me - ml );
308
-
309
- if ( w_aux < 0.0 ){
310
- virtual_motor .we = 0 ;
311
- }else {
312
- virtual_motor .we = w_aux ;
313
- }
359
+ virtual_motor .we += virtual_motor .tsj * (virtual_motor .me - ml );
314
360
315
361
// phi
316
362
virtual_motor .phi += virtual_motor .we * virtual_motor .Ts ;
@@ -323,13 +369,15 @@ static inline void run_virtual_motor_mechanics(float ml){
323
369
while ( virtual_motor .phi < -1.0 * M_PI ){
324
370
virtual_motor .phi += ( 2 * M_PI );
325
371
}
326
-
327
372
}
328
373
329
374
/**
330
375
* Take the id and iq calculated values and translate them into ADC_Values
331
376
*/
332
377
static inline void run_virtual_motor_park_clark_inverse ( void ){
378
+ utils_fast_sincos_better ( virtual_motor .phi , (float * )& virtual_motor .sin_phi ,
379
+ (float * )& virtual_motor .cos_phi );
380
+
333
381
// Park Inverse
334
382
virtual_motor .i_alpha = virtual_motor .cos_phi * virtual_motor .id -
335
383
virtual_motor .sin_phi * virtual_motor .iq ;
@@ -366,28 +414,20 @@ static inline void run_virtual_motor_park_clark_inverse( void ){
366
414
* connect_virtual_motor command
367
415
*/
368
416
static void terminal_cmd_connect_virtual_motor (int argc , const char * * argv ) {
369
- if ( argc == 8 ){
417
+ if ( argc == 4 ){
370
418
float ml ; //torque load in motor axis
371
- float Ld ; //inductance in d axis
372
- float Lq ; //inductance in q axis
373
419
float J ; //rotor inertia
374
- float Rs ; //resistance of motor inductance
375
- float lambda ;//rotor flux linkage
376
420
float Vbus ;//Bus voltage
377
421
378
422
sscanf (argv [1 ], "%f" , & ml );
379
423
sscanf (argv [2 ], "%f" , & J );
380
- sscanf (argv [3 ], "%f" , & Ld );
381
- sscanf (argv [4 ], "%f" , & Lq );
382
- sscanf (argv [5 ], "%f" , & Rs );
383
- sscanf (argv [6 ], "%f" , & lambda );
384
- sscanf (argv [7 ], "%f" , & Vbus );
424
+ sscanf (argv [3 ], "%f" , & Vbus );
385
425
386
- connect_virtual_motor ( ml , J , Ld , Lq , Rs , lambda , Vbus );
426
+ connect_virtual_motor ( ml , J , Vbus );
387
427
commands_printf ("virtual motor connected" );
388
428
}
389
429
else {
390
- commands_printf ("arguments should be 7 " );
430
+ commands_printf ("arguments should be 3 " );
391
431
}
392
432
}
393
433
0 commit comments