GCode_A3200.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 = ['X','Y','Z','PH','RH','RZ']
48 
49 
50 # ----------------------------------------------------
51 def pose_2_str(pose, joints = None):
52  """Prints a pose target"""
53  [x,y,z,r,p,w] = Pose_2_KUKA(pose)
54  #str_xyzwpr = 'X %.3f Y %.3f Z %.3f A %.3f B %.3f C %.3f' % (x,y,z,r,p,w)
55  str_xyzwpr = ''
56  if joints is not None:
57  for j in range(len(joints)):
58  str_xyzwpr += ('%s %.6f ' % (JOINT_DATA[j], joints[j]))
59 
60  str_xyzwpr = str_xyzwpr[:-1]
61  else:
62  str_xyzwpr = 'X %.3f Y %.3f Z %.3f A %.3f B %.3f C %.3f' % (x,y,z,r,p,w)
63 
64  return str_xyzwpr
65 
66 def joints_2_str(joints):
67  """Prints a joint target"""
68  str = ''
69  for i in range(len(joints)):
70  str = str + ('%s %.6f ' % (JOINT_DATA[i], joints[i]))
71  str = str[:-1]
72  return str
73 
74 # ----------------------------------------------------
75 # Object class that handles the robot instructions/syntax
76 class RobotPost(object):
77  """Robot post object"""
78  PROG_EXT = 'cnc' # set the program extension
79 
80  # other variables
81  ROBOT_POST = ''
82  ROBOT_NAME = ''
83  PROG_FILES = []
84 
85  SPEED_MMS = 100
86  PROG = ''
87  LOG = ''
88  nAxes = 6
89  nId = 0
90  REF_FRAME = eye(4)
91 
92 
93  def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
94  self.ROBOT_POST = robotpost
95  self.ROBOT_NAME = robotname
96  self.PROG = ''
97  self.LOG = ''
98  self.nAxes = robot_axes
99  for k,v in kwargs.items():
100  if k == 'lines_x_prog':
102 
103  def ProgStart(self, progname):
104  self.addline('// program: %s' % progname)
105  self.addline('VELOCITY ON')
106 
107  def ProgFinish(self, progname):
108  self.addline('// end of program ' + progname)
109 
110  def ProgSave(self, folder, progname, ask_user=False, show_result=False):
111  progname = progname + '.' + self.PROG_EXT
112  if ask_user or not DirExists(folder):
113  filesave = getSaveFile(folder, progname, 'Save program as...')
114  if filesave is not None:
115  filesave = filesave.name
116  else:
117  return
118  else:
119  filesave = folder + '/' + progname
120  fid = open(filesave, "w")
121  fid.write(self.PROG)
122  fid.close()
123  print('SAVED: %s\n' % filesave)
124  self.PROG_FILES = filesave
125  #---------------------- show result
126  if show_result:
127  if type(show_result) is str:
128  # Open file with provided application
129  import subprocess
130  p = subprocess.Popen([show_result, filesave])
131  elif type(show_result) is list:
132  import subprocess
133  p = subprocess.Popen(show_result + [filesave])
134  else:
135  # open file with default application
136  import os
137  os.startfile(filesave)
138 
139  if len(self.LOG) > 0:
140  mbox('Program generation LOG:\n\n' + self.LOG)
141 
142  def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass):
143  """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".
144  The connection parameters must be provided in the robot connection menu of RoboDK"""
145  UploadFTP(self.PROG_FILES, robot_ip, remote_path, ftp_user, ftp_pass)
146 
147  def MoveJ(self, pose, joints, conf_RLF=None):
148  """Add a joint movement"""
149  self.addline('JOINTS %s F%.2f' % (joints_2_str(joints), self.SPEED_MMS))
150 
151  def MoveL(self, pose, joints, conf_RLF=None):
152  """Add a linear movement"""
153  self.addline('LINEAR %s F%.2f' % (pose_2_str(self.REF_FRAME*pose, joints), self.SPEED_MMS))
154 
155  def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
156  """Add a circular movement"""
157  self.addline('CIRCULAR %s F%.2f' % (pose_2_str(self.REF_FRAME*pose1, joints1), self.SPEED_MMS))
158  self.addline('CIRCULAR %s F%.2f' % (pose_2_str(self.REF_FRAME*pose2, joints2), self.SPEED_MMS))
159 
160  def setFrame(self, pose, frame_id=None, frame_name=None):
161  """Change the robot reference frame"""
162  self.REF_FRAME = pose
163  self.addline('// Reference frame set to: ' + 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 
170  def Pause(self, time_ms):
171  """Pause the robot program"""
172  if time_ms < 0:
173  self.addline('PAUSE')
174  else:
175  self.addline('DWELL %.3f' % (time_ms*0.001))
176 
177  def setSpeed(self, speed_mms):
178  """Changes the robot speed (in mm/s)"""
179  self.SPEED_MMS = speed_mms
180  #self.addline('F%.3f' % (speed_mms*60))
181 
182  def setAcceleration(self, accel_mmss):
183  """Changes the robot acceleration (in mm/s2)"""
184  #self.addlog('setAcceleration not defined')
185  pass
186 
187  def setSpeedJoints(self, speed_degs):
188  """Changes the robot joint speed (in deg/s)"""
189  #self.addlog('setSpeedJoints not defined')
190  pass
191 
192  def setAccelerationJoints(self, accel_degss):
193  """Changes the robot joint acceleration (in deg/s2)"""
194  #self.addlog('setAccelerationJoints not defined')
195  pass
196 
197  def setZoneData(self, zone_mm):
198  """Changes the rounding radius (aka CNT, APO or zone data) to make the movement smoother"""
199  if zone_mm > 0:
200  self.addline('ROUNDING ON')
201  else:
202  self.addline('ROUNDING OFF')
203 
204  def setDO(self, io_var, io_value):
205  """Sets a variable (digital output) to a given value"""
206  if type(io_var) != str: # set default variable name if io_var is a number
207  io_var = 'OUT[%s]' % str(io_var)
208  if type(io_value) != str: # set default variable value if io_value is a number
209  if io_value > 0:
210  io_value = 'TRUE'
211  else:
212  io_value = 'FALSE'
213 
214  # at this point, io_var and io_value must be string values
215  self.addline('%s=%s' % (io_var, io_value))
216 
217  def waitDI(self, io_var, io_value, timeout_ms=-1):
218  """Waits for a variable (digital input) io_var to attain a given value io_value. Optionally, a timeout can be provided."""
219  if type(io_var) != str: # set default variable name if io_var is a number
220  io_var = 'IN[%s]' % str(io_var)
221  if type(io_value) != str: # set default variable value if io_value is a number
222  if io_value > 0:
223  io_value = 'TRUE'
224  else:
225  io_value = 'FALSE'
226 
227  # at this point, io_var and io_value must be string values
228  if timeout_ms < 0:
229  self.addline('WAIT FOR %s==%s' % (io_var, io_value))
230  else:
231  self.addline('WAIT FOR %s==%s TIMEOUT=%.1f' % (io_var, io_value, timeout_ms))
232 
233  def RunCode(self, code, is_function_call = False):
234  """Adds code or a function call"""
235  if is_function_call:
236  code.replace(' ','_')
237  if not code.endswith(')'):
238  code = code + '()'
239  self.addline("CALL " + code)
240  else:
241  self.addline(code)
242 
243  def RunMessage(self, message, iscomment = False):
244  """Display a message in the robot controller screen (teach pendant)"""
245  if iscomment:
246  self.addline('// ' + message)
247  else:
248  self.addline('MSGBOX (DF_MSGBOX_OKONLY),"%s" ' % message)
249 
250 # ------------------ private ----------------------
251  def addline(self, newline):
252  """Add a program line"""
253  self.PROG = self.PROG + newline + '\n'
254 
255  def addlog(self, newline):
256  """Add a log message"""
257  self.LOG = self.LOG + newline + '\n'
258 
259 # -------------------------------------------------
260 # ------------ For testing purposes ---------------
261 def Pose(xyzrpw):
262  [x,y,z,r,p,w] = xyzrpw
263  a = r*math.pi/180
264  b = p*math.pi/180
265  c = w*math.pi/180
266  ca = math.cos(a)
267  sa = math.sin(a)
268  cb = math.cos(b)
269  sb = math.sin(b)
270  cc = math.cos(c)
271  sc = math.sin(c)
272  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]])
273 
274 def test_post():
275  """Test the post with a basic program"""
276 
277  robot = RobotPost()
278 
279  robot.ProgStart("Program")
280  robot.RunMessage("Program generated by RoboDK using a custom post processor", True)
281  robot.setFrame(Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]))
282  robot.setTool(Pose([62.5, -108.253175, 100, -60, 90, 0]))
283  robot.MoveJ(Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
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([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
286  robot.RunMessage("Setting air valve 1 on")
287  robot.RunCode("TCP_On", True)
288  robot.Pause(1000)
289  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
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, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
292  robot.RunMessage("Setting air valve off")
293  robot.RunCode("TCP_Off", True)
294  robot.Pause(1000)
295  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
296  robot.MoveL(Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
297  robot.MoveL(Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
298  robot.MoveJ(None, [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
299  robot.ProgFinish("Program")
300  # robot.ProgSave(".","Program",True)
301  print(robot.PROG)
302  if len(robot.LOG) > 0:
303  mbox('Program generation LOG:\n\n' + robot.LOG)
304 
305  input("Press Enter to close...")
306 
307 if __name__ == "__main__":
308  """Function to call when the module is executed by itself: test"""
309  test_post()
def setFrame(self, pose, frame_id=None, frame_name=None)
Definition: GCode_A3200.py:160
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
Definition: GCode_A3200.py:110
def MoveJ(self, pose, joints, conf_RLF=None)
Definition: GCode_A3200.py:147
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: robodk.py:1312
def waitDI(self, io_var, io_value, timeout_ms=-1)
Definition: GCode_A3200.py:217
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
Definition: GCode_A3200.py:155
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
Definition: robodk.py:1458
def RunMessage(self, message, iscomment=False)
Definition: GCode_A3200.py:243
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: GCode_A3200.py:142
def MoveL(self, pose, joints, conf_RLF=None)
Definition: GCode_A3200.py:151
def setTool(self, pose, tool_id=None, tool_name=None)
Definition: GCode_A3200.py:165
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
Definition: GCode_A3200.py:93
def RunCode(self, code, is_function_call=False)
Definition: GCode_A3200.py:233
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