KUKA_KRC2_CamRob.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 Kuka robot with RoboDK
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 # ----------------------------------------------------
45 # Import RoboDK tools
46 from robodk import *
47 
48 
49 HEADER = '''
50 ;FOLD INI
51 BAS (#INITMOV,0 )
52 ;ENDFOLD (INI)
53 
54 ;FOLD STARTPOS
55 $BWDSTART = FALSE
56 PDAT_ACT = PDEFAULT
57 BAS(#PTP_DAT)
58 FDAT_ACT = {TOOL_NO 0,BASE_NO 0,IPO_FRAME #BASE}
59 BAS(#FRAMES)
60 ;ENDFOLD
61 
62 ;FOLD SET DEFAULT SPEED
63 $VEL.CP=0.2
64 BAS(#VEL_PTP,100)
65 BAS(#TOOL,0)
66 BAS(#BASE,0)
67 ;ENDFOLD
68 
69 PTP $AXIS_ACT ; skip BCO quickly
70 '''
71 
72 # ----------------------------------------------------
73 def pose_2_str(pose):
74  """Converts a pose target to a string"""
75  #[x,y,z,w,p,r] = Pose_2_KUKA(pose)
76  #return ('X %.3f, Y %.3f, Z %.3f, A %.3f, B %.3f, C %.3f' % (x,y,z,r,p,w)) # old version had to be switched
77  [x,y,z,r,p,w] = pose_2_xyzrpw(pose)
78  return ('X %.3f,Y %.3f,Z %.3f,A %.3f,B %.3f,C %.3f' % (x,y,z,w,p,r))
79 
80 def pose_2_str_ext(pose,joints):
81  njoints = len(joints)
82  if njoints <= 6:
83  return pose_2_str(pose)
84  else:
85  extaxes = ''
86  for i in range(njoints-6):
87  extaxes = extaxes + (',E%i %.5f' % (i+1, joints[i+6]))
88  return pose_2_str(pose) + extaxes
89 
90 def angles_2_str(angles):
91  """Prints a joint target"""
92  str = ''
93  data = ['A1','A2','A3','A4','A5','A6','E1','E2','E3','E4','E5','E6']
94  for i in range(len(angles)):
95  str = str + ('%s %.5f,' % (data[i], angles[i]))
96  str = str[:-1]
97  return str
98 
99 # ----------------------------------------------------
100 # Object class that handles the robot instructions/syntax
101 class RobotPost(object):
102  """Robot post object"""
103  PROG_EXT = 'src' # set the program extension
104 
105  # other variables
106  ROBOT_POST = ''
107  ROBOT_NAME = ''
108  PROG_FILES = []
109 
110  PROG = ''
111  PROG_CSV = []
112  LOG = ''
113  nAxes = 6
114  E01 = 0
115  nProgs = 0
116  nLineCSV = 0
117  ProgCSV = -1
118  SPEED_MMS = 150
119  SPEED_MMS_MAX = 2000
120  ACCEL_MMSS = 2000
121  TOOL_ID = 0
122  FRAME_ID = 0
123  LAST_POSE_CSV = None
124  PROG_NAME_CSV = None
125 
126  #APO_VALUE = 1
127  C_DIS = ''#' C_DIS'
128  C_PTP = ''#' C_PTP'
129 
130 
131  def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
132  self.ROBOT_POST = robotpost
133  self.ROBOT_NAME = robotname
134  self.PROG = ''
135  self.LOG = ''
136  self.nAxes = robot_axes
137 
138  def ProgStart(self, progname):
139  self.nProgs = self.nProgs + 1
140  self.PROG_NAME_CSV = progname
141  self.addline('DEF %s ( )' % progname)
142  self.PROG = self.PROG + HEADER
143  self.addline('$ACC.CP = %.5f' % (self.ACCEL_MMSS/1000.0))
144 
145  def ProgFinish(self, progname):
146  self.addline('END')
147 
148  def ProgSave(self, folder, progname, ask_user = False, show_result = False):
149  progname = progname + '.' + self.PROG_EXT
150  progname_csv = self.PROG_NAME_CSV + '.csv'
151  if ask_user or not DirExists(folder):
152  filesave = getSaveFile(folder, progname, 'Save program as...')
153  if filesave is not None:
154  filesave = filesave.name
155  filesave_csv = getFileDir(filesave) + '/' + progname_csv
156  else:
157  return
158  else:
159  filesave = folder + '/' + progname
160  filesave_csv = folder + '/' + progname_csv
161  fid = open(filesave, "w")
162  fid.write(self.PROG)
163  fid.close()
164  fidcsv = open(filesave_csv, "w")
165  for line in self.PROG_CSV:
166  fidcsv.write(line)
167  fidcsv.write('\n')
168  fidcsv.close()
169 
170  print('SAVED: %s\n' % filesave) # tell RoboDK the path of the saved file
171  self.PROG_FILES = filesave
172 
173  # open file with default application
174  if show_result:
175  if type(show_result) is str:
176  # Open file with provided application
177  import subprocess
178  p = subprocess.Popen([show_result, filesave, filesave_csv])
179  elif type(show_result) is list:
180  import subprocess
181  p = subprocess.Popen(show_result + [filesave])
182  else:
183  # open file with default application
184  import os
185 
186  os.startfile(filesave)
187  if len(self.LOG) > 0:
188  mbox('Program generation LOG:\n\n' + self.LOG)
189 
190  def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass):
191  """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".
192  The connection parameters must be provided in the robot connection menu of RoboDK"""
193  UploadFTP(self.PROG_FILES, robot_ip, remote_path, ftp_user, ftp_pass)
194 
195  def MoveJ(self, pose, joints, conf_RLF=None):
196  """Add a joint movement"""
197  self.addline('PTP {' + angles_2_str(joints) + '}' + self.C_PTP)
198 
199  def MoveL(self, pose, joints, conf_RLF=None):
200  """Add a linear movement"""
201  if self.nAxes > 6:
202  self.E01 = joints[6]
203 
204  if self.ProgCSV == self.nProgs:
205  self.addline_csv(pose)
206  elif self.ProgCSV < 0:
207  self.ProgCSV = self.nProgs
208  self.addline('CR_PROCESS_FILE("%s.csv", 1, -1, "OK" )' % (self.PROG_NAME_CSV));
209  self.addline_csv(pose)
210  else:
211  self.addline('LIN {' + pose_2_str_ext(pose,joints) + '}' + self.C_DIS)
212 
213  def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
214  """Add a circular movement"""
215  if self.ProgCSV < 0:
216  self.addline('CIRC {' + pose_2_str_ext(pose1,joints1) + '},{' + pose_2_str_ext(pose2,joints2) + '}' + self.C_DIS)
217  else:
218  self.addlog('Warning: Can not move circular inside a CSV file')
219 
220 
221  def setFrame(self, pose, frame_id=None, frame_name=None):
222  """Change the robot reference frame"""
223  if frame_id is not None and frame_id >= 0:
224  self.FRAME_ID = frame_id
225  if self.ProgCSV < 0:
226  self.addline('$BASE = {FRAME: ' + pose_2_str(pose) + '}')
227  else:
228  self.addlog('Warning: Can not set the reference frame inside CSV file')
229 
230  def setTool(self, pose, tool_id, tool_name):
231  """Change the robot TCP"""
232  if tool_id is not None and tool_id >= 0:
233  self.TOOL_ID = tool_id
234 
235  if self.ProgCSV < 0:
236  self.addline('$TOOL = {FRAME: ' + pose_2_str(pose) + '}')
237  else:
238  self.addlog('Warning: Can not set the tool frame inside CSV file')
239 
240  def Pause(self, time_ms):
241  """Pause the robot program"""
242  if self.ProgCSV < 0:
243  if time_ms <= 0:
244  self.addline('HALT')
245  else:
246  self.addline('WAIT SEC %.3f' % (time_ms*0.001))
247  else:
248  self.addlog('Warning: Can not pause inside CSV file')
249 
250  def setSpeed(self, speed_mms):
251  """Changes the robot speed (in mm/s)"""
252  self.SPEED_MMS = speed_mms
253  if self.ProgCSV < 0:
254  self.addline('$VEL.CP = %.5f' % (speed_mms/1000.0))
255 
256  def setAcceleration(self, accel_mmss):
257  """Changes the current robot acceleration"""
258  if self.ProgCSV < 0:
259  self.ACCEL_MMSS = accel_mmss
260  self.addline('$ACC.CP = %.5f' % (accel_mmss/1000.0))
261  else:
262  self.addlog('Warning: Can not set acceleration inside CSV file')
263 
264  def setSpeedJoints(self, speed_degs):
265  """Changes the robot joint speed (in deg/s)"""
266  if self.ProgCSV < 0:
267  self.ACCEL_MMSS = accel_mmss
268  self.addline('$VEL.ORI1 = %.5f' % speed_degs)
269  self.addline('$VEL.ORI2 = %.5f' % speed_degs)
270  else:
271  self.addlog('Warning: Can not set joint speed inside CSV file')
272 
273  def setAccelerationJoints(self, accel_degss):
274  """Changes the robot joint acceleration (in deg/s2)"""
275  if self.ProgCSV < 0:
276  self.ACCEL_MMSS = accel_mmss
277  self.addline('$ACC.ORI1 = %.5f' % accel_degss)
278  self.addline('$ACC.ORI2 = %.5f' % accel_degss)
279  else:
280  self.addlog('Warning: Can not set joint acceleration inside CSV file')
281 
282 
283  def setZoneData(self, zone_mm):
284  """Changes the zone data approach (makes the movement more smooth)"""
285  self.APO_VALUE = zone_mm
286  if zone_mm >= 0:
287  self.addline('$APO.CPTP = %.3f' % zone_mm)
288  self.addline('$APO.CDIS = %.3f' % zone_mm)
289  self.C_DIS = ' C_DIS'
290  self.C_PTP = ' C_PTP'
291  else:
292  self.C_DIS = ''
293  self.C_PTP = ''
294 
295  def setDO(self, io_var, io_value):
296  """Sets a variable (output) to a given value"""
297  if type(io_var) != str: # set default variable name if io_var is a number
298  io_var = '$OUT[%s]' % str(io_var)
299  if type(io_value) != str: # set default variable value if io_value is a number
300  if io_value > 0:
301  io_value = 'TRUE'
302  else:
303  io_value = 'FALSE'
304 
305  # at this point, io_var and io_value must be string values
306  self.addline('%s=%s' % (io_var, io_value))
307 
308  def waitDI(self, io_var, io_value, timeout_ms=-1):
309  """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided."""
310  if type(io_var) != str: # set default variable name if io_var is a number
311  io_var = '$IN[%s]' % str(io_var)
312  if type(io_value) != str: # set default variable value if io_value is a number
313  if io_value > 0:
314  io_value = 'TRUE'
315  else:
316  io_value = 'FALSE'
317 
318  # at this point, io_var and io_value must be string values
319  if timeout_ms < 0:
320  self.addline('WAIT FOR (%s==%s)' % (io_var, io_value))
321  else:
322  self.addline('START_TIMER:')
323  self.addline('$TIMER_STOP[1]=TRUE')
324  self.addline('$TIMER_FLAG[1]=FALSE')
325  self.addline('$TIMER[1]=%.3f' % (float(timeout_ms)*0.001))
326  self.addline('$TIMER_STOP[1]=FALSE')
327  self.addline('WAIT FOR (%s==%s OR $TIMER_FLAG[1])' % (io_var, io_value))
328  self.addline('$TIMER_STOP[1]=TRUE')
329  self.addline('IF $TIMER_FLAG[1]== TRUE THEN')
330  self.addline(' HALT ; Timed out!')
331  self.addline(' GOTO START_TIMER')
332  self.addline('ENDIF')
333 
334  def RunCode(self, code, is_function_call = False):
335  """Adds code or a function call"""
336  if self.ProgCSV < 0:
337  if is_function_call:
338  code = code.replace(' ','_')
339  if not code.endswith(')'):
340  code = code + '()'
341  self.addline(code)
342  else:
343  self.addline(code)
344  #else:
345  # self.addlog('Warning: Can not run program inside CSV file')
346 
347 
348  def RunMessage(self, message, iscomment = False):
349  """Add a joint movement"""
350  if iscomment:
351  self.addline('; ' + message)
352  else:
353  pass
354  #self.addline('Wait for StrClear($LOOP_MSG[])')
355  #self.addline('$LOOP_CONT = TRUE')
356  #self.addline('$LOOP_MSG[] = "%s"' % message)
357 
358 # ------------------ private ----------------------
359  def addline_csv(self, pose_csv):
360  self.nLineCSV = self.nLineCSV + 1
361  [x,y,z,r,p,w] = pose_2_xyzrpw(pose_csv)
362  speed_time_desired = self.SPEED_MMS
363  newline = '%i;%.4f;%.4f;%.4f;%.4f;%.4f;%.4f;%i;%.3f;1;0;0;0;%i;%.4f' % (self.nLineCSV, x,y,z,r,p,w, self.nLineCSV, speed_time_desired, self.TOOL_ID, self.E01)
364  self.PROG_CSV.append(newline)
365 
366 #1 Order of targets
367 #2,3,4,5,6,7: X,Y,Z,A,B,C-axis movements (coordinates relative to the workspace frame)
368 #8 User Parameter[1], Order of CNC line (same as column 1 if no other subprograms are running)
369 #9 User Parameter[2], Feed rate in mm/sec
370 #10 User Parameter[3], Spindle State (Boolean)
371 #11 User Parameter[4], Spindle Speed (rpm)
372 #12 User Parameter[5], Spindle Rotation (CLW=0/CCLW=1)
373 #13 User Parameter[6], Coolant (This should always be 0, we don't use coolants)
374 #14 User Parameter[7], Tool Number.
375 #15 User Parameter[8], E01 movement
376 
377  def addline(self, newline):
378  """Add a program line"""
379  self.PROG = self.PROG + newline + '\n'
380 
381  def addlog(self, newline):
382  """Add a log message"""
383  self.LOG = self.LOG + newline + '\n'
384 
385 # -------------------------------------------------
386 # ------------ For testing purposes ---------------
387 def Pose(xyzrpw):
388  [x,y,z,r,p,w] = xyzrpw
389  a = r*math.pi/180
390  b = p*math.pi/180
391  c = w*math.pi/180
392  ca = math.cos(a)
393  sa = math.sin(a)
394  cb = math.cos(b)
395  sb = math.sin(b)
396  cc = math.cos(c)
397  sc = math.sin(c)
398  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]])
399 
400 def test_post():
401  """Test the post with a basic program"""
402 
403  robot = RobotPost('Kuka_custom', 'Generic Kuka')
404 
405  robot.ProgStart("Program")
406  robot.RunMessage("Program generated by RoboDK", True)
407  robot.setFrame(Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]))
408  robot.setTool(Pose([62.5, -108.253175, 100, -60, 90, 0]))
409  robot.MoveJ(Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
410  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
411  robot.MoveL(Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
412  robot.RunMessage("Setting air valve 1 on")
413  robot.RunCode("TCP_On", True)
414  robot.Pause(1000)
415  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
416  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
417  robot.MoveL(Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
418  robot.RunMessage("Setting air valve off")
419  robot.RunCode("TCP_Off", True)
420  robot.Pause(1000)
421  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
422  robot.MoveL(Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
423  robot.MoveL(Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
424  robot.ProgFinish("Program")
425  # robot.ProgSave(".","Program",True)
426  print(robot.PROG)
427  print(robot.PROG_CSV)
428  if len(robot.LOG) > 0:
429  mbox('Program generation LOG:\n\n' + robot.LOG)
430 
431  input("Press Enter to close...")
432 
433 if __name__ == "__main__":
434  """Function to call when the module is executed by itself: test"""
435  test_post()
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
def waitDI(self, io_var, io_value, timeout_ms=-1)
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: robodk.py:1312
def setFrame(self, pose, frame_id=None, frame_name=None)
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
Definition: robodk.py:1458
def RunCode(self, code, is_function_call=False)
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
Definition: robodk.py:1354


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