-
Notifications
You must be signed in to change notification settings - Fork 8
A1 cam updates #178
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
A1 cam updates #178
Conversation
|
So far no. Previously the HF timeout expired too early but that’s about it.
________________________________
From: Sterling G. Baird ***@***.***>
Sent: Friday, February 28, 2025 7:06:06 PM
To: AccelerationConsortium/ac-training-lab ***@***.***>
Cc: Jonathan Woo ***@***.***>; Author ***@***.***>
Subject: Re: [AccelerationConsortium/ac-training-lab] A1 cam updates (PR #178)
@sgbaird commented on this pull request.
________________________________
In src/ac_training_lab/A1-cam/device.py<#178 (comment)>:
+def on_message(client, userdata, message):
+ data = json.loads(message.payload)
+ command = data["command"]
+
+ if command == "capture_image":
+ logging.info(f"Received command: {command}")
+
+ # only keeping one local copy at any given time called image.jpg
+ file_path = "image.jpeg"
+
+ logging.info("Begin autofocus")
+ try:
+ picam2.autofocus_cycle()
+ logging.info("Successfully finished autofocus")
+ except Exception as e:
+ logging.error(f"Error autofocusing: {e}")
Did you run into errors here at any point?
—
Reply to this email directly, view it on GitHub<#178 (review)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AL3OVBLMKETJLVJZ6PPZJSL2SD2W5AVCNFSM6AAAAABYDMPSFWVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDMNJRHE4DGMBRGE>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
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.
The logic seems sound - overall was easy to follow the script. Few minor points and clarifications listed. Overall, it seems like a lot of logging - I'm guessing because it's operating in a headless state, usually unsupervised, and you want to keep track of it for when you go into the device to check?
I've certainly been one to implement this style at times, but usually I start simple, try to do some stress testing, and then add try-except logic as needed (rather than anticipating). For example, I iterated a lot on https://github.com/sparks-baird/self-driving-lab-demo/blob/main/src/public_mqtt_sdl_demo/main.py because it was pretty fragile and hard to debug without the logging. Some key commits: https://github.com/sparks-baird/self-driving-lab-demo/blob/6dc95458027962a303e93390992c34f7f1b9c262/src/public_mqtt_sdl_demo/main.py --> sparks-baird/self-driving-lab-demo@8103b54
I don't know as well as you what all went wrong or is likely to go wrong (and what is making it easier to maintain) and I know you've done a lot of troubleshooting and debugging with the cameras, so I'll defer to you on this one. Just trying to get a handle on these topics within the training lab.
src/ac_training_lab/A1-cam/device.py
Outdated
| picam2.capture_file(file_path) | ||
| logging.info("Successfully capture image") | ||
| except Exception as e: | ||
| logging.error(f"Error capturing image: {e}") |
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 you run into errors here at any point?
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.
Is the public access setup such that anyone can read files if given the URI, but access is restricted for the upload of files? (i.e., requires authentication)
src/ac_training_lab/A1-cam/device.py
Outdated
| picam2.autofocus_cycle() | ||
| logging.info("Successfully finished autofocus") | ||
| except Exception as e: | ||
| logging.error(f"Error autofocusing: {e}") |
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 you run into errors here at any point?
src/ac_training_lab/A1-cam/device.py
Outdated
| except Exception as e: | ||
| logging.error(f"Error capturing image: {e}") | ||
|
|
||
| # make sure to setup S3 bucket with ACL and public access so that the link works publically |
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.
Thanks for comments like these!
src/ac_training_lab/A1-cam/device.py
Outdated
| ) | ||
| logging.info("Successfully uploaded to S3") | ||
| except Exception as e: | ||
| logging.error(f"Error uploading to S3: {e}") |
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 you run into errors here at any point?
src/ac_training_lab/A1-cam/device.py
Outdated
| client.publish(CAMERA_WRITE_ENDPOINT, json.dumps({"image_url": file_uri})) | ||
| logging.info(f"Published {file_uri} to {CAMERA_WRITE_ENDPOINT}") | ||
| except Exception as e: | ||
| logging.error( |
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 you run into errors here at any point?
src/ac_training_lab/A1-cam/device.py
Outdated
| picam2.set_controls({"AfMode": "auto"}) | ||
| # JPEG quality level (0 is worst, 95 is best) | ||
| picam2.options["quality"] = 90 | ||
| config = picam2.create_still_configuration(transform=Transform(vflip=1)) |
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.
Maybe comment that the vflip is because we use a camera mount that puts the camera upside down
src/ac_training_lab/A1-cam/device.py
Outdated
| object_name = datetime.utcnow().strftime("%Y-%m-%d-%H:%M:%S") + ".jpeg" | ||
| logging.info("Begin upload to S3") | ||
| try: | ||
| s3.upload_file( |
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.
How is s3 being used prior to being defined? If it were a global variable, I'd understand, but I only see it being defined in the if __main__ towards the end. Maybe I'm missing something basic.
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.
src/ac_training_lab/A1-cam/device.py
Outdated
| logger = logging.getLogger("device") | ||
|
|
||
|
|
||
| def on_message(client, userdata, message): |
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.
Any thoughts about queuing in this context? I.e., what will happen if it gets a request while it's still processing another (will it be ignored completely, will it sit in a queue, etc.?). This is more of a fringe case atm, but I wanted to double check what the expected behavior is
I think I designed https://ac-microcourses.readthedocs.io/en/latest/courses/hello-world/1.4-hardware-software-communication.html and the corresponding assignment microcontroller script to handle requests in a FIFO style, but the use-case is somewhat different and that uses MicroPython mqtt_as instead of Python paho-mqtt (see also orchestrator nb).
src/ac_training_lab/A1-cam/device.py
Outdated
| import logging | ||
| import sys | ||
|
|
||
| logging.basicConfig( |
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.
Could you comment on the reasoning behind the more involved logging setup? (file handler, stream handler, why default basicConfig doesn't suffice, etc.). I imagine something to do with the Pi using a headless OS and having a file in case of unexpected shut-down, while still being able to see the stdout when you're SSH'd into it and debugging/prototyping.
src/ac_training_lab/A1-cam/device.py
Outdated
| from libcamera import controls, Transform | ||
|
|
||
| from my_secrets import ( | ||
| CAMERA_READ_ENDPOINT, |
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.
In this case because it's MQTT, let's call this a topic rather than an endpoint
…script with top-level try-except and mqtt error publish)
…ation instructions
… clean up temporary files
…e "bucket owner enforced setting" (recommended to not have object ACLs, instead have bucket-wide settings))
|
I did a bit of refactoring and modification. In particular, I added a dummy package that can be installed to emulate picamera2 and libcamera. @Jonathan-Woo What instructions did you follow for installing libcamera? Could you include a link? I'm assuming picamera2 and paho-mqtt were just via pip. |
|
I don't fully remember but I believe libcamera was installed when I installed picamera2 with the |
|
Great! EDIT: Looks like in a venv, there is a special consideration: EDIT: However, OS Lite doesn't install pip, which requires it's own install command. Since venv comes with pip, maybe not a big deal (though I still lean somewhat towards using the default Python installation since it's fewer steps once set up). EDIT: Since this complicates the cron job (e.g., I had installed venv rather than .venv), moving back to use of built-in Python and manual installation of pip: EDIT: So, back to using venv... planning to just add final instructions to README to avoid having to update the issues over and over again. |
…nd libcamera; improve logging in client.py
src/ac_training_lab/A1-cam/device.py
Outdated
| object_name = datetime.utcnow().strftime("%Y-%m-%d-%H:%M:%S") + ".jpeg" | ||
| logging.info("Begin upload to S3") | ||
| try: | ||
| s3.upload_file( |
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.
src/ac_training_lab/A1-cam/device.py
Outdated
| s3 = boto3.client("s3", region_name=AWS_REGION) | ||
| logging.info("Successfully configured AWS S3") | ||
| except Exception as e: | ||
| logging.error(f"Error configuring S3: {e}") |
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.
Would logging.exception make sense here? https://stackoverflow.com/questions/5191830/how-do-i-log-a-python-error-with-debug-information
Generally cleaned stuff up. Added logging, autofocus, quality options.