New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError in motion detector recipe #109

Closed
jepicken opened this Issue Jun 18, 2014 · 4 comments

Comments

Projects
None yet
2 participants
@jepicken

jepicken commented Jun 18, 2014

I tried running the recipe for a simple motion detector from the documentation section 5.8, unmodified. It gives the following error soon after startup:

Traceback (most recent call last):
  File "motion_recipe.py", line 64, in <module>
    camera.stop_recording()
  File "/home/pi/downloads/picamera/picamera/camera.py", line 1052, in stop_recording
    self.wait_recording(0, splitter_port)
  File "/home/pi/downloads/picamera/picamera/camera.py", line 1027, in wait_recording
    self._encoders[splitter_port].wait(timeout)
  File "/home/pi/downloads/picamera/picamera/encoders.py", line 692, in wait
    raise self.exception
AttributeError: 'PiCookedOneImageEncoder' object has no attribute 'frame'

I've tried debugging it for about a day, but I haven't found anything yet. I'm a newbie at both python and picamera, so I may be missing something obvious...

P.S. thanks waveform80 for your amazing work on picamera! The documentation in particular is top notch.

@waveform80 waveform80 added the bug label Jun 25, 2014

@waveform80 waveform80 added this to the 1.6 milestone Jun 25, 2014

@waveform80 waveform80 self-assigned this Jun 25, 2014

@waveform80

This comment has been minimized.

Owner

waveform80 commented Jun 25, 2014

Sorry for the late reply on this one - it's taken me a while to track down the root cause! It's a bug in the library but an annoyingly subtle and difficult to fix one.

For my own reference and possibly for the vague amusement of others: the cause stems from the dirty hack on the frame property (introduced when the splitter_port parameter was added to permit multiple-res recording) and the fact that 1.5 made a small change to ensure that all encoders (video and image, instead of just video) got stored in the internal PiCamera._encoders property so we could accurately track when capture should be enabled or disabled on the camera port (#105).

However, the circular stream assumes any encoders in PiCamera._encoders will be video encoders (moreover it seems _get_frame assumes all encoders in there are video encoders...). Eurgh.

How to fix this (and it definitely needs fixing for 1.6)? First idea that springs to mind is that since 1.5 introduced the concept of custom encoders, if anyone really wants frame info from multiple encoders it's far better for them to go the custom encoder route than mess around with frame's schizophrenic output (sometimes a dict of tuples, sometimes a tuple). It'd be a backwards incompatible change (tut tut) but we could revert frame to always returning a tuple (from the first video encoder in the _encoders dict, if one was present).

That would fix the issue and maintain the simplicity of the library for the vast majority of users, but it would break things for anyone relying on frame's dict-behaviour for multi-res recording (they'd have to switch to using a custom encoder, although they'd probably benefit from doing so as they'd get per-frame capabilities).

Another alternatively would be to introduce a splitter_port parameter on the circular IO stream so that it knows which video encoder to query in frame's dict output. That maintains backward compatibility (as the new parameter would be optional, just as it is in start_recording) but complicates the use of the circular stream (but then, does it even work with multi-res at the moment? Something to test...). Would still need to fix _get_frame in this scenario though...

@waveform80

This comment has been minimized.

Owner

waveform80 commented Jun 25, 2014

Oh, and we should add a test for capture+record with a circular stream (to catch any regressions on this).

@jepicken

This comment has been minimized.

jepicken commented Jun 27, 2014

I'm not sure if you wanted my input on what's the best solution, but I don't feel qualified to comment since I just started using python and picamera a few days ago. FWIW, I worked around the issue by making my own stream-like object that operates as a circular buffer, so I don't even need to use the built in PiCameraCircularIO any more.

@waveform80

This comment has been minimized.

Owner

waveform80 commented Jun 28, 2014

No worries - my ramblings above are mostly for my own reference (and I suppose any interested parties!). With half a dozen projects going on, I frequently find unless I make a note of everything I discover when debugging something, I'll have forgotten it all by the time I get around to actually fixing it (which can be a week or two, sometimes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment