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' 193 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)
425 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)""" 433 self.
addlog(
'setSpeedJoints not defined')
436 """Changes the robot joint acceleration (in deg/s2)""" 437 self.
addlog(
'setAccelerationJoints not defined')
440 """Changes the zone data approach (makes the movement more smooth)""" 444 self.
CNT_VALUE =
'CNT%i' % round(min(zone_mm, 100.0))
447 """Sets a variable (output) to a given value""" 448 if type(io_var) != str:
449 io_var =
'DO[%s]' % str(io_var)
450 if type(io_value) != str:
457 self.
addline(
'%s=%s ;' % (io_var, io_value))
459 def waitDI(self, io_var, io_value, timeout_ms=-1):
460 """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided.""" 461 if type(io_var) != str:
462 io_var =
'DI[%s]' % str(io_var)
463 if type(io_value) != str:
471 self.
addline(
'WAIT %s=%s ;' % (io_var, io_value))
474 self.
addline(
'$WAITTMOUT=%i ;' % round(timeout_ms))
481 """Add parameters to the last command""" 482 if len(self.
PROG) > 0
and self.
PROG[-1].endswith(
';\n'):
483 self.
PROG[-1] = self.
PROG[-1][:-2] + add_params +
';' 485 def RunCode(self, code, is_function_call = False):
486 """Adds code or a function call""" 489 if code.startswith(
"ArcStart"):
490 if not code.endswith(
')'):
500 self.
SPEED =
'WELD_SPEED' 508 elif code.startswith(
"ArcEnd"):
520 code.replace(
' ',
'_')
521 self.
addline(
'CALL %s ;' % (code))
523 if not code.endswith(
';'):
528 """Add a joint movement""" 531 for i
in range(0,len(message), 20):
532 i2 = min(i + 20, len(message))
533 self.
addline(
'! %s ;' % message[i:i2])
536 for i
in range(0,len(message), 20):
537 i2 = min(i + 20, len(message))
538 self.
addline(
'MESSAGE[%s] ;' % message[i:i2])
549 """Add a program line""" 556 newline_ok = (
'%4i:%s ' % (self.
LINE_COUNT, movetype)) + newline
557 self.
PROG.append(newline_ok)
560 """Add a line at the end of the program (used for targets)""" 564 """Add a log message""" 567 self.
LOG = self.
LOG + newline +
'\n' 580 self.
addline_targets(
'\tJ1= %.3f deg,\tJ2= %.3f deg,\tJ3= %.3f deg,' % (joints[0], joints[1], joints[2]))
581 self.
addline_targets(
'\tJ4= %.3f deg,\tJ5= %.3f deg,\tJ6= %.3f deg%s' % (joints[3], joints[4], joints[5], add_comma))
586 track_str = track_str +
'\tE%i=%10.3f mm,' % (i+1, joints[self.
AXES_TRACK[i]])
587 track_str = track_str[:-1]
595 turntable_str = turntable_str +
'\tJ%i=%10.3f deg,' % (i+1, joints[self.
AXES_TURNTABLE[i]])
596 turntable_str = turntable_str[:-1]
604 def angle_2_turn(angle):
606 return +math.floor((+angle+180.0)/360.0)
608 return -math.floor((-angle+180.0)/360.0)
611 config = [
'N',
'U','T'] #normal
613 if conf_RLF
is not None:
621 turnJ1 = angle_2_turn(joints[0])
622 turnJ4 = angle_2_turn(joints[3])
623 turnJ6 = angle_2_turn(joints[5])
631 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))
632 self.
addline_targets(
'\tX =%10.3f mm,\tY =%10.3f mm,\tZ =%10.3f mm,' % (xyzwpr[0], xyzwpr[1], xyzwpr[2]))
633 self.
addline_targets(
'\tW =%10.3f deg,\tP =%10.3f deg,\tR =%10.3f deg%s' % (xyzwpr[3], xyzwpr[4], xyzwpr[5], add_comma))
638 track_str = track_str +
'\tE%i=%10.3f mm,' % (i+1, joints[self.
AXES_TRACK[i]])
639 track_str = track_str[:-1]
647 turntable_str = turntable_str +
'\tJ%i=%10.3f deg,' % (i+1, joints[self.
AXES_TURNTABLE[i]])
648 turntable_str = turntable_str[:-1]
690 [x,y,z,r,p,w] = xyzrpw
700 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]])
703 """Test the post with a basic program""" 705 robot =
RobotPost(
'Fanuc_custom',
'Fanuc robot', 6)
707 robot.ProgStart(
"Program")
708 robot.RunMessage(
"Program generated by RoboDK",
True)
709 robot.setFrame(
Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]))
710 robot.setTool(
Pose([62.5, -108.253175, 100, -60, 90, 0]))
711 robot.MoveJ(
Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
712 robot.MoveL(
Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
713 robot.MoveL(
Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
714 robot.RunMessage(
"Setting air valve 1 on")
715 robot.RunCode(
"TCP_On",
True)
717 robot.MoveL(
Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
718 robot.MoveL(
Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
719 robot.MoveL(
Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
720 robot.RunMessage(
"Setting air valve off")
721 robot.RunCode(
"TCP_Off",
True)
723 robot.MoveL(
Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
724 robot.MoveL(
Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
725 robot.MoveL(
Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
726 robot.ProgFinish(
"Program")
729 robot.PROG = robot.PROG_LIST.pop()
730 for line
in robot.PROG:
733 if len(robot.LOG) > 0:
734 mbox(
'Program generation LOG:\n\n' + robot.LOG)
736 input(
"Press Enter to close...")
738 if __name__ ==
"__main__":
739 """Function to call when the module is executed by itself: test"""
def setAccelerationJoints(self, accel_degss)
def addlastline(self, add_params)
def setSpeedJoints(self, speed_degs)
def setFrame(self, pose, frame_id=None, frame_name=None)
def setZoneData(self, zone_mm)
def setSpeed(self, speed_mms)
def setTool(self, pose, tool_id=None, tool_name=None)
def MoveL(self, pose, joints, conf_RLF=None)
def ProgStart(self, progname, new_page=False)
def get_safe_name(progname, max_chars=10)
def addline_targets(self, newline)
def ProgFinish(self, progname, new_page=False)
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
def addline(self, newline, movetype=' ')
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
def add_target_joints(self, pose, joints)
def page_size_control(self)
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
def add_target_cartesian(self, pose, joints, conf_RLF=None)
def progsave(self, folder, progname, ask_user=False, show_result=False)
def RunMessage(self, message, iscomment=False)
def waitDI(self, io_var, io_value, timeout_ms=-1)
def RunCode(self, code, is_function_call=False)
def MoveJ(self, pose, joints, conf_RLF=None)
def setAcceleration(self, accel_mmss)
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
def addlog(self, newline)
def setDO(self, io_var, io_value)
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
bool INCLUDE_SUB_PROGRAMS
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)