3 from __future__
import with_statement
5 PKG=
'pr2_camera_synchronizer' 6 import roslib; roslib.load_manifest(PKG)
8 from ethercat_trigger_controllers.msg
import MultiWaveform
9 import dynamic_reconfigure.client
27 pts = [ (x % self.period, y)
for (x, y)
in self.pts ]
28 firstpt = pts.index(min(pts, key =
lambda xy:xy[0]))
29 pts = pts[firstpt:] + pts[:firstpt]
38 raise Exception(
"Last point in sequence has non-zero y coord in %s."%self.name)
41 while idx < len(self.pts):
45 while self.pts[idx][1]:
46 max_value = max(max_value, self.pts[idx][1])
48 intervals.append((self.pts[startidx][0], self.pts[idx][0], max_value))
54 for i
in range(1, reps):
56 out += [(s+offset,e+offset,v)
for (s,e,v)
in intervals]
60 return [e-s
for s,e,v
in intervals]
90 total = max(0, min(b1w, a1w) - max(b0w, a0w))
97 total += max(0, min(b1w, a1w) - max(b0w, a0w) )
112 rospy.Subscriber(trigger_name +
"/waveform", MultiWaveform, self.
callback)
127 offset = msg.zero_offset
128 self.
pts = [ ((trans.time + offset) % self.
period, trans.value % 2)
for trans
in msg.transitions ]
141 parent.add_camera(self)
145 self.
client = dynamic_reconfigure.client.Client(node_name,
150 projector_intervals = projector.intervals()
158 reps = self.
period / projector.period
160 raise Exception(
"Camera %s period is %f, projector period is %f, ratio %f"%
161 (self.
name,self.
period,projector.period,reps))
167 for s, e, v
in camera_intervals:
168 info =
"camera %s exposing from %f to %f"%(self.
name,s,e)
171 interval = s+0.0004, e-0.0004, v
174 interval = s-0.0005, e+0.0005, v
176 raise Exception(
"Can't determine register set, %s.", info)
179 red_light_times.sort()
180 red_light_time = sum(red_light_times)
181 if red_light_time
and red_light_time != red_light_times[-1]:
184 raise Exception(
"Intersection with multiple pulses, %s."%info)
186 if red_light_time
and abs(red_light_time - projector_pulse_len) > slight_shift:
189 raise Exception(
"Partial intersection with pulse (alt=%s), %s, %f s of %f, delta %e."%(alt, info, red_light_time, projector_pulse_len, red_light_time-projector_pulse_len))
190 if alt
and not red_light_time:
191 raise Exception(
"Alternate imager but no projector, %s."%info)
192 if not alt
and red_light_time:
193 raise Exception(
"Primary imager and has projector, %s."%info)
194 with_proj_exp = projector_pulse_len + 0.0015 + 2 * slight_shift
195 if alt
and e - s > with_proj_exp:
196 raise Exception(
"Too long exposure for textured image %f instead of %f, %s."%(e-s,with_proj_exp,info))
197 except Exception
as e:
200 self.parent.set_error(repr(e))
203 if not self.
ready or not self.trigger.ready:
206 if not self.
config[
'ext_trig']:
211 rising = self.
config[
'rising_edge_trig']
212 before = 0
if rising
else 1
215 imager_period = 1.0 / self.
config[
'imager_rate']
220 tpts = self.trigger.sorted_pts()
221 for i
in range(len(tpts)):
222 if tpts[i-1][1] == before
and tpts[i][1] == after:
229 last_trig = -imager_period
232 for i
in range(len(pretrigpts)):
234 if pretrigpts[i] - last_trig > imager_period:
235 last_trig = pretrigpts[i]
236 last_count = trig_count
239 first_trig = last_trig
240 last_trig = first_trig - self.
period 241 for i
in range(len(pretrigpts)):
243 if pretrigpts[i] - last_trig > imager_period:
244 last_trig = pretrigpts[i]
245 reg_set = self.
config[
'register_set']
247 reg_set = 1
if (last_count - trig_count) % 2
else 0
248 trigpts.append((pretrigpts[i], reg_set))
249 last_count = trig_count
253 if last_trig != first_trig:
254 self.parent.set_error(
"Non-consistent triggering times for %s."%self.
name)
257 cfg_suffix = [
"",
"_alternate" ]
260 max_exp = self.
config[
'max_exposure']
262 auto_exp = self.
config[
'auto_exposure'+cfg_suffix[i]]
263 set_exp = self.
config[
'exposure'+cfg_suffix[i]]
267 cur_min = min(max_exp, set_exp)
269 exposure_min.append(cur_min)
270 exposure_max.append(cur_max)
273 for (t, rs)
in trigpts:
274 alternate_offset = - rs * 0.25
275 exp_end = t + imager_period
276 exp_start_early = exp_end - exposure_max[rs]
277 exp_start_late = exp_end - exposure_min[rs]
278 if exp_start_early != exp_start_late:
279 self.pts.append((exp_start_early - slight_shift, 0.5 + alternate_offset))
280 self.pts.append((exp_start_late, 1 + alternate_offset))
281 self.pts.append((exp_end + slight_shift, 0))
288 self.
config = copy.deepcopy(config)
309 self.
gnuplot = subprocess.Popen(
'gnuplot', stdin = subprocess.PIPE)
311 print(
"Gnuplot must be installed to allow plotting of waveforms.")
313 atexit.register(self.gnuplot.kill)
316 self.triggers.append(trigger)
319 self.cameras.append(cam)
338 self.
set_error(
'No data for %s. (This is normal at startup.)'%self.
triggers[i].name)
351 rospy.loginfo(
"All checks passed.")
353 rospy.logerr(
"Some checks failed.")
363 period = max(t.period
for t
in self.
triggers)
365 if (period / self.
triggers[i].period) % 1:
366 self.
set_error(
'Period for %s is %f, expected divisor of %f'%(self.
triggers[i].name,
369 style =
'with linespoints title "%s"' 370 print(
'plot "-"', style%self.
triggers[0].name, end=
' ', file=self.gnuplot.stdin)
371 for i
in range(1, n):
372 print(
', "-"', style%self.
triggers[i].name, end=
' ', file=self.gnuplot.stdin)
373 print(file=self.gnuplot.stdin)
376 reps = int(period / t.period)
381 print(x, (n - i - 1) * 1.1 + y%2, file=self.gnuplot.stdin)
382 plot_pt(0, pts[-1][1])
383 for k
in range(reps):
385 for j
in range(len(pts)):
386 plot_pt(pts[j][0] + xoffs, pts[j-1][1])
387 plot_pt(pts[j][0] + xoffs, pts[j][1])
388 plot_pt(period, pts[-1][1])
389 print(
"e", file=self.gnuplot.stdin)
390 print(file=self.gnuplot.stdin)
399 global tp, reconfig_client
403 self.reconfig_client.update_configuration({
'projector_mode': 1})
408 starttime = time.time()
409 while not rospy.is_shutdown():
410 if time.time() > starttime + 5:
411 self.fail(
"Took too long to get responses.")
421 self.assertFalse(tp.error, tp.error)
424 self.reconfig_client.update_configuration({
425 'projector_pulse_shift': 0.0,
426 'wide_stereo_trig_mode': 3,
427 'prosilica_projector_inhibit':
False,
428 'camera_reset':
False,
429 'forearm_r_rate': 30.0,
430 'projector_rate': 58.823529411764703,
431 'stereo_rate': 29.411764705882351,
432 'projector_pulse_length': 0.002,
434 'forearm_r_trig_mode': 3,
435 'projector_tweak': 0.0,
436 'forearm_l_trig_mode': 3,
437 'forearm_l_rate': 30.0,
438 'narrow_stereo_trig_mode': 3,
443 self.reconfig_client.update_configuration({
444 'projector_pulse_shift': 0.0,
445 'wide_stereo_trig_mode': 4,
446 'prosilica_projector_inhibit':
False,
447 'camera_reset':
False,
448 'forearm_r_rate': 30.0,
449 'projector_rate': 58.823529411764703,
450 'stereo_rate': 29.411764705882351,
451 'projector_pulse_length': 0.002,
453 'forearm_r_trig_mode': 4,
454 'projector_tweak': 0.0,
455 'forearm_l_trig_mode': 4,
456 'forearm_l_rate': 30.0,
457 'narrow_stereo_trig_mode': 4,
462 self.reconfig_client.update_configuration({
463 'projector_pulse_shift': 0.0,
464 'wide_stereo_trig_mode': 4,
465 'prosilica_projector_inhibit':
False,
466 'camera_reset':
False,
467 'forearm_r_rate': 30.0,
468 'projector_rate': 58.823529411764703,
469 'stereo_rate': 29.411764705882351,
470 'projector_pulse_length': 0.002,
472 'forearm_r_trig_mode': 4,
473 'projector_tweak': 0.0,
474 'forearm_l_trig_mode': 4,
475 'forearm_l_rate': 30.0,
476 'narrow_stereo_trig_mode': 5,
481 self.reconfig_client.update_configuration({
482 'projector_pulse_shift': 0.0,
483 'wide_stereo_trig_mode': 4,
484 'prosilica_projector_inhibit':
False,
485 'camera_reset':
False,
486 'forearm_r_rate': 5.0,
487 'projector_rate': 58.823529411764703,
489 'projector_pulse_length': 0.002,
491 'forearm_r_trig_mode': 4,
492 'projector_tweak': 0.0,
493 'forearm_l_trig_mode': 3,
494 'forearm_l_rate': 5.0,
495 'narrow_stereo_trig_mode': 5,
500 global tp, reconfig_client
501 regression_test = rospy.get_param(
'~regression_test',
False)
502 tp =
TriggerChecker(plot =
not regression_test, silent = regression_test)
503 head_trig =
Trigger(tp,
'/head_camera_trigger')
504 l_forearm_trig =
Trigger(tp,
'l_forearm_cam_trigger')
505 r_forearm_trig =
Trigger(tp,
'r_forearm_cam_trigger')
506 Camera(tp,
'/narrow_stereo_both', head_trig)
507 tp.set_projector(
Trigger(tp,
'/projector_trigger'))
508 Camera(tp,
'/wide_stereo_both', head_trig)
509 Camera(tp,
'/l_forearm_cam', l_forearm_trig)
510 Camera(tp,
'/r_forearm_cam', r_forearm_trig)
513 rospy.loginfo(
"Running in unit test mode")
514 reconfig_client = dynamic_reconfigure.client.Client(
'synchronizer')
515 rostest.rosrun(PKG,
'test_bare_bones', Test)
517 rospy.loginfo(
"Running in plotting mode")
518 while not rospy.is_shutdown():
521 if __name__ ==
"__main__":
522 rospy.init_node(
'trigger_plotter', anonymous =
True)
def __init__(self, parent, node_name, trigger)
def set_projector(self, projector)
def __init__(self, plot, silent=False)
def replicate_interval(intervals, period, reps)
def add_camera(self, cam)
def check(self, projector)
def callback(self, config)
def __init__(self, parent, trigger_name)
def interval_intersection(a, b, period)
def interval_lengths(intervals)