45     """Get a safe program name"""    47     for c 
in r'-[]/\;,><&*:%=+@!#^()|?^':
    48         progname = progname.replace(c,
'')
    50     if len(progname) <= 0:
    53     if progname[0].isdigit():
    54         progname = 
'P' + progname
    56     if len(progname) > max_chars:
    57         progname = progname[:max_chars]
    69     """Robot post object defined for Motoman robots"""    71     MAX_LINES_X_PROG = 2000      
    72     DONT_USE_MFRAME = 
True           73     DONT_USE_SETTOOL = 
True          74     USE_RELATIVE_JOB = 
True          76     INCLUDE_SUB_PROGRAMS = 
True     87     PULSES_X_DEG = [1,1,1,1,1,1] 
   105     PROG_NAME = 
'unknown'     106     PROG_NAME_CURRENT = 
'unknown'    108     PROG_COMMENT = 
'Generated using RoboDK'   118     AXES_TYPE = [
'R','R','R','R','R','R']  # Important: This is usually set up by RoboDK automatically. Otherwise, override the __init__ procedure.   124     HAS_TURNTABLE = 
False   131     LAST_CONFDATA = [
None, 
None, 
None, 
None] 
   133     def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
   142         for k,v 
in kwargs.items():
   143             if k == 
'lines_x_prog':
   147             if k == 
'pulses_x_deg':
   161         progname_i = progname
   166                     print(
"Can't split %s: Two or more programs are split into smaller programs" % progname)
   168                     raise Exception(
"Only one program at a time can be split into smaller programs")
   187         if len(foldername) 
is not 0:
   202         header += 
'/JOB' + 
'\n'   203         header += 
'//NAME %s' % progname + 
'\n'   205             header += 
'///FOLDERNAME %s' % self.
FOLDERNAME + 
'\n'   206         header += 
'//POS' + 
'\n'   212         datestr = time.strftime(
"%Y/%m/%d %H:%M")
   215         header_ins += 
'//INST' + 
'\n'   216         header_ins += 
'///DATE %s' % datestr + 
'\n'   220             header_ins += 
'///ATTR SC,RW,RJ' + 
'\n'   222                 header_ins += 
'////FRAME USER %i' % self.
ACTIVE_FRAME + 
'\n'              224             header_ins += 
'///ATTR SC,RW' + 
'\n'   226         header_ins += 
'///GROUP1 RB1' + 
'\n'   231         self.
PROG.insert(0, header_ins)
   232         self.
PROG.append(
'END')
   250     def progsave(self, folder, progname, ask_user = False, show_result = False):
   252         if not folder.endswith(
'/'):
   253             folder = folder + 
'/'   254         progname = progname + 
'.' + self.
PROG_EXT   256             filesave = 
getSaveFile(folder, progname, 
'Save program as...')
   257             if filesave 
is not None:
   258                 filesave = filesave.name
   262             filesave = folder + progname
   264         fid = io.open(filesave, 
"w", newline=
'\r\n')
   266         for line 
in self.
PROG:
   267             fid.write(line.decode(
'unicode-escape'))
   270         print(
'SAVED: %s\n' % filesave) 
   275             if type(show_result) 
is str:
   278                 p = subprocess.Popen([show_result, filesave])
   279             elif type(show_result) 
is list:
   281                 p = subprocess.Popen(show_result + [filesave])   
   285                 os.startfile(filesave)
   291     def ProgSave(self, folder, progname, ask_user = False, show_result = False):
   297                 print(
"Warning: ProgFinish was not called properly")
   316             self.
progsave(folder, progname_last, ask_user, show_result)
   334             self.
progsave(folder, progname, ask_user, show_result)
   337             print(
"Warning! Program has not been properly finished")
   338             self.
progsave(folder, progname, ask_user, show_result)
   340         if show_result 
