MARS.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 MARS 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 
50 # ----------------------------------------------------
51 def pose_2_str(pose):
52  """Prints a pose target"""
53  [x,y,z,r,p,w] = pose_2_xyzrpw(pose)
54  return ('%.3f %.3f %.3f %.3f %.3f %.3f' % (x,y,z,r,p,w))
55 
56 def angles_2_str(angles):
57  """Prints a joint target"""
58  str = ''
59  data = ['','','','','','']
60  for i in range(len(angles)):
61  str = str + ('%.3f ' % angles[i])
62  str = str[:-1]
63  return str
64 
65 # ----------------------------------------------------
66 # Object class that handles the robot instructions/syntax
67 class RobotPost(object):
68  """Robot post object"""
69  PROG_EXT = 'gpl' # set the program extension
70 
71  # other variables
72  ROBOT_POST = 'unset'
73  ROBOT_NAME = 'generic'
74  PROG_FILES = []
75 
76  nPROGS = 0
77  PROG = ''
78  TAB = ''
79  LOG = ''
80  nAxes = 6
81 
82 
83  def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
84  self.ROBOT_POST = robotpost
85  self.ROBOT_NAME = robotname
86  self.PROG = ''
87  self.LOG = ''
88  self.nAxes = robot_axes
89 
90  def ProgStart(self, progname):
91  #self.addline('PROC %s()' % progname)
92  self.nPROGS = self.nPROGS + 1
93  if self.nPROGS == 1:
94  self.addline('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%')
95  self.addline(' VERSION:1')
96  self.addline(' Creator:MARS')
97  self.addline('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%')
98  self.addline('Module GPL')
99  self.addline(' Dim prof1 As New Profile')
100  self.addline(' Dim loc1 As New Location')
101  self.addline(' prof1.Speed = 40')
102  self.addline(' prof1.Straight = True')
103  self.addline(' Public Sub MAIN')
104 
105  self.addline(' Controller.PowerEnabled = 1')
106  self.addline(' Robot.Attached = 1')
107  self.addline(' Robot.Home')
108 
109 
110  def ProgFinish(self, progname):
111  self.addline(' End Sub')
112  self.addline('End Module')
113 
114  def ProgSave(self, folder, progname, ask_user=False, show_result=False):
115  progname = progname + '.' + self.PROG_EXT
116  if ask_user or not DirExists(folder):
117  filesave = getSaveFile(folder, progname, 'Save program as...')
118  if filesave is not None:
119  filesave = filesave.name
120  else:
121  return
122  else:
123  filesave = folder + '/' + progname
124  fid = open(filesave, "w")
125  fid.write(self.PROG)
126  fid.close()
127  print('SAVED: %s\n' % filesave) # tell RoboDK the path of the saved file
128  self.PROG_FILES = filesave
129 
130  #---------------------- show result
131  if show_result:
132  if type(show_result) is str:
133  # Open file with provided application
134  import subprocess
135  p = subprocess.Popen([show_result, filesave])
136  elif type(show_result) is list:
137  import subprocess
138  p = subprocess.Popen(show_result + [filesave])
139  else:
140  # open file with default application
141  import os
142  os.startfile(filesave)
143 
144  if len(self.LOG) > 0:
145  mbox('Program generation LOG:\n\n' + self.LOG)
146 
147  def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass):
148  """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".
149  The connection parameters must be provided in the robot connection menu of RoboDK"""
150  UploadFTP(self.PROG_FILES, robot_ip, remote_path, ftp_user, ftp_pass)
151 
152  def MoveJ(self, pose, joints, conf_RLF=None):
153  """Add a joint movement"""
154  #self.addline('MOVJ ' + angles_2_str(joints))
155  self.addline(' Move.Loc(Loc1.XYZ(%s),prof1)' % angles_2_str(joints))
156 
157  def MoveL(self, pose, joints, conf_RLF=None):
158  """Add a linear movement"""
159  self.addline(' Move.Loc(Loc1.XYZ(%s),prof1)' % pose_2_str(pose))
160 
161  def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
162  """Add a circular movement"""
163  self.addline(' Move.Circle(Loc1.XYZ(%s),Loc1.XYZ(%s),prof1) ' % (pose_2_str(pose1),pose_2_str(pose2)))
164 
165  def setFrame(self, pose, frame_id=None, frame_name=None):
166  """Change the robot reference frame"""
167  self.addline('BASE_FRAME ' + pose_2_str(pose))
168 
169  def setTool(self, pose, tool_id=None, tool_name=None):
170  """Change the robot TCP"""
171  self.addline('TOOL_FRAME ' + pose_2_str(pose))
172 
173  def Delay(self, time_ms):
174  """Pause the robot program"""
175  self.addline(' Move.Delay(%s)' % (time_ms*0.001))
176 
177  def Speed(self, speed_mms):
178  """Changes the robot speed (in mm/s)"""
179  self.addline(' prof1.Speed = %0.2f' % speed_mms)
180 
181  def Acceleration(self, accel_ptg):
182  """Changes the robot acceleration (in %)"""
183  self.addline(' prof1.Accel = %0.2f' % accel_ptg)
184 
185  def Deceleration(self, decel_ptg):
186  """Changes the robot deceleration (in %)"""
187  self.addlog(' prof1.decel = %0.2f' % decel_ptg)
188 
189  def setSpeedJoints(self, speed_degs):
190  """Changes the robot joint speed (in deg/s)"""
191  self.addlog('setSpeedJoints not defined')
192 
193  def setAccelerationJoints(self, accel_degss):
194  """Changes the robot joint acceleration (in deg/s2)"""
195  self.addlog('setAccelerationJoints not defined')
196 
197  def setZoneData(self, zone_mm):
198  """Changes the zone data approach (makes the movement more smooth)"""
199  self.addlog('setZoneData not defined (%.1f mm)' % zone_mm)
200 
201  def setDO(self, io_var, io_value):
202  """Sets a variable (output) to a given value"""
203  if type(io_var) != str: # set default variable name if io_var is a number
204  io_var = 'OUT[%s]' % str(io_var)
205  if type(io_value) != str: # set default variable value if io_value is a number
206  if io_value > 0:
207  io_value = 'TRUE'
208  else:
209  io_value = 'FALSE'
210 
211  # at this point, io_var and io_value must be string values
212  self.addline('%s=%s' % (io_var, io_value))
213 
214  def waitDI(self, io_var, io_value, timeout_ms=-1):
215  """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided."""
216  if type(io_var) != str: # set default variable name if io_var is a number
217  io_var = 'IN[%s]' % str(io_var)
218  if type(io_value) != str: # set default variable value if io_value is a number
219  if io_value > 0:
220  io_value = 'TRUE'
221  else:
222  io_value = 'FALSE'
223 
224  # at this point, io_var and io_value must be string values
225  if timeout_ms < 0:
226  self.addline('WAIT FOR %s==%s' % (io_var, io_value))
227  else:
228  self.addline('WAIT FOR %s==%s TIMEOUT=%.1f' % (io_var, io_value, timeout_ms))
229 
230  def RunCode(self, code, is_function_call = False):
231  """Adds code or a function call"""
232  if is_function_call:
233  code.replace(' ','_')
234  if not code.endswith(')'):
235  code = code + '()'
236  self.addline(code)
237  else:
238  self.addline(code)
239 
240  def RunMessage(self, message, iscomment = False):
241  """Display a message in the robot controller screen (teach pendant)"""
242  if iscomment:
243  self.addline('% ' + message)
244  else:
245  self.addlog('Show message on teach pendant not implemented (%s)' % message)
246 
247 # ------------------ private ----------------------
248  def addline(self, newline):
249  """Add a program line"""
250  self.PROG = self.PROG + newline + '\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]))
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, 15, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
282  robot.MoveC(Pose([200, 200, 34, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122],Pose([200, 200, 15, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122])
283  robot.Speed(30)
284  robot.Delay(1000)
285  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
286  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
287  robot.MoveL(Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
288 
289  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
290  robot.MoveL(Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
291  robot.MoveL(Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
292  robot.ProgFinish("Program")
293  #robot.ProgSave(".","Program",True)
294  print(robot.PROG)
295  if len(robot.LOG) > 0:
296  mbox('Program generation LOG:\n\n' + robot.LOG)
297 
298  input("Press Enter to close...")
299 
300 if __name__ == "__main__":
301  """Function to call when the module is executed by itself: test"""
302  test_post()
def RunMessage(self, message, iscomment=False)
Definition: MARS.py:240
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
Definition: MARS.py:161
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
Definition: MARS.py:114
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: robodk.py:1312
def MoveL(self, pose, joints, conf_RLF=None)
Definition: MARS.py:157
def setDO(self, io_var, io_value)
Definition: MARS.py:201
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: MARS.py:147
def MoveJ(self, pose, joints, conf_RLF=None)
Definition: MARS.py:152
def setAccelerationJoints(self, accel_degss)
Definition: MARS.py:193
def waitDI(self, io_var, io_value, timeout_ms=-1)
Definition: MARS.py:214
def RunCode(self, code, is_function_call=False)
Definition: MARS.py:230
def setFrame(self, pose, frame_id=None, frame_name=None)
Definition: MARS.py:165
def setSpeedJoints(self, speed_degs)
Definition: MARS.py:189
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
Definition: robodk.py:1354
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
Definition: MARS.py:83
def setTool(self, pose, tool_id=None, tool_name=None)
Definition: MARS.py:169


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