CLOOS.py
Go to the documentation of this file.
1 # Copyright 2017 - RoboDK Software S.L. - http://www.robodk.com/
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at
5 # http://www.apache.org/licenses/LICENSE-2.0
6 # Unless required by applicable law or agreed to in writing, software
7 # distributed under the License is distributed on an "AS IS" BASIS,
8 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9 # See the License for the specific language governing permissions and
10 # limitations under the License.
11 
12 # ----------------------------------------------------
13 # This file is a POST PROCESSOR for Robot Offline Programming to generate programs
14 # for a CLOOS robot (TXT file and PKT)
15 #
16 # To edit/test this POST PROCESSOR script file:
17 # Select "Program"->"Add/Edit Post Processor", then select your post or create a new one.
18 # You can edit this file using any text editor or Python editor. Using a Python editor allows to quickly evaluate a sample program at the end of this file.
19 # Python should be automatically installed with RoboDK
20 #
21 # You can also edit the POST PROCESSOR manually:
22 # 1- Open the *.py file with Python IDLE (right click -> Edit with IDLE)
23 # 2- Make the necessary changes
24 # 3- Run the file to open Python Shell: Run -> Run module (F5 by default)
25 # 4- The "test_post()" function is called automatically
26 # Alternatively, you can edit this file using a text editor and run it with Python
27 #
28 # To use a POST PROCESSOR file you must place the *.py file in "C:/RoboDK/Posts/"
29 # To select one POST PROCESSOR for your robot in RoboDK you must follow these steps:
30 # 1- Open the robot panel (double click a robot)
31 # 2- Select "Parameters"
32 # 3- Select "Unlock advanced options"
33 # 4- Select your post as the file name in the "Robot brand" box
34 #
35 # To delete an existing POST PROCESSOR script, simply delete this file (.py file)
36 #
37 # ----------------------------------------------------
38 # More information about RoboDK Post Processors and Offline Programming here:
39 # http://www.robodk.com/help#PostProcessor
40 # http://www.robodk.com/doc/en/PythonAPI/postprocessor.html
41 # ----------------------------------------------------
42 
43 
44 def get_safe_name(progname, max_chars = 7):
45  """Get a safe program name"""
46  # Remove special characters
47  for c in r'-[]/\;,><&*:%=+@!#^()|?^':
48  progname = progname.replace(c,'')
49  # Set a program name by default:
50  if len(progname) <= 0:
51  progname = 'Program'
52  # Force the program to start with a letter (not a number)
53  if progname[0].isdigit():
54  progname = 'P' + progname
55  # Set the maximum size of a program (number of characters)
56  if len(progname) > max_chars:
57  progname = progname[:max_chars]
58  return progname
59 
60 
61 # ----------------------------------------------------
62 # Import RoboDK tools
63 from robodk import *
64 import sys
65 
66 # ----------------------------------------------------
67 # Object class that handles the robot instructions/syntax
68 class RobotPost(object):
69  """Robot post object defined for Motoman robots"""
70  # Enter the robot model:
71  PATH_MAKE_SP = 'C:/Program Files (x86)/CLOOS/'
72  ROBOT_MODEL = '310'
73  SERIAL_NR = '3511462'
74  PROG_EXT = 'txt' # set the program extension
75  MAX_LINES_X_PROG = 5000 # maximum number of lines per program. It will then generate multiple "pages (files)". This can be overriden by RoboDK settings.
76  SPEED_MMS = 50 # Default speed in mm/s
77 
78  INCLUDE_SUB_PROGRAMS = True # Generate sub programs
79 
80  PULSES_ZERO = 4194304 # zero position for pulses
81 
82  # Pulses per degree (provide these in the robot parameters menu: Double click the motoman robot in RoboDK, select "Parameters"
83  PULSES_X_DEG = [1,1,1,1,1,1]
84 
85  # PROG specific variables:
86  LINE_COUNT = 0 # Count the number of instructions (limited by MAX_LINES_X_PROG)
87  P_COUNT = 0 # Count the number of P targets in one file
88  C_COUNT = 0 # Count the number of P targets in one file
89  nProgs = 0 # Count the number of programs and sub programs
90 
91  # other variables
92  ROBOT_POST = ''
93  ROBOT_NAME = ''
94  PROG_FILES = [] # List of Program files to be uploaded through FTP
95 
96  PROG_NAMES = [] # List of PROG NAMES
97  PROG_LIST = [] # List of PROG
98  PROG_TARGETS_LIST = [] # List of PROG
99 
100  PROG_NAME = 'unknown' # Original name of the current program (example: ProgA)
101  PROG_NAME_CURRENT = 'unknown' # Auto generated name (different from PROG_NAME if we have more than 1 page per program. Example: ProgA2)
102 
103  nPages = 0 # Count the number of pages
104  PROG_NAMES_MAIN = [] # List of programs called by a main program due to splitting
105 
106  PROG = [] # Save the program lines
107  PROG_TARGETS = [] # Save the program lines (targets section)
108  LOG = '' # Save a log
109 
110  nAxes = 6 # Important: This is usually provided by RoboDK automatically. Otherwise, override the __init__ procedure.
111  AXES_TYPE = ['R','R','R','R','R','R'] # Important: This is usually set up by RoboDK automatically. Otherwise, override the __init__ procedure.
112  # 'R' for rotative axis, 'L' for linear axis, 'T' for external linear axis (linear track), 'J' for external rotative axis (turntable)
113  #AXES_TYPE = ['R','R','R','R','R','R','T','J','J'] #example of a robot with one external linear track axis and a turntable with 2 rotary axes
114  AXES_TRACK = []
115  AXES_TURNTABLE = []
116  HAS_TRACK = False
117  HAS_TURNTABLE = False
118 
119  # Specific to ARC welding applications
120  SPEED_BACKUP = None
121  LAST_POSE = None
122  POSE_FRAME = eye(4)
123  POSE_FRAME = eye(4)
124 
125  def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
126  self.ROBOT_POST = robotpost
127  self.ROBOT_NAME = robotname
128  self.nAxes = robot_axes
129  self.PROG = []
130  self.LOG = ''
131  #for k,v in kwargs.iteritems(): # python2
132  for k,v in kwargs.items():
133  if k == 'lines_x_prog':
135  if k == 'axes_type':
136  self.AXES_TYPE = v
137  if k == 'pulses_x_deg':
138  self.PULSES_X_DEG = v
139 
140  for i in range(len(self.AXES_TYPE)):
141  if self.AXES_TYPE[i] == 'T':
142  self.AXES_TRACK.append(i)
143  self.HAS_TRACK = True
144  elif self.AXES_TYPE[i] == 'J':
145  self.AXES_TURNTABLE.append(i)
146  self.HAS_TURNTABLE = True
147 
148 
149  def ProgStart(self, progname, new_page = False):
150  progname = get_safe_name(progname)
151  progname_i = progname
152  if new_page:
153  #nPages = len(self.PROG_LIST)
154  if self.nPages == 0:
155  if len(self.PROG_NAMES_MAIN) > 0:
156  print("Can't split %s: Two or more programs are split into smaller programs" % progname)
157  print(self.PROG_NAMES_MAIN)
158  raise Exception("Only one program at a time can be split into smaller programs")
159  self.PROG_NAMES_MAIN.append(self.PROG_NAME) # add the first program in the list to be genrated as a subprogram call
160  self.nPages = self.nPages + 1
161 
162  self.nPages = self.nPages + 1
163  progname_i = "%s%i" % (self.PROG_NAME, self.nPages)
164  self.PROG_NAMES_MAIN.append(progname_i)
165 
166  else:
167  if self.nProgs > 1 and not self.INCLUDE_SUB_PROGRAMS:
168  return
169  self.PROG_NAME = progname
170  self.nProgs = self.nProgs + 1
171  self.MoveJ(None, [0]*self.nAxes)
172  #self.PROG_NAMES = []
173 
174  self.PROG_NAME_CURRENT = progname_i
175  self.PROG_NAMES.append(progname_i)
176 
177  def ProgFinish(self, progname, new_page = False):
178  progname = get_safe_name(progname)
179  if not new_page:
180  # Reset page count
181  self.nPages = 0
182 
183  header = ''
184  header += 'RESTART' + '\n'
185  header += 'LIST 1=(4211,3,0,49,91,20,530,0,0,40,50,0,0,0,0,0,0,3,0,0,3,0)' + '\n'
186  header += '' + '\n'
187 
188  header += 'MAIN' + '\n'
189  header += 'STCP (10,0,4998)' + '\n'
190  header += 'STOV (-1,0,-1)' + '\n'
191  header += '$ (1)' + '\n'
192 
193  header_pkt = ''
194  header_pkt += '( Robot : %s )' % self.ROBOT_MODEL + '\n'
195  header_pkt += '( Serial Nr : %s )' % self.SERIAL_NR + '\n'
196  header_pkt += '( Achszahl : %i )' % self.nAxes + '\n'
197  header_pkt += '( Resolution: 2:2:2:2:2:2: Konfigend)'
198 
199  self.PROG.insert(0, header)
200  self.PROG.append('\nEND')
201 
202  self.PROG_TARGETS.insert(0, header_pkt)
203 
204  # Save PROG in PROG_LIST
205  self.PROG_LIST.append(self.PROG)
206  self.PROG_TARGETS_LIST.append(self.PROG_TARGETS)
207 
208  self.PROG = []
209  self.PROG_TARGETS = []
210  self.LINE_COUNT = 0
211  self.P_COUNT = 0
212  self.C_COUNT = 0
213 
214 #RESTART
215 #LIST 1=(4211,3,0,49,91,20,530,0,0,40,50,0,0,0,0,0,0,3,0,0,3,0)
216 #
217 #MAIN
218 #$ (1)
219 
220  def progsave(self, folder, progname, ask_user = False, show_result = False):
221  print(folder)
222  if not folder.endswith('/'):
223  folder = folder + '/'
224  progname = progname + '.' + self.PROG_EXT
225  if ask_user or not DirExists(folder):
226  filesave = getSaveFile(folder, progname, 'Save program as...')
227  if filesave is not None:
228  filesave = filesave.name
229  else:
230  return
231  else:
232  filesave = folder + progname
233 
234  # Save TXT file
235  fid = open(filesave, "w")
236  for line in self.PROG:
237  fid.write(line)
238  fid.write('\n')
239  fid.close()
240 
241  # Save PKT file
242  filesave_pkt = filesave[:-3]+'pkt'
243  fid2 = open(filesave_pkt, "w")
244  for line in self.PROG_TARGETS:
245  fid2.write(line)
246  fid2.write('\n')
247  fid2.close()
248 
249  print('SAVED: %s\n' % filesave) # tell RoboDK the path of the saved file
250  self.PROG_FILES.append(filesave)
251 
252 
253  # open file with default application
254  if show_result:
255  if type(show_result) is str:
256  # Open file with provided application
257  import subprocess
258  p = subprocess.Popen([show_result, filesave, filesave_pkt])
259  elif type(show_result) is list:
260  import subprocess
261  p = subprocess.Popen(show_result + [filesave])
262  else:
263  # open file with default application
264  import os
265  os.startfile(filesave)
266  #if len(self.LOG) > 0:
267  # mbox('Program generation LOG:\n\n' + self.LOG)
268 
269 
270  # -------- build with CONVSP ---------
271  if FileExists(self.PATH_MAKE_SP + 'CONVSP.exe'):
272  filesave_S = filesave[:-4] + 'S'
273  filesave_P = filesave[:-4] + 'P'
274  print("POPUP: Compiling S file with CONVSP.exe: %s..." % progname)
275  sys.stdout.flush()
276  import subprocess
277  command_list = []
278  command_list.append([self.PATH_MAKE_SP + 'CONVSP', filesave.replace('/','\\'), filesave_S.replace('/','\\')])
279  command_list.append([self.PATH_MAKE_SP + 'CONVSP', filesave_pkt.replace('/','\\'), filesave_P.replace('/','\\')])
280 
281  #output = subprocess.check_output(command)
282  #self.LOG = output.decode('utf-8')
283  self.LOG += 'Program generation for: ' + progname + '\n'
284  for command in command_list:
285  with subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=1, universal_newlines=True) as p:
286  for line in p.stdout:
287  line_ok = line.strip()
288  self.LOG += line_ok + '\n'
289  print("POPUP: " + line_ok)
290  sys.stdout.flush()
291  self.LOG += '\n'
292 
293 
294  def ProgSave(self, folder, progname, ask_user = False, show_result = False):
295  progname = get_safe_name(progname)
296  nfiles = len(self.PROG_LIST)
297  if nfiles >= 1:
298  if self.LINE_COUNT > 0:
299  # Progfinish was not called!
300  print("Warning: ProgFinish was not called properly")
301  self.PROG_LIST.append(self.PROG)
302  self.PROG_TARGETS_LIST.append(self.PROG_TARGETS)
303  self.PROG_NAMES.append("Unknown")
304  self.PROG = []
305  self.PROG_TARGETS = []
306  self.LINE_COUNT = 0
307  self.P_COUNT = 0
308  self.C_COUNT = 0
309 
310  if len(self.PROG_NAMES_MAIN) > 1:
311  # Warning: the program might be cut to a maximum number of chars
312  progname_main = "M_" + self.PROG_NAMES_MAIN[0]
313  self.INCLUDE_SUB_PROGRAMS = True # Force generation of main program
314  self.ProgStart(progname_main)
315  for prog_call in self.PROG_NAMES_MAIN:
316  self.RunCode(prog_call, True)
317 
318  self.ProgFinish(progname_main)
319 
320  # Save the last program added to the PROG_LIST
321  self.PROG = self.PROG_LIST.pop()
322  self.PROG_TARGETS = self.PROG_TARGETS_LIST.pop()
323  progname_last = self.PROG_NAMES.pop()
324  self.progsave(folder, progname_last, ask_user, show_result)
325  #-------------------------
326  #self.LOG = ''
327  if len(self.PROG_FILES) == 0:
328  # cancelled by user
329  return
330 
331  first_file = self.PROG_FILES[0]
332  folder_user = getFileDir(first_file)
333  # progname_user = getFileName(self.FILE_SAVED)
334 
335  # Generate each program
336  for i in range(len(self.PROG_LIST)):
337  self.PROG = self.PROG_LIST[i]
338  self.PROG_TARGETS = self.PROG_TARGETS_LIST[i]
339  self.progsave(folder_user, self.PROG_NAMES[i], False, show_result)
340 
341  elif nfiles == 1:
342  self.PROG = self.PROG_LIST[0]
343  self.PROG_TARGETS = self.PROG_TARGETS_LIST[0]
344  self.progsave(folder, progname, ask_user, show_result)
345 
346  else:
347  print("Warning! Program has not been properly finished")
348  self.progsave(folder, progname, ask_user, show_result)
349 
350  if show_result and len(self.LOG) > 0:
351  mbox('Program generation LOG:\n\n' + self.LOG)
352 
353  def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass):
354  """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".
355  The connection parameters must be provided in the robot connection menu of RoboDK"""
356  UploadFTP(self.PROG_FILES, robot_ip, remote_path, ftp_user, ftp_pass)
357 
358  def MoveJ(self, pose, joints, conf_RLF=None):
359  """Add a joint movement"""
360  self.page_size_control() # Important to control the maximum lines per program and not save last target on new program
361  target_id = self.add_target_joints(joints, 1)
362  self.addline("GP (%i)" % (target_id))
363  self.LAST_POSE = pose
364 
365  def MoveL(self, pose, joints, conf_RLF=None):
366  """Add a linear movement"""
367  self.page_size_control() # Important to control the maximum lines per program and not save last target on new program
368  target_id = -1
369  if pose is None:
370  target_id = self.add_target_joints(joints)
371  else:
372  target_id = self.add_target_cartesian(self.POSE_FRAME*pose, joints, conf_RLF)
373 
374  self.addline("GC (%i)" % (target_id))
375  self.LAST_POSE = pose
376 
377  def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
378  """Add a circular movement"""
379  self.page_size_control() # Important to control the maximum lines per program and not save last target on new program
380  target_id1 = self.add_target_cartesian(self.POSE_FRAME*pose1, joints1, conf_RLF_1)
381  target_id2 = self.add_target_cartesian(self.POSE_FRAME*pose2, joints2, conf_RLF_2)
382  self.addline("ARC (%i,%i,%i)" % (target_id1-1,target_id1,target_id2))
383 
384  def setFrame(self, pose, frame_id, frame_name):
385  """Change the robot reference frame"""
386  xyzwpr = Pose_2_Motoman(pose)
387  self.POSE_FRAME = pose
388  self.RunMessage('Using %s (targets wrt base):' % (str(frame_name)), True)
389  self.RunMessage('%.1f,%.1f,%.1f,%.1f,%.1f,%.1f' % (xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]), True)
390 
391  def setTool(self, pose, tool_id, tool_name):
392  """Change the robot TCP"""
393  xyzwpr = Pose_2_Motoman(pose)
394  self.RunMessage('Tool %s should be close to:' % (str(tool_name)), True)
395  self.RunMessage('%.1f,%.1f,%.1f,%.1f,%.1f,%.1f' % (xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]), True)
396 
397  def Pause(self, time_ms):
398  """Pause the robot program"""
399  if time_ms <= 0:
400  self.addline('PAUSE')
401  else:
402  self.addline('WAITM %.0f' % (time_ms))
403 
404  def setSpeed(self, speed_mms):
405  """Changes the robot speed (in mm/s)"""
406  self.SPEED_MMS = speed_mms
407 
408  def setAcceleration(self, accel_mmss):
409  """Changes the robot acceleration (in mm/s2)"""
410  self.addlog('Set acceleration not defined')
411 
412  def setSpeedJoints(self, speed_degs):
413  """Changes the robot joint speed (in deg/s)"""
414  speedj = max(0.01,min(speed,100.0)) # Joint speed must be in %
415  if speedj < 100:
416  self.STR_VJ = "VJ=%.2f" % speedj
417  else:
418  self.STR_VJ = "VJ=%.1f" % speedj
419 
420  def setAccelerationJoints(self, accel_degss):
421  """Changes the robot joint acceleration (in deg/s2)"""
422  self.addlog('Set acceleration not defined')
423 
424  def setZoneData(self, zone_mm):
425  """Changes the zone data approach (makes the movement more smooth)"""
426  if zone_mm < 0:
427  self.STR_PL = ''
428  else:
429  self.STR_PL = ' PL=%i' % round(min(zone_mm/25, 4))
430 
431  def setDO(self, io_var, io_value):
432  """Sets a variable (output) to a given value"""
433  if type(io_var) != str: # set default variable name if io_var is a number
434  io_var = 'OT#(%s)' % str(io_var)
435  if type(io_value) != str: # set default variable value if io_value is a number
436  if io_value > 0:
437  io_value = 'ON'
438  else:
439  io_value = 'OFF'
440 
441  # at this point, io_var and io_value must be string values
442  #DOUT OT#(2) ON
443  self.addline('DOUT %s %s' % (io_var, io_value))
444 
445  def waitDI(self, io_var, io_value, timeout_ms=-1):
446  """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided."""
447  if type(io_var) != str: # set default variable name if io_var is a number
448  io_var = 'IN#(%s)' % str(io_var)
449  if type(io_value) != str: # set default variable value if io_value is a number
450  if io_value > 0:
451  io_value = 'ON'
452  else:
453  io_value = 'OFF'
454 
455  # at this point, io_var and io_value must be string values
456  if timeout_ms < 0:
457  #WAIT IN#(12)=ON
458  self.addline('WAIT %s=%s' % (io_var, io_value))
459  else:
460  #self.LBL_ID_COUNT = self.LBL_ID_COUNT + 1
461  self.addline('WAIT %s=%s T=%.2f' % (io_var, io_value, timeout_ms*0.001))
462 
463 
464  def RunCode(self, code, is_function_call = False):
465  """Adds code or a function call"""
466  if is_function_call:
467  code = get_safe_name(code)
468  #if code.startswith("ArcStart"):
469  #return
470 
471  # default program call
472  if code.startswith("Extrude"):
473  return
474 
475  code.replace(' ','_')
476  self.addline('CALL %s' % (code))
477  else:
478  #if code.endswith(';'):
479  #code = code[:-1]
480  self.addline(code)
481 
482  def RunMessage(self, message, iscomment = False):
483  """Add a joint movement"""
484  if iscomment:
485  self.addline("! %s" % message)
486 
487  else:
488  self.addline('! MSG %s' % message)
489 
490 # ------------------ private ----------------------
491  def page_size_control(self):
492  if self.LINE_COUNT >= self.MAX_LINES_X_PROG:
493  self.ProgFinish(self.PROG_NAME, True)
494  self.ProgStart(self.PROG_NAME, True)
495 
496 
497  def addline(self, newline, movetype = ' '):
498  """Add a program line"""
499  if self.nProgs > 1 and not self.INCLUDE_SUB_PROGRAMS:
500  return
501 
502  self.page_size_control()
503  self.LINE_COUNT = self.LINE_COUNT + 1
504  self.PROG.append(newline)
505 
506  def addline_targets(self, newline):
507  """Add a line at the end of the program (used for targets)"""
508  self.PROG_TARGETS.append(newline)
509 
510  def addlog(self, newline):
511  """Add a log message"""
512  if self.nProgs > 1 and not self.INCLUDE_SUB_PROGRAMS:
513  return
514 
515  self.LOG = self.LOG + newline + '\n'
516 
517 # ------------------ targets ----------------------
518  def add_target_joints(self, joints, interpolation = 0):
519  if self.nProgs > 1 and not self.INCLUDE_SUB_PROGRAMS:
520  return
521 
522 
523  self.C_COUNT = self.C_COUNT + 1
524  cid = self.C_COUNT
525 
526  str_pulses=[]
527  for i in range(len(joints)):
528  str_pulses.append('%010i' % round(self.PULSES_ZERO + joints[i] * self.PULSES_X_DEG[i]))
529 
530  speed = self.SPEED_MMS
531  outputs = 0
532  self.addline_targets('%05i,%05i,%05i,%05i,' % (cid, speed, interpolation, outputs) + ','.join(str_pulses))
533  return cid
534 
535 #cid,speed,0,0,
536 #00000,00000,00000,00000,004194304,004194304,004194304,004194304,004194304,004194304
537 #00001,00050,00000,00001,004294285,005054619,004652139,004286872,003928097,004116772
538 #00002,00050,00000,00000,004321619,005055554,004649218,004312598,003928967,004111329
539 #00003,00050,00000,00000,004346289,005060069,004635445,004338196,003934233,004105402
540 
541  def add_target_cartesian(self, pose, joints, conf_RLF):
542  if self.nProgs > 1 and not self.INCLUDE_SUB_PROGRAMS:
543  return
544 
545  return self.add_target_joints(joints)
546 
547  xyzwpr = Pose_2_Motoman(pose)
548 
549  if conf_RLF is None:
550  conf_RLF = [0,0,0]
551 
552  turns = [0,0,0]
553  if len(joints) >= 6:
554  turnJ4 = (joints[3]+180)//360
555  turnJ6 = (joints[5]+180)//360
556  turnJ1 = (joints[0]+180)//360
557  turns = [turnJ4, turnJ6, turnJ1]
558 
559  confdata = '%i,%i,%i,%i,%i,%i,0,0' % tuple(conf_RLF[:3] + turns[:3])
560  self.C_COUNT = self.C_COUNT + 1
561  cid = self.C_COUNT
562  self.addline_targets('%i,' % cid + '%.3f,%.3f,%.3f,%.2f,%.2f,%.2f' % tuple(xyzwpr))
563  return cid
564 
565 
566 
567 
568 # -------------------------------------------------
569 # ------------ For testing purposes ---------------
570 def Pose(xyzrpw):
571  [x,y,z,r,p,w] = xyzrpw
572  a = r*math.pi/180
573  b = p*math.pi/180
574  c = w*math.pi/180
575  ca = math.cos(a)
576  sa = math.sin(a)
577  cb = math.cos(b)
578  sb = math.sin(b)
579  cc = math.cos(c)
580  sc = math.sin(c)
581  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]])
582 
583 def test_post():
584  """Test the post with a basic program"""
585 
586  robot = RobotPost('CLOOS test', 'CLOOS robot robot', 6)
587 
588  robot.ProgStart("Program")
589  robot.RunMessage("Program generated by RoboDK", True)
590  robot.setFrame(Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]), None, 0)
591  robot.setTool(Pose([62.5, -108.253175, 100, -60, 90, 0]), None, 0)
592  robot.MoveJ(Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
593  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
594  robot.MoveL(Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
595  robot.RunMessage("Setting air valve 1 on")
596  robot.RunCode("TCP_On", True)
597  robot.Pause(1000)
598  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
599  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
600  robot.MoveL(Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
601  robot.RunMessage("Setting air valve off")
602  robot.RunCode("TCP_Off", True)
603  robot.Pause(1000)
604  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
605  robot.MoveL(Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
606  robot.MoveL(Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
607  robot.ProgFinish("Program")
608  # robot.ProgSave(".","Program",True)
609 
610  robot.PROG = robot.PROG_LIST.pop()
611  print("\n\n--------------- TXT file ----------------\n")
612  for line in robot.PROG:
613  print(line)
614 
615  print("\n\n--------------- PKT file ----------------\n")
616  robot.PROG_TARGETS = robot.PROG_TARGETS_LIST.pop()
617  for line in robot.PROG_TARGETS:
618  print(line)
619 
620  if len(robot.LOG) > 0:
621  mbox('Program generation LOG:\n\n' + robot.LOG)
622 
623  input("Press Enter to close...")
624 
625 if __name__ == "__main__":
626  """Function to call when the module is executed by itself: test"""
627  test_post()
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
Definition: CLOOS.py:294
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
Definition: CLOOS.py:377
def RunCode(self, code, is_function_call=False)
Definition: CLOOS.py:464
def add_target_cartesian(self, pose, joints, conf_RLF)
Definition: CLOOS.py:541
def setDO(self, io_var, io_value)
Definition: CLOOS.py:431
def waitDI(self, io_var, io_value, timeout_ms=-1)
Definition: CLOOS.py:445
def get_safe_name(progname, max_chars=7)
Definition: CLOOS.py:44
def setSpeedJoints(self, speed_degs)
Definition: CLOOS.py:412
def MoveJ(self, pose, joints, conf_RLF=None)
Definition: CLOOS.py:358
def MoveL(self, pose, joints, conf_RLF=None)
Definition: CLOOS.py:365
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: robodk.py:1312
def setTool(self, pose, tool_id, tool_name)
Definition: CLOOS.py:391
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
Definition: CLOOS.py:125
def ProgFinish(self, progname, new_page=False)
Definition: CLOOS.py:177
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
Definition: robodk.py:1458
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: CLOOS.py:353
def setAccelerationJoints(self, accel_degss)
Definition: CLOOS.py:420
def setFrame(self, pose, frame_id, frame_name)
Definition: CLOOS.py:384
def ProgStart(self, progname, new_page=False)
Definition: CLOOS.py:149
def RunMessage(self, message, iscomment=False)
Definition: CLOOS.py:482
def add_target_joints(self, joints, interpolation=0)
Definition: CLOOS.py:518
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
Definition: robodk.py:1354
def progsave(self, folder, progname, ask_user=False, show_result=False)
Definition: CLOOS.py:220
def setAcceleration(self, accel_mmss)
Definition: CLOOS.py:408
def addline(self, newline, movetype=' ')
Definition: CLOOS.py:497


ros_robodk_post_processors
Author(s): Victor Lamoine - Institut Maupertuis
autogenerated on Sun Jun 7 2020 03:50:22