The quickest way to determine if the used FOC gains are suitable is to run the motor in Open Loop and confirm that the Flux amps are stable and close to zero. Another way is to see the actual response of the current when giving a steop command. The below script is giving a square wave input as a torque demand and prints the Flux and Torque current values. Then the parameters can be plotted in a data handling software to assess the FOC response. Ideally, the motor rotor should be locked with brake or with any other external tool, but the script will work both ways. In the case that the rotor is unlocked the current response will be a bit distorted.


Some inportant thing to take into consideration are below:


  • The script will provide a current equal to 1/4 of the nominal motor power, as it is configured in the reference seek power parameter
  • The script operation will bypass/disable the ramp command and will restor it after it finishes. If the script is paused then the internal ramp command of the controller will be off and this will have a big impact on the given motor command! If the script is paused for some reason, then restart it and let it finish its execution
  • Depending on the configured settings, the rotor might vibrate or slightly mode in both directions. It is preferable to have the rotor locked by aplying load or brake


Script Parametrization


The following parameters must be set on the script:



CURRENT_PERIOD is the period of the provided waveform, in milliseconds.

AMP_LIMIT is the maximum allowed current, in Amps* 10 (eg. 100 equals 10 A)

REPEATS is the number of pulses will be given by the script



The script follows: 



 
'************************************************************
 
'                 FOC EVALUATION SCRIPT
 
'************************************************************
 
 
 
'Purpose:
 
'-------
 
'This script can be used for the FOC loop evaluation
 
'It will drive the motor by giving a square wave current demand
 
'and print the actual current values. The amplitude of the given
 
'current will be equal to a quarter of the rated motor current   
 
'(reference seek power / 4). The wavefor period and the number
 
'of periods that will be proivided ar econifgurable
 
 
 
 
 
'
 
'                _____       _____       _____
 
' set           |     |     |      |    |     |
 
'          _____|     |_____|      |____|     |____
 
 
 
'                  ____        ____       ____
 
' actual         /     \      /    \     /    \
 
'         ______/       \____/      \___/      \___
 
 
 
 
 
'Use:
 
'----
 
'After running the script, copy the printed values and plot in
 
'a data illustration software for validation.
 
 
 
'WARNING:
 
'---------
 
'The script will modify the controller settings at
 
'the beggining and will restore them before it ends. If the script
 
'is stopped early, some parameters will not be restored and 
 
'the controller will malfunction. DON'T pause the script before it
 
'finishes and if for some reason this happens, ensure that you will
 
'load the previous profile configurations. Pay attention to the 
 
'BPR configuration parameter, as if it is changed (value different
 
' than 1) the controller will behave in a very aggressive way.
 
 
 
'Disclaimer:
 
'----------
 
'The script is tested and validated by Roboteq and is believed to be fault-free. 
 
'The possibility always exists, however, that the particular configuration and/or use 
 
'condition uncovers a fault that escaped our validation test coverage. Always 
 
'extensively test the script under your use conditions prior to deploying it in the field. 
 
 
 
option explicit
 
 
 
'**************************************************
 
'      MODIFY BELOW TO PARAMETRIZE THE SCRIPT
 
'**************************************************
 
'   
 
#define CURRENT_PERIOD 100  'Period of the set current waveform. Value in ms.
 
#define AMP_LIMIT 200       'The maximum allowed motor current during the test. Value in amps*10
 
#define REPEATS 10          'Number of current waveform periods
 
#define CH 1           'Configure the test channel
 
 
 
 
 
'**************************************************
 
'     SCRIPT STARTS HERE. DON'T MODIFY BELOW
 
'**************************************************
 
 
 
'------------------------------
 
'         MAIN PROGRAM
 
'------------------------------
 
 
 
'Variable declarations
 
 
 
dim setTorque as integer 
 
dim setFlux as integer
 
dim actTorque as integer
 
dim actFlux as integer
 
dim i as integer
 
dim j as integer
 
dim prAmplimit as integer
 
dim prMode as integer ' The previous operating mode used
 
dim prRWD as integer
 
dim PH1 as integer
 
dim PH2 as integer
 
dim PH3 as integer
 
 
 
setTorque = getconfig(_BZPW,1)/4 ' give a set torque equal to reference seek power / 5
 
setFlux = 0 ' the target flux current will be zero
 
actTorque = 0
 
actFlux = 0
 
PH1 = PH2 = PH3 = 0
 
 
 
gosub modify_parameters
 
 
 
print("Set Torque","\t","Act Torque","\t","Set Flux","\t","Act Flux","\t","PHA 1","\t","PHA 2","\t","PHA 3","\n")
 
 
 
while(j < REPEATS-1)
 
    
 
    gosub give_positive
 
    gosub give_negative
 
 
 
    j++
 
    
 
end while
 
 
 
gosub give_zero
 
 
 
gosub restore_parameters
 
 
 