and len(self.
LOG) > 0:
   341             mbox(
'Program generation LOG:\n\n' + self.
LOG)
   344         """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".   345         The connection parameters must be provided in the robot connection menu of RoboDK"""   348     def MoveJ(self, pose, joints, conf_RLF=None):
   349         """Add a joint movement"""   355     def MoveL(self, pose, joints, conf_RLF=None):
   356         """Add a linear movement"""           372     def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
   373         """Add a circular movement"""   389         """Change the robot reference frame"""   394             self.
RunMessage(
'Using %s (targets wrt base):' % (str(frame_name)), 
True)
   395             self.
RunMessage(
'%.1f,%.1f,%.1f,%.1f,%.1f,%.1f' % (xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]), 
True)
   398             if frame_id 
is None or frame_id < 0:
   400                 decimals = [1000,1000,1000,100,100,100]
   405                         self.
addline(
"SETE P%05d (%i) %i" % (self.
SPARE_PR+m, i+1, round(xyzwpr_pm[i]*decimals[i])))
   406                     for i 
in range(6,self.
nAxes):
   414                 self.
RunMessage(
'%.1f,%.1f,%.1f,%.1f,%.1f,%.1f' % (xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]), 
True)
   417         """Change the robot TCP"""   419         if tool_id 
is None or tool_id < 0:
   421                 self.
RunMessage(
'Tool %s should be close to:' % (str(tool_name)), 
True)
   422                 self.
RunMessage(
'%.1f,%.1f,%.1f,%.1f,%.1f,%.1f' % (xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]), 
True)
   425                 decimals = [1000,1000,1000,100,100,100]
   427                     self.
addline(
"SETE P%05d (%i) %i" % (self.
SPARE_PR, i+1, round(xyzwpr[i]*decimals[i])))
   428                 for i 
in range(6,self.
nAxes):
   436             self.
RunMessage(
'%.1f,%.1f,%.1f,%.1f,%.1f,%.1f' % (xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]), 
True)
   439         """Pause the robot program"""   443             self.
addline(
'TIMER T=%.2f' % (time_ms*0.001))
   446         speedl = max(1, speed_mms)
   450         """Changes the robot acceleration (in mm/s2)"""   451         self.
addlog(
'Set acceleration not defined')
   454         """Changes the robot joint speed (in deg/s)"""   455         speedj = max(0.01, min(speed_degs, 100.0)) 
   459             self.
STR_VJ = 
"VJ=%.1f" % speedj
   462         """Changes the robot joint acceleration (in deg/s2)"""   463         self.
addlog(
'Set acceleration not defined')
   466         """Changes the zone data approach (makes the movement more smooth)"""   470             self.
STR_PL = 
' PL=%i' % round(min(zone_mm, 8))        
   473         """Sets a variable (output) to a given value"""   474         if type(io_var) != str:  
   475             io_var = 
'OT#(%s)' % str(io_var)        
   476         if type(io_value) != str: 
   484         self.
addline(
'DOUT %s %s' % (io_var, io_value))
   486     def waitDI(self, io_var, io_value, timeout_ms=-1):
   487         """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided."""   488         if type(io_var) != str:  
   489             io_var = 
'IN#(%s)' % str(io_var)        
   490         if type(io_value) != str: 
   499             self.
addline(
'WAIT %s=%s' % (io_var, io_value))
   502             self.
addline(
'WAIT %s=%s T=%.2f' % (io_var, io_value, timeout_ms*0.001))
   505     def RunCode(self, code, is_function_call = False):
   506         """Adds code or a function call"""   513             code.replace(
' ',
'_')
   514             self.
addline(
'CALL JOB:%s' % (code))
   521         """Add a message/comment"""   523             for i 
in range(0,len(message), 29):
   524                 i2 = min(i + 29, len(message))
   525                 self.
addline(
"'%s" % message[i:i2])
   528             for i 
in range(0,len(message), 25):
   529                 i2 = min(i + 25, len(message))
   530                 self.
addline(
'MSG "%s"' % message[i:i2])
   534         macro_line = 
'MACRO%s MJ#(%s)' % (number, mf)
   537           self.
addlog(
'Macro supports only 16 arguments')
   542             macro_line += (
' ARGF%s' % (arg))
   550             self.
