-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
961 protect from empty camera image #967
Conversation
- prior code just waited a couple of seconds. - this new code now starts asking for frames and will wait until a frame is return or a timeout happens - Generally this is a more reliable and faster way to warm the camera; if it is going to work it will return a frame quickly. So start up is faster. - The warmup code also declares a better error if the camera can't start; it raises the error in the camera part rather than downstream where the image is used or later in the pipeline. That makes it easier to diagnose what is going on.
- if the camera returns a None image the code would crash. That could happen with the prior CISC camera if it did not start properly. However, that error was confusing. - Now this code will simply ignore an None image.
- added --debug flag. if this is passed to 'drive' command then debug window is shown. Otherwise it does not. - this fixes an issue when using a headless OS on the donkeycar; open cv cannot create a debug window and so crashes.
- this guarantees we can produce frames before the camera is used - also detects if pygame is not installed and prints instructions
- if both a CSIC camera and a USB camera are connected then there will be more than one camera available - The current code always just choose index 0 - This change allows the index to be chose with cfg.CAMERA_INDEX, which defaults to zero
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also squash your commits into one?
donkeycar/parts/camera.py
Outdated
print('PiCamera loaded.. .warming camera') | ||
time.sleep(2) | ||
# get the first frame or timeout | ||
print('PiCamera loaded...') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you convert your print
into logger.info
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did do.
donkeycar/parts/camera.py
Outdated
print('PiCamera opened.. .warming camera') | ||
warming_time = time.time() + 5 # quick after 5 seconds | ||
while self.frame is None and time.time() < warming_time: | ||
print(".", end="") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how to do this w/ logging though...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... actually I figured out a way to do it like this:
import logging
import time
# handler = logging.StreamHandler()
dfmt = "%d %b %Y %H:%M:%S"
format = '%(asctime)s %(message)s'
logging.basicConfig(format=format, datefmt=dfmt, level='INFO')
logger = logging.getLogger(__name__)
handler = logging.StreamHandler()
if __name__ == "__main__":
logger.info('Starting')
logger.propagate = False
logger.addHandler(handler)
handler.terminator = ""
for i in range(20):
logger.info(f'-' if i % 2 == 0 else '>')
time.sleep(0.3)
logger.info('\n')
logger.removeHandler(handler)
logger.propagate = True
logger.info('bye')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't see this. I've made a change that is satisfactory I think.
Also added support for CAMERA_INDEX config when using CVCAM |
import os | ||
import time | ||
import numpy as np | ||
from PIL import Image | ||
import glob | ||
from donkeycar.utils import rgb2gray | ||
|
||
logger = logging.getLogger(__name__) | ||
logging.basicConfig(level=logging.INFO) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are already setting the logging level in the car app (in complete.py
) to INFO already. Because this goes to the root logger, you would optimally set this only once where you start the application. There is no harm with this line, but if we decide to dynamically change the logger level per argument or config then we have to find and remove all these local settings as they might interfere/overwrite the application settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, thanks for the comprehensive documentation of the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually - could you still squash all your commits into one, so we only see a single commit in the repo after merging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed with @Ezward - squash merging should be fine here.
This PR addresses Issue 961 and a little more. Basically our cameras could return None images if they did not start correctly. The warmup was just a sleep(2) and no check was actually made to know that the camera started. This could result in hard to understand downstream errors.