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 Fanuc robots"""    71     MAX_LINES_X_PROG = 9999    
    72     INCLUDE_SUB_PROGRAMS = 
True     95     PROG_NAME_CURRENT = 
'unknown'    105     AXES_TYPE = [
'R','R','R','R','R','R']  # Important: This is usually set up by RoboDK automatically. Otherwise, override the __init__ procedure.   111     HAS_TURNTABLE = 
False   117     def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
   124         for k,v 
in kwargs.items():
   125             if k == 
'lines_x_prog':
   140         progname_i = progname
   145                     print(
"Can't split %s: Two or more programs are split into smaller programs" % progname)
   147                     raise Exception(
"Only one program at a time can be split into smaller programs")
   176         header = header + 
'/ATTR' + 
'\n'   177         header = header + 
'OWNER\t\t= MNEDITOR;' + 
'\n'   178         header = header + 
'COMMENT\t\t= "RoboDK sequence";' + 
'\n'   179         header = header + 
'PROG_SIZE\t= 0;' + 
'\n'   180         header = header + 
'CREATE\t\t= DATE 31-12-14  TIME 12:00:00;' + 
'\n'   181         header = header + 
'MODIFIED\t= DATE 31-12-14  TIME 12:00:00;' + 
'\n'   182         header = header + 
'FILE_NAME\t= ;' + 
'\n'   183         header = header + 
'VERSION\t\t= 0;' + 
'\n'   184         header = header + (
'LINE_COUNT\t= %i;' % (self.
LINE_COUNT)) + 
'\n'   185         header = header + 
'MEMORY_SIZE\t= 0;' + 
'\n'   186         header = header + 
'PROTECT\t\t= READ_WRITE;' + 
'\n'   187         header = header + 
'TCD:  STACK_SIZE\t= 0,' + 
'\n'   188         header = header + 
'      TASK_PRIORITY\t= 50,' + 
'\n'   189         header = header + 
'      TIME_SLICE\t= 0,' + 
'\n'   190         header = header + 
'      BUSY_LAMP_OFF\t= 0,' + 
'\n'   191         header = header + 
'      ABORT_REQUEST\t= 0,' + 
'\n'   192         header = header + 
'      PAUSE_REQUEST\t= 0;' + 
'\n'   194         header = header + 
'DEFAULT_GROUP\t= 1,*,*,*,*,*,*;' + 
'\n'   195         header = header + 
'CONTROL_CODE\t= 00000000 00000000;' + 
'\n'   197             header = header + 
'/APPL' + 
'\n'   198             header = header + 
'' + 
'\n'   199             header = header + 
'LINE_TRACK;' + 
'\n'   200             header = header + 
'LINE_TRACK_SCHEDULE_NUMBER      : 0;' + 
'\n'   201             header = header + 
'LINE_TRACK_BOUNDARY_NUMBER      : 0;' + 
'\n'   202             header = header + 
'CONTINUE_TRACK_AT_PROG_END      : FALSE;' + 
'\n'   203             header = header + 
'' + 
'\n'   204         header = header + 
'/MN'   207         self.
PROG.insert(0, header)
   208         self.
PROG.append(
'/POS')
   210         self.
PROG.append(
'/END')
   221     def progsave(self, folder, progname, ask_user = False, show_result = False):
   223         if not folder.endswith(
'/'):
   224             folder = folder + 
'/'   225         progname = progname + 
'.' + self.
PROG_EXT   227             filesave = 
getSaveFile(folder, progname, 
'Save program as...')
   228             if filesave 
is not None:
   229                 filesave = filesave.name
   233             filesave = folder + progname
   234         fid = open(filesave, 
"w")
   236         for line 
in self.
PROG:
   240         print(
'SAVED: %s\n' % filesave) 
   245             if type(show_result) 
is str:
   248                 p = subprocess.Popen([show_result, filesave])
   249             elif type(show_result) 
is list:
   251                 p = subprocess.Popen(show_result + [filesave])   
   255                 os.startfile(filesave)
   260         PATH_MAKE_TP = 
'C:/Program Files (x86)/FANUC/WinOLPC/bin/'   262             filesave_TP = filesave[:-3] + 
'.TP'   263             print(
"POPUP: Compiling LS file with MakeTP.exe: %s..." % progname)
   266             command = [PATH_MAKE_TP + 
'MakeTP.exe', filesave.replace(
'/',
'\\'), filesave_TP.replace(
'/',
'\\'), 
'/config', PATH_MAKE_TP + 
'robot.ini']
   269             self.
LOG += 
'Program generation for: ' + progname + 
'\n'   270             with subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=1, universal_newlines=
True) 
as p:
   271                 for line 
in p.stdout:
   272                     line_ok = line.strip()
   273                     self.
LOG += line_ok + 
'\n'   274                     print(
"POPUP: " + line_ok)
   279     def ProgSave(self, folder, progname, ask_user = False, show_result = False):
   285                 print(
"Warning: ProgFinish was not called properly")
   304             self.
progsave(folder, progname_last, ask_user, show_result)
   322             self.
progsave(folder, progname, ask_user, show_result)
   325             print(
"Warning! Program has not been properly finished")
   326             self.
progsave(folder, progname, ask_user, show_result)
   328         if show_result 
and len(self.
LOG) > 0:
   329             mbox(
'Program generation LOG:\n\n' + self.
LOG)
   332         """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".   333         The connection parameters must be provided in the robot connection menu of RoboDK"""   336     def MoveJ(self, pose, joints, conf_RLF=None):
   337         """Add a joint movement"""   345     def MoveL(self, pose, joints, conf_RLF=None):
   346         """Add a linear movement"""   357             move_ins = 
