KAIRO.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 KEBA's KAIRO controllers using 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 def pose_2_str(pose):
50  """Prints a pose target"""
51  [x,y,z,r,p,w] = Pose_2_KUKA(pose)
52  return ('%.3f, %.3f, %.3f, %.3f, %.3f, %.3f, 1' % (x,y,z,r,p,w))
53 
54 def angles_2_str(angles):
55  """Prints a joint target"""
56  str = ''
57  data = ['a1','a2','a3','a4','a5','a6','e1','e2','e3','e4','e5','e6']
58  for i in range(len(angles)):
59  str = str + ('%s := %.6f, ' % (data[i], angles[i]))
60  str = str[:-2]
61  return str
62 
63 # ----------------------------------------------------
64 # Object class that handles the robot instructions/syntax
65 class RobotPost(object):
66  """Robot post object"""
67  PROG_EXT = 'tip' # set the program extension
68  PROG_EXT_VAR = 'tid'
69  count_var_ptp = 0
70  count_var_lin = 0
71 
72  # other variables
73  ROBOT_POST = ''
74  ROBOT_NAME = ''
75  PROG_FILES = []
76 
77  PROG = ''
78  LOG = ''
79  nAxes = 6
80 
81 
82  def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
83  self.ROBOT_POST = robotpost
84  self.ROBOT_NAME = robotname
85  self.PROG = ''
86  self.PROG_VAR = ''
87  self.LOG = ''
88  self.nAxes = robot_axes
89 
90  def ProgStart(self, progname):
91  self.addline('//KEBA')
92  self.addline('//0.0HZ')
93  self.addline('//100.0%')
94  self.addline_var('EROP_OL : OVLREL := (ovl := 100)')
95  self.addline_var('EROP_D0 : DYNAMIC := (velAxis := 10, accAxis := 100, decAxis := 100, jerkAxis := 50, vel := 200, acc := 3000, dec := 3000, jerk := 10000, velOri := 90, accOri := 180, decOri := 180, jerkOri := 10000)')
96 
97 
98  def ProgFinish(self, progname):
99  #self.addline('ENDPROC')
100  a=1
101 
102  def ProgSave(self, folder, progname, ask_user = False, show_result = False):
103  prognametip = progname + '.' + self.PROG_EXT
104  if ask_user or not DirExists(folder):
105  filesave = getSaveFile(folder, prognametip, 'Save program as...')
106  if filesave is not None:
107  filesave = filesave.name
108  else:
109  return
110  else:
111  filesave = folder + '/' + prognametip
112  fid = open(filesave, "w")
113  fid.write(self.PROG)
114  fid.close()
115  print('SAVED: %s\n' % filesave) # tell RoboDK the path of the saved file
116  self.PROG_FILES = filesave
117 
118  # variables file:
119  filesave_var = filesave[:-3] + self.PROG_EXT_VAR
120  fid = open(filesave_var, "w")
121  fid.write(self.PROG_VAR)
122  fid.close()
123 
124  # open file with default application
125  if show_result:
126  if type(show_result) is str:
127  # Open file with provided application
128  import subprocess
129  p = subprocess.Popen([show_result, filesave])
130  p = subprocess.Popen([show_result, filesave_var])
131 
132  elif type(show_result) is list:
133  import subprocess
134  p = subprocess.Popen(show_result + [filesave])
135  else:
136  # open file with default application
137  import os
138  os.startfile(filesave)
139  os.startfile(filesave_var)
140  if len(self.LOG) > 0:
141  mbox('Program generation LOG:\n\n' + self.LOG)
142 
143  def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass):
144  """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".
145  The connection parameters must be provided in the robot connection menu of RoboDK"""
146  UploadFTP(self.PROG_FILES, robot_ip, remote_path, ftp_user, ftp_pass)
147 
148  def MoveJ(self, pose, joints, conf_RLF=None):
149  """Add a joint movement"""
150  varname = 'ap%i' % self.count_var_ptp
151  self.addline('PTP(%s, EROP_D0, EROP_OL)' % varname)
152  self.addline_var('%s : AXISPOS := (%s)' % (varname, angles_2_str(joints)))
153  self.count_var_ptp = self.count_var_ptp + 1
154 
155  def MoveL(self, pose, joints, conf_RLF=None):
156  """Add a linear movement"""
157  varname = 'pos%i' % self.count_var_lin
158  self.addline('Lin(%s, EROP_D0, EROP_OL)' % varname)
159  self.addline_var('%s : CARTPOS := (%s)' % (varname, pose_2_str(pose)))
160  self.count_var_lin = self.count_var_lin + 1
161 
162  def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
163  """Add a circular movement"""
164  varname1 = 'pos%i' % self.count_var_lin
165  self.count_var_lin = self.count_var_lin + 1
166  varname2 = 'pos%i' % self.count_var_lin
167  self.count_var_lin = self.count_var_lin + 1
168  self.addline('Circ(%s, %s, EROP_D0, EROP_OL)' % (varname1, varname2))
169  self.addline_var('%s : CARTPOS := (%s)' % (varname1, pose_2_str(pose1)))
170  self.addline_var('%s : CARTPOS := (%s)' % (varname2, pose_2_str(pose2)))
171 
172  def setFrame(self, pose, frame_id=None, frame_name=None):
173  """Change the robot reference frame"""
174  #self.addline('BASE_FRAME ' + pose_2_str(pose))
175 
176  def setTool(self, pose, tool_id=None, tool_name=None):
177  """Change the robot TCP"""
178  #self.addline('TOOL_FRAME ' + pose_2_str(pose))
179 
180  def Pause(self, time_ms):
181  """Pause the robot program"""
182  if time_ms < 0:
183  self.addline('WaitIsFinished()')
184  self.addline('Stop()')
185  else:
186  self.addline('WaitTime(%.3f)' % (time_ms*0.001))
187 
188  def setSpeed(self, speed_mms):
189  """Changes the robot speed (in mm/s)"""
190  self.addline('EROP_D0.vel := %.3f' % speed_mms)
191 
192  def setAcceleration(self, accel_mmss):
193  """Changes the robot acceleration (in mm/s2)"""
194  self.addline('EROP_D0.acc := %.3f' % accel_mmss)
195  self.addline('EROP_D0.dec := %.3f' % accel_mmss)
196 
197  def setSpeedJoints(self, speed_degs):
198  """Changes the robot joint speed (in deg/s)"""
199  self.addlog('setSpeedJoints not defined')
200 
201  def setAccelerationJoints(self, accel_degss):
202  """Changes the robot joint acceleration (in deg/s2)"""
203  self.addlog('setAccelerationJoints not defined')
204 
205  def setZoneData(self, zone_mm):
206  """Changes the zone data approach (makes the movement more smooth)"""
207  self.addlog('setZoneData not defined (%.1f mm)' % zone_mm)
208 
209  def setDO(self, io_var, io_value):
210  """Sets a variable (output) to a given value"""
211  if type(io_var) != str: # set default variable name if io_var is a number
212  io_var = 'Out%s' % str(io_var)
213  if type(io_value) != str: # set default variable value if io_value is a number
214  if io_value > 0:
215  io_value = 'TRUE'
216  else:
217  io_value = 'FALSE'
218 
219  # at this point, io_var and io_value must be string values
220  self.addline('%s.Set(%s)' % (io_var, io_value))
221 
222  def waitDI(self, io_var, io_value, timeout_ms=-1):
223  """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided."""
224  if type(io_var) != str: # set default variable name if io_var is a number
225  io_var = 'In%s' % str(io_var)
226  if type(io_value) != str: # set default variable value if io_value is a number
227  if io_value > 0:
228  io_value = 'TRUE'
229  else:
230  io_value = 'FALSE'
231 
232  # at this point, io_var and io_value must be string values
233  if timeout_ms < 0:
234  self.addline('%s.Wait(%s)' % (io_var, io_value))
235  else:
236  self.addline('%s.Wait(%s, %.1f)' % (io_var, io_value, timeout_ms))
237 
238  def RunCode(self, code, is_function_call = False):
239  """Adds code or a function call"""
240  if is_function_call:
241  code.replace(' ','_')
242  self.addline(code + '()')
243  else:
244  self.addline(code)
245 
246  def RunMessage(self, message, iscomment = False):
247  """Display a message in the robot controller screen (teach pendant)"""
248  if iscomment:
249  self.addline('// ' + message)
250  else:
251  self.addlog('Show message on teach pendant not implemented (%s)' % message)
252 
253 # ------------------ private ----------------------
254  def addline(self, newline):
255  """Add a program line"""
256  self.PROG = self.PROG + newline + '\n'
257 
258  def addline_var(self, newline):
259  """Add a program line"""
260  self.PROG_VAR = self.PROG_VAR + newline + '\n'
261 
262 
263  def addlog(self, newline):
264  """Add a log message"""
265  self.LOG = self.LOG + newline + '\n'
266 
267 # -------------------------------------------------
268 # ------------ For testing purposes ---------------
269 def Pose(xyzrpw):
270  [x,y,z,r,p,w] = xyzrpw
271  a = r*math.pi/180
272  b = p*math.pi/180
273  c = w*math.pi/180
274  ca = math.cos(a)
275  sa = math.sin(a)
276  cb = math.cos(b)
277  sb = math.sin(b)
278  cc = math.cos(c)
279  sc = math.sin(c)
280  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]])
281 
282 def test_post():
283  """Test the post with a basic program"""
284 
285  robot = RobotPost()
286 
287  robot.ProgStart("Program")
288  robot.RunMessage("Program generated by RoboDK using a custom post processor", True)
289  robot.setFrame(Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]))
290  robot.setTool(Pose([62.5, -108.253175, 100, -60, 90, 0]))
291  robot.MoveJ(Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
292  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
293  robot.MoveL(Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
294  robot.RunMessage("Setting air valve 1 on")
295  robot.RunCode("TCP_On", True)
296  robot.Pause(1000)
297  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
298  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
299  robot.MoveL(Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
300  robot.RunMessage("Setting air valve off")
301  robot.RunCode("TCP_Off", True)
302  robot.Pause(1000)
303  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
304  robot.MoveL(Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
305  robot.MoveL(Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
306  robot.ProgFinish("Program")
307  # robot.ProgSave(".","Program",True)
308  print(robot.PROG)
309  if len(robot.LOG) > 0:
310  mbox('Program generation LOG:\n\n' + robot.LOG)
311 
312  input("Press Enter to close...")
313 
314 if __name__ == "__main__":
315  """Function to call when the module is executed by itself: test"""
316  test_post()
def RunMessage(self, message, iscomment=False)
Definition: KAIRO.py:246
def RunCode(self, code, is_function_call=False)
Definition: KAIRO.py:238
def setAcceleration(self, accel_mmss)
Definition: KAIRO.py:192
def setTool(self, pose, tool_id=None, tool_name=None)
Definition: KAIRO.py:176
def setSpeedJoints(self, speed_degs)
Definition: KAIRO.py:197
def MoveJ(self, pose, joints, conf_RLF=None)
Definition: KAIRO.py:148
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
Definition: KAIRO.py:162
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: KAIRO.py:82
def setDO(self, io_var, io_value)
Definition: KAIRO.py:209
def waitDI(self, io_var, io_value, timeout_ms=-1)
Definition: KAIRO.py:222
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: KAIRO.py:143
def setAccelerationJoints(self, accel_degss)
Definition: KAIRO.py:201
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
Definition: KAIRO.py:102
def setFrame(self, pose, frame_id=None, frame_name=None)
Definition: KAIRO.py:172
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
Definition: robodk.py:1354
def MoveL(self, pose, joints, conf_RLF=None)
Definition: KAIRO.py:155


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