Allen_Bradley_Logix5000.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 generic robot 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 def pose_2_str(pose):
50  """Prints a pose target"""
51  [x,y,z,r,p,w] = pose_2_xyzrpw(pose)
52  return ('X%.3f Y%.3f Z%.3f R%.3f P%.3f W%.3f' % (x,y,z,r,p,w))
53 
54 def angles_2_str(angles):
55  """Prints a joint target"""
56  str = ''
57  data = ['A','B','C','D','E','F','G','H','I','J','K','L']
58  for i in range(len(angles)):
59  str = str + ('%s%.6f ' % (data[i], angles[i]))
60  str = str[:-1]
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 = 'txt' # set the program extension
68 
69  # other variables
70  ROBOT_POST = ''
71  ROBOT_NAME = ''
72  PROG_FILES = []
73 
74  PROG = ''
75  LOG = ''
76  nAxes = 6
77 
78  def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
79  self.ROBOT_POST = robotpost
80  self.ROBOT_NAME = robotname
81  self.PROG = ''
82  self.LOG = ''
83  self.nAxes = robot_axes
84  self.COUNT_STATE = 0
85  self.COUNT_MOVE = 0
86 
87 
88  def ProgStart(self, progname):
89  self.addline('(** This is a program sample generated by RoboDK post processor for Logix5000**)')
90  self.addline('(***** Enable Axis_0 and Axis_1 *****)')
91  self.addline('if (input_0 & State = 0) then ')
92  self.addline('\tMSO(Axis_0, Axis_0_MSO);')
93  self.addline('\tState [:=] 1;')
94  self.addline('\tcounter [:=] .5;')
95  self.addline('end_if;')
96  self.addline('')
97  self.addline('(***** Check for servos on *****)');
98  self.addline('If (Axis_0.ServoActionStatus & Axis_1.ServoActionStatus & State = 1) then');
99  self.addline('\tgear_ratio := counter;');
100  self.addline('(**\tMAG(Axis_0, Axis_1, Axis0_1_MAG, 1, gear_ratio, 1, 1, Actual, Real, Disabled, 10, 1 );**)');
101  self.addline('\tState := 2;');
102  self.addline('end_if;');
103  self.addline('')
104  self.addline('(********** MOVE AXES START **********)')
105  self.COUNT_STATE = 2
106 
107 
108  def ProgFinish(self, progname):
109  self.addline('(***** Check if move is complete and axis is in position *****)')
110  MAM_PC_ALL = ''
111  for i in range(self.nAxes):
112  MAM_PC_ALL = MAM_PC_ALL + ('Axis_%i_MAM.PC & ' % i)
113 
114  self.addline('If (%sState = %i) then' % (MAM_PC_ALL, self.COUNT_STATE))
115  self.COUNT_STATE = self.COUNT_STATE + 1
116  self.addline('\tState := %i;' % self.COUNT_STATE)
117  self.addline('end_if;')
118  self.addline('If (%s & counter = 2 & Axis_1.PositionLockStatus & State = %i) then' % (MAM_PC_ALL, self.COUNT_STATE))
119  self.COUNT_STATE = self.COUNT_STATE + 1
120  self.addline('\tState := %i;' % self.COUNT_STATE)
121  self.addline('end_if;')
122  self.addline('If (input_1 & State = %i) then' % self.COUNT_STATE)
123  self.addline('\tcounter := counter + .5;')
124  self.addline('\tState := 1; (* This directs the program to loop back and re-enter at State = 1 *) ')
125  self.addline('end_if;')
126  self.addline('If (Axis_0.ActualVelocity = 0 & Axis_1.ActualVelocity = 0 & State = %i) then' % self.COUNT_STATE)
127  self.addline('\tMSF(Axis_0, Axis_0_MSF); MSF(Axis_1, Axis_1_MSF);')
128  self.addline('\tJSR(LadderFile, 0 ); (* Jump to Ladder program *) (* Return from Ladder enters here *)')
129  self.addline('end_if;')
130  self.addline('If timer_1.DN & State = %i then (* Wait for timer done then reset ' % self.COUNT_STATE)
131  self.addline('\tState := 0;')
132  self.addline('\tcounter := 0;')
133  self.addline('end_if;')
134  self.addline('')
135  self.addline('(** this program contains %i sequential movements **)' % self.COUNT_MOVE)
136 
137  def ProgSave(self, folder, progname, ask_user = False, show_result = False):
138  progname = progname + '.' + self.PROG_EXT
139  if ask_user or not DirExists(folder):
140  filesave = getSaveFile(folder, progname, 'Save program as...')
141  if filesave is not None:
142  filesave = filesave.name
143  else:
144  return
145  else:
146  filesave = folder + '/' + progname
147  # save file
148  fid = open(filesave, "w")
149  fid.write(self.PROG)
150  fid.close()
151  print('SAVED: %s\n' % filesave) # tell RoboDK the path of the saved file
152  self.PROG_FILES = filesave
153 
154  # open file with default application
155  if show_result:
156  if type(show_result) is str:
157  # Open file with provided application
158  import subprocess
159  p = subprocess.Popen([show_result, filesave])
160  elif type(show_result) is list:
161  import subprocess
162  p = subprocess.Popen(show_result + [filesave])
163  else:
164  # open file with default application
165  import os
166  os.startfile(filesave)
167  if len(self.LOG) > 0:
168  mbox('Program generation LOG:\n\n' + self.LOG)
169 
170  def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass):
171  """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".
172  The connection parameters must be provided in the robot connection menu of RoboDK"""
173  UploadFTP(self.PROG_FILES, robot_ip, remote_path, ftp_user, ftp_pass)
174 
175  def MoveJ(self, pose, joints, conf_RLF=None):
176  """Add a joint movement"""
177  self.addline('(** move instruction %i (joint move)**)' % self.COUNT_MOVE)
178  MAM_PC_ALL = ''
179  for i in range(len(joints)):
180  MAM_PC_ALL = MAM_PC_ALL + ('Axis_%i_MAM.PC & ' % i)
181 
182  self.addline('if (%sState = %i) then' % (MAM_PC_ALL, self.COUNT_STATE))
183  self.COUNT_STATE = self.COUNT_STATE + 1
184  self.COUNT_MOVE = self.COUNT_MOVE + 1
185  for i in range(len(joints)):
186  self.addline('\tMAM(Axis_%i, Axis_%i_MAM, 1, %.3f, Move_Speed, Unitspersec, 50, %%ofMaximum, 50, %%ofMaximum, 1,100.0,100.0,%%ofTime, 0, 0 ,0,None,0,0);' % (i, i, joints[i]))
187 
188  self.addline('\tState := %i;' % self.COUNT_STATE)
189  self.addline('end_if;')
190 
191  def MoveL(self, pose, joints, conf_RLF=None):
192  """Add a linear movement"""
193  self.addline('(** move instruction %i (linear move)**)' % self.COUNT_MOVE)
194  MAM_PC_ALL = ''
195  for i in range(len(joints)):
196  MAM_PC_ALL = MAM_PC_ALL + ('Axis_%i_MAM.PC & ' % i)
197 
198  self.addline('if (%sState = %i) then' % (MAM_PC_ALL, self.COUNT_STATE))
199  self.COUNT_STATE = self.COUNT_STATE + 1
200  self.COUNT_MOVE = self.COUNT_MOVE + 1
201  for i in range(len(joints)):
202  self.addline('\tMAM(Axis_%i, Axis_%i_MAM, 1, %.3f, Move_Speed, Unitspersec, 50, %%ofMaximum, 50, %%ofMaximum, 1,100.0,100.0,%%ofTime, 0, 0 ,0,None,0,0);' % (i, i, joints[i]))
203 
204  self.addline('\tState := %i;' % self.COUNT_STATE)
205  self.addline('end_if;')
206 
207  def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
208  """Add a circular movement"""
209  self.addlog('MoveC not defined')
210 
211  def setFrame(self, pose, frame_id=None, frame_name=None):
212  """Change the robot reference frame"""
213  self.addlog('setFrame not defined')
214 
215  def setTool(self, pose, tool_id=None, tool_name=None):
216  """Change the robot TCP"""
217  self.addlog('setTool not defined')
218 
219  def Pause(self, time_ms):
220  """Pause the robot program"""
221  self.addlog('Pause not defined')
222 
223  def setSpeed(self, speed_mms):
224  """Changes the current robot speed (in mm/s)"""
225  self.addlog('setSpeed not defined')
226 
227  def setAcceleration(self, accel_mmss):
228  """Changes the current robot acceleration (in mm/s2)"""
229  self.addlog('setAcceleration not defined')
230 
231  def setSpeedJoints(self, speed_degs):
232  """Changes the robot joint speed (in deg/s)"""
233  self.addlog('setSpeedJoints not defined')
234 
235  def setAccelerationJoints(self, accel_degss):
236  """Changes the robot joint acceleration (in deg/s2)"""
237  self.addlog('setAccelerationJoints not defined')
238 
239  def setZoneData(self, zone_mm):
240  """Changes the zone data approach (makes the movement more smooth)"""
241  self.addlog('Zone data not implemented (%.1f mm)' % zone_mm)
242 
243  def setDO(self, io_var, io_value):
244  """Sets a variable (output) to a given value"""
245  if type(io_var) != str: # set default variable name if io_var is a number
246  io_var = 'OUT[%s]' % str(io_var)
247  if type(io_value) != str: # set default variable value if io_value is a number
248  if io_value > 0:
249  io_value = 'TRUE'
250  else:
251  io_value = 'FALSE'
252 
253  # at this point, io_var and io_value must be string values
254  self.addline('%s=%s' % (io_var, io_value))
255 
256  def waitDI(self, io_var, io_value, timeout_ms=-1):
257  """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided."""
258  if type(io_var) != str: # set default variable name if io_var is a number
259  io_var = 'IN[%s]' % str(io_var)
260  if type(io_value) != str: # set default variable value if io_value is a number
261  if io_value > 0:
262  io_value = 'TRUE'
263  else:
264  io_value = 'FALSE'
265 
266  # at this point, io_var and io_value must be string values
267  if timeout_ms < 0:
268  self.addline('WAIT FOR %s==%s' % (io_var, io_value))
269  else:
270  self.addline('WAIT FOR %s==%s TIMEOUT=%.1f' % (io_var, io_value, timeout_ms))
271 
272  def RunCode(self, code, is_function_call = False):
273  """Adds code or a function call"""
274  self.addlog('RunCode not defined')
275 
276  def RunMessage(self, message, iscomment = False):
277  """Show a message on the controller screen"""
278  self.addlog('RunMessage not defined')
279 
280 # ------------------ private ----------------------
281  def addline(self, newline):
282  """Add a program line"""
283  self.PROG = self.PROG + newline + '\n'
284 
285  def addlog(self, newline):
286  """Add a log message"""
287  self.LOG = self.LOG + newline + '\n'
288 
289 # -------------------------------------------------
290 # ------------ For testing purposes ---------------
291 def Pose(xyzrpw):
292  [x,y,z,r,p,w] = xyzrpw
293  a = r*math.pi/180
294  b = p*math.pi/180
295  c = w*math.pi/180
296  ca = math.cos(a)
297  sa = math.sin(a)
298  cb = math.cos(b)
299  sb = math.sin(b)
300  cc = math.cos(c)
301  sc = math.sin(c)
302  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]])
303 
304 def test_post():
305  """Test the post with a basic program"""
306 
307  robot = RobotPost()
308 
309  robot.ProgStart("Program")
310  robot.RunMessage("Program generated by RoboDK", True)
311  robot.setFrame(Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]))
312  robot.setTool(Pose([62.5, -108.253175, 100, -60, 90, 0]))
313  robot.MoveJ(Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
314  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
315  robot.MoveL(Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
316  robot.RunMessage("Setting air valve 1 on")
317  robot.RunCode("TCP_On", True)
318  robot.Pause(1000)
319  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
320  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
321  robot.MoveL(Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
322  robot.RunMessage("Setting air valve off")
323  robot.RunCode("TCP_Off", True)
324  robot.Pause(1000)
325  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
326  robot.MoveL(Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
327  robot.MoveL(Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
328  robot.ProgFinish("Program")
329  # robot.ProgSave(".","Program",True)
330  print(robot.PROG)
331  if len(robot.LOG) > 0:
332  mbox('Program generation LOG:\n\n' + robot.LOG)
333 
334  input("Press Enter to close...")
335 
336 if __name__ == "__main__":
337  """Function to call when the module is executed by itself: test"""
338  test_post()
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)
def setFrame(self, pose, frame_id=None, frame_name=None)
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)
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
Definition: robodk.py:1458
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
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