GCode_BnR.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 sample POST PROCESSOR script to generate robot programs for a B&R Automation controller
14 #
15 # To edit/test this POST PROCESSOR script file:
16 # Select "Program"->"Add/Edit Post Processor", then select your post or create a new one.
17 # 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.
18 # Python should be automatically installed with RoboDK
19 #
20 # You can also edit the POST PROCESSOR manually:
21 # 1- Open the *.py file with Python IDLE (right click -> Edit with IDLE)
22 # 2- Make the necessary changes
23 # 3- Run the file to open Python Shell: Run -> Run module (F5 by default)
24 # 4- The "test_post()" function is called automatically
25 # Alternatively, you can edit this file using a text editor and run it with Python
26 #
27 # To use a POST PROCESSOR file you must place the *.py file in "C:/RoboDK/Posts/"
28 # To select one POST PROCESSOR for your robot in RoboDK you must follow these steps:
29 # 1- Open the robot panel (double click a robot)
30 # 2- Select "Parameters"
31 # 3- Select "Unlock advanced options"
32 # 4- Select your post as the file name in the "Robot brand" box
33 #
34 # To delete an existing POST PROCESSOR script, simply delete this file (.py file)
35 #
36 # ----------------------------------------------------
37 # More information about RoboDK Post Processors and Offline Programming here:
38 # http://www.robodk.com/help#PostProcessor
39 # http://www.robodk.com/doc/en/PythonAPI/postprocessor.html
40 # ----------------------------------------------------
41 
42 
43 # ----------------------------------------------------
44 # Import RoboDK tools
45 from robodk import *
46 
47 JOINT_DATA = ['Q1','Q2','Q3','Q4','Q5','Q6','Ra','Rb','Rc']
48 
49 # ----------------------------------------------------
50 def pose_2_str(pose, joints = None):
51  """Prints a pose target"""
52  [x,y,z,r,p,w] = Pose_2_KUKA(pose)
53  str_xyzwpr = 'X %.3f Y %.3f Z %.3f A %.3f B %.3f C %.3f' % (x,y,z,r,p,w)
54  if joints is not None:
55  if len(joints) > 6:
56  for j in range(6,len(joints)):
57  str_xyzwpr += (' %s %.6f ' % (JOINT_DATA[j], joints[j]))
58 
59  return str_xyzwpr
60 
61 def joints_2_str(joints):
62  """Prints a joint target"""
63  str = ''
64  for i in range(len(joints)):
65  str = str + ('%s %.6f ' % (JOINT_DATA[i], joints[i]))
66  str = str[:-1]
67  return str
68 
69 # ----------------------------------------------------
70 # Object class that handles the robot instructions/syntax
71 class RobotPost(object):
72  """Robot post object"""
73  PROG_EXT = 'cnc' # set the program extension
74 
75  # other variables
76  ROBOT_POST = ''
77  ROBOT_NAME = ''
78  PROG_FILES = []
79 
80  PROG = ''
81  LOG = ''
82  nAxes = 6
83  nId = 0
84  REF_FRAME = eye(4)
85 
86 
87  def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
88  self.ROBOT_POST = robotpost
89  self.ROBOT_NAME = robotname
90  self.PROG = ''
91  self.LOG = ''
92  self.nAxes = robot_axes
93 
94  def ProgStart(self, progname):
95  self.addline('; program: %s()' % progname)
96  self.addline('G161')
97  self.addline('G90')
98  self.addline('F15000')
99 
100  def ProgFinish(self, progname):
101  self.addline('; ENDPROC')
102 
103  def ProgSave(self, folder, progname, ask_user=False, show_result=False):
104  progname = progname + '.' + self.PROG_EXT
105  if ask_user or not DirExists(folder):
106  filesave = getSaveFile(folder, progname, 'Save program as...')
107  if filesave is not None:
108  filesave = filesave.name
109  else:
110  return
111  else:
112  filesave = folder + '/' + progname
113  fid = open(filesave, "w")
114  fid.write(self.PROG)
115  fid.close()
116  print('SAVED: %s\n' % filesave)
117  self.PROG_FILES = filesave
118  #---------------------- show result
119  if show_result:
120  if type(show_result) is str:
121  # Open file with provided application
122  import subprocess
123  p = subprocess.Popen([show_result, filesave])
124  elif type(show_result) is list:
125  import subprocess
126  p = subprocess.Popen(show_result + [filesave])
127  else:
128  # open file with default application
129  import os
130  os.startfile(filesave)
131 
132  if len(self.LOG) > 0:
133  mbox('Program generation LOG:\n\n' + self.LOG)
134 
135  def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass):
136  """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".
137  The connection parameters must be provided in the robot connection menu of RoboDK"""
138  UploadFTP(self.PROG_FILES, robot_ip, remote_path, ftp_user, ftp_pass)
139 
140  def MoveJ(self, pose, joints, conf_RLF=None):
141  """Add a joint movement"""
142  self.nId = self.nId + 1
143  self.addline('N%02i G101 ' % self.nId + joints_2_str(joints))
144 
145  def MoveL(self, pose, joints, conf_RLF=None):
146  """Add a linear movement"""
147  self.nId = self.nId + 1
148  self.addline('N%02i G1 ' % self.nId + pose_2_str(self.REF_FRAME*pose, joints))
149  #self.addline('N%02i G90 G1 ' % self.nId + joints_2_str(joints))
150 
151  def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
152  """Add a circular movement"""
153  self.nId = self.nId + 1
154  xyz1 = (self.REF_FRAME*pose1).Pos()
155  xyz2 = (self.REF_FRAME*pose2).Pos()
156  self.addline('N%02i G90 G102 X%.3f Y%.3f Z%.3f I1=%.3f J1=%.3f K1=%.3f' % (self.nId, xyz2[0], xyz2[1], xyz2[2], xyz1[0], xyz1[1], xyz1[2]))
157  #self.addline('N%02i G102 X%.3f Y%.3f Z%.3f I1=%.3f J1=%.3f K1=%.3f' % (self.nId, xyz1[0], xyz1[1], xyz1[2], xyz2[0]-xyz1[0], xyz2[1]-xyz1[1], xyz2[2]-xyz1[2]))
158 
159  def setFrame(self, pose, frame_id=None, frame_name=None):
160  """Change the robot reference frame"""
161  self.REF_FRAME = pose
162  self.addline('; Reference frame set to: ' + pose_2_str(pose))
163  self.addline(('; N%02i G90 G92 ' % self.nId) + pose_2_str(pose))
164 
165  def setTool(self, pose, tool_id=None, tool_name=None):
166  """Change the robot TCP"""
167  self.nId = self.nId + 1
168  self.addline('; Tool frame set to: ' + pose_2_str(pose))
169  self.addline(('; N%02i G90 G92 ' % self.nId) + pose_2_str(pose))
170  pass
171 
172  def Pause(self, time_ms):
173  """Pause the robot program"""
174  if time_ms < 0:
175  self.addline('; PAUSE')
176  else:
177  self.addline('; WAIT %.3f' % (time_ms*0.001))
178 
179  def setSpeed(self, speed_mms):
180  """Changes the robot speed (in mm/s)"""
181  self.addline('F%.3f' % (speed_mms*60))
182 
183  def setAcceleration(self, accel_mmss):
184  """Changes the robot acceleration (in mm/s2)"""
185  self.addlog('setAcceleration not defined')
186 
187  def setSpeedJoints(self, speed_degs):
188  """Changes the robot joint speed (in deg/s)"""
189  self.addlog('setSpeedJoints not defined')
190 
191  def setAccelerationJoints(self, accel_degss):
192  """Changes the robot joint acceleration (in deg/s2)"""
193  self.addlog('setAccelerationJoints not defined')
194 
195  def setZoneData(self, zone_mm):
196  """Changes the rounding radius (aka CNT, APO or zone data) to make the movement smoother"""
197  self.addlog('setZoneData not defined (%.1f mm)' % zone_mm)
198 
199  def setDO(self, io_var, io_value):
200  """Sets a variable (digital output) to a given value"""
201  if type(io_var) != str: # set default variable name if io_var is a number
202  io_var = 'OUT[%s]' % str(io_var)
203  if type(io_value) != str: # set default variable value if io_value is a number
204  if io_value > 0:
205  io_value = 'TRUE'
206  else:
207  io_value = 'FALSE'
208 
209  # at this point, io_var and io_value must be string values
210  self.addline('%s=%s' % (io_var, io_value))
211 
212  def waitDI(self, io_var, io_value, timeout_ms=-1):
213  """Waits for a variable (digital input) io_var to attain a given value io_value. Optionally, a timeout can be provided."""
214  if type(io_var) != str: # set default variable name if io_var is a number
215  io_var = 'IN[%s]' % str(io_var)
216  if type(io_value) != str: # set default variable value if io_value is a number
217  if io_value > 0:
218  io_value = 'TRUE'
219  else:
220  io_value = 'FALSE'
221 
222  # at this point, io_var and io_value must be string values
223  if timeout_ms < 0:
224  self.addline('WAIT FOR %s==%s' % (io_var, io_value))
225  else:
226  self.addline('WAIT FOR %s==%s TIMEOUT=%.1f' % (io_var, io_value, timeout_ms))
227 
228  def RunCode(self, code, is_function_call = False):
229  """Adds code or a function call"""
230  if is_function_call:
231  code.replace(' ','_')
232  if not code.endswith(')'):
233  code = code + '()'
234  self.addline(code)
235  else:
236  self.addline(code)
237 
238  def RunMessage(self, message, iscomment = False):
239  """Display a message in the robot controller screen (teach pendant)"""
240  if iscomment:
241  self.addline('; ' + message)
242  else:
243  self.addline('; Show message: %s' % message)
244 
245 # ------------------ private ----------------------
246  def addline(self, newline):
247  """Add a program line"""
248  self.PROG = self.PROG + newline + '\n'
249 
250  def addlog(self, newline):
251  """Add a log message"""
252  self.LOG = self.LOG + newline + '\n'
253 
254 # -------------------------------------------------
255 # ------------ For testing purposes ---------------
256 def Pose(xyzrpw):
257  [x,y,z,r,p,w] = xyzrpw
258  a = r*math.pi/180
259  b = p*math.pi/180
260  c = w*math.pi/180
261  ca = math.cos(a)
262  sa = math.sin(a)
263  cb = math.cos(b)
264  sb = math.sin(b)
265  cc = math.cos(c)
266  sc = math.sin(c)
267  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]])
268 
269 def test_post():
270  """Test the post with a basic program"""
271 
272  robot = RobotPost()
273 
274  robot.ProgStart("Program")
275  robot.RunMessage("Program generated by RoboDK using a custom post processor", True)
276  robot.setFrame(Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]))
277  robot.setTool(Pose([62.5, -108.253175, 100, -60, 90, 0]))
278  robot.MoveJ(Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
279  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
280  robot.MoveL(Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
281  robot.RunMessage("Setting air valve 1 on")
282  robot.RunCode("TCP_On", True)
283  robot.Pause(1000)
284  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
285  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
286  robot.MoveL(Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
287  robot.RunMessage("Setting air valve off")
288  robot.RunCode("TCP_Off", True)
289  robot.Pause(1000)
290  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
291  robot.MoveL(Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
292  robot.MoveL(Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
293  robot.MoveJ(None, [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
294  robot.ProgFinish("Program")
295  # robot.ProgSave(".","Program",True)
296  print(robot.PROG)
297  if len(robot.LOG) > 0:
298  mbox('Program generation LOG:\n\n' + robot.LOG)
299 
300  input("Press Enter to close...")
301 
302 if __name__ == "__main__":
303  """Function to call when the module is executed by itself: test"""
304  test_post()
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
Definition: GCode_BnR.py:87
def setTool(self, pose, tool_id=None, tool_name=None)
Definition: GCode_BnR.py:165
def RunMessage(self, message, iscomment=False)
Definition: GCode_BnR.py:238
def waitDI(self, io_var, io_value, timeout_ms=-1)
Definition: GCode_BnR.py:212
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: robodk.py:1312
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
Definition: GCode_BnR.py:103
def MoveL(self, pose, joints, conf_RLF=None)
Definition: GCode_BnR.py:145
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: GCode_BnR.py:135
def MoveJ(self, pose, joints, conf_RLF=None)
Definition: GCode_BnR.py:140
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
Definition: robodk.py:1458
def pose_2_str(pose, joints=None)
Definition: GCode_BnR.py:50
def setFrame(self, pose, frame_id=None, frame_name=None)
Definition: GCode_BnR.py:159
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
Definition: robodk.py:1354
def RunCode(self, code, is_function_call=False)
Definition: GCode_BnR.py:228
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
Definition: GCode_BnR.py:151


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