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)