'P[%i] %s %s ;' % (target_id, self.
SPEED, self.
CNT_VALUE)
   360             move_ins = 
'P[%i] %s %s ;' % (target_id, self.
SPEED, self.
CNT_VALUE)
   365     def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
   366         """Add a circular movement"""   371         move_ins = 
'P[%i] \n       P[%i] %s %s ;' % (target_id1, target_id2, self.
SPEED, self.
CNT_VALUE)
   375     def setFrame(self, pose, frame_id=None, frame_name=None):
   376         """Change the robot reference frame"""   378         if frame_id 
is None or frame_id < 0:            
   381             for i 
in range(6,self.
nAxes):
   388             self.
RunMessage(
'UF%i:%.1f,%.1f,%.1f,%.1f,%.1f,%.1f' % (frame_id, xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]), 
True)
   390     def setTool(self, pose, tool_id=None, tool_name=None):
   391         """Change the robot TCP"""   393         if tool_id 
is None or tool_id < 0:
   396             for i 
in range(6,self.
nAxes):
   403             self.
RunMessage(
'UT%i:%.1f,%.1f,%.1f,%.1f,%.1f,%.1f' % (tool_id, xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]), 
True)
   406         """Pause the robot program"""   410             self.
addline(
'WAIT  %.2f(sec) ;' % (time_ms*0.001))
   413         """Changes the robot speed (in mm/s)"""   416             self.
SPEED = 
'%.0fmm/sec' % max(speed_mms, 0.01)
   418             self.
JOINT_SPEED = 
'%.0f%%' % max(min(100.0*speed_mms/5000.0, 100.0), 1) 
   428         """Changes the robot acceleration (in mm/s2)"""   429         self.
addlog(
'setAcceleration not defined')
   432         """Changes the robot joint speed (in deg/s)"""   434         self.
JOINT_SPEED = 
'%.0f%%' % max(min(100.0*speed_degs/200.0, 100.0), 1) 
   437         """Changes the robot joint acceleration (in deg/s2)"""   438         self.
addlog(
'setAccelerationJoints not defined')
   441         """Changes the zone data approach (makes the movement more smooth)"""   445             self.
CNT_VALUE = 
'CNT%i' % round(min(zone_mm, 100.0))        
   448         """Sets a variable (output) to a given value"""   449         if type(io_var) != str:  
   450             io_var = 
'DO[%s]' % str(io_var)        
   451         if type(io_value) != str: 
   458         self.
addline(
'%s=%s ;' % (io_var, io_value))
   460     def waitDI(self, io_var, io_value, timeout_ms=-1):
   461         """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided."""   462         if type(io_var) != str:  
   463             io_var = 
'DI[%s]' % str(io_var)        
   464         if type(io_value) != str: 
   472             self.
addline(
'WAIT %s=%s ;' % (io_var, io_value))
   475             self.
addline(
'$WAITTMOUT=%i ;' % round(timeout_ms))
   482         """Add parameters to the last command"""   483         if len(self.
PROG) > 0 
and self.
PROG[-1].endswith(
';\n'):
   484             self.
PROG[-1] = self.
PROG[-1][:-2] + add_params + 
';'    486     def RunCode(self, code, is_function_call = False):
   487         """Adds code or a function call"""   490             if code.startswith(
"ArcStart"):
   491                 if not code.endswith(
')'):
   501                 self.
SPEED = 
'WELD_SPEED'   509             elif code.startswith(
"ArcEnd"):
   521             code.replace(
' ',
'_')
   522             self.
addline(
'CALL %s ;' % (code))
   524             if not code.endswith(
';'):
   529         """Add a joint movement"""   532             for i 
in range(0,len(message), 20):
   533                 i2 = min(i + 20, len(message))
   534                 self.
addline(
'! %s ;' % message[i:i2])
   537             for i 
in range(0,len(message), 20):
   538                 i2 = min(i + 20, len(message))
   539                 self.
addline(
'MESSAGE[%s] ;' % message[i:i2])
   550         """Add a program line"""   557         newline_ok = (
'%4i:%s ' % (self.
LINE_COUNT, movetype)) + newline            
   558         self.
PROG.append(newline_ok)
   561         """Add a line at the end of the program (used for targets)"""   565         """Add a log message"""   568         self.
