test_classes.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Software License Agreement (BSD License)
3 #
4 # Copyright (c) 2008, Willow Garage, Inc.
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 #
11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following
15 # disclaimer in the documentation and/or other materials provided
16 # with the distribution.
17 # * Neither the name of Willow Garage, Inc. nor the names of its
18 # contributors may be used to endorse or promote products derived
19 # from this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 # POSSIBILITY OF SUCH DAMAGE.
33 
34 PKG = "pr2_camera_synchronizer"
35 import roslib; roslib.load_manifest(PKG)
37 import unittest
38 import pr2_camera_synchronizer.cfg.CameraSynchronizerConfig as Config
39 
40 DIGITS = 16
41 
42 def issorted(l):
43  copy = list(l)
44  copy.sort()
45  return copy == l
46 
47 def interlace(l1, l2):
48  l = zip(l1, l2)
49  return list(sum(l, ()))
50 
51 class TestProjector(unittest.TestCase):
52  def runCase(self, rate, length, shift, out_repeat_period, out_proj_end, out_alt_end, out_noproj_end, level = lvl_projector):
53  config = {
54  param_proj_rate : rate,
55  "projector_pulse_length" : length,
56  "projector_pulse_shift" : shift,
57  "projector_tweak" : 0,
58  "projector_mode" : Config.CameraSynchronizer_ProjectorOn,
59  }
60  proj = Projector()
61  proj.process_update(config, level)
62 
63  if level & lvl_projector != 0:
64  self.assert_(math.fmod(config["projector_rate"], ETHERCAT_INTERVAL)) # Integer multiples of ethercat rate
65  self.assert_(config["projector_pulse_length"] >= length, "Pulse length %f"%config["projector_pulse_length"]) # Never shorten the pulse length
66  self.assertEqual(config["projector_pulse_length"], proj.pulse_length) # Pulse lengths are consistent
67  self.assert_(math.fmod(proj.pulse_length, ETHERCAT_INTERVAL) == 0, "Pulse length %f"%proj.pulse_length) # Integer multiples of ethercat rate
68  self.assertEqual(len(proj.pulse_ends), 4) # Right number of pulses
69  self.assertEqual(len(proj.pulse_starts), 4) # Right number of pulses
70  self.assert_(issorted(interlace(proj.pulse_starts, proj.pulse_ends))) # Starts and stops are in right order
71  self.assertEqual(4. / proj.repeat_period, config["projector_rate"]) # Base period and repeat period are consistent.
72 
73  self.assertEqual(out_repeat_period, proj.repeat_period)
74  self.assertEqual(out_proj_end, proj.proj_end_offset)
75  self.assertEqual(out_noproj_end, proj.noproj_end_offset)
76  self.assertAlmostEqual(out_alt_end, proj.alt_end_offset, DIGITS)
77 
78  return proj, config
79 
81  proj,config = self.runCase(30, 0.002, 0, 0.132, 0.003, 0.036, 0.032)
82 
83 class TestCamera(unittest.TestCase):
84  def runCase(self, proj_rate, proj_length, proj_shift, rate, trig_mode, out_period, out_ext_trig, out_imager_period, out_end_offset, level = 1, reset_camera = False):
85  paramnames = dict((name,name) for name in camera_parameters)
86  config = {
87  param_proj_rate : proj_rate,
88  "projector_pulse_length" : proj_length,
89  "projector_pulse_shift" : proj_shift,
90  "projector_tweak" : 0,
91  "projector_mode" : Config.CameraSynchronizer_ProjectorOn,
92  param_rate : rate,
93  param_trig_mode : trig_mode,
94  "camera_reset" : reset_camera,
95  }
96 
97  proj = Projector()
98  proj.process_update(config, lvl_projector)
99  camera = Camera("test_cam", proj, 1, **paramnames)
100  camera.process_update(config, level)
101 
102  if level & 1 == 0:
103  self.assert_(math.fmod(camera.period, ETHERCAT_INTERVAL) == 0) # Integer multiples of ethercat rate
104  self.assertEqual(config[param_rate], 1. / camera.period) # Rate was correctly set in config
105 
106  self.assert_(out_period > 0, "Period %f"%out_period) # Non-zero period
107  self.assertAlmostEqual(camera.period, out_period, DIGITS) # Correct camera period
108  self.assertEqual(camera.ext_trig, out_ext_trig) # Ext trig when expected
109  self.assert_(out_imager_period > 0, "Imager period %f"%out_imager_period) # Non-zero imager period
110  self.assertAlmostEqual(camera.imager_period, out_imager_period, DIGITS) # Correct imager period
111  self.assertAlmostEqual(camera.end_offset, out_end_offset, DIGITS) # Correct end offset
112 
113  return camera, proj, config
114 
116  self.runCase(60, 0.001, 0, 30, Config.CameraSynchronizer_WithProjector, 0.034, True, 0.033, 0.002) # Always proj
118  self.runCase(60, 0.001, 0, 30, Config.CameraSynchronizer_AlternateProjector, 0.034, True, 0.033, 0.019) # Alternate proj
119  def testBasicNoProj(self):
120  self.runCase(60, 0.001, 0, 30, Config.CameraSynchronizer_WithoutProjector, 0.034, True, 0.033, 0.016) # No proj
121  def testBasicFreeRun(self):
122  self.runCase(60, 0.001, 0, 30, Config.CameraSynchronizer_InternalTrigger, 1/30.0, False, 1/30.0, -1) # Freerun
123 
124 if __name__ == '__main__':
125  import rostest
126  import rospy
127  import time
128 
129  # Not starting a node, so we can't use rospy's time functions.
130  rospy.get_time = time.time
131 
132  rostest.rosrun(PKG, 'test_projector', TestProjector)
133  rostest.rosrun(PKG, 'test_camera', TestCamera)
def issorted(l)
Definition: test_classes.py:42
def interlace(l1, l2)
Definition: test_classes.py:47
def runCase(self, proj_rate, proj_length, proj_shift, rate, trig_mode, out_period, out_ext_trig, out_imager_period, out_end_offset, level=1, reset_camera=False)
Definition: test_classes.py:84
def runCase(self, rate, length, shift, out_repeat_period, out_proj_end, out_alt_end, out_noproj_end, level=lvl_projector)
Definition: test_classes.py:52
def testBasicAlternateProj(self)


pr2_camera_synchronizer
Author(s): Blaise Gassend
autogenerated on Tue Jun 1 2021 02:50:50