Denso_RC8.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 POST PROCESSOR for Robot Offline Programming to generate programs
14 # for Denso robots using RC8 controller (PACScript programming)
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  """Converts a pose target to a string"""
51  [x,y,z,w,p,r] = Pose_2_Adept(pose)
52  return ('P(%.3f,%.3f,%.3f,%.3f,%.3f,%.3f)' % (x,y,z,w,p,r))
53 
54 def joints_2_str(angles):
55  """Contverts a joint target to a string"""
56  return 'J(%s)' % (','.join(format(ji, ".5f") for ji in angles))
57 
58 # ----------------------------------------------------
59 # Object class that handles the robot instructions/syntax
60 class RobotPost(object):
61  """Robot post object"""
62  PROG_EXT = 'pcs' # set the program extension
63 
64  # other variables
65  ROBOT_POST = ''
66  ROBOT_NAME = ''
67  PROG_FILES = []
68 
69  PROG = ''
70  LOG = ''
71  nAxes = 6
72  TAB = ''
73  SPEED_MPS = 10
74  PASS = '@0' # Nothing = default = '@0'
75  ACTIVE_TOOL = 2
76  ACTIVE_WOBJ = 3
77  nProgs = 0
78 
79  def __init__(self, robotpost=None, robotname=None, robot_axes = 6, **kwargs):
80  self.ROBOT_POST = robotpost
81  self.ROBOT_NAME = robotname
82  self.PROG = ''
83  self.LOG = ''
84  self.nAxes = robot_axes
85 
86  def ProgStart(self, progname):
87  #self.addline('Sub Main%s()' % progname)
88  self.nProgs = self.nProgs + 1
89  if self.nProgs <= 1:
90  self.addline('Sub Main')
91  else:
92  self.addline('Sub %s' % progname)
93  self.TAB = ' '
94 
95  def ProgFinish(self, progname):
96  self.TAB = ''
97  self.addline('End Sub')
98 
99  def ProgSave(self, folder, progname, ask_user = False, show_result = False):
100  progname = progname + '.' + self.PROG_EXT
101  if ask_user or not DirExists(folder):
102  filesave = getSaveFile(folder, progname, 'Save program as...')
103  if filesave is not None:
104  filesave = filesave.name
105  else:
106  return
107  else:
108  filesave = folder + '/' + progname
109  fid = open(filesave, "w")
110  fid.write(self.PROG)
111  fid.close()
112  print('SAVED: %s\n' % filesave) # tell RoboDK the path of the saved file
113  self.PROG_FILES = filesave
114 
115  # open file with default application
116  if show_result:
117  if type(show_result) is str:
118  # Open file with provided application
119  import subprocess
120  p = subprocess.Popen([show_result, filesave])
121  elif type(show_result) is list:
122  import subprocess
123  p = subprocess.Popen(show_result + [filesave])
124  else:
125  # open file with default application
126  import os
127  os.startfile(filesave)
128  if len(self.LOG) > 0:
129  mbox('Program generation LOG:\n\n' + self.LOG)
130 
131  def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass):
132  """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".
133  The connection parameters must be provided in the robot connection menu of RoboDK"""
134  UploadFTP(self.PROG_FILES, robot_ip, remote_path, ftp_user, ftp_pass)
135 
136  def MoveJ(self, pose, joints, conf_RLF=None):
137  """Add a joint movement"""
138  #MOVE P, @P J(20.007, 70.475, 85.691, -137.266, 18.729, 64.496), Speed=20
139  self.addline('MOVE P, %s %s, Speed=20' % (self.PASS, joints_2_str(joints)))
140 
141  def MoveL(self, pose, joints, conf_RLF=None):
142  """Add a linear movement"""
143  #MOVE L,@P P( -28.99, 20, 67.243, -90, -50.442, -180)
144  if pose is None:
145  self.addline('MOVE L, %s %s, Speed=20' % (self.PASS, joints_2_str(joints)))
146  else:
147  self.addline('MOVE L, %s %s, Speed=Mps(%.1f)' % (self.PASS, pose_2_str(pose), self.SPEED_MPS))
148 
149  def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None):
150  """Add a circular movement"""
151  #self.addlog('Circular move is not supported!')
152  #MOVE C, P( -25.306, 20, 68.895, -90, -49.948, -180),@[5] P( -19.256, 20, 62, -90, -50.06, -180), Speed=Mps(3)
153  self.addline('MOVE C, %s,%s %s, Speed=Mps(%.1f)' % (pose_2_str(pose1), self.PASS, pose_2_str(pose1), self.SPEED_MPS))
154 
155  def setFrame(self, pose, frame_id=None, frame_name=None):
156  """Change the robot reference frame"""
157  if frame_id is not None and frame_id > 0:
158  self.ACTIVE_TOOL = frame_id
159  self.addline('Work %i, %s' % (self.ACTIVE_TOOL, pose_2_str(pose)))
160  self.addline('ChangeWork %i' % self.ACTIVE_TOOL)
161 
162  def setTool(self, pose, tool_id=None, tool_name=None):
163  """Change the robot TCP"""
164  if tool_id is not None and tool_id > 0:
165  self.ACTIVE_WOBJ = frame_id
166  self.addline('Tool %i, %s' % (self.ACTIVE_WOBJ, pose_2_str(pose)))
167  self.addline('ChangeTool %i' % self.ACTIVE_WOBJ)
168 
169  def Pause(self, time_ms):
170  """Pause the robot program"""
171  if time_ms <= 0:
172  self.addline('PAUSE') # Important for calibration
173  else:
174  self.addline('DELAY %i' % time_ms)
175 
176  def setSpeed(self, speed_mms):
177  """Changes the robot speed (in mm/s)"""
178  self.SPEED_MPS = speed_mms/1000.0
179 
180  def setAcceleration(self, accel_mmss):
181  """Changes the robot acceleration (in mm/s2)"""
182  # Warning! Here, acceleration in mmss is considered as a percentage!
183  #accel_percentage = min(100,max(0,accel_mmss))
184  #self.addline('ACCEL %.1f, %.1f' % (accel_percentage, accel_percentage))
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 zone data approach (makes the movement more smooth)"""
199  #self.addlog('setZoneData not defined (%.1f mm)' % zone_mm)
200  # Encoder value check / pass @0 (fine), @P (approximated), @value (pulse value approximation) or @E
201  if zone_mm <=0:
202  self.PASS = '@0'
203  else:
204  self.PASS = '@P'
205  #self.PASS = '@[%i]' % zone_mm # Define zone data in pulses
206 
207  def setDO(self, io_var, io_value):
208  """Sets a variable (output) to a given value"""
209  if type(io_var) != str: # set default variable name if io_var is a number
210  io_var = 'IO[%s]' % str(io_var)
211  if type(io_value) != str: # set default variable value if io_value is a number
212  if io_value > 0:
213  io_value = 'ON'
214  else:
215  io_value = 'OFF'
216 
217  # at this point, io_var and io_value must be string values
218  self.addline('OUT %s = %s' % (io_var, io_value))
219 
220  def waitDI(self, io_var, io_value, timeout_ms=-1):
221  """Waits for an input io_var to attain a given value io_value. Optionally, a timeout can be provided."""
222  if type(io_var) != str: # set default variable name if io_var is a number
223  io_var = 'IO[%s]' % str(io_var)
224  if type(io_value) != str: # set default variable value if io_value is a number
225  if io_value > 0:
226  io_value = 'ON'
227  else:
228  io_value = 'OFF'
229 
230  # at this point, io_var and io_value must be string values
231  if timeout_ms < 0:
232  self.addline('WAIT %s = %s' % (io_var, io_value))
233  else:
234  self.addline('WAIT %s = %s, %.0f' % (io_var, io_value, timeout_ms))
235 
236  def RunCode(self, code, is_function_call = False):
237  """Adds code or a function call"""
238  if is_function_call:
239  code.replace(' ','_')
240  if code.find('(') < 0:
241  code = code + '()'
242  self.addline(code)
243  else:
244  self.addline(code)
245 
246  def RunMessage(self, message, iscomment = False):
247  """Add a joint movement"""
248  if iscomment:
249  self.addline('\' ' + message)
250  else:
251  self.addline('\'Output "' + message + '"')
252 
253 # ------------------ private ----------------------
254  def addline(self, newline):
255  """Add a program line"""
256  self.PROG = self.PROG + self.TAB + newline + '\n'
257 
258  def addlog(self, newline):
259  """Add a log message"""
260  self.LOG = self.LOG + newline + '\n'
261 
262 # -------------------------------------------------
263 # ------------ For testing purposes ---------------
264 def Pose(xyzrpw):
265  [x,y,z,r,p,w] = xyzrpw
266  a = r*math.pi/180
267  b = p*math.pi/180
268  c = w*math.pi/180
269  ca = math.cos(a)
270  sa = math.sin(a)
271  cb = math.cos(b)
272  sb = math.sin(b)
273  cc = math.cos(c)
274  sc = math.sin(c)
275  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]])
276 
277 def test_post():
278  """Test the post with a basic program"""
279 
280  robot = RobotPost('Vplus_custom', 'Generic Adept Robot')
281 
282  robot.ProgStart("Program")
283  robot.RunMessage("Program generated by RoboDK", True)
284  robot.setFrame(Pose([807.766544, -963.699898, 41.478944, 0, 0, 0]))
285  robot.setTool(Pose([62.5, -108.253175, 100, -60, 90, 0]))
286  robot.MoveJ(Pose([200, 200, 500, 180, 0, 180]), [-46.18419, -6.77518, -20.54925, 71.38674, 49.58727, -302.54752] )
287  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
288  robot.MoveL(Pose([200, 200, 262.132034, 180, 0, -150]), [-43.73892, -3.91728, -35.77935, 58.57566, 54.11615, -253.81122] )
289  robot.RunMessage("Setting air valve 1 on")
290  robot.RunCode("TCP_On", True)
291  robot.Pause(1000)
292  robot.MoveL(Pose([200, 250, 348.734575, 180, 0, -150]), [-41.62707, -8.89064, -30.01809, 60.62329, 49.66749, -258.98418] )
293  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
294  robot.MoveL(Pose([250, 250, 191.421356, 180, 0, -150]), [-39.75778, -1.04537, -40.37883, 52.09118, 54.15317, -246.94403] )
295  robot.RunMessage("Setting air valve off")
296  robot.RunCode("TCP_Off(55)", True)
297  robot.Pause(1000)
298  robot.MoveL(Pose([250, 300, 278.023897, 180, 0, -150]), [-37.52588, -6.32628, -34.59693, 53.52525, 49.24426, -251.44677] )
299  robot.MoveL(Pose([250, 200, 278.023897, 180, 0, -150]), [-41.85389, -1.95619, -34.89154, 57.43912, 52.34162, -253.73403] )
300  robot.MoveL(Pose([250, 150, 191.421356, 180, 0, -150]), [-43.82111, 3.29703, -40.29493, 56.02402, 56.61169, -249.23532] )
301  robot.ProgFinish("Program")
302  # robot.ProgSave(".","Program",True)
303  print(robot.PROG)
304  if len(robot.LOG) > 0:
305  mbox('Program generation LOG:\n\n' + robot.LOG)
306 
307  input("Press Enter to close...")
308 
309 if __name__ == "__main__":
310  """Function to call when the module is executed by itself: test"""
311  test_post()
def ProgSave(self, folder, progname, ask_user=False, show_result=False)
Definition: Denso_RC8.py:99
def MoveJ(self, pose, joints, conf_RLF=None)
Definition: Denso_RC8.py:136
def ProgSendRobot(self, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: Denso_RC8.py:131
def setFrame(self, pose, frame_id=None, frame_name=None)
Definition: Denso_RC8.py:155
def MoveL(self, pose, joints, conf_RLF=None)
Definition: Denso_RC8.py:141
def waitDI(self, io_var, io_value, timeout_ms=-1)
Definition: Denso_RC8.py:220
def MoveC(self, pose1, joints1, pose2, joints2, conf_RLF_1=None, conf_RLF_2=None)
Definition: Denso_RC8.py:149
def __init__(self, robotpost=None, robotname=None, robot_axes=6, kwargs)
Definition: Denso_RC8.py:79
def RunMessage(self, message, iscomment=False)
Definition: Denso_RC8.py:246
def UploadFTP(program, robot_ip, remote_path, ftp_user, ftp_pass)
Definition: robodk.py:1312
def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=None)
Definition: robodk.py:1458
def setTool(self, pose, tool_id=None, tool_name=None)
Definition: Denso_RC8.py:162
def getSaveFile(strdir='C:\\', strfile='file.txt', strtitle='Save file as ...')
Definition: robodk.py:1354
def RunCode(self, code, is_function_call=False)
Definition: Denso_RC8.py:236


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