addline(
'ARCON ASF#(%s)' % asf_number)
   556             self.
addline(
'ARCOF AEF#(%s)' % aef_number)
   566         """Add a program line"""   572         self.
PROG.append(newline)
   575         """Add a line at the end of the program (used for targets)"""   579         """Add a log message"""   582         self.
LOG = self.
LOG + newline + 
'\n'   638         for i 
in range(len(joints)):
   639             str_pulses.append(
'%i' % round(joints[i] * self.
PULSES_X_DEG[i]))
   658             turnJ4 = (joints[3]+180)//360
   659             turnJ6 = (joints[5]+180)//360
   660             turnJ1 = (joints[0]+180)//360
   661             turns = [turnJ4, turnJ6, turnJ1]
   663         confdata = 
'%i,%i,%i,%i,%i,%i,0,0' % tuple(conf_RLF[:3] + turns[:3])
   667         self.
addline_targets(
'C%05i=' % cid + 
'%.3f,%.3f,%.3f,%.2f,%.2f,%.2f' % tuple(xyzwpr))
   732     [x,y,z,r,p,w] = xyzrpw
   742     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]])
   745     """Test the post with a basic program"""   747     robot = 
RobotPost(
'Motomantest', 
'Motoman robot', 6)
   749     robot.ProgStart(
"Program")
   750     robot.RunMessage(
"Program generated by RoboDK", 
True)
   751     robot.setFrame(
Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]), 
None, 0)
   752     robot.setTool(
Pose([62.5, -108.253175, 100, -60, 90, 0]), 
None, 0)
   753     robot.MoveJ(
Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
   754     robot.MoveL(
Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
   755     robot.MoveL(
Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
   756     robot.RunMessage(
"Setting air valve 1 on")
   757     robot.RunCode(
"TCP_On", 
True)
   759     robot.MoveL(
Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
   760     robot.MoveL(
Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
   761     robot.MoveL(
Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
   762     robot.RunMessage(
"Setting air valve off")
   763     robot.RunCode(
"TCP_Off", 
True)
   765     robot.MoveL(
Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
   766     robot.MoveL(
Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
   767     robot.MoveL(
Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
   768     robot.ProgFinish(
"Program")
   771     robot.PROG = robot.PROG_LIST.pop()
   772     for line 
in robot.PROG:
   775     if len(robot.LOG) > 0:
   776         mbox(
'Program generation LOG:\n\n' + robot.LOG)
   778     input(
"Press Enter to close...")
   780 if __name__ == 
"__main__":
   781     """Function to call when the module is executed by itself: test""" def ProgFinish(self, progname, new_page=False)
def setSpeedJoints(self, speed_degs)
def setAcceleration(self, accel_mmss)
def add_target_joints(self, joints)
def setDO(self, io_var, io_value)
def setTool(self, pose, tool_id, tool_name)
def RunMessage(self, message, iscomment=False)
def transl(tx, ty=None, tz=None)
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
def MoveL(self, pose, joints, conf_RLF=None)
def waitDI(self, io_var, io_value, timeout_ms=-1)
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)
def setCartesian(self, confdata)
def setZoneData(self, zone_mm)
def MoveJ(self, pose, joints, conf_RLF=None)
def add_target_cartesian(self, pose, joints, conf_RLF)
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
bool INCLUDE_SUB_PROGRAMS
def addline_targets(self, newline)
def RunCode(self, code, is_function_call=False)
def SetFolder(self, foldername)
def ProgStart(self, progname, new_page=False)
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
def Macro(self, number, mf, args)
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
def Arcon(self, asf_number=0)
def addlog(self, newline)
def setFrame(self, pose, frame_id, frame_name)
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
def get_safe_name(progname, max_chars=32)
def setSpeed(self, speed_mms)
def page_size_control(self)
def Arcof(self, aef_number=0)
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
def setAccelerationJoints(self, accel_degss)
def addline(self, newline, movetype=' ')
def progsave(self, folder, progname, ask_user=False, show_result=False)