LOG = self.
LOG + newline + 
'\n'   581         self.
addline_targets(
'\tJ1=    %.3f deg,\tJ2=    %.3f deg,\tJ3=    %.3f deg,' % (joints[0], joints[1], joints[2]))
   582         self.
addline_targets(
'\tJ4=    %.3f deg,\tJ5=    %.3f deg,\tJ6=    %.3f deg%s' % (joints[3], joints[4], joints[5], add_comma))
   587                 track_str = track_str + 
'\tE%i=%10.3f  mm,' % (i+1, joints[self.
AXES_TRACK[i]])
   588             track_str = track_str[:-1]
   596                 turntable_str = turntable_str + 
'\tJ%i=%10.3f deg,' % (i+1, joints[self.
AXES_TURNTABLE[i]])
   597             turntable_str = turntable_str[:-1]
   605         def angle_2_turn(angle):
   607                 return +math.floor((+angle+180.0)/360.0)
   609                 return -math.floor((-angle+180.0)/360.0)
   612         config = [
'N',
'U','T'] #normal        
   614         if conf_RLF 
is not None:
   622         turnJ1 = angle_2_turn(joints[0])
   623         turnJ4 = angle_2_turn(joints[3])
   624         turnJ6 = angle_2_turn(joints[5])       
   632         self.
addline_targets(
'    UF : %i, UT : %i,        CONFIG : \'%c %c %c, %i, %i, %i\',' % (self.
ACTIVE_UF, self.
ACTIVE_UT, config[0], config[1], config[2], turnJ1, turnJ4, turnJ6))        
   633         self.
addline_targets(
'\tX =%10.3f  mm,\tY =%10.3f  mm,\tZ =%10.3f  mm,' % (xyzwpr[0], xyzwpr[1], xyzwpr[2]))
   634         self.
addline_targets(
'\tW =%10.3f deg,\tP =%10.3f deg,\tR =%10.3f deg%s' % (xyzwpr[3], xyzwpr[4], xyzwpr[5], add_comma))
   639                 track_str = track_str + 
'\tE%i=%10.3f  mm,' % (i+1, joints[self.
AXES_TRACK[i]])
   640             track_str = track_str[:-1]
   648                 turntable_str = turntable_str + 
'\tJ%i=%10.3f deg,' % (i+1, joints[self.
AXES_TURNTABLE[i]])
   649             turntable_str = turntable_str[:-1]
   691     [x,y,z,r,p,w] = xyzrpw
   701     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]])
   704     """Test the post with a basic program"""   706     robot = 
RobotPost(
'Fanuc_custom', 
'Fanuc robot', 6)
   708     robot.ProgStart(
"Program")
   709     robot.RunMessage(
"Program generated by RoboDK", 
True)
   710     robot.setFrame(
Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]))
   711     robot.setTool(
Pose([62.5, -108.253175, 100, -60, 90, 0]))
   712     robot.MoveJ(
Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
   713     robot.MoveL(
Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
   714     robot.MoveL(
Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
   715     robot.RunMessage(
"Setting air valve 1 on")
   716     robot.RunCode(
"TCP_On", 
True)
   718     robot.MoveL(
Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
   719     robot.MoveL(
Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
   720     robot.MoveL(
Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
   721     robot.RunMessage(
"Setting air valve off")
   722     robot.RunCode(
"TCP_Off", 
True)
   724     robot.MoveL(
Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
   725     robot.MoveL(
Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
   726     robot.MoveL(
Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
   727     robot.ProgFinish(
"Program")
   730     robot.PROG = robot.PROG_LIST.pop()
   731     for line 
in robot.PROG:
   734     if len(robot.LOG) > 0:
   735         mbox(
'Program generation LOG:\n\n' + robot.LOG)
   737     input(
"Press Enter to close...")
   739 if __name__ == 
"__main__":
   740     """Function to call when the module is executed by itself: test""" def setDO(self, io_var, io_value)
def add_target_cartesian(self, pose, joints, conf_RLF=None)
def setZoneData(self, zone_mm)
def addline_targets(self, newline)
def addlastline(self, add_params)
def waitDI(self, io_var, io_value, timeout_ms=-1)
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
def page_size_control(self)
def get_safe_name(progname, max_chars=10)
def RunMessage(self, message, iscomment=False)
def MoveL(self, pose, joints, conf_RLF=None)
def progsave(self, folder, progname, ask_user=False, show_result=False)
def addline(self, newline, movetype=' ')
def setAcceleration(self, accel_mmss)
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
def setTool(self, pose, tool_id=None, tool_name=None)
bool INCLUDE_SUB_PROGRAMS
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
def ProgFinish(self, progname, new_page=False)
def setSpeedJoints(self, speed_degs)
def ProgStart(self, progname, new_page=False)
def setAccelerationJoints(self, accel_degss)
def MoveJ(self, pose, joints, conf_RLF=None)
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
def RunCode(self, code, is_function_call=False)
def setSpeed(self, speed_mms)
def setFrame(self, pose, frame_id=None, frame_name=None)
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
def add_target_joints(self, pose, joints)
def addlog(self, newline)
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)