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


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