Panasonic.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 Motoman robot (Inform III programming language)
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 # Import RoboDK tools
62 from robodk import *
63 import sys
64 
65 def Pose_2_Panasonic(pose):
66  return Pose_2_Motoman(pose)
67 
68 # ----------------------------------------------------
69 # Object class that handles the robot instructions/syntax
70 class RobotPost(object):
71  """Robot post object defined for Motoman robots"""
72  PROG_EXT = 'prg' # set the program extension
73  MAX_LINES_X_PROG = 2000 # maximum number of lines per program. It will then generate multiple "pages (files)". This can be overriden by RoboDK settings.
74 
75  INCLUDE_SUB_PROGRAMS = True # Generate sub programs
76  STR_V = '3.00 m/min' # set default cartesian speed
77  STR_VJ = '25.00 %%' # set default joints speed
78  STR_CNT = '' # Rounding value (from 0 to 4) (in RoboDK, set to 100 mm rounding for PL=4
79  ACTIVE_FRAME = 9 # Active UFrame Id (register)
80  ACTIVE_TOOL = 9 # Active UTool Id (register)
81  SPARE_PR = 95 # Spare Position register for calculations
82 
83  REGISTER_DIGITS = 5
84 
85  # Pulses per degree (provide these in the robot parameters menu: Double click the motoman robot in RoboDK, select "Parameters"
86  PULSES_X_DEG = [1,1,1,1,1,1]
87 
88  # PROG specific variables:
89  LINE_COUNT = 0 # Count the number of instructions (limited by MAX_LINES_X_PROG)
90  P_COUNT = 0 # Count the number of P targets in one file
91  C_COUNT = 0 # Count the number of P targets in one file
92  nProgs = 0 # Count the number of programs and sub programs
93  LBL_ID_COUNT = 0 # Number of labels used
94 
95  # other variables
96  ROBOT_POST = ''
97  ROBOT_NAME = ''
98  PROG_FILES = [] # List of Program files to be uploaded through FTP
99 
100  PROG_NAMES = [] # List of PROG NAMES
101  PROG_LIST = [] # List of PROG
102 
103  PROG_NAME = 'unknown' # Original name of the current program (example: ProgA)
104  PROG_NAME_CURRENT = 'unknown' # Auto generated name (different from PROG_NAME if we have more than 1 page per program. Example: ProgA2)
105 
106  nPages = 0 # Count the number of pages
107  PROG_NAMES_MAIN = [] # List of programs called by a main program due to splitting
108 
109  PROG = [] # Save the program lines
110  PROG_TARGETS = [] # Save the program lines (targets section)
111  LOG = '' # Save a log
112 
113  nAxes = 6 # Important: This is usually provided by RoboDK automatically. Otherwise, override the __init__ procedure.
114  AXES_TYPE = ['R','R','R','R','R','R'] # Important: This is usually set up by RoboDK automatically. Otherwise, override the __init__ procedure.
115  # 'R' for rotative axis, 'L' for linear axis, 'T' for external linear axis (linear track), 'J' for external rotative axis (turntable)
116  #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
117  AXES_TRACK = []
118  AXES_TURNTABLE = []
119  HAS_TRACK = False
120  HAS_TURNTABLE = False
121 
122  # Specific to ARC welding applications
123  SPEED_BACKUP = None
124  LAST_POSE = None
125  POSE_FRAME = eye(4)
126  POSE_FRAME = eye(4)
127  LAST_CONFDATA = [None, None, None, None] # [pulses(None, Pulses(0), Cartesian) , base(or None), tool, config]
128 
129  def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
130  self.ROBOT_POST = robotpost
131  self.ROBOT_NAME = robotname
132  self.nAxes = robot_axes
133  self.PROG = []
134  self.LOG = ''
135  #for k,v in kwargs.iteritems(): # python2
136  for k,v in kwargs.items():
137  if k == 'lines_x_prog':
139  if k == 'axes_type':
140  self.AXES_TYPE = v
141  if k == 'pulses_x_deg':
142  self.PULSES_X_DEG = v
143 
144  for i in range(len(self.AXES_TYPE)):
145  if self.AXES_TYPE[i] == 'T':
146  self.AXES_TRACK.append(i)
147  self.HAS_TRACK = True
148  elif self.AXES_TYPE[i] == 'J':
149  self.AXES_TURNTABLE.append(i)
150  self.HAS_TURNTABLE = True
151 
152 
153  def ProgStart(self, progname, new_page = False):
154  progname = get_safe_name(progname)
155  progname_i = progname
156  if new_page:
157  #nPages = len(self.PROG_LIST)
158  if self.nPages == 0:
159  if len(self.PROG_NAMES_MAIN) > 0:
160  print("Can't split %s: Two or more programs are split into smaller programs" % progname)
161  print(self.PROG_NAMES_MAIN)
162  raise Exception("Only one program at a time can be split into smaller programs")
163  self.PROG_NAMES_MAIN.append(self.PROG_NAME) # add the first program in the list to be genrated as a subprogram call
164  self.nPages = self.nPages + 1
165 
166  self.nPages = self.nPages + 1
167  progname_i = "%s%i" % (self.PROG_NAME, self.nPages)
168  self.PROG_NAMES_MAIN.append(progname_i)
169 
170  else:
171  if self.nProgs > 1 and not self.INCLUDE_SUB_PROGRAMS:
172  return
173  self.PROG_NAME = progname
174  self.nProgs = self.nProgs + 1
175  #self.PROG_NAMES = []
176 
177  self.PROG_NAME_CURRENT = progname_i
178  self.PROG_NAMES.append(progname_i)
179 
180  def ProgFinish(self, progname, new_page = False):
181  progname = get_safe_name(progname)
182  if not new_page:
183  # Reset page count
184  self.nPages = 0
185 
186  #if self.nPROGS > 1:
187  # # Motoman does not support defining multiple programs in the same file, so one program per file
188  # return
189  header = ''
190  header += '/JOB' + '\n'
191  header += '//NAME %s' % progname + '\n'
192  header += '//POS' + '\n'
193  header += '///NPOS %i,0,0,%i,0,0' % (self.C_COUNT, self.P_COUNT)
194 
195  # Targets are added at this point
196 
197  import time
198  datestr = time.strftime("%Y/%m/%d %H:%M")
199 
200  header_ins = ''
201  header_ins += '//INST' + '\n'
202  header_ins += '///DATE %s' % datestr + '\n'
203  #///DATE 2012/04/25 14:11
204  header_ins += '///COMM Generated using RoboDK\n' # comment: max 28 chars
205  header_ins += '///ATTR SC,RW' + '\n'
206 
207  header_ins += '///GROUP1 RB1' + '\n'
208  header_ins += 'NOP'
209  #if self.HAS_TURNTABLE:
210  # header = header + '/APPL' + '\n'
211 
212  self.PROG.insert(0, header_ins)
213  self.PROG.append('END')
214 
215  self.PROG_TARGETS.insert(0, header)
216 
217  self.PROG = self.PROG_TARGETS + self.PROG
218 
219  # Save PROG in PROG_LIST
220  self.PROG_LIST.append(self.PROG)
221  self.PROG = []
222  self.PROG_TARGETS = []
223  self.LINE_COUNT = 0
224  self.P_COUNT = 0
225  self.C_COUNT = 0
226  self.LAST_CONFDATA = [None, None, None, None]
227  self.LBL_ID_COUNT = 0
228 
229  def progsave(self, folder, progname, ask_user = False, show_result = False):
230  print(folder)
231  if not folder.endswith('/'):
232  folder = folder + '/'
233  progname = progname + '.' + self.PROG_EXT
234  if ask_user or not DirExists(folder):
235  filesave = getSaveFile(folder, progname, 'Save program as...')
236  if filesave is not None:
237  filesave = filesave.name
238  else:
239  return
240  else:
241  filesave = folder + progname
242  fid = open(filesave, "w")
243  #fid.write(self.PROG)
244  for line in self.PROG:
245  fid.write(line)
246  fid.write('\n')
247  fid.close()
248  print('SAVED: %s\n' % filesave) # tell RoboDK the path of the saved file
249  self.PROG_FILES.append(filesave)
250 
251  # open file with default application
252  if show_result:
253  if type(show_result) is str:
254  # Open file with provided application
255  import subprocess
256  p = subprocess.Popen([show_result, filesave])
257  elif type(show_result) is list:
258  import subprocess
259  p = subprocess.Popen(show_result + [filesave])
260  else:
261  # open file with default application
262  import os
263  os.startfile(filesave)
264  #if len(self.LOG) > 0:
265  # mbox('Program generation LOG:\n\n' + self.LOG)
266 
267 
268 
269  def ProgSave(self, folder, progname, ask_user = False, show_result = False):
270  progname = get_safe_name(progname)
271  nfiles = len(self.PROG_LIST)
272  if nfiles >= 1:
273  if self.LINE_COUNT > 0:
274  # Progfinish was not called!
275  print("Warning: ProgFinish was not called properly")
276  self.PROG_LIST.append(self.PROG)
277  self.PROG_NAMES.append("Unknown")
278  self.PROG = []
279  self.LINE_COUNT = 0
280 
281  if len(self.PROG_NAMES_MAIN) > 1:
282  # Warning: the program might be cut to a maximum number of chars
283  progname_main = "M_" + self.PROG_NAMES_MAIN[0]
284  self.INCLUDE_SUB_PROGRAMS = True # Force generation of main program
285  self.ProgStart(progname_main)
286  for prog_call in self.PROG_NAMES_MAIN:
287  self.RunCode(prog_call, True)
288 
289  self.ProgFinish(progname_main)
290 
291  # Save the last program added to the PROG_LIST
292  self.PROG = self.PROG_LIST.pop()
293  progname_last = self.PROG_NAMES.pop()
294  self.progsave(folder, progname_last, ask_user, show_result)
295  #-------------------------
296  #self.LOG = ''
297  if len(self.PROG_FILES) == 0:
298  # cancelled by user
299  return
300 
301  first_file = self.PROG_FILES[0]
302  folder_user = getFileDir(first_file)
303  # progname_user = getFileName(self.FILE_SAVED)
304 
305  # Generate each program
306  for i in range(len(self.PROG_LIST)):
307  self.PROG = self.PROG_LIST[i]
308  self.progsave(folder_user, self.PROG_NAMES[i], False, show_result)
309 
310  elif nfiles == 1:
311  self.PROG = self.PROG_NAMES[0]
312  self.progsave(folder, progname, ask_user, show_result)
313 
314  else:
315  print("Warning! Program has not been properly finished")
316  self.progsave(folder, progname, ask_user, show_result)
317 
318  if show_result and len(self.LOG) > 0:
319  mbox('Program generation LOG:\n\n' + self.LOG)
320 
321  def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass):
322  """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".
323  The connection parameters must be provided in the robot connection menu of RoboDK"""
324  UploadFTP(self.PROG_FILES, robot_ip, remote_path, ftp_user, ftp_pass)
325 
326  def MoveJ(self, pose, joints, conf_RLF=None):
327  """Add a joint movement"""
328  self.page_size_control() # Important to control the maximum lines per program and not save last target on new program
329  target_id = self.add_target_joints(joints)
330  self.addline("MOVEP P%i %s%s" % (target_id, self.STR_VJ, self.STR_CNT))
331  self.LAST_POSE = pose
332 
333  def MoveL(self, pose, joints, conf_RLF=None):
334  """Add a linear movement"""
335  #if self.LAST_POSE is not None and pose is not None:
336  # # Skip adding a new movement if the new position is the same as the last one
337  # if distance(pose.Pos(), self.LAST_POSE.Pos()) < 0.1 and pose_angle_between(pose, self.LAST_POSE) < 0.1:
338  # return
339  self.page_size_control() # Important to control the maximum lines per program and not save last target on new program
340 
341  if pose is None:
342  target_id = self.add_target_joints(joints)
343  else:
344  target_id = self.add_target_cartesian(self.POSE_FRAME*pose, joints, conf_RLF)
345 
346  self.addline("MOVL P%i, %s%s" % (target_id, self.STR_V, self.STR_CNT))
347  self.LAST_POSE = pose
348 
349  def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
350  """Add a circular movement"""
351  self.page_size_control() # Important to control the maximum lines per program and not save last target on new program
352 
353  if self.LAST_POSE is not None:
354  target_id0 = self.add_target_cartesian(self.POSE_FRAME*self.LAST_POSE, joints1, conf_RLF_1)
355  self.addline("MOVEC P%i, %s%s" % (target_id0, self.STR_V, self.STR_CNT))
356 
357  target_id1 = self.add_target_cartesian(self.POSE_FRAME*pose1, joints1, conf_RLF_1)
358  target_id2 = self.add_target_cartesian(self.POSE_FRAME*pose2, joints2, conf_RLF_2)
359 
360  self.addline("MOVEC P%i, %s%s" % (target_id1, self.STR_V, self.STR_PL))
361  self.addline("MOVEC P%i, %s%s" % (target_id2, self.STR_V, self.STR_PL))
362 
363  self.LAST_POSE = None
364 
365  def setFrame(self, pose, frame_id, frame_name):
366  """Change the robot reference frame"""
367  xyzwpr = Pose_2_Panasonic(pose)
368  self.POSE_FRAME = pose
369  return
370 
371  if frame_id is None or frame_id < 0:
372  self.RunMessage('Setting Frame %i (%s):' % (self.ACTIVE_FRAME, str(frame_name)), True)
373  self.addline("FRAME %i:%s" % (self.ACTIVE_FRAME, str(frame_name)))
374 
375  else:
376  self.ACTIVE_FRAME = frame_id
377  self.RunMessage('Frame %i (%s) should be close to:' % (self.ACTIVE_FRAME, str(frame_name)), True)
378  self.RunMessage('%.1f,%.1f,%.1f,%.1f,%.1f,%.1f' % (xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]), True)
379 
380  def setTool(self, pose, tool_id, tool_name):
381  """Change the robot TCP"""
382  xyzwpr = Pose_2_Panasonic(pose)
383  if tool_id is None or tool_id < 0:
384  self.RunMessage('Setting Tool %i (%s):' % (self.ACTIVE_TOOL, str(tool_name)), True)
385  self.addline("TOOL %i:%s" % (self.ACTIVE_TOOL, str(tool_name)))
386  else:
387  self.ACTIVE_TOOL = tool_id
388  self.RunMessage('Tool %i (%s) should be close to:' % (self.ACTIVE_TOOL, str(tool_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 Pause(self, time_ms):
392  """Pause the robot program"""
393  if time_ms <= 0:
394  self.addline('STOP')
395  else:
396  self.addline('DELAY %.2fs' % (time_ms*0.001))
397 
398  def setSpeed(self, speed_mms):
399  """Changes the robot speed (in mm/s)"""
400  speed_m_min = speed_mms * 60.0 * 0.001
401  speed = max(0.01,min(speed_m_min,120.0)) # Important! Filter linear speed is in mm/s or cm/min (otherwise the program stops)
402  self.STR_V = "%.2f m/min" % speed
403 
404  def setAcceleration(self, accel_mmss):
405  """Changes the robot acceleration (in mm/s2)"""
406  self.addlog('Set acceleration not defined')
407 
408  def setSpeedJoints(self, speed_degs):
409  """Changes the robot joint speed (in deg/s)"""
410  speedj = max(0.01,min(speed,100.0)) # Joint speed must be in %
411  self.STR_VJ = "%.2f %%" % speedj
412 
413  def setAccelerationJoints(self, accel_degss):
414  """Changes the robot joint acceleration (in deg/s2)"""
415  self.addlog('Set acceleration not defined')
416 
417  def setZoneData(self, zone_mm):
418  """Changes the zone data approach (makes the movement more smooth)"""
419  if zone_mm < 0:
420  self.STR_PL = ''
421  else:
422  self.STR_PL = ' R=%i' % round(zone_mm)
423 
424  def setDO(self, io_var, io_value):
425  """Sets a variable (output) to a given value"""
426  if type(io_var) != str: # set default variable name if io_var is a number
427  io_var = 'o1#%04d' % io_var
428  if type(io_value) != str: # set default variable value if io_value is a number
429  if io_value > 0:
430  io_value = 'ON'
431  else:
432  io_value = 'OFF'
433 
434  # at this point, io_var and io_value must be string values
435  #DOUT OT#(2) ON
436  self.addline('OUT %s = %s' % (io_var, io_value))
437 
438  def waitDI(self, io_var, io_value, timeout_ms=-1):
439  """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided."""
440  if type(io_var) != str: # set default variable name if io_var is a number
441  io_var = 'I1#%04d' % io_var
442  if type(io_value) != str: # set default variable value if io_value is a number
443  if io_value > 0:
444  io_value = 'ON'
445  else:
446  io_value = 'OFF'
447 
448  # at this point, io_var and io_value must be string values
449  if timeout_ms < 0:
450  #WAIT IN#(12)=ON
451  self.addline('WAIT_IP %s=%s' % (io_var, io_value))
452  else:
453  #self.LBL_ID_COUNT = self.LBL_ID_COUNT + 1
454  self.addline('WAIT_IP %s=%s T=%.2f' % (io_var, io_value, timeout_ms*0.001))
455 
456 
457  def RunCode(self, code, is_function_call = False):
458  """Adds code or a function call"""
459  if is_function_call:
460  code = get_safe_name(code)
461  #if code.startswith("ArcStart"):
462  #return
463 
464  # default program call
465  code.replace(' ','_')
466  self.addline('CALL %s' % (code))
467  else:
468  #if code.endswith(';'):
469  #code = code[:-1]
470  self.addline(code)
471 
472  def RunMessage(self, message, iscomment = False):
473  """Add a joint movement"""
474  if iscomment:
475  for i in range(0,len(message), 29):
476  i2 = min(i + 29, len(message))
477  self.addline(";%s" % message[i:i2])
478 
479  else:
480  for i in range(0,len(message), 25):
481  i2 = min(i + 25, len(message))
482  self.addline('MSG "%s"' % message[i:i2])
483 
484 # ------------------ private ----------------------
485  def page_size_control(self):
486  if self.LINE_COUNT >= self.MAX_LINES_X_PROG:
487  self.ProgFinish(self.PROG_NAME, True)
488  self.ProgStart(self.PROG_NAME, True)
489 
490  def addline(self, newline, movetype = ' '):
491  """Add a program line"""
492  if self.nProgs > 1 and not self.INCLUDE_SUB_PROGRAMS:
493  return
494 
495  self.page_size_control()
496  self.LINE_COUNT = self.LINE_COUNT + 1
497  self.PROG.append(newline)
498 
499  def addline_targets(self, newline):
500  """Add a line at the end of the program (used for targets)"""
501  self.PROG_TARGETS.append(newline)
502 
503  def addlog(self, newline):
504  """Add a log message"""
505  if self.nProgs > 1 and not self.INCLUDE_SUB_PROGRAMS:
506  return
507  self.LOG = self.LOG + newline + '\n'
508 
509 # ------------------ targets ----------------------
510 
511  def setCartesian(self, confdata):
512  #self.LAST_CONFDATA = [none/pulses(0)/postype(1), base, tool, config]
513  if self.ACTIVE_FRAME is not None and self.ACTIVE_FRAME != self.LAST_CONFDATA[1]:
514  self.addline_targets("///USER %i" % self.ACTIVE_FRAME)
515  self.LAST_CONFDATA[1] = self.ACTIVE_FRAME
516 
517  if self.ACTIVE_TOOL != self.LAST_CONFDATA[2]:
518  self.addline_targets("///TOOL %i" % self.ACTIVE_TOOL)
519  self.LAST_CONFDATA[2] = self.ACTIVE_TOOL
520 
521  if self.LAST_CONFDATA[0] != 2:
522  if self.ACTIVE_FRAME is not None:
523  self.addline_targets("///POSTYPE USER")
524  else:
525  self.addline_targets("///POSTYPE BASE")
526 
527  self.addline_targets("///RECTAN")
528  self.addline_targets("///RCONF %s" % confdata)
529  self.LAST_CONFDATA[3] = confdata
530 
531 
532  elif self.LAST_CONFDATA[3] != confdata:
533  self.addline_targets("///RCONF %s" % confdata)
534  self.LAST_CONFDATA[3] = confdata
535 
536  self.LAST_CONFDATA[0] = 2
537 
538  def setPulses(self):
539  #self.LAST_CONFDATA = [none/pulses(0)/postype(1), base, tool, config]
540  if self.LAST_CONFDATA[0] is None:
541  self.addline_targets("///TOOL %i" % self.ACTIVE_TOOL)
542  self.LAST_CONFDATA[2] = self.ACTIVE_TOOL
543 
544  if self.LAST_CONFDATA[0] != 1:
545  self.addline_targets("///POSTYPE PULSE")
546  self.addline_targets("///PULSE")
547  self.LAST_CONFDATA[0] = 1
548 
549  self.LAST_CONFDATA[0] = 1
550  self.LAST_CONFDATA[1] = None
551  self.LAST_CONFDATA[2] = None
552  self.LAST_CONFDATA[3] = None
553 
554  def add_target_joints(self, joints):
555  if self.nProgs > 1 and not self.INCLUDE_SUB_PROGRAMS:
556  return
557 
558  self.setPulses()
559  self.C_COUNT = self.C_COUNT + 1
560  cid = self.C_COUNT
561 
562 
563  str_pulses=[]
564  for i in range(len(joints)):
565  str_pulses.append('%i' % round(joints[i] * self.PULSES_X_DEG[i]))
566 
567  self.addline_targets('C%05i=' % cid + ','.join(str_pulses))
568  return cid
569 
570  def add_target_cartesian(self, pose, joints, conf_RLF):
571  if self.nProgs > 1 and not self.INCLUDE_SUB_PROGRAMS:
572  return
573 
574  xyzwpr = Pose_2_Panasonic(pose)
575 
576  if conf_RLF is None:
577  conf_RLF = [0,0,0]
578 
579  turns = [0,0,0]
580  if len(joints) >= 6:
581  turnJ4 = (joints[3]+180)//360
582  turnJ6 = (joints[5]+180)//360
583  turnJ1 = (joints[0]+180)//360
584  turns = [turnJ4, turnJ6, turnJ1]
585 
586  confdata = '%i,%i,%i,%i,%i,%i,0,0' % tuple(conf_RLF[:3] + turns[:3])
587  self.setCartesian(confdata)
588  self.C_COUNT = self.C_COUNT + 1
589  cid = self.C_COUNT
590  self.addline_targets('C%05i=' % cid + '%.3f,%.3f,%.3f,%.2f,%.2f,%.2f' % tuple(xyzwpr))
591  return cid
592 
593 # -------------------------------------------------
594 # ------------ For testing purposes ---------------
595 def Pose(xyzrpw):
596  [x,y,z,r,p,w] = xyzrpw
597  a = r*math.pi/180
598  b = p*math.pi/180
599  c = w*math.pi/180
600  ca = math.cos(a)
601  sa = math.sin(a)
602  cb = math.cos(b)
603  sb = math.sin(b)
604  cc = math.cos(c)
605  sc = math.sin(c)
606  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]])
607 
608 def test_post():
609  """Test the post with a basic program"""
610 
611  robot = RobotPost('Motomantest', 'Motoman robot', 6)
612 
613  robot.ProgStart("Program")
614  robot.RunMessage("Program generated by RoboDK", True)
615  robot.setFrame(Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]), None, 0)
616  robot.setTool(Pose([62.5, -108.253175, 100, -60, 90, 0]), None, 0)
617  robot.MoveJ(Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
618  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
619  robot.MoveL(Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
620  robot.RunMessage("Setting air valve 1 on")
621  robot.RunCode("TCP_On", True)
622  robot.Pause(1000)
623  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
624  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
625  robot.MoveL(Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
626  robot.RunMessage("Setting air valve off")
627  robot.RunCode("TCP_Off", True)
628  robot.Pause(1000)
629  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
630  robot.MoveL(Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
631  robot.MoveL(Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
632  robot.ProgFinish("Program")
633  # robot.ProgSave(".","Program",True)
634 
635  robot.PROG = robot.PROG_LIST.pop()
636  for line in robot.PROG:
637  print(line)
638 
639  if len(robot.LOG) > 0:
640  mbox('Program generation LOG:\n\n' + robot.LOG)
641 
642  input("Press Enter to close...")
643 
644 if __name__ == "__main__":
645  """Function to call when the module is executed by itself: test"""
646  test_post()
def waitDI(self, io_var, io_value, timeout_ms=-1)
Definition: Panasonic.py:438
def add_target_cartesian(self, pose, joints, conf_RLF)
Definition: Panasonic.py:570
def ProgStart(self, progname, new_page=False)
Definition: Panasonic.py:153
def MoveJ(self, pose, joints, conf_RLF=None)
Definition: Panasonic.py:326
def setFrame(self, pose, frame_id, frame_name)
Definition: Panasonic.py:365
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: Panasonic.py:321
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
Definition: Panasonic.py:349
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: robodk.py:1312
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
Definition: Panasonic.py:129
def RunMessage(self, message, iscomment=False)
Definition: Panasonic.py:472
def get_safe_name(progname, max_chars=7)
Definition: Panasonic.py:44
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
Definition: robodk.py:1458
def MoveL(self, pose, joints, conf_RLF=None)
Definition: Panasonic.py:333
def progsave(self, folder, progname, ask_user=False, show_result=False)
Definition: Panasonic.py:229
def ProgFinish(self, progname, new_page=False)
Definition: Panasonic.py:180
def RunCode(self, code, is_function_call=False)
Definition: Panasonic.py:457
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
Definition: Panasonic.py:269
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
Definition: robodk.py:1354
def setTool(self, pose, tool_id, tool_name)
Definition: Panasonic.py:380
def addline(self, newline, movetype=' ')
Definition: Panasonic.py:490


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