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 '************************************************** ' #defineCURRENT_PERIOD100'Period of the set current waveform. Value in ms.
#defineAMP_LIMIT200'The maximum allowed motor current during the test. Value in amps*10
#defineREPEATS10'Number of current waveform periods
#defineCH1'Configure the test channel
'************************************************** ' SCRIPT STARTS HERE. DON'T MODIFY BELOW '************************************************** '------------------------------ ' MAIN PROGRAM '------------------------------ 'Variable declarations dimsetTorqueas integer
dimsetFluxas integer
dimactTorqueas integer
dimactFluxas integer
dimias integer
dimjas integer
dimprAmplimitas integer
dimprModeas integer' The previous operating mode used
dimprRWDas integer
dimPH1as integer
dimPH2as integer
dimPH3as 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
gosubmodify_parameters
"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)
gosubgive_positive
gosubgive_negative
j++ end while gosubgive_zero
gosubrestore_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)
ifCH=1
actTorque=getValue(_MA,2)
actFlux=getValue(_MA,1)
PH1=getvalue(_PHA,1)
PH2=getvalue(_PHA,2)
PH3=getvalue(_PHA,3)
elseifCH=2
actTorque=getValue(_MA,4)
actFlux=getValue(_MA,3)
PH1=getvalue(_PHA,4)
PH2=getvalue(_PHA,5)
PH3=getvalue(_PHA,6)
end if 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)
ifCH=1
actTorque=getValue(_MA,2)
actFlux=getValue(_MA,1)
PH1=getvalue(_PHA,1)
PH2=getvalue(_PHA,2)
PH3=getvalue(_PHA,3)
elseifCH=2
actTorque=getValue(_MA,4)
actFlux=getValue(_MA,3)
PH1=getvalue(_PHA,4)
PH2=getvalue(_PHA,5)
PH3=getvalue(_PHA,6)
end if 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)
ifCH=1
actTorque=getValue(_MA,2)
actFlux=getValue(_MA,1)
PH1=getvalue(_PHA,1)
PH2=getvalue(_PHA,2)
PH3=getvalue(_PHA,3)
elseifCH=2
actTorque=getValue(_MA,4)
actFlux=getValue(_MA,3)
PH1=getvalue(_PHA,4)
PH2=getvalue(_PHA,5)
PH3=getvalue(_PHA,6)
end if setTorque,"\t",actTorque,"\t",setFlux,"\t",actFlux,"\t",PH1,"\t",PH2,"\t",PH3,"\n")
i++ wait(1)
end while return