For adding KRL statements, I attached a sample layout. The script is in the robot. Here is the script, which can you modify into a module that you can import in other scripts:
from vcScript import *
KRLStatements = {
VC_STATEMENT_CALL:'VisualComponents.Create3D.ICallStatement, Create3D.Shared',
'CIRMOTION':'KukaBe.Applications.JobMap.JobMapCommands.CircStatement',
VC_STATEMENT_COMMENT:'KukaBe.Applications.JobMap.JobMapCommands.CommentStatement',
'FOLD':'KukaBe.Applications.JobMap.JobMapCommands.FoldStatement',
VC_STATEMENT_WAITBIN:'KukaBe.Applications.JobMap.JobMapCommands.GetInputStatement',
VC_STATEMENT_HALT:'VisualComponents.Create3D.IHaltStatement, Create3D.Shared',
VC_STATEMENT_IF:'VisualComponents.Create3D.IIfStatement, Create3D.Shared',
VC_STATEMENT_LINMOTION:'KukaBe.Applications.JobMap.JobMapCommands.LinStatement',
VC_STATEMENT_PTPMOTION:'KukaBe.Applications.JobMap.JobMapCommands.PtpStatement',
'PTPHOME':'KukaBe.Applications.JobMap.JobMapCommands.PtpHomeStatement',
VC_STATEMENT_DEFINE_BASE:'VisualComponents.Create3D.ISetBaseStatement, Create3D.Shared',
VC_STATEMENT_SETBIN:'KukaBe.Applications.JobMap.JobMapCommands.SetOutputStatement',
VC_STATEMENT_SETPROPERTY:'VisualComponents.Create3D.ISetPropertyStatement, Create3D.Shared',
VC_STATEMENT_DEFINE_TOOL:'VisualComponents.Create3D.ISetToolStatement, Create3D.Shared',
VC_STATEMENT_DELAY:'KukaBe.Applications.JobMap.JobMapCommands.WaitStatement',
VC_STATEMENT_WHILE:'VisualComponents.Create3D.IWhileStatement, Create3D.Shared'
}
def addKRLStatement(scope,type,index=-1,before=False):
'''
Adds a KRL statement to a given scope based on the given type of VC statement.
The default index for new statement in scope is -1, end of scope.
A placeholder is used to place new statement in scope.
Afterward, the placeholder is removed.
If you want new statement to come before placeholder, pass before a True value.
Technical: The netCommand is used to call <LoadStatementAction> to add the KRL statement.
'''
placeholder = scope.addStatement(VC_STATEMENT_COMMENT,index)
app.SelectionManager.setSelection(placeholder,True)
krl_type = KRLStatements[type]
netCommand = app.findCommand("netCommand")
netCommand.execute("LoadStatementAction",krl_type, before)
scope.deleteStatement(placeholder)
def testPlacementOfNewKRLStatementInProgram(prop):
'''
An event handler used to test the creation of KRL statements in robot program.
Handler is triggered when button, a component property, is clicked in GUI.
'''
rx = comp.findBehavioursByType(VC_ROBOTEXECUTOR)[0]
mr = rx.Program.MainRoutine
mr.clear()
sr = rx.Program.Routines[0]
sr.clear()
##Simple test scenarios
addKRLStatement(mr,VC_STATEMENT_DELAY)
addKRLStatement(sr,VC_STATEMENT_DELAY)
##statement scope test scenario
addKRLStatement(sr,VC_STATEMENT_WHILE)
curveball = sr.Statements[-1]
#current iteration of method requires vcScope not statement
#createKRLStatement(curveball,VC_STATEMENT_DELAY)
createKRLStatement(curveball.Scope,VC_STATEMENT_DELAY)
app = getApplication()
comp = getComponent()
button = comp.getProperty("TEST::KRL")
button.OnChanged = testPlacementOfNewKRLStatementInProgram
My script is based on the following script developed by someone else:
#-------------------------------------------------------------------------------
# Dictionary which maps VC statements to KRL equivalence
KRLStatements = {
VC_STATEMENT_CALL:'VisualComponents.Create3D.ICallStatement, Create3D.Shared',
'CIRMOTION':'KukaBe.Applications.JobMap.JobMapCommands.CircStatement',
VC_STATEMENT_COMMENT:'KukaBe.Applications.JobMap.JobMapCommands.CommentStatement',
'FOLD':'KukaBe.Applications.JobMap.JobMapCommands.FoldStatement',
VC_STATEMENT_WAITBIN:'KukaBe.Applications.JobMap.JobMapCommands.GetInputStatement',
VC_STATEMENT_HALT:'VisualComponents.Create3D.IHaltStatement, Create3D.Shared',
VC_STATEMENT_IF:'VisualComponents.Create3D.IIfStatement, Create3D.Shared',
VC_STATEMENT_LINMOTION:'KukaBe.Applications.JobMap.JobMapCommands.LinStatement',
VC_STATEMENT_PTPMOTION:'KukaBe.Applications.JobMap.JobMapCommands.PtpStatement',
'PTPHOME':'KukaBe.Applications.JobMap.JobMapCommands.PtpHomeStatement',
VC_STATEMENT_DEFINE_BASE:'VisualComponents.Create3D.ISetBaseStatement, Create3D.Shared',
VC_STATEMENT_SETBIN:'KukaBe.Applications.JobMap.JobMapCommands.SetOutputStatement',
VC_STATEMENT_SETPROPERTY:'VisualComponents.Create3D.ISetPropertyStatement, Create3D.Shared',
VC_STATEMENT_DEFINE_TOOL:'VisualComponents.Create3D.ISetToolStatement, Create3D.Shared',
VC_STATEMENT_DELAY:'KukaBe.Applications.JobMap.JobMapCommands.WaitStatement',
VC_STATEMENT_WHILE:'VisualComponents.Create3D.IWhileStatement, Create3D.Shared'
}
def addKRLStatement( scope, VCStatementType ):
global activeStatement
if not activeStatement: # dirty trick for special case of an empty program
dummyStatement = scope.addStatement(VC_STATEMENT_PTPMOTION, -1)
selectionManager.setSelection(dummyStatement)
else:
dummyStatement = None
selectionManager.setSelection(activeStatement) # This trick is needed so dotNET knows where to add the statement
statementtype = KRLStatements[VCStatementType] # dictionary lookup to map desired VC statement to the KRL equivalent in dotNET.
netCommand.execute('LoadStatementAction', statementtype, False ) # False flag operation means AFTER active statement
activeStatement = selectionManager.getSelection(VC_SELECTION_STATEMENT)[0] # how we get the new statement created in dotNET
#activeStatement.Index += 1
if dummyStatement: # clean up the empty program special case
scope.deleteStatement(dummyStatement)
selectionManager.setSelection(activeStatement) # Make sure statement is really active for the next round
return activeStatement
def addPTPStatement( worldPosition, base, tool, speed ):
global stmtIndex
if KUKASIM:
stmt = addKRLStatement(scope, VC_STATEMENT_PTPMOTION )
stmt.VelPtp = speed
else:
stmt = scope.addStatement(VC_STATEMENT_PTPMOTION, stmtIndex )
stmt.JointSpeed = speed
stmt.Base = base
stmt.Tool = tool
positionFrame = stmt.Positions[0]
positionFrame.PositionInWorld = worldPosition
stmtIndex = stmt.Index + 1 # next statement will be added AFTER this one
return stmt
def addLINStatement( worldPosition, base, tool, speed ):
global stmtIndex
if KUKASIM:
stmt = addKRLStatement(scope, VC_STATEMENT_LINMOTION )
stmt.VelAbs = speed
else:
stmt = scope.addStatement(VC_STATEMENT_LINMOTION, stmtIndex )
stmt.MaxSpeed = speed
stmt.Base = base
stmt.Tool = tool
positionFrame = stmt.Positions[0]
positionFrame.PositionInWorld = worldPosition
stmtIndex = stmt.Index + 1 # next statement will be added AFTER this one
return stmt
def addDelayStatement( delay ):
global stmtIndex
if KUKASIM:
stmt = addKRLStatement(scope, VC_STATEMENT_DELAY )
stmt.Time = delay
else:
stmt = scope.addStatement(VC_STATEMENT_DELAY, stmtIndex )
stmt.Delay = delay
stmtIndex = stmt.Index + 1 # next statement will be added AFTER this one
return stmt
This is what I know:
- You cannot use vcTeachContext to make this work. The placement of the statement is dependent on the active statement in robot program, thereby dependent on selection manager. For example, even if you change the active statement in teach context using vcTeachContext methods, it won't update selection manager nor matter to the .NET command called to add the KRL statement.
- The latter script was checking a lot of stuff, like the active statement in selection manager. I tried that, but it got too complicated when dealing with statements that have one or more scopes like While and If statements. So the former script just adds the placeholder to the given scope and "appends" it to the selection recognized by the manager.
This is what I do not know:
- Where do we go from here?
Testing-KRL-statements-in-Python-API.vcmx (985 KB)