def test_real_defer(self): """ check that real axes update as expected on virtual axis moves """ for _ in range(4): # retry for possible occasional race condition tb = TestBrick() tb.set_cs_group(tb.g2) tb.set_deferred_moves(True) tb.jack1.go(5, wait=False) tb.jack2.go(4, wait=False) Sleep(1) # verify no motion yet self.assertAlmostEqual(tb.jack1.pos, 0, DECIMALS) self.assertAlmostEqual(tb.jack2.pos, 0, DECIMALS) m = MoveMonitor(tb.jack1.pv_root) start = datetime.now() tb.set_deferred_moves(False) m.wait_for_one_move(10) elapsed = datetime.now() - start print(elapsed) # verify motion self.assertAlmostEqual(tb.jack1.pos, 5, DECIMALS) self.assertAlmostEqual(tb.jack2.pos, 4, DECIMALS) self.assertTrue(elapsed.seconds < 4)
def test_kinematic_axis_creep(self): """ Check that a move in a coordinate system starts from the previous demand for axes that are not being demanded in this move. i.e. jitter does not accumulate in CS axes that are not being demanded. :return: None """ tb = TestBrick() tb.set_cs_group(tb.g3) tb.cs3.set_move_time(0) # do a CS move of Height tb.height.go(1) # pretend that axis 3 moved by itself and monitor change in height. monitor = MoveMonitor(tb.height.pv_root) tb.send_command('#3J:1000') monitor.wait_for_one_move(10) # this should make Height 1.5mm self.assertAlmostEqual(tb.height.pos, 1.5, DECIMALS) # now move Angle tb.angle.go(1) self.assertAlmostEqual(tb.angle.pos, 1, DECIMALS) # Height should return to 1 self.assertAlmostEqual(tb.height.pos, 1, DECIMALS)
def test_stop_on_limit_resets_cs_demands(self): tb = TestBrick() tb.set_cs_group(tb.g3) m = MoveMonitor(tb.height.pv_root) tb.cs3.set_deferred_moves(True) tb.cs3.set_move_time(3000) tb.height.go(10, wait=False) tb.cs3.M1.go_direct(10, wait=False) # verify no motion yet Sleep(.1) self.assertAlmostEqual(tb.height.pos, 0, DECIMALS) self.assertAlmostEqual(tb.m1.pos, 0, DECIMALS) # start motion but stop on lim tb.m3.set_limits(-1, 1) tb.cs3.set_deferred_moves(False) # let axes settle m.wait_for_one_move(2) h = tb.height.pos m1 = tb.m1.pos self.assertLess(h, 10) self.assertLess(m1, 10) # for some reason a large wait is required before go_direct # in a real scenario this is fine even though I don't understand it Sleep(5) # now move a different motor in the CS, the other two would continue to # their previous destinations if makeCSDemandsConsistent has failed tb.cs3.M2.go_direct(10) self.assertAlmostEqual(h, tb.height.pos, DECIMALS) self.assertAlmostEqual(m1, tb.m1.pos, DECIMALS) self.assertAlmostEqual(10, tb.m2.pos, DECIMALS)
def test_virtual_abort(self): tb = TestBrick() tb.set_cs_group(tb.g3) big_move = 1000 monitor = MoveMonitor(tb.height.pv_root) tb.height.go(big_move, wait=False) Sleep(.2) tb.cs3.abort() monitor.wait_for_one_move(2) self.assertTrue(0 < tb.height.pos < big_move)
def test_unmapped_real_stop(self): tb = TestBrick() tb.set_cs_group(tb.g3) big_move = 1000 monitor = MoveMonitor(tb.m8.pv_root) tb.m8.go(big_move, wait=False) Sleep(.2) tb.m8.stop() monitor.wait_for_one_move(2) self.assertTrue(0 < tb.m8.pos < big_move)
def test_direct_axis_creep(self): """ Check that a move in a coordinate system starts from the previous demand for axes that are not being demanded in this move. i.e. jitter does not accumulate in CS axes that are not being demanded. This test is the same as test_kinematic_axis_creep except that the initial move and position verification is via real axes. This did raise an interesting issue not seen in the previous test. See comment NOTE below :return: None """ tb = TestBrick() # set the appropriate coordinate system group tb.set_cs_group(tb.g3) # the first CS move after a coord sys group switch clears the cached real motor positions # so this test must do that initial CS move here # MAKE SURE this actually initiates a move, else makeCSDemandsConsistent wont be called tb.height.go(1) # NOTE: the above is a little artificial and masks a very minor issue: any axis creep that occurs # between changing coordinate system mappings and the first CS move will be kept - fixing # this would require architecture changes for an unlikely event with little consequence for cs_move in range(6, 10): move = cs_move tb.cs3.set_move_time(0) # move affected axes to start # note this is also testing that moving the real axes updates the # Q7x variables for the associated virtual axes tb.all_go([tb.m1, tb.m2, tb.m3, tb.m4], [0, 0, 0, 0]) # pretend that axis 1 moved by itself. monitor = MoveMonitor(tb.m1.pv_root) tb.send_command('#1J:{}'.format(move)) monitor.wait_for_one_move(1, throw=False) # this should put axis 1 at {move}mm self.assertEquals(tb.m1.pos, move) # now move the CS axis Height tb.height.go(cs_move) self.assertAlmostEqual(tb.height.pos, cs_move, DECIMALS) # Axis 1 should return to 0 self.assertAlmostEqual(tb.m1.pos, 0, DECIMALS)
def test_cs_defer(self): """ check timed deferred moves and also individual cs moves """ tb = TestBrick() tb.set_cs_group(tb.g3) tb.cs3.set_deferred_moves(True) tb.cs3.set_move_time(3000) tb.height.go(5, wait=False) tb.angle.go(1, wait=False) # verify no motion yet Sleep(1) self.assertAlmostEqual(tb.height.pos, 0, DECIMALS) self.assertAlmostEqual(tb.angle.pos, 0, DECIMALS) m = MoveMonitor(tb.height.pv_root) start = datetime.now() tb.cs3.set_deferred_moves(False) m.wait_for_one_move(10) elapsed = datetime.now() - start print(elapsed) # verify motion self.assertAlmostEqual(tb.angle.pos, 1, DECIMALS) self.assertAlmostEqual(tb.height.pos, 5, DECIMALS) # todo this seems to take longer than I would expect - is this an issue? # todo YES - moves to real and virtual axes are taking an extra SLOW POLL # todo before DMOV is set True self.assertTrue(3 <= elapsed.seconds < 6) # single axis move should be controlled by speed setting, not CsMoveTime start = datetime.now() tb.height.go(0) elapsed = datetime.now() - start print(elapsed) self.assertAlmostEqual(tb.height.pos, 0, DECIMALS) self.assertTrue(elapsed.seconds < 2)