python: better imaging management of the raspimjpeg process
This commit is contained in:
parent
d732c8d4ce
commit
cf2f15594d
|
@ -12,10 +12,11 @@ import datetime
|
|||
import time
|
||||
|
||||
# Libraries manipulate json format, execute bash commands
|
||||
import json, shutil
|
||||
import json
|
||||
|
||||
# Library for path and filesystem manipulations
|
||||
import os
|
||||
import shutil
|
||||
|
||||
# Library for starting processes
|
||||
import multiprocessing
|
||||
|
@ -166,6 +167,7 @@ class ImagerProcess(multiprocessing.Process):
|
|||
self.__pump_direction = "FORWARD"
|
||||
self.__img_goal = None
|
||||
self.imager_client = None
|
||||
self.__error = 0
|
||||
|
||||
# Initialise the camera and the process
|
||||
# Also starts the streaming to the temporary file
|
||||
|
@ -196,7 +198,7 @@ class ImagerProcess(multiprocessing.Process):
|
|||
self.__white_balance_gain = (
|
||||
configuration.get("wb_red_gain", 2.00) * 100,
|
||||
configuration.get("wb_blue_gain", 1.40) * 100,
|
||||
) # Those values were tested on a HQ camera to give a whitish background
|
||||
)
|
||||
|
||||
self.__base_path = "/home/pi/data/img"
|
||||
# Let's make sure the base path exists
|
||||
|
@ -491,7 +493,9 @@ class ImagerProcess(multiprocessing.Process):
|
|||
self.__imager.change(planktoscope.imager_state_machine.Capture)
|
||||
self.imager_client.client.unsubscribe("status/pump")
|
||||
else:
|
||||
logger.info(f"The pump is not done yet {payload}")
|
||||
logger.info(
|
||||
f"The pump is not done yet {self.imager_client.msg['payload']}"
|
||||
)
|
||||
else:
|
||||
logger.error(
|
||||
"There is an error, we received an unexpected pump message"
|
||||
|
@ -641,39 +645,25 @@ class ImagerProcess(multiprocessing.Process):
|
|||
# Sleep a duration before to start acquisition
|
||||
time.sleep(self.__sleep_before)
|
||||
|
||||
# Capture an image with the proper filename
|
||||
# Capture an image to the temporary file
|
||||
try:
|
||||
self.__camera.capture(filename_path)
|
||||
self.__camera.capture("", timeout=5)
|
||||
except TimeoutError as e:
|
||||
logger.error("A timeout happened while waiting for a capture to happen")
|
||||
# Publish the name of the image to via MQTT to Node-RED
|
||||
self.imager_client.client.publish(
|
||||
"status/imager",
|
||||
f'{{"status":"Image {self.__img_done + 1}/{self.__img_goal} WAS NOT CAPTURED! STOPPING THE PROCESS!"}}',
|
||||
)
|
||||
# Reset the counter to 0
|
||||
self.__img_done = 0
|
||||
self.__img_goal = 0
|
||||
self.__imager.change(planktoscope.imager_state_machine.Stop)
|
||||
planktoscope.light.error()
|
||||
self.__capture_error("timeout during capture")
|
||||
return
|
||||
|
||||
logger.debug(f"Copying the image from the temp file to {filename_path}")
|
||||
shutil.copy("/dev/shm/mjpeg/image.jpg", filename_path)
|
||||
logger.debug("Syncing the disk")
|
||||
os.sync()
|
||||
|
||||
# Add the checksum of the captured image to the integrity file
|
||||
try:
|
||||
planktoscope.integrity.append_to_integrity_file(filename_path)
|
||||
except FileNotFoundError as e:
|
||||
logger.error(
|
||||
f"{filename_path} was not found, the camera did not work properly! Trying again"
|
||||
)
|
||||
self.imager_client.client.publish(
|
||||
"status/imager",
|
||||
f'{{"status":"Image {self.__img_done + 1}/{self.__img_goal} was not found, retrying the capture now."}}',
|
||||
)
|
||||
# Let's try again after a tiny delay!
|
||||
time.sleep(1)
|
||||
self.__capture_error(f"{filename_path} was not found")
|
||||
return
|
||||
|
||||
# Publish the name of the image to via MQTT to Node-RED
|
||||
self.imager_client.client.publish(
|
||||
"status/imager",
|
||||
f'{{"status":"Image {self.__img_done + 1}/{self.__img_goal} has been imaged to {filename}"}}',
|
||||
|
@ -681,6 +671,7 @@ class ImagerProcess(multiprocessing.Process):
|
|||
|
||||
# Increment the counter
|
||||
self.__img_done += 1
|
||||
self.__error = 0
|
||||
|
||||
# If counter reach the number of frame, break
|
||||
if self.__img_done >= self.__img_goal:
|
||||
|
@ -690,7 +681,6 @@ class ImagerProcess(multiprocessing.Process):
|
|||
|
||||
self.__imager.change(planktoscope.imager_state_machine.Stop)
|
||||
planktoscope.light.ready()
|
||||
return
|
||||
else:
|
||||
# We have not reached the final stage, let's keep imaging
|
||||
self.imager_client.client.subscribe("status/pump")
|
||||
|
@ -699,6 +689,27 @@ class ImagerProcess(multiprocessing.Process):
|
|||
|
||||
self.__imager.change(planktoscope.imager_state_machine.Waiting)
|
||||
|
||||
def __capture_error(self, message=""):
|
||||
logger.error(f"An error occurred during the capture: {message}")
|
||||
planktoscope.light.error()
|
||||
if self.__error:
|
||||
logger.error("This is a repeating problem, stopping the capture now")
|
||||
self.imager_client.client.publish(
|
||||
"status/imager",
|
||||
f'{{"status":"Image {self.__img_done + 1}/{self.__img_goal} WAS NOT CAPTURED! STOPPING THE PROCESS!"}}',
|
||||
)
|
||||
self.__img_done = 0
|
||||
self.__img_goal = 0
|
||||
self.__error = 0
|
||||
self.__imager.change(planktoscope.imager_state_machine.Stop)
|
||||
else:
|
||||
self.__error += 1
|
||||
self.imager_client.client.publish(
|
||||
"status/imager",
|
||||
f'{{"status":"Image {self.__img_done + 1}/{self.__img_goal} was not captured due to this error:{message}! Retrying once!"}}',
|
||||
)
|
||||
time.sleep(1)
|
||||
|
||||
@logger.catch
|
||||
def state_machine(self):
|
||||
if self.__imager.state.name == "imaging":
|
||||
|
|
|
@ -458,9 +458,10 @@ class raspimjpeg(object):
|
|||
self.__send_command(f"im")
|
||||
else:
|
||||
self.__send_command(f"im {path}")
|
||||
time.sleep(0.1)
|
||||
|
||||
self.__wait_for_output("Capturing image", timeout / 2)
|
||||
self.__wait_for_status("ready", timeout / 2)
|
||||
self.__wait_for_output("Ready", timeout / 2)
|
||||
|
||||
def stop(self):
|
||||
"""Halt and release the camera. """
|
||||
|
|
|
@ -354,7 +354,7 @@ class StepperProcess(multiprocessing.Process):
|
|||
command = self.actuator_client.msg["topic"].split("/", 1)[1]
|
||||
logger.debug(command)
|
||||
self.actuator_client.read_message()
|
||||
|
||||
|
||||
if command == "pump":
|
||||
self.__message_pump(last_message)
|
||||
elif command == "focus":
|
||||
|
|
Binary file not shown.
|
@ -120,9 +120,9 @@ motion_file 0
|
|||
# image, video and lapse may be configured relative to media_path if first / left out
|
||||
base_path /home/pi/PlanktonScope/scripts/raspimjpeg/
|
||||
preview_path /dev/shm/mjpeg/cam.jpg
|
||||
image_path /home/pi/data/%Y%M%D/im_%i_%h%m%s.jpg
|
||||
lapse_path /home/pi/media/tl_%i_%t_%Y%M%D_%h%m%s.jpg
|
||||
video_path /home/pi/media/vi_%v_%Y%M%D_%h%m%s.mp4
|
||||
image_path /dev/shm/mjpeg/image.jpg
|
||||
lapse_path /dev/shm/mjpeg/tl_%i_%t_%Y%M%D_%h%m%s.jpg
|
||||
video_path /dev/shm/mjpeg/vi_%v_%Y%M%D_%h%m%s.mp4
|
||||
status_file /dev/shm/mjpeg/status_mjpeg.txt
|
||||
control_file /dev/shm/mjpeg/FIFO
|
||||
media_path /home/pi/data/
|
||||
|
@ -165,7 +165,7 @@ watchdog_errors 5
|
|||
# Set callback_timeout to 0 to disable it
|
||||
callback_timeout 30
|
||||
#optional user_config file to overwrite (persist) changes
|
||||
user_config /home/pi/PlanktonScope/scripts/raspimjpeg/uconfig
|
||||
user_config
|
||||
|
||||
#logfile for raspimjpeg, default to merge with scheduler log
|
||||
log_file /home/pi/PlanktonScope/scripts/raspimjpeg/raspimjpeg.log
|
||||
|
|
Loading…
Reference in a new issue