terminate
 
 
 
'-----------------------------
 
'          ROUTINE
 
'-----------------------------
 
 
 
modify_parameters:
 
 
 
prAmplimit = getconfig(_ALIM,CH) 'get the previous amplimit value
 
wait(5)
 
prMode = getconfig(_MMOD,CH) ' get the previous operating mode used
 
wait(5)
 
prRWD = getconfig(_RWD,1)   ' get the previous watchdog timer value
 
wait(5)
 
setconfig(_ALIM,CH,AMP_LIMIT) 'modify the amp limit value. For safety reasons, when the rotor is locked
 
wait(5)
 
setconfig(_BPR,CH,1) ' enable the bypass ramp function
 
wait(5)
 
setconfig(_MMOD,CH,5) ' configure torque mode
 
wait(5)
 
setconfig(_RWD,0) ' disable watchdog
 
wait(5)
 
 
 
return
 
 
 
'-----------------------------
 
'          ROUTINE
 
'-----------------------------
 
 
 
restore_parameters:
 
 
 
setconfig(_BPR,CH,0) ' restore bypass ramp
 
wait(5)
 
setconfig(_ALIM,CH,prAmpLimit) 'restore previous amp limit
 
wait(5)
 
setconfig(_RWD,prRWD) ' restore previous watchdog timer value
 
wait(5)
 
setconfig(_MMOD,CH,prMode) 'restore prvious operating mode
 
 
 
return
 
 
 
'-----------------------------
 
'          ROUTINE
 
'-----------------------------
 
 
 
give_positive:
 
 
 
i=0
 
    
 
setcommand(_GIQ,CH,setTorque)
 
setCommand(_GID,CH,setFlux)
 
    
 
while(i<CURRENT_PERIOD/2)
 
if CH = 1    
 
    actTorque = getValue(_MA,2)
 
    actFlux = getValue(_MA,1)        
 
    PH1= getvalue(_PHA,1)
 
    PH2= getvalue(_PHA,2)
 
    PH3= getvalue(_PHA,3)
    
elseif CH = 2
 
    actTorque = getValue(_MA,4)
 
    actFlux = getValue(_MA,3)        
 
    PH1= getvalue(_PHA,4)
 
    PH2= getvalue(_PHA,5)
 
    PH3= getvalue(_PHA,6)
    
end if
 
        
 
    print (setTorque,"\t",actTorque,"\t",setFlux,"\t",actFlux, "\t",PH1,"\t",PH2,"\t",PH3, "\n")
 
        
 
    i++
 
 
 
    wait(1)
 
    
 
end while
 
 
 
return
 
 
 
'-----------------------------
 
'          ROUTINE
 
'-----------------------------
 
 
 
give_negative:
 
 
 
i = 0 
 
    
 
setcommand(_GIQ,CH,-setTorque)
 
setCommand(_GID,CH,-setFlux)
 
    
 
    
 
while(i<CURRENT_PERIOD/2)
 
    
 
 if CH = 1    
 
    actTorque = getValue(_MA,2)
 
    actFlux = getValue(_MA,1)        
 
    PH1= getvalue(_PHA,1)
 
    PH2= getvalue(_PHA,2)
 
    PH3= getvalue(_PHA,3)
    
elseif CH = 2
 
    actTorque = getValue(_MA,4)
 
    actFlux = getValue(_MA,3)        
 
    PH1= getvalue(_PHA,4)
 
    PH2= getvalue(_PHA,5)
 
    PH3= getvalue(_PHA,6)
    
end if
       
 
    print (-setTorque,"\t",actTorque,"\t",-setFlux,"\t",actFlux,"\t",PH1,"\t",PH2,"\t",PH3, "\n")
      
 
    i++
 
    wait(1)
 
    
 
end while
 
    
 
return
 
 
 
'-----------------------------
 
'          ROUTINE
 
'-----------------------------
 
 
 
give_zero:
 
 
 
i=0
 
 
 
setcommand(_GIQ,CH,0)
 
setCommand(_GID,CH,0)
 
 
 
while(i<CURRENT_PERIOD/2)
 
 
 
 if CH = 1    
 
    actTorque = getValue(_MA,2)
 
    actFlux = getValue(_MA,1)        
 
    PH1= getvalue(_PHA,1)
 
    PH2= getvalue(_PHA,2)
 
    PH3= getvalue(_PHA,3)
    
elseif CH = 2
 
    actTorque = getValue(_MA,4)
 
    actFlux = getValue(_MA,3)        
 
    PH1= getvalue(_PHA,4)
 
    PH2= getvalue(_PHA,5)
 
    PH3= getvalue(_PHA,6)
    
end if
        
    print (setTorque,"\t",actTorque,"\t",setFlux,"\t",actFlux, "\t",PH1,"\t",PH2,"\t",PH3, "\n")
 
    i++
 
    wait(1)
 
 
 
end while
 
 
 
return