- TP+ Examples
IN DEVELOPMENT : If you any examples to contribute post them to issues.
TP+
LS
/PROG example_1
/MN
/END
TP+
bar := DO[1]
baz := DO[2]
bar = on if foo == 5
toggle bazLS
/PROG example
/MN
: IF (R[1:foo]=5),DO[1:bar]=(ON) ;
: DO[2:baz]=(!DO[2:baz]) ;
/END
TP+
i := R[178]
j := R[180]
COLUMNS := 6
userclear()
usershow()
for i in (COLUMNS downto 1)
for j in (1 to i)
print('* ')
end
print_line('')
endLS
/PROG TEST
/ATTR
COMMENT = "TEST";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/APPL
/MN
: ;
: ;
: CALL USERCLEAR ;
: CALL USERSHOW ;
: ;
: FOR R[178:i]=6 DOWNTO 1 ;
: FOR R[180:j]=1 TO R[178:i] ;
: CALL PRINT('* ') ;
: ENDFOR ;
: CALL PRINT_LINE('') ;
: ENDFOR ;
: ;
: ;
/END
..note:: contains Ka_Boost Methods
TP+
i := R[178]
total := R[192]
type := R[264]
axes := R[223]
foo := PR[21]
TP_GROUPMASK = "1,1,1,*,*"
namespace PRTypes
POSITION := 1
XYZWPR := 2
XYZWPREXT := 6
JOINTPOS := 9
end
userclear()
# get total number of groups on controller
total = pos::grplen()
#get current position
get_linear_position(foo)
for i in (1 to total)
type = pos::prtype(&foo, i)
axes = pos::axescnt(&foo, i)
case type
when PRTypes::POSITION
print('Group ')
printnr(&i)
print_line(' is a Cartesian Pose.')
when PRTypes::XYZWPR
print('Group ')
printnr(&i)
print_line(' is a Cartesian Pose.')
when PRTypes::XYZWPREXT
print('Group ')
printnr(&i)
print(' is a Cartesian Pose. with ')
printnr(&axes)
print(' Extended axes.')
print_line('')
when PRTypes::JOINTPOS
print('Group ')
printnr(&i)
print(' is a Joint Pose. with ')
printnr(&axes)
print(' axes.')
print_line('')
end
end
usershow()LS
/PROG TEST
/ATTR
COMMENT = "TEST";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,1,1,*,*;
/APPL
/MN
: ;
: ;
: ;
: ;
: CALL USERCLEAR ;
: ;
: ! get total number of groups on ;
: ! controller ;
: CALL POS_GRPLEN(192) ;
: ;
: ! get current position ;
: PR[21:foo]=LPOS ;
: ;
: FOR R[178:i]=1 TO R[192:total] ;
: CALL POS_PRTYPE(21,R[178:i],264) ;
: CALL POS_AXESCNT(21,R[178:i],223) ;
: ;
: SELECT R[264:type]=1,JMP LBL[100] ;
: =2,JMP LBL[101] ;
: =6,JMP LBL[102] ;
: =9,JMP LBL[103] ;
: ;
: LBL[100:caselbl1] ;
: CALL PRINT('Group ') ;
: CALL PRINTNR(178) ;
: CALL PRINT_LINE(' is a Cartesian Pose.') ;
: JMP LBL[104] ;
: LBL[101:caselbl2] ;
: CALL PRINT('Group ') ;
: CALL PRINTNR(178) ;
: CALL PRINT_LINE(' is a Cartesian Pose.') ;
: JMP LBL[104] ;
: LBL[102:caselbl3] ;
: CALL PRINT('Group ') ;
: CALL PRINTNR(178) ;
: CALL PRINT(' is a Cartesian Pose. with ') ;
: CALL PRINTNR(223) ;
: CALL PRINT(' Extended axes.') ;
: CALL PRINT_LINE('') ;
: JMP LBL[104] ;
: LBL[103:caselbl4] ;
: CALL PRINT('Group ') ;
: CALL PRINTNR(178) ;
: CALL PRINT(' is a Joint Pose. with ') ;
: CALL PRINTNR(223) ;
: CALL PRINT(' axes.') ;
: CALL PRINT_LINE('') ;
: JMP LBL[104] ;
: LBL[104:endcase] ;
: ENDFOR ;
: ;
: CALL USERSHOW ;
: ;
: ;
/END
..note:: Contains KaBoost Routines
TP+
number := R[56]
sum := R[143]
userclear()
usershow()
number = userReadInt('enter an Integer')
sum = 0
while number > 0
sum += number
number = userReadInt('enter next Integer. 0 to exit.')
end
print('The total sum is:')
printnr(&sum)LS
/PROG MAIN
/ATTR
COMMENT = "MAIN";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/APPL
/MN
: ;
: CALL USERCLEAR ;
: CALL USERSHOW ;
: ;
: CALL USERREADINT('enter an Integer',56) ;
: R[143:sum]=0 ;
: ;
: LBL[100] ;
: IF R[56:number]<=0,JMP LBL[101] ;
: R[143:sum]=R[143:sum]+R[56:number] ;
: CALL USERREADINT('enter next Integer. 0 to exit.',56) ;
: JMP LBL[100] ;
: LBL[101] ;
: ;
: CALL PRINT('The total sum is:') ;
: CALL PRINTNR(143) ;
: ;
/END
TP+
foo := R[1]
foo = 1
@loop
foo += 1
jump_to @loop if foo < 10LS
/PROG example_1
/MN
: R[1:foo] = 1 ;
: ;
: LBL[100:loop] ;
: R[1:foo]=R[1:foo]+1 ;
: IF R[1:foo]<10,JMP LBL[100] ;
/END
TP+
foo := R[1]
pin1 := DO[33]
pin2 := DO[34]
# if with no else
if foo == 1 then
# do something
pin1 = on
end
#if else block
if $SCR.$NUM_GROUP > 1 then
#true block
pin1 = on
else
#false block
pin1 = off
end
# else if block
if foo == 1 then
#true block
pin1 = on
elsif foo==2 then
#false block
pin2 = off
end
# else if - else block
if foo == 1 then
#true block
pin1 = on
elsif foo==2 then
#false block
pin2 = on
else
pin1 = off
pin2 = off
endCan use evaluators true, false, on, and off
TP+
foo := DI[1]
bar := F[2]
if (foo == on) && (bar == off) then
print('hello')
end
foo2 := UO[3]
if foo2 == true then
print('Program is running')
end
if foo2 == false then
print('Program is not running')
endLS
/PROG main
/MN
: IF ((DI[1:foo]=ON) AND (F[2:bar]=OFF)) THEN ;
: CALL PRINT('hello') ;
: ENDIF ;
: ;
: IF (UO[3:foo2]=ON) THEN ;
: CALL PRINT('Program is running') ;
: ENDIF ;
: ;
: IF (UO[3:foo2]=OFF) THEN ;
: CALL PRINT('Program is not running') ;
: ENDIF ;
/END
Constants can be used in expressions:
TP+
CONST1 := true
if CONST1 == false
print('hello')
endwill evaluate to:
LS
/PROG main
/MN
: IF ON=OFF,CALL PRINT('hello') ;
/END
which is legal syntax
An infinite while loop can be constructed like so:
TP+
while true == true
print('hello')
wait_for(1, 's')
endLS
/PROG main
/MN
: LBL[100] ;
: IF ON<>ON,JMP LBL[101] ;
: CALL PRINT('hello') ;
: WAIT 1.00(sec) ;
: JMP LBL[100] ;
: LBL[101] ;
/END
TP+
foo := R[1]
foo2 := R[2]
foo3 := DO[1]
t := TIMER[1]
case foo
when 1
message('foo == 1')
wait_for(1, 's')
foo3 = on
when 2
PROG1()
foo2 += 1
else
stop t
GO_HOME()
endLS
/PROG example_1
/MN
: ;
: SELECT R[1:foo]=1,JMP LBL[100] ;
: =2,JMP LBL[101] ;
: ELSE,JMP LBL[102] ;
: ;
: LBL[100:caselbl1] ;
: MESSAGE[foo == 1] ;
: WAIT 1.00(sec) ;
: DO[1:foo3]=ON ;
: JMP LBL[103] ;
: LBL[101:caselbl2] ;
: CALL PROG1 ;
: R[2:foo2]=R[2:foo2]+1 ;
: JMP LBL[103] ;
: LBL[102:caselbl3] ;
: TIMER[1]=STOP ;
: CALL GO_HOME ;
: JMP LBL[103] ;
: LBL[103:endcase] ;
/END
TP+
foo := R[1]
bar := R[2]
flg := F[1]
@lbl
jump_to @lbl if foo==1
jump_to @lbl unless foo==1
jump_to @lbl unless flg
foo=2 if foo==1
foo = on if bar < 10
prog() if foo >= 5
prog() unless foo
bar = 2 if foo >= (bar-1) && foo <= (bar+1) LS
/PROG TEST
/ATTR
COMMENT = "TEST";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/APPL
/MN
: LBL[100:lbl] ;
: ;
: IF R[1:foo]=1,JMP LBL[100] ;
: IF R[1:foo]<>1,JMP LBL[100] ;
: IF (!F[1:flg]),JMP LBL[100] ;
: ;
: IF (R[1:foo]=1),R[1:foo]=(2) ;
: IF (R[2:bar]<10),R[1:foo]=(ON) ;
: ;
: IF R[1:foo]>=5,CALL PROG ;
: IF (!R[1:foo]),CALL PROG ;
: ;
: IF (R[1:foo]>=(R[2:bar]-1) AND R[1:foo]<=(R[2:bar]+1)),R[2:bar]=(2) ;
/END
namespaces, variables, constants, and functions must be scoped into functions and namespaces with the "using" keyword, and the name of the identifier.
TP+
namespace ns1
VAL1 := 1
VAL2 := 2
end
namespace ns2
VAL1 := 3.14
VAL2 := 2.72
end
namespace ns3
using ns1
VAL1 := 'Hello'
def test2() : numreg
using ns1
return(ns1::VAL1 + 5)
end
end
def test()
using ns1, ns2, ns3
foo := R[1]
bar := R[2]
foostr := SR[3]
foo = ns2::VAL1
bar = ns2::VAL2
foostr = Str::set(ns3::VAL1)
foo = ns3::test2()
endTP+
namespace Foo
bar := R[1]
deligate := DI[1]
end
namespace struct1
CONST1 := 5
end
namespace struct2
CONST1 := 2
end
if Foo::deligate then
Foo::bar = struct1::CONST1
else
Foo::bar = struct2::CONST1
endLS
/PROG TEST
/ATTR
COMMENT = "TEST";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/MN
: IF (DI[1:Foo deligate]) THEN ;
: R[1:Foo bar]=5 ;
: ELSE ;
: R[1:Foo bar]=2 ;
: ENDIF ;
/END
TP+
namespace Infeed
part_present? := DI[2]
part_scanning? := DI[3]
part_welding? := DI[4]
is_weldable? := F[2]
end
namespace Alarms
gripper := UALM[1]
part_presence := UALM[2]
cannot_weld := UALM[3]
end
namespace Perch
pickup := PR[1]
scan := PR[2]
weld := PR[3]
end
state := R[1]
loop := F[3]
loop = on
namespace states
PICKUP := 1
SCAN := 2
WELD := 3
DROPOFF := 4
end
while loop
case state
when states::PICKUP
pickup_part()
if !Infeed::part_present? then
raise Alarms::part_presence
loop = off
else
state = states::SCAN
linear_move.to(Perch::scan).at(2000, 'mm/s').term(-1)
end
when states::SCAN
scan_part()
if !Infeed::part_scanning? && Infeed::is_weldable? then
state = states::WELD
linear_move.to(Perch::weld).at(2000, 'mm/s').term(-1)
elsif !Infeed::part_scanning? && !Infeed::is_weldable? then
raise Alarms::cannot_weld
loop = off
end
when states::WELD
weld_part()
if !Infeed::part_welding? then
state = states::DROPOFF
linear_move.to(Perch::pickup).at(2000, 'mm/s').term(-1)
end
when states::DROPOFF
drop_off_part()
if !Infeed::part_present? then
#increment counter
next_part()
state = states::PICKUP
linear_move.to(Perch::pickup).at(2000, 'mm/s').term(-1)
else
raise Alarms::gripper
loop = off
end
end
endNOTE:: Currently in development
TP+
pose := PR[1]
def set_pose(x,y,z,w,p,r) : posreg
dummy := PR[50]
clpr(&dummy, 0)
dummy.x = x
dummy.y = y
dummy.z = z
dummy.w = w
dummy.p = p
dummy.r = r
return (dummy)
end
pose = set_pose(100,0,50,90,0,-90)LS
/PROG SET_POSE
/ATTR
COMMENT = "SET_POSE";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = *,*,*,*,*;
/MN
: ;
: CALL CLPR(50,0) ;
: PR[50,1:dummy]=AR[1] ;
: PR[50,2:dummy]=AR[2] ;
: PR[50,3:dummy]=AR[3] ;
: PR[50,4:dummy]=AR[4] ;
: PR[50,5:dummy]=AR[5] ;
: PR[50,6:dummy]=AR[6] ;
: ;
: PR[AR[7]]=PR[50:dummy] ;
/END
/PROG MAIN
/ATTR
COMMENT = "MAIN";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/MN
: ;
: CALL SET_POSE(100,0,50,90,0,(-90),1) ;
: ;
/END
TP+
sum := R[1]
prop := R[2]
i := R[3]
j := R[4]
SEED := 1
INCREMENTS := 5
AMPLITUDE := 100
MAX_PROPIGATION := 30
WAVE_DISTANCE := 20
def linear_sequence(n1, n2) : numreg
return(n1*n2 + AMPLITUDE)
end
def divide_sequence(n1, n2) : numreg
if n2 < 1 then
return(n1)
end
return(n1/n2)
end
i=0
while i < MAX_PROPIGATION
# inital seed
sum = SEED
j = 0
while (j < WAVE_DISTANCE)
sum = divide_sequence(sum, j)
sum = linear_sequence(sum, i)
j += 1
end
i += INCREMENTS
endNOTE:: Currently inlined functions have to have different arguement variable names than register names in order to work. If functions are not inlined the argument name can be the same as the register name being passed into it.
TP+
namespace Math
M_PI := 3.14159
inline def arclength(ang, rad) : numreg
using M_PI
return(ang*rad*M_PI/180)
end
inline def arcangle(len, rad) : numreg
using M_PI
return(len/rad*180/M_PI)
end
end
radius := R[1]
angle := R[2]
length := R[3]
radius = 100
angle = 90
length = Math::arclength(angle, radius)
angle = Math::arcangle(length, radius)LS
/PROG MAIN
/ATTR
COMMENT = "MAIN";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/MN
: R[1:radius]=100 ;
: R[2:angle]=90 ;
: ;
: ! inline Math_arclength ;
: ;
: R[3:length]=(R[2:angle]*R[1:radius]*3.14159/180) ;
: ! end Math_arclength ;
: ;
: ! inline Math_arcangle ;
: ;
: R[2:angle]=(R[3:length]/R[1:radius]*180/3.14159) ;
: ! end Math_arcangle ;
: ;
/END
TP+
namespace Pose
def goHome()
pHome := P[1]
use_uframe 0
use_utool 1
pHome.joints -> [127.834, 24.311, -29.462, -110.295, 121.424, 54.899]
joint_move.to(pHome).at(10, '%').term(-1)
end
endLS
/PROG POSE_GOHOME
/ATTR
COMMENT = "POSE_GOHOME";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/MN
: J P[1:pHome] 10% FINE ;
: ;
/POS
P[1:"Home Position"]{
GP1:
UF : 0, UT : 1,
J1 = 127.834 deg,
J2 = 24.311 deg,
J3 = -29.462 deg,
J4 = -110.295 deg,
J5 = 121.424 deg,
J6 = 54.899 deg
};
/END
..note:: Includes Ka-Boost Methods
TP+
pr1 := PR[20]
#set robot pose
pr1.group(1) = Pos::setxyz(500, 500, 0, 90, 0, 180)
pr1.group(1) = Pos::setcfg('F U T, 0, 0, 0')
#set rotary pose
pr1.group(2) = Pos::setjnt2(90, 0)
#no group
pr1 = Pos::move()LS
/PROG MAIN
/ATTR
COMMENT = "MAIN";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/APPL
/MN
: ;
: ! set robot pose ;
: CALL POS_SETXYZ(500,500,0,90,0,180,20,1) ;
: CALL POS_SETCFG('F U T, 0, 0, 0',20,1) ;
: ! set rotary pose ;
: CALL POS_SETJNT2(90,0,20,2) ;
: ;
: ! no group ;
: CALL POS_MOVE(20) ;
: ;
/END
WARNING New feature is without unit tesst coverage. There may be issues with usage.
imports outside of current working directory are set with
tpp test.tpp -o "./ls/test.ls" -i "path/to/include/dir"import names refer to the filenames without the .tpp extension
imports can be chosen to be printed or not with the compile keyword infront of the import statement
NOTE : importing the same file in nested files may cause problems as there are currently no collision guards.
main
import tool2
compile import test_import
Sense::findZero()Replacing the import with a different file with the same struct format can be used to quickly swap configurations.
tool1.tpp
namespace tool
frame := UTOOL[1]
read_pin := AI[1]
interupt_pin := DI[8]
SEARCH_DIST := 10
SEARCH_SPEED := 3
endusing keyword still has to be used to pass outside namespaces into the current namespace or function scope.
test_import.tpp
namespace Sense
using tool
measure := R[1]
ulrm := UALM[1]
def read()
using measure, tool
while 0
measure = tool::read_pin
wait_for(250,'ms')
end
end
def findZero()
using measure, ulrm, tool
lpos := PR[1]
ofst := PR[2]
use_utool tool::frame
#measure current pose
get_linear_position(lpos)
run Sense::read()
#determine serch vector
Pos::clrpr(&ofst)
if measure > 0
ofst.z = -1*tool::SEARCH_DIST
else
ofst.z = 1*tool::SEARCH_DIST
end
#get tool offset pose
ofst = Pos::mult(&lpos, &ofst)
#search until
set_skip_condition tool::interupt_pin
linear_move.to(ofst).at(tool::SEARCH_SPEED, 'mm/s').term(-1).skip_to(@not_zerod)
return
@not_zerod
raise ulrm
end
endTP+
frame := UFRAME[1]
tool := UTOOL[2]
temp_frame := PR[5]
offst := PR[6]
use_uframe frame
use_utool tool
#copy frame to posreg
temp_frame = frame
#set offet amount
Pos::clrpr(&offst)
offst.z = 100
#get offset frame
temp_frame = Pos::mult(&temp_frame, &offst)
#set new frame
frame = temp_frameLS
: UFRAME_NUM=1 ;
: UTOOL_NUM=2 ;
: ;
: ! copy frame to posreg ;
: PR[5:temp_frame]=UFRAME[1] ;
: ;
: ! set offet amount ;
: CALL POS_CLRPR(6,1) ;
: PR[6,3:offst]=100 ;
: ;
: ! get offset frame ;
: CALL POS_MULT(5,6,5) ;
: ;
: ! set new frame ;
: UFRAME[1]=PR[5:temp_frame] ;
TP+
#make sure you declare a group mask
TP_GROUPMASK = "1,*,*,*,*"
home := PR[1]
lpos := PR[2]
arc1 := PR[3]
arc2 := PR[4]
p1 := P[1]
p2 := P[2]
p3 := P[3]
p4 := P[4]
FINE := -1
#make sure to specify frame
use_uframe 1
use_utool 1
#save current location of the robot
get_linear_position(lpos)
#basic joint movement
joint_move.to(home).at(20, '%').term(FINE)
#linear move
linear_move.to(lpos).at(20, 'mm/s').term(100)
#circular move
joint_move.to(lpos).at(100, '%').term(FINE)
circular_move.mid(arc1).to(arc2).at(100, 'mm/s').term(100)
#arc move
arc_move.to(p1).at(200, 'mm/s').term(FINE)
arc_move.to(p2).at(200, 'mm/s').term(100)
arc_move.to(p3).at(200, 'mm/s').term(100)
arc_move.to(p4).at(200, 'mm/s').term(FINE)
Start_Offset := PR[5]
Stop_Offset := PR[6]
FrameOffset := PR[7]
ToolOffset := PR[8]
pr_num := AR[1]
#indirect position
linear_move.to(indirect('posreg', pr_num)).at(2000, 'mm/s').term(0)
#offsets
linear_move.to(p1).at(100, 'mm/s').term(100).offset(FrameOffset)
linear_move.to(p2).at(100, 'mm/s').term(100).tool_offset(ToolOffset)
#motion program call
linear_move.to(p1).at(100, 'mm/s').term(100).
time_after(0.0, START_TOOL()).offset(Start_Offset)
linear_move.to(p2).at(100, 'mm/s').term(100).
time_after(0.0, STOP_TOOL()).offset(Stop_Offset)
#run program before reaching pose (time based)
joint_move.to(p1).at(40, '%').term(FINE)
linear_move.to(p2).at(100, 'mm/s').term(100).
time_before(0.5, PREP_NOZZLE())
#run program before reaching pose (distance based)
joint_move.to(p1).at(40, '%').term(FINE)
linear_move.to(p2).at(100, 'mm/s').term(100).
distance_before(100, CHECK_STATE())
#coordinated motion
joint_move.to(p1).at(40, '%').term(FINE)
linear_move.to(p2).at(400, 'mm/s').term(100).coord
linear_move.to(p3).at(400, 'mm/s').term(FINE).coord
#Remote TCP
joint_move.to(p1).at(40, '%').term(FINE)
linear_move.to(p2).at(400, 'mm/s').term(100).acc(100).rtcp
#move through a 20mm corner distance
joint_move.to(p1).at(100, '%').term(FINE)
linear_move.to(p2).at(1000,'mm/s').term(100).acc(100).cd(20)
linear_move.to(p3).at(1000,'mm/s').term(FINE)
# corner region (radius). Move through 20mm radius
joint_move.to(p1).at(100, '%').term(FINE)
linear_move.to(p2).at(1000,'mm/s').corner_region(20)
linear_move.to(p3).at(1000,'mm/s').term(FINE)
#ellipical corner region (radius)
linear_move.to(p1).at(1000, 'mm/s').corner_region(5,10)
#extended velocity
joint_move.to(p1).at(20, '%').term(FINE).simultaneous_ev(50)
joint_move.to(p2).at(20, '%').term(FINE).independent_ev(50)
#continuous rotation speed
linear_move.to(p1).at(100, 'mm/s').term(FINE).continuous_rotation_speed(0)
#linear distance
linear_move.to(p1).at(100, 'mm/s').term(FINE).approach_ld(100)
linear_move.to(p2).at(100, 'mm/s').term(100).retract_ld(100)
#minimum rotational error
joint_move.to(p1).at(100, '%').term(FINE)
joint_move.to(p2).at(100, '%').term(FINE).mrot
joint_move.to(p3).at(100, '%').term(FINE)
#process speed optimization
joint_move.to(p1).at(100, '%').term(FINE)
linear_move.to(p2).at(500, 'mm/s').term(100).acc(120).process_speed(110) #moves faster
linear_move.to(p3).at(500, 'mm/s').term(10).acc(50).process_speed(50) #moves slower
#corner path used if linear distance is satisfied
linear_move.to(p1).at(1000, 'mm/s').corner_region(50)
linear_move.to(p2).at(100, 'mm/s').term(FINE).approach_ld(100)
#minimum rotation for wrist axes
joint_move.to(p1).at(100, '%').term(FINE).minimal_rotation
linear_move.to(p2).at(400, 'mm/s').term(FINE).acc(100).
wrist_joint.
mrot
# break motion depending on sensor response
break_flag := DI[1]
joint_move.to(p1).at(50, '%').term(FINE)
linear_move.to(p2).at(500, 'mm/s').term(100).break
wait_until(break_flag).after(300, 'ms')
linear_move.to(p3).at(500, 'mm/s').term(0)
#move through short motions
linear_move.to(p1).at(50, 'mm/s').term(100).acc(150).pthTP+
namespace touchPose
strt := PR[1]
search_dist := PR[2]
found := PR[3]
end
namespace sensor
signal := DI[1]
val := AI[1]
zerod := DI[2]
POLLING_RATE := 0.1
SAMPLING_TIME := 0.4
def sample(pin, time) : numreg
using POLLING_RATE, SAMPLING_TIME
t := R[150]
sum := R[151]
inc := R[152]
t = 0
sum = 0
inc = 0
while t < time
sum += indirect('ai', pin)
wait_for(POLLING_RATE, 's')
inc += 1
t += POLLING_RATE
end
return(sum/inc)
end
end
sensor_reading := R[1]
i := R[150]
FINE := -1
#get start position
get_linear_position(touchPose::strt)
#clear found pose
pos::clrpr(&touchPose::found)
if !sensor::signal
warning('Sensor is not starting on a surface. Check sensor measurement.')
end
#skip condition when sensor read 0. Setup as a digital pin from sensor.
set_skip_condition sensor::zerod
i = 0
@find_zero
i += 1
#offset value. Assuming tool frame is pointing into the surface.
case i
when 1
#initially move down 100mm.
pos::clrpr(&touchPose::search_dist)
touchPose::search_dist.z = 100
#search for touch if not found go back to start of loop
#On next iteration move from previous position
linear_move.to(touchPose::strt).at(20, 'mm/s').term(FINE).
tool_offset(touchPose::search_dist).
skip_to(@find_zero)
#if found jump label
jump_to @found_zero
when 2
#next try moving up 100mm
pos::clrpr(&touchPose::search_dist)
touchPose::search_dist.z = -100
#search for touch if not found go back to start of loop
#On next iteration move from lpos
linear_move.to(touchPose::strt).at(20, 'mm/s').term(FINE).
tool_offset(touchPose::search_dist).
skip_to(@find_zero, touchPose::strt)
jump_to @found_zero
when 3
#next try moving down 500mm
pos::clrpr(&touchPose::search_dist)
touchPose::search_dist.z = 500
#search for touch if not found go back to start of loop
#save lpos position
linear_move.to(touchPose::strt).at(50, 'mm/s').term(FINE).
tool_offset(touchPose::search_dist).
skip_to(@find_zero, touchPose::strt)
jump_to @found_zero
else
# raise warning
warning('Could not find surface after 4 iterations!')
end
jump_to @end
@found_zero
get_linear_position(touchPose::found)
#sample sensor
wait_for(100, "ms") # make sure robot isnt moving
sensor_reading = sensor::sample(&sensor::val, sensor::SAMPLING_TIME)
jump_to @end
@end..note:: This section is currently in development, and replacing the old method.
Current modifiers are:
- pose
- joints
- xyz
- orient
- config
- offset
A default pose named default should be specified in full before
setting position variables, or else the default pose of
default.group(1).pose -> [0,0,0,0,0,0]
default.group(1).config -> ['N', 'B', 'D', 0, 0, 0]
will be used
Frames can be changed with the use_utool and use_uframe keywords.
TP+
TP_GROUPMASK = "1,1,1,*,*"
TP_COMMENT = "test prog"
p := P[1..6]
tool := UTOOL[5]
frame := UFRAME[3]
use_utool tool
use_uframe frame
default.group(1).pose -> [0,0,0,90,0,-90]
default.group(1).config -> ['F', 'U', 'T', 0, 0, 0]
default.group(2).joints -> [90,0]
default.group(3).joints -> [[500,'mm']]
#apprach
p1.group(1).pose -> [0,50,0,0,0,0]
#start
p2.group(1).xyz -> [0,50,100]
#move circle
p3.group(1).xyz -> [50,0,100]
p3.group(2).joints -> [90,90]
use_utool 1
use_uframe 1
p4.group(1).xyz -> [0,-50,100]
p4.group(2).joints -> [90,180]
p5.group(1).xyz -> [-50,0,100]
p5.group(1).orient -> [0,0,0]
p5.group(2).joints -> [90,-90]
p6.group(1).joints -> [0, 20, 90, 0 ,0 ,0]LS
/POS
P[1:"p1"]{
GP1:
UF : 3, UT : 5, CONFIG : 'F U T, 0, 0, 0',
X = 0.000 mm, Y = 50.000 mm, Z = 0.000 mm,
W = 90.000 deg, P = 0.000 deg, R = -90.000 deg
GP2:
UF : 3, UT : 5,
J1 = 90.000 deg,
J2 = 0.000 deg
GP3:
UF : 3, UT : 5,
J1 = 500.000 mm
};
P[2:"p2"]{
GP1:
UF : 3, UT : 5, CONFIG : 'F U T, 0, 0, 0',
X = 0.000 mm, Y = 50.000 mm, Z = 100.000 mm,
W = 90.000 deg, P = 0.000 deg, R = -90.000 deg
GP2:
UF : 3, UT : 5,
J1 = 90.000 deg,
J2 = 0.000 deg
GP3:
UF : 3, UT : 5,
J1 = 500.000 mm
};
P[3:"p3"]{
GP1:
UF : 3, UT : 5, CONFIG : 'F U T, 0, 0, 0',
X = 50.000 mm, Y = 0.000 mm, Z = 100.000 mm,
W = 90.000 deg, P = 0.000 deg, R = -90.000 deg
GP2:
UF : 3, UT : 5,
J1 = 90.000 deg,
J2 = 90.000 deg
GP3:
UF : 3, UT : 5,
J1 = 500.000 mm
};
P[4:"p4"]{
GP1:
UF : 1, UT : 1, CONFIG : 'F U T, 0, 0, 0',
X = 0.000 mm, Y = -50.000 mm, Z = 100.000 mm,
W = 90.000 deg, P = 0.000 deg, R = -90.000 deg
GP2:
UF : 1, UT : 1,
J1 = 90.000 deg,
J2 = 180.000 deg
GP3:
UF : 1, UT : 1,
J1 = 500.000 mm
};
P[5:"p5"]{
GP1:
UF : 1, UT : 1, CONFIG : 'F U T, 0, 0, 0',
X = -50.000 mm, Y = 0.000 mm, Z = 100.000 mm,
W = 90.000 deg, P = 0.000 deg, R = -90.000 deg
GP2:
UF : 1, UT : 1,
J1 = 90.000 deg,
J2 = -90.000 deg
GP3:
UF : 1, UT : 1,
J1 = 500.000 mm
};
/END
Any unspecified positions declared will be automatically set to the default position.
TP+
p := P[1..3]
default.group(1).pose -> [0, 0, 10500, 90, 0 ,0]
default.group(1).config -> ['F', 'U', 'T', 0, 0, 0]
default.group(3).joints -> [[10500, 'mm']]
default.group(4).joints -> [0]LS
/POS
P[1:"p1"]{
GP1:
UF : 0, UT : 0, CONFIG : 'F U T, 0, 0, 0',
X = 0.000 mm, Y = 0.000 mm, Z = 10500.000 mm,
W = 90.000 deg, P = 0.000 deg, R = 0.000 deg
GP3:
UF : 0, UT : 0,
J1 = 10500.000 mm
GP4:
UF : 0, UT : 0,
J1 = 0.000 deg
};
P[2:"p2"]{
GP1:
UF : 0, UT : 0, CONFIG : 'F U T, 0, 0, 0',
X = 0.000 mm, Y = 0.000 mm, Z = 10500.000 mm,
W = 90.000 deg, P = 0.000 deg, R = 0.000 deg
GP3:
UF : 0, UT : 0,
J1 = 10500.000 mm
GP4:
UF : 0, UT : 0,
J1 = 0.000 deg
};
P[3:"p3"]{
GP1:
UF : 0, UT : 0, CONFIG : 'F U T, 0, 0, 0',
X = 0.000 mm, Y = 0.000 mm, Z = 10500.000 mm,
W = 90.000 deg, P = 0.000 deg, R = 0.000 deg
GP3:
UF : 0, UT : 0,
J1 = 10500.000 mm
GP4:
UF : 0, UT : 0,
J1 = 0.000 deg
};
/END
positions can be offset from the previous position using the offset modifier
p := P[1..5]
use_uframe 3
use_utool 2
default.group(1).pose -> [0, 0, 0, 0, 0 ,0]
default.group(1).config -> ['N', 'U', 'T', 0, 0, 0]
default.group(2).joints -> [90, 0]
p1.group(1).pose -> [0, 80, 300, 90, 180, 0]
p2.group(1).xyz.offset -> [0, 10, 10]
p2.group(2).joints.offset -> [0, 10]
p3.group(1).xyz.offset -> [0, 10, 10]
p3.group(2).joints.offset -> [0, 10]
p4.group(1).orient.offset -> [0, 10, 10]
p4.group(2).joints.offset -> [0, 10]
p5.group(1).orient.offset -> [0, 10, 10]
p5.group(2).joints.offset -> [0, 10]LS
/POS
P[1:"p1"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N U T, 0, 0, 0',
X = 0.000 mm, Y = 80.000 mm, Z = 300.000 mm,
W = 90.000 deg, P = 180.000 deg, R = 0.000 deg
GP2:
UF : 3, UT : 2,
J1 = 90.000 deg,
J2 = 0.000 deg
};
P[2:"p2"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N U T, 0, 0, 0',
X = 0.000 mm, Y = 90.000 mm, Z = 310.000 mm,
W = 90.000 deg, P = 180.000 deg, R = 0.000 deg
GP2:
UF : 3, UT : 2,
J1 = 90.000 deg,
J2 = 10.000 deg
};
P[3:"p3"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N U T, 0, 0, 0',
X = 0.000 mm, Y = 100.000 mm, Z = 320.000 mm,
W = 90.000 deg, P = 180.000 deg, R = 0.000 deg
GP2:
UF : 3, UT : 2,
J1 = 90.000 deg,
J2 = 20.000 deg
};
P[4:"p4"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N U T, 0, 0, 0',
X = 0.000 mm, Y = 100.000 mm, Z = 320.000 mm,
W = 90.000 deg, P = 190.000 deg, R = 10.000 deg
GP2:
UF : 3, UT : 2,
J1 = 90.000 deg,
J2 = 30.000 deg
};
P[5:"p5"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N U T, 0, 0, 0',
X = 0.000 mm, Y = 100.000 mm, Z = 320.000 mm,
W = 90.000 deg, P = 200.000 deg, R = 20.000 deg
GP2:
UF : 3, UT : 2,
J1 = 90.000 deg,
J2 = 40.000 deg
};
/END
Ranges can be assigned using
TP+
p := P[1..6]
p1..p3 = p4..p6A range can be assigned a single pose with
TP+
p := P[1..6]
p2..p6 = p1The rval range can be less than the lval range, where the unassociated poses will be assigned the last pose in the lval range.
TP+
p := P[1..6]
p1..p4 = p5..p6Modifier for range assignment currently are:
TP+
p := P[1..6]
p1..p3 = (p4..p6).reverseWARNING Including brackets around the range before the modifier is manditory.
Ranges can also be speicified in declaration statements.
TP+
p := P[1..5]
(p1..p5).group(1).pose -> [0, 80, 300, 90, 180, 0]This will set positions p1 to p5 all to the same position specified.
Offsets with a position range will apply the offset sequentially through the range
TP+
p := P[1..5]
use_uframe 3
use_utool 2
p1.group(1).pose -> [0, 80, 300, 90, 180, 0]
(p2..p5).group(1).xyz.offset -> [0, 0 ,10]LS
/POS
P[1:"p1"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = 0.000 mm, Y = 80.000 mm, Z = 300.000 mm,
W = 90.000 deg, P = 180.000 deg, R = 0.000 deg
};
P[2:"p2"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = 0.000 mm, Y = 80.000 mm, Z = 310.000 mm,
W = 90.000 deg, P = 180.000 deg, R = 0.000 deg
};
P[3:"p3"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = 0.000 mm, Y = 80.000 mm, Z = 320.000 mm,
W = 90.000 deg, P = 180.000 deg, R = 0.000 deg
};
P[4:"p4"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = 0.000 mm, Y = 80.000 mm, Z = 330.000 mm,
W = 90.000 deg, P = 180.000 deg, R = 0.000 deg
};
P[5:"p5"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = 0.000 mm, Y = 80.000 mm, Z = 340.000 mm,
W = 90.000 deg, P = 180.000 deg, R = 0.000 deg
};
/END
position modifiers for converting between coordinate systems is also provided. Currently you can use
polar: to convert from cylindrical space (theta, radius, z) to cartesian spacesphere: to convert from spherical space (theta, rho, radius) to cartesian space
The modifier after the coordinate system must be x, y, or z to specify the z-axis of the space. For example, to trace a cylinder along the x axis you would use p1.group(1).pose.polar.x -> [0, 80, 300, 0, 0, 0]
The modifier fix will fix the position to the orientation specified. Without the fix modifier the position will align the orientation to the normal of the surface.
TP+
p := P[1..4]
q := P[5..8]
use_uframe 3
use_utool 2
p1.group(1).pose.polar.z -> [0, 80, 300, 90, 180, 0]
p2.group(1).pose.polar.z -> [90, 80, 300, 90, 180, 0]
p3.group(1).pose.polar.z -> [180, 80, 300, 90, 180, 0]
p4.group(1).pose.polar.z -> [270, 80, 300, 90, 180, 0]
q5.group(1).pose.polar.z.fix -> [0, 80, 300, 180, 0, 0]
q6.group(1).pose.polar.z.fix -> [90, 80, 300, 180, 0, 0]
q7.group(1).pose.polar.z.fix -> [180, 80, 300, 180, 0, 0]
q8.group(1).pose.polar.z.fix -> [270, 80, 300, 180, 0, 0]LS
/POS
P[1:"p1"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = 0.000 mm, Y = 80.000 mm, Z = 300.000 mm,
W = -90.000 deg, P = 0.000 deg, R = 180.000 deg
};
P[2:"p2"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = -80.000 mm, Y = 0.000 mm, Z = 300.000 mm,
W = -90.000 deg, P = 0.000 deg, R = -90.000 deg
};
P[3:"p3"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = -0.000 mm, Y = -80.000 mm, Z = 300.000 mm,
W = -90.000 deg, P = 0.000 deg, R = -0.000 deg
};
P[4:"p4"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = 80.000 mm, Y = -0.000 mm, Z = 300.000 mm,
W = -90.000 deg, P = 0.000 deg, R = 90.000 deg
};
P[5:"q5"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = 0.000 mm, Y = 80.000 mm, Z = 300.000 mm,
W = 180.000 deg, P = -0.000 deg, R = 0.000 deg
};
P[6:"q6"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = -80.000 mm, Y = 0.000 mm, Z = 300.000 mm,
W = 180.000 deg, P = -0.000 deg, R = 0.000 deg
};
P[7:"q7"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = -0.000 mm, Y = -80.000 mm, Z = 300.000 mm,
W = 180.000 deg, P = -0.000 deg, R = 0.000 deg
};
P[8:"q8"]{
GP1:
UF : 3, UT : 2, CONFIG : 'N B D, 0, 0, 0',
X = 80.000 mm, Y = -0.000 mm, Z = 300.000 mm,
W = 180.000 deg, P = -0.000 deg, R = 0.000 deg
};
/END
The origin location of the coordinate system can be speicifed with the origin keyword
TP+
p1 := P[1]
use_uframe 3
use_utool 2
p1.group(1).pose.origin -> [50, 50, 0, 0, 0, 0]
p1.group(1).pose.polar.z -> [0, 80, 300, 90, 180, 0]WARNING origins must be specified by a list of six values. Using the xyz modifier also currently does not work. The modifier must be pose.
Offsets in a coordinate system also work
p := P[1..5]
use_uframe 3
use_utool 2
default.group(1).pose -> [0, 0, 0, 0, 0 ,0]
default.group(1).config -> ['F', 'U', 'T', 0, 0, 0]
default.group(2).joints -> [0]
p1.group(1).pose.polar.z -> [0, 80, 300, 90, 180, 0]
p1.group(2).joints -> [0]
#rotate 45 degrees each pose
(p2..p5).group(1).xyz.offset.polar.z -> [45, 0 ,0]
#keep tool straight
(p2..p5).group(2).joints.offset -> [-45]TP+
foo := PR[1]
bar := PR[2]
#assign full position
foo = bar
foo = Pos::setxyz(500, 500, 0, 90, 0, 180) #Ka-Boost method
#assign a axis
foo.x = 5
foo.y = 10
foo.z = 4
foo.w = 0
foo.p = -90
foo.r = 90
foo.x = bar.x + 10
foo.x = indirect('pr', 5) + 5
#assign specific group
foo.group(1) = bar.group(1)
foo.group(2).x += 180
foo.group(2).y += 90
foo.group(1) = Pos::setxyz(500, 500, 0, 90, 0, 180) #Ka-Boost method
foo.group(2) = Pos::setjnt2(0, 20) #Ka-Boost methodLS
/PROG TEST
/ATTR
COMMENT = "TEST";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/APPL
/MN
: ;
: ! assign full position ;
: PR[1:foo]=PR[2:bar] ;
: CALL POS_SETXYZ(500,500,0,90,0,180,1) ;
: ! Ka-Boost method ;
: ;
: ! assign a axis ;
: PR[1,1:foo]=5 ;
: PR[1,2:foo]=10 ;
: PR[1,3:foo]=4 ;
: PR[1,4:foo]=0 ;
: PR[1,5:foo]=(-90) ;
: PR[1,6:foo]=90 ;
: ;
: PR[1,1:foo]=PR[2,1:bar]+10 ;
: PR[1,1:foo]=PR[5]+5 ;
: ;
: ! assign specific group ;
: PR[GP1:1:foo]=PR[GP1:2:bar] ;
: PR[GP2:1,1:foo]=PR[GP2:1,1:foo]+180 ;
: PR[GP2:1,2:foo]=PR[GP2:1,2:foo]+90 ;
: ;
: CALL POS_SETXYZ(500,500,0,90,0,180,1,1) ;
: ! Ka-Boost method ;
: CALL POS_SETJNT6(0,20,1,2) ;
: ! Ka-Boost method ;
/END
TP+
ar1 := AR[1]
ar2 := AR[2]
foo1 := R[3]
foo2 := R[4]
# pass ar1 and foo1 by reference
# pass ar2 and foo2 by value
FUNC01(&ar1, ar2, &foo1, foo2)LS
/PROG example_1
/MN
: ;
: ! pass ar1 and foo1 by reference ;
: ! pass ar2 and foo2 by value ;
: CALL FUNC01(1,AR[2],3,R[4:foo2]) ;
/END
LS
foo := R[1]
val := R[2]
val2 := R[2]
val = 90
#trig
foo = SIN[val]
foo = COS[val]
foo = TAN[val]
foo = ATAN[val]
foo = ACOS[val]
foo = ASIN[val]
val = 1
val2 = 2
foo = ATAN2[val, val2]
#logrithms
val = 1
foo = LN[val]
foo = EXP[val]
#exponentials
#power
val = 2
val2 = 4
val2 = LN[val2]
val = val*val2
val2 = EXP[val]
#or with kaboost
val = Mth::pow(val2, val)
val = 2
foo = SQRT[val]
#integer math
val = -1
foo = ABS[val]
val = 5.5
foo = TRUNC[val]
foo = ROUND[val]
ret := R[3]
val = 20
val2 = 2
ret = val % val2 # modulus operator
ret = val // val2 #integer divisionLS
#matrix math
#with ka-boost
pr1 := PR[1]
pr2 := PR[2]
pr1 = Pos::mult(&pr1, &pr2)
pr1 = Pos::inv(&pr1)
pr1 = Pos::cross(&pr1, &pr2)
pr1 = Pos::dot(&pr1, &pr2)
pr2 = Pos::slcmult(&pr1, 10)
pr2 = Pos::slcdiv(&pr1, 2)
#convert pose to cartesian representation
tool := UTOOL[1]
pr1 = tool
pr1 = Pos::cnvcart(&pr1)
#create a frame
pr3 := PR[3]
prFrame := PR[4]
frame := UFRAME[1]
prFrame = Pos::frame(&pr1, &pr2, &pr3)
frame = prFrameTP+
ar1 := AR[1]
ar2 := AR[2]
poo1 := PR[1]
#if AR[1] is a posreg number set y = 5
indirect('pr', ar1).group(1).y=5
#if Ar[1], AR[2] are numreg addresses
indirect('r', ar2) = SIN[indirect('r', ar1)]
# if AR[1] is a posreg number put current position
# into that register
get_linear_position(indirect('PR', ar1))
# if AR[1] is a posreg number goto that posreg
linear_move.to(indirect('pr', ar1)).at(2000, 'mm/s').term(-1)
# if AR[2] is a posreg number use that posreg as the user offset
linear_move.to(poo1).at(100, 'mm/s').term(-1).offset(indirect('pr', ar2))LS
/PROG example_1
/MN
: ;
: ! if AR[1] is a posreg number set ;
: ! y = 5 ;
: PR[GP1:AR[1],2]=5 ;
: ;
: ! if Ar[1], AR[2] are numreg ;
: ! addresses ;
: R[AR[2]]=SIN[R[AR[1]]] ;
: ;
: ! if AR[1] is a posreg number put ;
: ! current position ;
: ! into that register ;
: PR[AR[1]]=LPOS ;
: ;
: ! if AR[1] is a posreg number ;
: ! goto that posreg ;
: L PR[AR[1]] 2000mm/sec FINE ;
: ;
: ! if AR[2] is a posreg number use ;
: ! that posreg as the user offset ;
: L PR[1:poo1] 100mm/sec FINE Offset,PR[AR[2]] ;
/END
..note:: Contains KaBoost Routines
TP+
name := SR[1]
arg1 := AR[1]
arg2 := AR[2]
name = Str::set('PROGRAM')
call name(arg1, arg2)LS
/PROG example_1
/MN
: CALL STR_SET('PROGRAM',1) ;
: CALL SR[1:name](AR[1],AR[2]) ;
/END
TP+
my_timer := TIMER[1]
start my_timer
stop my_timer
reset my_timer
# restart short-cut
restart my_timerLS
/PROG TEST
/ATTR
COMMENT = "TEST";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/APPL
/MN
: ;
: TIMER[1]=START ;
: TIMER[1]=STOP ;
: TIMER[1]=RESET ;
: ! restart short-cut ;
: TIMER[1]=STOP ;
: TIMER[1]=RESET ;
: TIMER[1]=START ;
/END
TP+
foo := R[1]
# automatic WAIT time-unit conversion
wait_for(1, 's')
wait_for(100, 'ms')
# wait_until for expression conditions
wait_until(foo>3)
# wait timeouts
wait_until(foo>3).timeout_to(@bar)
# automatically set $WAITTMOUT
wait_until(foo>3).timeout_to(@bar).after(5,'s')
@barLS
/PROG TEST
/ATTR
COMMENT = "TEST";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/APPL
/MN
: ;
: ! automatic WAIT time-unit ;
: ! conversion ;
: WAIT 1.00(sec) ;
: WAIT .10(sec) ;
: ;
: ! wait_until for expression ;
: ! conditions ;
: WAIT (R[1:foo]>3) ;
: ;
: ! wait timeouts ;
: WAIT (R[1:foo]>3) TIMEOUT,LBL[100] ;
: ;
: ! automatically set $WAITTMOUT ;
: $WAITTMOUT=(500) ;
: WAIT (R[1:foo]>3) TIMEOUT,LBL[100] ;
: ;
: LBL[100:bar] ;
/END
TP+
foo := R[1]
#adjust payload
use_payload(1,group(1))
use_payload(foo,group(2))
#jog override
use_override 50
use_override foo
#set frames
use_uframe foo
use_utool fooLS
/PROG TEST
/ATTR
COMMENT = "TEST";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/APPL
/MN
: ;
: ! adjust payload ;
: PAYLOAD[GP1:1] ;
: PAYLOAD[GP2:R[1:foo]] ;
: ;
: ! jog override ;
: OVERRIDE=50% ;
: OVERRIDE=R[1:foo] ;
: ;
: ! set frames ;
: UFRAME_NUM=R[1:foo] ;
: UTOOL_NUM=R[1:foo] ;
/END
TP+
foo := R[1]
colguard_on
adjust_colguard
adjust_colguard 80
colguard_offLS
/PROG TEST
/ATTR
COMMENT = "TEST";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/APPL
/MN
: COL DETECT ON ;
: COL GUARD ADJUST ;
: COL GUARD ADJUST 80 ;
: COL DETECT OFF ;
/END
TP+
PAINT_PROCESS = {
DEFAULT_USER_FRAME : 1,
DEFAULT_TOOL_FRAME : 1,
START_DELAY : 0,
TRACKING_PROCESS : no
}LS
/PROG TEST
/ATTR
COMMENT = "TEST";
TCD: STACK_SIZE = 0,
TASK_PRIORITY = 50,
TIME_SLICE = 0,
BUSY_LAMP_OFF = 0,
ABORT_REQUEST = 0,
PAUSE_REQUEST = 0;
DEFAULT_GROUP = 1,*,*,*,*;
/APPL
PAINT_PROCESS ;
DEFAULT_USER_FRAME : 1 ;
DEFAULT_TOOL_FRAME : 1 ;
START_DELAY : 0 ;
TRACKING_PROCESS : no ;
/MN
/END