fix: bring the existing impl to a usable state

* fix: existing impl always passed None as the port, it never worked
* feat: initial handling of unplugging usb serial device
* feat: check if port exists before trying to open it
* fix: existing impl caused division by zero when calculating fps
* fix: existing impl did not exit when image not found then crashed
* fix: warn logs were marked as info
This commit is contained in:
Sebastian Fitt 2023-04-08 18:30:19 +02:00
parent 09a9fbb052
commit b3f444ee3a

View File

@ -1,9 +1,10 @@
from config import EyeTrackConfig from config import EyeTrackConfig
from enum import Enum from enum import Enum
import threading
import queue
import cv2 import cv2
import queue
import serial import serial
import serial.tools.list_ports
import threading
import time import time
import numpy as np import numpy as np
@ -40,6 +41,7 @@ class Camera:
self.serial_connection = None self.serial_connection = None
self.frame_number = 0 self.frame_number = 0
self.fps = 0
self.start = True self.start = True
self.serialByteBuffer = b'' self.serialByteBuffer = b''
@ -66,7 +68,8 @@ class Camera:
or self.camera_status == CameraState.DISCONNECTED or self.camera_status == CameraState.DISCONNECTED
or self.config.capture_source != self.current_capture_source or self.config.capture_source != self.current_capture_source
): ):
port = self.current_capture_source port = self.config.capture_source
self.current_capture_source = port
self.start_serial_connection(port) self.start_serial_connection(port)
else: else:
if ( if (
@ -109,11 +112,11 @@ class Camera:
self.wired_camera.set(cv2.CAP_PROP_POS_FRAMES, 0) self.wired_camera.set(cv2.CAP_PROP_POS_FRAMES, 0)
raise RuntimeError("Problem while getting frame") raise RuntimeError("Problem while getting frame")
frame_number = self.wired_camera.get(cv2.CAP_PROP_POS_FRAMES) frame_number = self.wired_camera.get(cv2.CAP_PROP_POS_FRAMES)
fps = self.wired_camera.get(cv2.CAP_PROP_FPS) self.fps = self.wired_camera.get(cv2.CAP_PROP_FPS)
if should_push: if should_push:
self.push_image_to_queue(image, frame_number, fps) self.push_image_to_queue(image, frame_number, self.fps)
except: except:
print("\033[93m[INFO] Capture source problem, assuming camera disconnected, waiting for reconnect.\033[0m") print("\033[93m[WARN] Capture source problem, assuming camera disconnected, waiting for reconnect.\033[0m")
self.camera_status = CameraState.DISCONNECTED self.camera_status = CameraState.DISCONNECTED
pass pass
@ -146,38 +149,48 @@ class Camera:
image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_UNCHANGED) image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
if image is None: if image is None:
print("image not found") print("image not found")
return
else: else:
self.frame_number = self.frame_number + 1 self.frame_number = self.frame_number + 1
fps = 1 / (time.time() - start) # Calculate FPS - This could use a better implementation delta_time = time.time() - start
if delta_time > 0:
self.fps = 1 / delta_time
if should_push: if should_push:
self.push_image_to_queue(image, self.frame_number, fps) self.push_image_to_queue(image, self.frame_number, self.fps)
except UnboundLocalError as ex: except UnboundLocalError as ex:
print(ex) print(ex)
except Exception as ex: except Exception:
print(ex.__class__) print("\033[93m[WARN]Serial capture source problem, assuming camera disconnected, waiting for reconnect.\033[0m")
print(
"\033[93m[INFO]Serial capture source problem, assuming camera disconnected, waiting for reconnect.\033[0m") self.serial_connection.close()
self.camera_status = CameraState.DISCONNECTED self.camera_status = CameraState.DISCONNECTED
pass pass
def start_serial_connection(self, port): def start_serial_connection(self, port):
if self.serial_connection is not None and self.serial_connection.is_open:
# Do nothing. The connection is already open on this port.
if self.serial_connection.port == port:
return
# Otherwise, close the connection before trying to reopen.
self.serial_connection.close()
com_ports = [tuple(p) for p in list(serial.tools.list_ports.comports())]
# Do not try connecting if no such port i.e. device was unplugged.
if not any(p for p in com_ports if port in p):
return
try: try:
serialInst = serial.Serial() conn = serial.Serial()
print("setting baud rate") conn.baudrate = 3000000
serialInst.baudrate = 2000000 conn.port = port
print("baud rate set") conn.setDTR(False)
conn.setRTS(False)
conn.open()
serialInst.port = port print(f"\033[94m[INFO] Serial Tracker successfully connected on {port}\033[0m")
serialInst.setDTR(False) self.serial_connection = conn
serialInst.setRTS(False)
serialInst.open()
print("port open")
self.serial_connection = serialInst
self.camera_status = CameraState.CONNECTED self.camera_status = CameraState.CONNECTED
except: except Exception as e:
print("Error Opening Serial Port") self.camera_status = CameraState.DISCONNECTED
def push_image_to_queue(self, image, frame_number, fps): def push_image_to_queue(self, image, frame_number, fps):
# If there's backpressure, just yell. We really shouldn't have this unless we start getting # If there's backpressure, just yell. We really shouldn't have this unless we start getting