/ tests / hard-limits / test-ui.py
test-ui.py
  1  #!/usr/bin/env python
  2  
  3  import linuxcnc
  4  import hal
  5  
  6  import time
  7  import sys
  8  import subprocess
  9  import os
 10  import signal
 11  import glob
 12  import re
 13  
 14  
 15  def print_status(status):
 16      status.poll()
 17      print "status.axis[0]:", status.axis[0]
 18      print "status.axis[1]:", status.axis[1]
 19      print "status.joint[0]:", status.joint[0]
 20      print "status.joint[1]:", status.joint[1]
 21      print "status.current_vel:", status.current_vel
 22      print "status.echo_serial_number:", status.echo_serial_number
 23      print "status.enabled:", status.enabled
 24      print "status.estop:", status.estop
 25      print "status.exec_state:", status.exec_state
 26      print "status.inpos:", status.inpos
 27      print "status.interp_state:", status.interp_state
 28      print "status.interpreter_errcode:", status.interpreter_errcode
 29      print "status.limit:", status.limit
 30      print "status.motion_mode:", status.motion_mode
 31      print "status.motion_type:", status.motion_type
 32      print "status.position:", status.position
 33      print "status.state:", status.state
 34      print "status.task_mode:", status.task_mode
 35      print "status.task_state:", status.task_state
 36      print "status.velocity:", status.velocity
 37      sys.stdout.flush()
 38  
 39  
 40  def assert_wait_complete(command):
 41      r = command.wait_complete()
 42      print "wait_complete() returns", r
 43      assert((r == linuxcnc.RCS_DONE) or (r == linuxcnc.RCS_ERROR))
 44  
 45  
 46  #
 47  # connect to HAL
 48  #
 49  
 50  comp = hal.component("test-ui")
 51  comp.newpin("x-neg-lim-sw", hal.HAL_BIT, hal.HAL_OUT)
 52  comp.ready()
 53  
 54  hal.connect('test-ui.x-neg-lim-sw', 'x-neg-lim-sw')
 55  
 56  
 57  #
 58  # connect to LinuxCNC
 59  #
 60  
 61  c = linuxcnc.command()
 62  s = linuxcnc.stat()
 63  e = linuxcnc.error_channel()
 64  
 65  
 66  #
 67  # Come out of E-stop, turn the machine on, switch to Manual mode, and home.
 68  #
 69  
 70  c.state(linuxcnc.STATE_ESTOP_RESET)
 71  c.state(linuxcnc.STATE_ON)
 72  c.mode(linuxcnc.MODE_MANUAL)
 73  c.home(0)
 74  c.home(1)
 75  c.home(2)
 76  c.wait_complete()
 77  
 78  # wait for homing to complete
 79  start_time = time.time()
 80  s.poll()
 81  all_homed = s.homed[0]+s.homed[1]+s.homed[2]
 82  while (all_homed is not 3) and (time.time() - start_time < 5):
 83      time.sleep(0.100)
 84      s.poll()
 85      all_homed = s.homed[0]+s.homed[1]+s.homed[2]
 86  
 87  if all_homed is not 3:
 88      print "failed to home"
 89      print "s.homed:", s.homed
 90      sys.exit(1)
 91  
 92  c.teleop_enable(0)
 93  
 94  
 95  #
 96  # run the test: start a jog on X, then trip a limit switch
 97  #
 98  
 99  # jog arguments are: (jog_type, joint_flag, axis, velocity)
