KUKA_IIWA.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 IIWA robot (7 axis) 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 = '''package application;
50 
51 import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication;
52 import static com.kuka.roboticsAPI.motionModel.BasicMotions.*;
53 
54 import com.kuka.roboticsAPI.deviceModel.LBR;
55 import com.kuka.roboticsAPI.deviceModel.LBRE1Redundancy;
56 import com.kuka.roboticsAPI.geometricModel.Frame;
57 import com.kuka.roboticsAPI.geometricModel.Tool;
58 import com.kuka.roboticsAPI.geometricModel.math.Transformation;
59 
60 import com.kuka.roboticsAPI.motionModel.LIN;
61 import com.kuka.roboticsAPI.motionModel.PTP;
62 import com.kuka.roboticsAPI.motionModel.Spline;
63 import com.kuka.roboticsAPI.uiModel.ApplicationDialogType;
64 
65 public class %s extends RoboticsAPIApplication {
66 \tprivate LBR robot;
67 \tprivate Tool TOOL;
68 \t// private Frame FRAME;
69 \t
70 \tpublic void initialize() {
71 \t\trobot = getContext().getDeviceFromType(LBR.class);
72 \t}
73 \tpublic void run() {
74 \t\tSpline move_curve;
75 '''
76 
77 # ----------------------------------------------------
78 def pose_2_str(pose, rot_in_deg = False):
79  """Converts a pose target to a string"""
80  torad = pi/180.0
81  if rot_in_deg:
82  torad = 1.0
83  #[x,y,z,w,p,r] = Pose_2_KUKA(pose)
84  [x,y,z,r,p,w] = pose_2_xyzrpw(pose)
85  return ('%.3f,%.3f,%.3f,%.5f,%.5f,%.5f' % (x,y,z,w*torad,p*torad,r*torad))
86 
87 def pose_2_str_ext(pose,joints):
88  njoints = len(joints)
89  if njoints <= 7:
90  return pose_2_str(pose)
91  else:
92  extaxes = ''
93  for i in range(njoints-7):
94  extaxes = extaxes + (',%.5f' % (i+1, joints[i+7]))
95  return pose_2_str(pose) + extaxes
96 
97 def angles_2_str(angles):
98  """Prints a joint target"""
99  str = ''
100  for i in range(len(angles)):
101  str = str + ('%.5f,' % (angles[i]*pi/180.0))
102  str = str[:-1]
103  return str
104 
105 # ----------------------------------------------------
106 # Object class that handles the robot instructions/syntax
107 class RobotPost(object):
108  """Robot post object"""
109  PROG_EXT = 'java' # set the program extension
110 
111  # other variables
112  ROBOT_POST = ''
113  ROBOT_NAME = ''
114  PROG_FILES = []
115 
116  PROG = ''
117  LOG = ''
118  nAxes = 7
119  MOVE_OBJECT = 'robot'
120  REF_FRAME = eye(4)
121  TARGET_PTP_id = 0
122  TARGET_LIN_id = 0
123  BLENDING_MM = 0
124  SPEED_MMS = 300
125  SPEED_RADS = 0.250
126  ACCEL_MMSS = 500
127  TAB = '\t\t'
128  MAIN_DONE = False
129  SPLINE = ''
130  SPLINE_COUNT = 0
131  SPLINE_LAST_FRAME = ''
132 
133 
134 
135  def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
136  self.ROBOT_POST = robotpost
137  self.ROBOT_NAME = robotname
138  #self.PROG = HEADER
139  self.LOG = ''
140  self.nAxes = robot_axes
141 
142  def ProgStart(self, progname):
143  if self.MAIN_DONE:
144  self.addline('public void %s() {' % progname.replace(' ','_'))
145  self.TAB = '\t\t'
146  else:
147  self.MAIN_DONE = True
148 
149  def ProgFinish(self, progname):
150  self.spline_flush()
151  self.TAB = '\t'
152  self.addline('}')
153 
154  def ProgSave(self, folder, progname, ask_user = False, show_result = False):
155  self.TAB = ''
156  self.addline('}')
157  progname_base = getFileName(progname)
158  progname = progname + '.' + self.PROG_EXT
159  if ask_user or not DirExists(folder):
160  filesave = getSaveFile(folder, progname, 'Save program as...')
161  if filesave is not None:
162  filesave = filesave.name
163  progname_base = getFileName(filesave)
164  else:
165  return
166  else:
167  filesave = folder + '/' + progname
168  fid = open(filesave, "w")
169  fid.write(HEADER % progname_base)
170  fid.write(self.PROG)
171  fid.close()
172  print('SAVED: %s\n' % filesave) # tell RoboDK the path of the saved file
173  self.PROG_FILES = filesave
174 
175  # open file with default application
176  if show_result:
177  if type(show_result) is str:
178  # Open file with provided application
179  import subprocess
180  p = subprocess.Popen([show_result, filesave])
181  elif type(show_result) is list:
182  import subprocess
183  p = subprocess.Popen(show_result + [filesave])
184  else:
185  # open file with default application
186  import os
187 
188  os.startfile(filesave)
189  if len(self.LOG) > 0:
190  mbox('Program generation LOG:\n\n' + self.LOG)
191 
192  def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass):
193  """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".
194  The connection parameters must be provided in the robot connection menu of RoboDK"""
195  UploadFTP(self.PROG_FILES, robot_ip, remote_path, ftp_user, ftp_pass)
196 
197  def MoveJ(self, pose, joints, conf_RLF=None):
198  """Add a joint movement"""
199  self.spline_flush()
200  #poseabs = self.REF_FRAME*pose
201  self.TARGET_PTP_id = self.TARGET_PTP_id + 1
202  targetname = ('MovePTP_%i' % self.TARGET_PTP_id)
203  self.addline('')
204  #self.addline('getLogger().info("Move ptp to %s");' % targetname)
205  #self.addline('robot.move(ptp(%s).setCartVelocity(%.2f).setBlendingCart(%.2f));' % (angles_2_str(joints), self.SPEED_MMS, self.BLENDING_MM))
206  self.addline('PTP %s = ptp(%s);' % (targetname, angles_2_str(joints)))
207  self.addline('%s.move(%s);' % (self.MOVE_OBJECT, targetname))
208 
209  def MoveL(self, pose, joints, conf_RLF=None):
210  """Add a linear movement"""
211  self.TARGET_LIN_id = self.TARGET_LIN_id + 1
212  targetname = ('TargetLIN_%i' % self.TARGET_LIN_id)
213  framename = ('FrameLIN_%i' % self.TARGET_LIN_id)
214  #self.addline('')
215  #self.addline('getLogger().info("Move linear to %s");' % targetname)
216  #self.addline('robot.move(lin(new Frame(%s)).setCartVelocity(%.2f).setBlendingCart(%.2f));' % (pose_2_str(poseabs), self.SPEED_MMS, self.BLENDING_MM))
217  if pose is not None:
218  poseabs = self.REF_FRAME*pose
219  self.addline('Frame %s = new Frame(%s);' % (framename, pose_2_str(poseabs)))
220  #self.addline('// LIN %s = lin(%s);' % (targetname, framename))
221  #self.addline('robot.move(%s);' % targetname)
222  self.spline_addbuffer(framename)
223  else:
224  # move linear by joints
225  self.spline_flush()
226  self.addline('LIN %s = lin(%s);' % (targetname, angles_2_str(joints)))
227  self.addline('%s.move(%s);' % (self.MOVE_OBJECT, targetname))
228 
229 
230 
231  def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
232  """Add a circular movement"""
233  self.spline_flush()
234  pose1abs = self.REF_FRAME*pose1
235  pose2abs = self.REF_FRAME*pose2
237  framename1 = ('FrameCIRC_%i' % self.TARGET_CIRC_id)
238  self.TARGET_CIRC_id = self.TARGET_CIRC_id + 1
239  framename2 = ('FrameCIRC_%i' % self.TARGET_CIRC_id)
240  self.addline('')
241  self.addline('getLogger().info("Move circular to %s and %s");' % (framename1, framename2))
242  self.addline('Frame %s = new Frame(%s);' % (framename1, pose_2_str(pose1abs)))
243  self.addline('Frame %s = new Frame(%s);' % (framename2, pose_2_str(pose2abs)))
244  self.addline('%s.move(circ(%s, %s).setCartVelocity(%.2f).setBlendingCart(%.2f));' % (self.MOVE_OBJECT, framename1, framename2, self.SPEED_MMS, self.BLENDING_MM))
245 
246  def setFrame(self, pose, frame_id=None, frame_name=None):
247  """Change the robot reference frame"""
248  if frame_name is None:
249  frame_name = "Reference"
250  self.REF_FRAME = pose
251  self.spline_flush()
252  # self.REF_FRAME = pose
253  self.addline('// Using Reference Frame: %s' % frame_name)
254  self.addline('// robot.addDefaultMotionFrame("%s", Transformation.ofDeg(%s);' % (frame_name,pose_2_str(pose, True)))
255 
256  def setTool(self, pose, tool_id=None, tool_name=None):
257  """Change the robot TCP"""
258  if tool_name is None:
259  tool_name = "Tool"
260  self.spline_flush()
261  self.addline('// Using TCP: %s' % tool_name)
262  self.addline('TOOL = new Tool("%s");' % tool_name)
263  self.addline('TOOL.attachTo(robot.getFlange(), Transformation.ofDeg(%s));' % pose_2_str(pose, True))
264  self.MOVE_OBJECT = 'TOOL'
265 
266 
267  def Pause(self, time_ms):
268  """Pause the robot program"""
269  self.spline_flush()
270  if time_ms < 0:
271  self.addline('if (getApplicationUI().displayModalDialog(ApplicationDialogType.QUESTION, "Program paused. Select Cancel to stop the program.", "OK", "Cancel") == 1)')
272  self.addline('{')
273  self.addline('\treturn;')
274  self.addline('}')
275  elif time_ms > 0:
276  self.addline('Thread.sleep(%.3f);' % (time_ms))
277 
278  def setSpeed(self, speed_mms):
279  """Changes the robot speed (in mm/s)"""
280  self.spline_flush()
281  self.SPEED_MMS = speed_mms
282  self.addline('// Linear speed set to %.3f mm/s' % self.SPEED_MMS)
283 
284  def setAcceleration(self, accel_mmss):
285  """Changes the current robot acceleration"""
286  self.addline('// Warning: set linear acceleration to %.3f mm/ss has no effect' % accel_mmss)
287  self.ACCEL_MMSS = accel_mmss
288 
289  def setSpeedJoints(self, speed_degs):
290  """Changes the robot joint speed (in deg/s)"""
291  self.SPEED_RADS = speed_degs*pi()/180.0
292  self.addline('// Joint speed set to %.3f rad/s' % self.SPEED_RADS)
293 
294  def setAccelerationJoints(self, accel_degss):
295  """Changes the robot joint acceleration (in deg/s2)"""
296  self.addline('// Warning: set angular acceleration to %.3f deg/s has no effect' % accel_degss)
297 
298  def setZoneData(self, zone_mm):
299  """Changes the zone data approach (makes the movement more smooth)"""
300  if zone_mm < 0:
301  zone_mm = 0
302  self.BLENDING_MM = zone_mm
303  self.addline('// smoothing/blending set to %.1f mm' % zone_mm)
304  #self.addline('IMotion.setBlendingCart(%.1f); ' % zone_mm)
305 
306  def setDO(self, io_var, io_value):
307  """Sets a variable (output) to a given value"""
308  if type(io_var) != str: # set default variable name if io_var is a number
309  io_var = 'OUT[%s]' % str(io_var)
310  if type(io_value) != str: # set default variable value if io_value is a number
311  if io_value > 0:
312  io_value = 'TRUE'
313  else:
314  io_value = 'FALSE'
315 
316  # at this point, io_var and io_value must be string values
317  self.addline('%s=%s' % (io_var, io_value))
318 
319  def waitDI(self, io_var, io_value, timeout_ms=-1):
320  """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided."""
321  if type(io_var) != str: # set default variable name if io_var is a number
322  io_var = 'IN[%s]' % str(io_var)
323  if type(io_value) != str: # set default variable value if io_value is a number
324  if io_value > 0:
325  io_value = 'TRUE'
326  else:
327  io_value = 'FALSE'
328 
329  # at this point, io_var and io_value must be string values
330  if timeout_ms < 0:
331  self.addline('WAIT FOR %s==%s' % (io_var, io_value))
332  else:
333  self.addline('WAIT FOR %s==%s TIMEOUT=%.1f' % (io_var, io_value, timeout_ms))
334 
335  def RunCode(self, code, is_function_call = False):
336  """Adds code or a function call"""
337  self.spline_flush()
338  if is_function_call:
339  code.replace(' ','_')
340  #self.addline(code + '();')
341  self.addline(code + ';')
342  else:
343  self.addline(code)
344 
345  def RunMessage(self, message, iscomment = False):
346  """Add a joint movement"""
347  self.spline_flush()
348  self.addline('')
349  if iscomment:
350  self.addline('// ' + message)
351  else:
352  self.addline('getLogger().info("%s");' % message)
353 
354 # ------------------ private ----------------------
355  def addline(self, newline):
356  """Add a program line"""
357  self.PROG = self.PROG + self.TAB + newline + '\n'
358 
359  def spline_addbuffer(self, frame):
360  self.SPLINE = self.SPLINE + ('spl(%s),' % frame)
361  self.SPLINE_COUNT = self.SPLINE_COUNT + 1
362  self.SPLINE_LAST_FRAME = frame
363 
364  def spline_flush(self):
365  if self.SPLINE_COUNT == 1:
366  self.addline('%s.move(lin(%s));' % (self.MOVE_OBJECT, self.SPLINE_LAST_FRAME))
367  elif self.SPLINE_COUNT > 1:
368  self.PROG = self.PROG + self.TAB + 'move_curve = new Spline(' + self.SPLINE[:-1] + ');\n'
369  self.PROG = self.PROG + self.TAB + ('%s.move(move_curve);\n' % self.MOVE_OBJECT)
370 
371  self.SPLINE = ''
372  self.SPLINE_COUNT = 0
373  self.SPLINE_LAST_FRAME = ''
374 
375  def addlog(self, newline):
376  """Add a log message"""
377  self.LOG = self.LOG + newline + '\n'
378 
379 # -------------------------------------------------
380 # ------------ For testing purposes ---------------
381 def Pose(xyzrpw):
382  [x,y,z,r,p,w] = xyzrpw
383  a = r*math.pi/180
384  b = p*math.pi/180
385  c = w*math.pi/180
386  ca = math.cos(a)
387  sa = math.sin(a)
388  cb = math.cos(b)
389  sb = math.sin(b)
390  cc = math.cos(c)
391  sc = math.sin(c)
392  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]])
393 
394 def test_post():
395  """Test the post with a basic program"""
396 
397  robot = RobotPost('Kuka_custom', 'Generic Kuka')
398 
399  robot.ProgStart("Program")
400  robot.RunMessage("Program generated by RoboDK", True)
401  robot.setFrame(Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]))
402  robot.setDO(123,1)
403  robot.waitDI(125,1,1000)
404  robot.waitDI(126,1)
405  robot.setTool(Pose([62.5, -108.253175, 100, -60, 90, 0]))
406  robot.MoveJ(Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
407  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
408  robot.MoveL(Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
409  robot.RunMessage("Setting air valve 1 on")
410  robot.RunCode("TCP_On", True)
411  robot.Pause(1000)
412  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
413  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
414  robot.MoveL(Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
415  robot.RunMessage("Setting air valve off")
416  robot.RunCode("TCP_Off", True)
417  robot.Pause(1000)
418  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
419  robot.MoveL(Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
420  robot.MoveL(Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
421  robot.ProgFinish("Program")
422  # robot.ProgSave(".","Program",True)
423  print(robot.PROG)
424  if len(robot.LOG) > 0:
425  mbox('Program generation LOG:\n\n' + robot.LOG)
426 
427  input("Press Enter to close...")
428 
429 if __name__ == "__main__":
430  """Function to call when the module is executed by itself: test"""
431  test_post()
def pose_2_str(pose, rot_in_deg=False)
Definition: KUKA_IIWA.py:78
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
Definition: KUKA_IIWA.py:135
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: robodk.py:1312
def setTool(self, pose, tool_id=None, tool_name=None)
Definition: KUKA_IIWA.py:256
def RunMessage(self, message, iscomment=False)
Definition: KUKA_IIWA.py:345
def RunCode(self, code, is_function_call=False)
Definition: KUKA_IIWA.py:335
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
Definition: KUKA_IIWA.py:231
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
Definition: robodk.py:1458
def waitDI(self, io_var, io_value, timeout_ms=-1)
Definition: KUKA_IIWA.py:319
def MoveJ(self, pose, joints, conf_RLF=None)
Definition: KUKA_IIWA.py:197
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
Definition: KUKA_IIWA.py:154
def setFrame(self, pose, frame_id=None, frame_name=None)
Definition: KUKA_IIWA.py:246
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: KUKA_IIWA.py:192
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
Definition: robodk.py:1354
def MoveL(self, pose, joints, conf_RLF=None)
Definition: KUKA_IIWA.py:209


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