47 from robolink
import *
51 PROGRAM_PJX =
'''<?xml version="1.0" encoding="utf-8" ?> 52 <project xmlns="ProjectNameSpace" > 53 <parameters version="s6.4.2" stackSize="5000" millimeterUnit="true" /> 55 <program file="start.pgx" /> 56 <program file="stop.pgx" /> 59 <data file="%s.dtx" /> 62 <alias name="io" interface="io" autoload="true" password="" /> 67 PROGRAM_PJX_MAIN =
'''<?xml version="1.0" encoding="utf-8" ?> 68 <project xmlns="ProjectNameSpace" > 69 <parameters version="s6.4.2" stackSize="5000" millimeterUnit="true" /> 71 <program file="start.pgx" /> 72 <program file="stop.pgx" /> 75 <data file="%s.dtx" /> 78 <alias name="io" interface="io" autoload="true" password="" /> 79 <alias name="prog" interface="prog" autoload="true" password="" path="./%s.pjx" /> 80 <alias name="prog_swap" interface="prog_swap" autoload="true" password="" path="./%s.pjx" /> 81 <alias name="tooldata" interface="tooldata" autoload="true" password="" path="saveChangeTool" /> 87 DATA_DTX =
'''<?xml version="1.0" encoding="utf-8" ?> 88 <dataList xmlns="DataNameSpace" > 96 <frame name="world" public="false" privilege="0" > 97 <fFather alias="" name="" fatherIndex="0" /> 98 <valueFrame index="0" > 99 <tfValue x="0" y="0" z="0" rx="0" ry="0" rz="0" /> 108 <mdesc name="mNomSpeed" public="true" privilege="0" > 109 <valueMdesc index="0" > 110 <mdescValue accel="100" vel="100" decel="100" tmax="99999" rmax="99999" blend="off" leave="50" reach="50" /> 122 <tool name="flange" public="false" privilege="0" > 123 <tFather alias="" name="" fatherIndex="0" /> 124 <valueTool index="0" > 125 <ttValue x="0" y="0" z="0" rx="0" ry="0" rz="0" /> 126 <io alias="io" name="valve1" ioIndex="0" open="0" close="0" /> 129 <tool name="tProg" public="false" privilege="0" > 130 <tFather alias="" name="flange" fatherIndex="0" /> 131 <valueTool index="0" > 133 <io alias="io" name="valve1" ioIndex="0" open="0" close="0" /> 144 START_PGX =
'''<?xml version="1.0" encoding="utf-8" ?> 145 <programList xmlns="ProgramNameSpace" > 146 <program name="start" public="false" > 164 STOP_PGX =
'''<?xml version="1.0" encoding="utf-8" ?> 165 <programList xmlns="ProgramNameSpace" > 166 <program name="stop" public="false" > 172 popUpMsg("Pending movement commands have been canceled") 182 LOAD_NEXT_ONE =
'''<?xml version="1.0" encoding="utf-8" ?> 183 <programList xmlns="ProgramNameSpace" > 184 <program name="stop" public="false" > 190 prog_swap:libLoad(x_sName) 199 LTX_FILE =
'''<?xml version="1.0" encoding="utf-8" ?> 205 """Converts a pose to a Staubli target target""" 214 if c > (1.0 - 1e-10):
217 rz1 =
atan2(H[1,0],H[1,1])
218 elif c < (-1.0 + 1e-10):
221 rz1 =
atan2(H[1,0],H[1,1])
232 return [x, y, z, rx1*180.0/pi, ry1*180.0/pi, rz1*180.0/pi]
236 """Prints a pose target""" 238 return (
'x="%.3f" y="%.3f" z="%.3f" rx="%.3f" ry="%.3f" rz="%.3f"' % (x,y,z,r,p,w))
241 """Prints a joint target for Staubli VAL3 XML""" 243 for i
in range(len(angles)):
244 str = str + (
'j%i="%.5f" ' % ((i+1), angles[i]))
250 from tkinter
import filedialog
252 options[
'initialdir'] = strdir
253 options[
'title'] = strtitle
256 file_path = tkinter.filedialog.askdirectory(**options)
262 """Robot post object""" 267 PROG_NAME =
'unknown' 268 MAIN_FOLDER =
'ProgRoboDK' 271 PROG_MOVE_COUNT_MAX = 2000
281 SPEED = DEFAULT_SPEED
284 SMOOTH = DEFAULT_SMOOTH
285 REF_NAME =
'fPartReal' 286 REF_CURRENT =
'world' 290 TOOL_CURRENT =
'tProg' 293 SPEED_NAME =
'mSpeed' 294 SPEED_CURRENT =
'mNomSpeed' 297 JOINT_NAME =
'jJoint' 300 POINT_NAME =
'pPoint' 304 def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
313 self.
addline(
'// Program %s start' % progname)
318 self.
addline(
'// Program %s end' % progname.lower())
323 """Recursively delete a directory tree on a remote server.""" 326 names = ftp.nlst(path)
327 except ftplib.all_errors
as e:
329 print(
'RemoveDirFTP: Could not remove {0}: {1}'.format(path, e))
333 if os.path.split(name)[1]
in (
'.',
'..'):
continue 334 print(
'RemoveDirFTP: Checking {0}'.format(name))
339 except ftplib.all_errors:
344 except ftplib.all_errors
as e:
345 print(
'RemoveDirFTP: Could not remove {0}: {1}'.format(path, e))
353 robot = RDK.Item(self.
ROBOT_NAME, ITEM_TYPE_ROBOT)
354 [server_ip, port, remote_path, username, password] = robot.ConnectionParams()
356 server_ip =
'localhost' 357 username =
'username' 358 password =
'password' 359 remote_path =
'/usr/usrapp/session/default/saveTraj/CAD' 362 print(
"POPUP: Uploading program through FTP. Enter server parameters...")
366 values_ok =
mbox(
'Using the following FTP connection parameters to transfer the program:\nRobot IP: %s\nRemote path: %s\nFTP username: %s\nFTP password: ****\n\nContinue?' % (server_ip, remote_path, username))
368 print(
"Using default connection parameters")
370 server_ip =
mbox(
'Enter robot IP', entry=server_ip)
372 print(
'FTP upload cancelled by user')
374 remote_path =
mbox(
'Enter the remote path (program folder) on the Staubli robot controller', entry=remote_path)
377 if remote_path.endswith(
'/'):
378 remote_path = remote_path[:-1]
379 rob_user_pass =
mbox(
'Enter user name and password as\nuser-password', entry=(
'%s-%s' % (username, password)))
380 if not rob_user_pass:
382 name_value = rob_user_pass.split(
'-')
383 if len(name_value) < 2:
386 password = name_value[1]
387 username = name_value[0]
388 print(
"POPUP: <p>Connecting to <strong>%s</strong> using user name <strong>%s</strong> and password ****</p><p>Please wait...</p>" % (server_ip, username))
391 if robot
is not None:
392 robot.setConnectionParams(server_ip, port, remote_path, username, password)
395 myFTP = ftplib.FTP(server_ip, username, password)
398 error_str = sys.exc_info()[1]
399 print(
"POPUP: Connection to %s failed: <p>%s</p>" % (server_ip,error_str))
401 contin =
mbox(
"Connection to %s failed. Reason:\n%s\n\nRetry?" % (server_ip,error_str))
405 remote_path_prog = remote_path +
'/' + self.
MAIN_FOLDER 406 myPath =
r'%s' % localpath
407 print(
"POPUP: Connected. Deleting existing files on %s..." % remote_path_prog)
410 print(
"POPUP: Connected. Uploading program to %s..." % server_ip)
413 myFTP.cwd(remote_path)
415 myFTP.cwd(remote_path_prog)
418 error_str = sys.exc_info()[1]
419 print(
"POPUP: Remote path not found or can't be created: %s" % (remote_path))
421 contin =
mbox(
"Remote path\n%s\nnot found or can't create folder.\n\nChange path and permissions and retry." % remote_path)
424 def uploadThis(path):
425 files = os.listdir(path)
428 if os.path.isfile(path +
r'\{}'.format(f)):
429 print(
' Sending file: %s' % f)
430 print(
"POPUP: Sending file: %s" % f)
433 myFTP.storbinary(
'STOR %s' % f, fh)
435 elif os.path.isdir(path +
r'\{}'.format(f)):
436 print(
' Sending folder: %s' % f)
439 uploadThis(path +
r'\{}'.format(f))
444 def ProgSave(self, folder, progname, ask_user = False, show_result = False):
445 progname = progname.lower()
450 if foldersave
is not None and len(foldersave) > 0:
451 foldersave = foldersave
458 print(
"Saving %i programs..." % nprogs)
460 main_progname =
'Main' + progname
462 folderprog = foldersave +
'/' + main_progname
465 folderprog = foldersave +
'/' + progname
470 os.makedirs(folderprog)
475 for i
in range(nprogs):
476 call_sequence+=(
' if prog:libLoad("./%s")!=0\n' % self.
PROG_NAME_LIST[i])
477 call_sequence+=(
' logMsg("Error Loading RoboDK library")\n')
478 call_sequence+=(
' popUpMsg("Error Loading RoboDK library")\n')
479 call_sequence+=(
' endIf\n')
480 call_sequence+=(
' wait(taskStatus("loading")==-1)\n')
482 call_sequence+=(
' taskCreate "loading",10,loadNextOne("./%s")\n' % self.
PROG_NAME_LIST[i+1])
483 call_sequence+=(
' prog:fPartReal.trsf=fPartCad.trsf*fCadToReal.trsf\n')
484 call_sequence+=(
' prog:tCad.trsf=prog:tCad.trsf*{0,0,tooldata:nLength,0,0,0}\n')
485 call_sequence+=(
' call prog:start()\n')
486 call_sequence+=(
' \n')
490 start_file = folderprog +
'/start.pgx' 491 show_file_list.append(start_file)
492 fid = open(start_file, mode=
"w", encoding=
'utf-8')
494 fid.write(START_PGX % call_sequence)
498 project_file = folderprog +
'/%s.pjx' % main_progname
500 fid = open(project_file, mode=
"w", encoding=
'utf-8')
503 fid.write(PROGRAM_PJX_MAIN % (main_progname, dummy_folder, dummy_folder))
505 print(
'SAVED: %s\n' % project_file)
508 program_data = folderprog +
'/%s.dtx' % main_progname
509 show_file_list.append(project_file)
510 fid = open(program_data, mode=
"w", encoding=
'utf-8')
513 fid.write(DATA_DTX % (self.
TOOL_DATA,
''))
517 stop_file = folderprog +
'/stop.pgx' 518 fid = open(stop_file, mode=
"w", encoding=
'utf-8')
524 program_data = folderprog +
'/loadNextOne.pgx' 525 fid = open(program_data, mode=
"w", encoding=
'utf-8')
527 fid.write(LOAD_NEXT_ONE)
531 ltx_f = folderprog +
'/%s.ltx' % main_progname
532 fid = open(ltx_f, mode=
"w", encoding=
'utf-8')
539 for i
in range(nprogs):
543 folderprog_final = folderprog
547 os.makedirs(folderprog_final)
551 start_file = folderprog_final +
'/start.pgx' 552 show_file_list.append(start_file)
553 fid = open(start_file, mode=
"w", encoding=
'utf-8')
559 stop_file = folderprog_final +
'/stop.pgx' 560 fid = open(stop_file, mode=
"w", encoding=
'utf-8')
566 project_file = folderprog_final +
'/%s.pjx' % self.
PROG_NAME_LIST[i]
568 fid = open(project_file, mode=
"w", encoding=
'utf-8')
572 print(
'SAVED: %s\n' % project_file)
575 program_data = folderprog_final +
'/%s.dtx' % self.
PROG_NAME_LIST[i]
576 show_file_list.append(project_file)
577 fid = open(program_data, mode=
"w", encoding=
'utf-8')
584 fid = open(ltx_f, mode=
"w", encoding=
'utf-8')
594 if type(show_result)
is str:
597 for file_i
in show_file_list:
598 p = subprocess.Popen([show_result, file_i])
601 elif type(show_result)
is list:
603 p = subprocess.Popen(show_result + [filesave])
607 os.startfile(start_file)
608 os.startfile(program_data)
609 if len(self.
LOG) > 0:
610 mbox(
'Program generation LOG:\n\n' + self.
LOG)
614 """Send a program to the robot using the provided parameters. This method is executed right after ProgSave if we selected the option "Send Program to Robot". 615 The connection parameters must be provided in the robot connection menu of RoboDK""" 618 def MoveJ(self, pose, joints, conf_RLF=None):
619 """Add a joint movement""" 637 def MoveL(self, pose, joints, conf_RLF=None):
638 """Add a linear movement""" 640 poseabs = self.
REF * pose
647 self.
POINT_DATA = self.
POINT_DATA +
'\n <point name="p%i" public="false" privilege="0" >\n <pFather alias="" name="world" fatherIndex="0" />\n <valuePoint index="0" >\n <tpValue %s />\n <cpValue shoulder="ssame" elbow="esame" wrist="wsame"/>\n </valuePoint>\n </point>' % (self.
POINT_COUNT,
pose_2_str(poseabs))
651 def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
652 """Add a circular movement""" 654 pose1abs = self.
REF * pose1
655 pose2abs = self.
REF * pose2
663 self.
POINT_DATA = self.
POINT_DATA +
'\n <point name="p%i" public="false" privilege="0" >\n <pFather alias="" name="world" fatherIndex="0" />\n <valuePoint index="0" >\n <tpValue %s />\n <cpValue shoulder="ssame" elbow="esame" wrist="wsame"/>\n </valuePoint>\n </point>' % (self.
POINT_COUNT,
pose_2_str(pose1abs))
666 self.
POINT_DATA = self.
POINT_DATA +
'\n <point name="p%i" public="false" privilege="0" >\n <pFather alias="" name="world" fatherIndex="0" />\n <valuePoint index="0" >\n <tpValue %s />\n <cpValue shoulder="ssame" elbow="esame" wrist="wsame"/>\n </valuePoint>\n </point>' % (self.
POINT_COUNT,
pose_2_str(pose2abs))
672 def setFrame(self, pose, frame_id=None, frame_name=None):
673 """Change the robot reference frame""" 675 self.
RunMessage(
'Warning: This post processor is meant to use one reference frame. Errors might follow.',
True)
676 self.log(
'This post processor is meant to use one reference frame. Errors might follow.')
682 def setTool(self, pose, tool_id=None, tool_name=None):
683 """Change the robot TCP""" 685 self.
RunMessage(
'Warning: Only one tool allowed per program. Tool change skipped.',
True)
686 self.log(
'Only one tool allowed per program')
694 """Pause the robot program""" 697 self.
addline(
'popUpMsg("Paused. Press OK to continue")')
699 self.
addline(
'delay(%.3f)' % (time_ms*0.001))
702 """Changes the robot speed (in mm/s)""" 703 if self.
SPEED != speed_mms:
705 self.
addline(
'mNomSpeed.tvel = %.3f' % speed_mms)
708 """Changes the robot acceleration (in mm/s2)""" 712 """Changes the robot joint speed (in deg/s)""" 716 """Changes the robot joint acceleration (in deg/s2)""" 720 """Changes the zone data approach (makes the movement more smooth)""" 725 """Sets a variable (output) to a given value""" 726 if type(io_var) != str:
727 io_var =
'OUT[%s]' % str(io_var)
728 if type(io_value) != str:
735 self.
addline(
'%s=%s' % (io_var, io_value))
737 def waitDI(self, io_var, io_value, timeout_ms=-1):
738 """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided.""" 739 if type(io_var) != str:
740 io_var =
'IN[%s]' % str(io_var)
741 if type(io_value) != str:
749 self.
addline(
'WAIT FOR %s==%s' % (io_var, io_value))
751 self.
addline(
'WAIT FOR %s==%s TIMEOUT=%.1f' % (io_var, io_value, timeout_ms))
753 def RunCode(self, code, is_function_call = False):
754 """Adds code or a function call""" 757 code.replace(
' ',
'_')
760 self.
addline(
'//call prog:%s' % code)
761 self.
addline(
'taskCreate "%sTSK",80,%s()' % (code, code))
767 """Display a message in the robot controller screen (teach pendant)""" 772 self.
addline(
'popUpMsg("%s")' % message)
776 """Add a program line""" 780 """Add a log message""" 781 self.
LOG = self.
LOG + newline +
'\n' 795 progname = progname + (
'%i' % (nprogs+1))
827 [x,y,z,r,p,w] = xyzrpw
837 return Mat([[cb*ca, ca*sc*sb - cc*sa, sc*sa + cc*ca*sb, x],[cb*sa, cc*ca + sc*sb*sa, cc*sb*sa - ca*sc, y],[-sb, cb*sc, cc*cb, z],[0,0,0,1]])
840 """Test the post with a basic program""" 844 robot.ProgStart(
"Program")
845 robot.RunMessage(
"Program generated by RoboDK using a custom post processor",
True)
846 robot.setFrame(
Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]))
847 robot.setTool(
Pose([62.5, -108.253175, 100, -60, 90, 0]))
848 robot.MoveJ(
Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
849 robot.MoveL(
Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
850 robot.MoveL(
Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
851 robot.RunMessage(
"Setting air valve 1 on")
852 robot.RunCode(
"TCP_On",
True)
854 robot.MoveL(
Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
855 robot.MoveL(
Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
856 robot.MoveL(
Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
857 robot.RunMessage(
"Setting air valve off")
858 robot.RunCode(
"TCP_Off",
True)
860 robot.MoveL(
Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
861 robot.MoveL(
Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
862 robot.MoveL(
Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
863 robot.ProgFinish(
"Program")
865 print(robot.PROG_PGX)
866 if len(robot.LOG) > 0:
867 mbox(
'Program generation LOG:\n\n' + robot.LOG)
869 input(
"Press Enter to close...")
871 if __name__ ==
"__main__":
872 """Function to call when the module is executed by itself: test""" def MoveJ(self, pose, joints, conf_RLF=None)
def setFrame(self, pose, frame_id=None, frame_name=None)
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
def RunMessage(self, message, iscomment=False)
def setTool(self, pose, tool_id=None, tool_name=None)
def UploadFTP(self, localpath)
def setDO(self, io_var, io_value)
def ProgFinish(self, progname)
def MoveL(self, pose, joints, conf_RLF=None)
def control_ProgSize(self)
def addlog(self, newline)
def setAccelerationJoints(self, accel_degss)
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
def ProgStart(self, progname)
def setAcceleration(self, accel_mmss)
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
def setZoneData(self, zone_mm)
def RunCode(self, code, is_function_call=False)
def setSpeed(self, speed_mms)
def RemoveDirFTP(self, ftp, path)
def getSaveFolder(strdir='C:\\', strtitle='Save program folder ...')
def waitDI(self, io_var, io_value, timeout_ms=-1)
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)
def addline(self, newline)
def setSpeedJoints(self, speed_degs)
def ProgSave(self, folder, progname, ask_user=False, show_result=False)