100  c.jog(linuxcnc.JOG_CONTINUOUS, 1, 0, -0.1)
101  
102  # verify that we're starting to move
103  s.poll()
104  old_x = s.position[0]
105  start_time = time.time()
106  while (old_x == s.position[0]) and (time.time() - start_time < 5):
107      time.sleep(0.1)
108      s.poll()
109  
110  if old_x == s.position[0]:
111      print "no jog movement"
112      sys.exit(1)
113  
114  print "x started moving (%.6f to %.6f)" % (old_x, s.position[0])
115  print_status(s)
116  
117  # verify that Status reflects the situation
118  assert(s.joint[0]['min_soft_limit'] == False)
119  assert(s.joint[0]['min_hard_limit'] == False)
120  assert(s.joint[0]['max_soft_limit'] == False)
121  assert(s.joint[0]['max_hard_limit'] == False)
122  assert(s.joint[0]['inpos'] == False)
123  assert(s.joint[0]['enabled'] == True)
124  
125  assert(not (1 in s.limit))
126  assert(s.inpos == False)
127  assert(s.enabled == True)
128  
129  # trip the limit switch
130  comp['x-neg-lim-sw'] = True
131  
132  # let linuxcnc react to the limit switch
133  expected_error = 'joint 0 on limit switch error'
134  start_time = time.time()
135  while (time.time() - start_time < 5):
136      error = e.poll()
137      if error != None:
138          if error[1] == expected_error:
139              break
140          else:
141              print "linuxcnc sent other error %d: %s" % (error[0], error[1])
142      time.sleep(0.1)
143  
144  if error == None or error[1] != expected_error:
145      print "no limit switch error from LinuxCNC"
146      sys.exit(1)
147  
148  print "linuxcnc sent error %d: %s" % (error[0], error[1])
149  print_status(s)
150  
151  # verify that we're stopping
152  s.poll()
153  start_time = time.time()
154  while (s.joint[0]['velocity'] != 0.0) and (time.time() - start_time < 5):
155      time.sleep(0.1)
156      s.poll()
157  
158  if s.joint[0]['velocity'] != 0.0:
159      print "limit switch didn't stop movement"
160      sys.exit(1)
161  
162  print "x stopped moving (pos=%.6f, vel=%.6f)" % (s.position[0], s.joint[0]['velocity'])
163  print_status(s)
164  
165  # verify that Status reflects the situation
166  assert(s.joint[0]['min_soft_limit'] == False)
167  assert(s.joint[0]['min_hard_limit'] == True)
168  assert(s.joint[0]['max_soft_limit'] == False)
169  assert(s.joint[0]['max_hard_limit'] == False)
170  assert(s.joint[0]['inpos'] == True)
171  assert(s.joint[0]['enabled'] == False)
172  
173  assert(s.limit[0] == 1)
174  assert(s.inpos == True)
175  assert(s.enabled == False)
176  
177  # turn the machine back on with Override Limits enabled
178  c.override_limits()
179  time.sleep(1)
180  s.poll()
181  print_status(s)
182  print "command.serial:", c.serial
183  # this fails in 2.6.12 due to the stat RCS message having a status of
184  # RCS_EXEC...  as if though the override_limits command didnt set status
185  # back to RCS_DONE when it finished.
186  # assert_wait_complete(c)
187  
188  c.state(linuxcnc.STATE_ON)
189  assert_wait_complete(c)
190  
191  # verify that Status reflects the new situation
192  s.poll()
193  assert(s.joint[0]['min_soft_limit'] == False)
194  assert(s.joint[0]['min_hard_limit'] == True)
195  assert(s.joint[0]['max_soft_limit'] == False)
196  assert(s.joint[0]['max_hard_limit'] == False)
197  assert(s.joint[0]['inpos'] == True)
198  assert(s.joint[0]['enabled'] == True)
199  
200  assert(s.limit[0] == 1)
201  assert(s.inpos == True)
202  assert(s.enabled == True)
203  
204  # jog X in the positive direction, off the negative limit switch
205  c.jog(linuxcnc.JOG_CONTINUOUS, 1, 0, 1)
206  
207  # verify that we're starting to move
208  s.poll()
209  old_x = s.position[0]
210  start_time = time.time()
211  while (old_x == s.position[0]) and (time.time() - start_time < 5):
212      time.sleep(0.1)
213      s.poll()
214  
215  if old_x == s.position[0]:
216      print "no jog movement"
217      sys.exit(1)
218  
219  print "x started moving (%.6f to %.6f)" % (old_x, s.position[0])
220  print_status(s)
221  
222  # un-trip the limit switch
223  comp['x-neg-lim-sw'] = False
224  
225  # let linuxcnc react to the limit switch untripping
226  start_time = time.time()
227  while (time.time() - start_time < 5):
228      s.poll()
229      if (s.joint[0]['min_hard_limit'] == False) and (s.limit[0] == 0):
230          break
231      time.sleep(0.1)
232  
233  # verify that Status reflects the new situation
234  assert(s.joint[0]['min_soft_limit'] == False)
235  assert(s.joint[0]['min_hard_limit'] == False)
236  assert(s.joint[0]['max_soft_limit'] == False)
237  assert(s.joint[0]['max_hard_limit'] == False)
238  assert(s.joint[0]['inpos'] == False)
239  assert(s.joint[0]['enabled'] == True)
240  
241  assert(s.limit[0] == 0)
242  assert(s.inpos == False)
243  assert(s.enabled == True)
244  
245  # stop the jog
246  c.jog(linuxcnc.JOG_STOP, 1, 0)
247  
248  # verify that we're stopping
249  s.poll()
250  old_x = s.position[0]
251  start_time = time.time()
252  while (old_x != s.position[0]) and (time.time() - start_time < 5):
253      time.sleep(0.1)
254      s.poll()
255  
256  if old_x != s.position[0]:
257      print "JOG_STOP didn't stop movement"
258      sys.exit(1)
259  
260  print "x stopped moving (%.6f)" % s.position[0]
261  print_status(s)
262  
263  # verify that Status reflects the new situation
264  assert(s.joint[0]['min_soft_limit'] == False)
265  assert(s.joint[0]['min_hard_limit'] == False)
266  assert(s.joint[0]['max_soft_limit'] == False)
267  assert(s.joint[0]['max_hard_limit'] == False)
268  # FIXME: another bug
269  #assert(s.joint[0]['inpos'] == True)
270  assert(s.joint[0]['enabled'] == True)
271  
272  assert(s.limit[0] == 0)
273  # FIXME: another bug
274  #assert(s.inpos == True)
275  assert(s.enabled == True)
276  
277  # success!
278  sys.exit(0)