diff --git a/foosball/models.py b/foosball/models.py index 622970e..c5ccf47 100644 --- a/foosball/models.py +++ b/foosball/models.py @@ -1,5 +1,6 @@ import collections from dataclasses import dataclass +from datetime import datetime from enum import Enum from typing import Optional, Union @@ -162,4 +163,4 @@ class PreprocessResult: preprocessed: Optional[CPUFrame] homography_matrix: Optional[np.ndarray] # 3x3 matrix used to warp the image and project points goals: Optional[Goals] - info: Info + info: InfoLog diff --git a/foosball/pipe/BaseProcess.py b/foosball/pipe/BaseProcess.py index c407cf6..401b521 100644 --- a/foosball/pipe/BaseProcess.py +++ b/foosball/pipe/BaseProcess.py @@ -3,6 +3,7 @@ import logging import multiprocessing import traceback +import datetime as dt from queue import Empty, Full from foosball.pipe.Pipe import clear, SENTINEL @@ -12,14 +13,16 @@ class Msg: args: list[any] kwargs: dict + timestamp: dt.datetime = dt.datetime.now() - def __init__(self, args=None, kwargs=None): + def __init__(self, args=None, kwargs=None, timestamp=dt.datetime.now()): if kwargs is None: kwargs = dict() if args is None: args = list() self.kwargs = kwargs self.args = args + self.timestamp = timestamp class BaseProcess(multiprocessing.Process): diff --git a/foosball/source/__init__.py b/foosball/source/__init__.py index 2ed30cc..1e8b8b7 100644 --- a/foosball/source/__init__.py +++ b/foosball/source/__init__.py @@ -1,4 +1,5 @@ import multiprocessing +import datetime as dt from abc import abstractmethod from multiprocessing import Queue from queue import Full @@ -53,8 +54,8 @@ def read_frame(self) -> (bool, Frame): def output(self) -> multiprocessing.Queue: return self.Q - def send_frame(self, frame) -> None: - msg = Msg(kwargs={'frame': frame}) if frame is not None else None + def send_frame(self, frame: Frame) -> None: + msg = Msg(timestamp=dt.datetime.now(), kwargs={'frame': frame}) if frame is not None else None while True: try: # try to put it into the queue diff --git a/foosball/tracking/analyze.py b/foosball/tracking/analyze.py index 2a3bde0..ae0ec8e 100644 --- a/foosball/tracking/analyze.py +++ b/foosball/tracking/analyze.py @@ -61,8 +61,7 @@ def process(self, msg: Msg) -> Msg: info = track_result.info try: self.check_reset_score() - now = dt.datetime.now() - # TODO: define goal grace period in seconds of runtime not seconds in rendering! + now = msg.timestamp # take frame timestamp as now instead of dt.datetime.now (to prevent drift due to pushing/dragging pipeline) no_track_sighting_in_grace_period = (now - self.last_track_sighting).total_seconds() >= self.goal_grace_period_sec if self.last_track_sighting is not None else None if not self.is_track_empty(track): # track is not empty, so we save our state and remove a potential goal (which was wrongly tracked) @@ -84,8 +83,7 @@ def process(self, msg: Msg) -> Msg: traceback.print_exc() self.last_track = track info.append(Info(verbosity=Verbosity.INFO, title="Score", value=self.score.to_string())) - return Msg(kwargs={"result": AnalyzeResult(score=self.score, ball=ball, goals=goals, frame=frame, info=info, - ball_track=track)}) + return Msg(timestamp=msg.timestamp, kwargs={"result": AnalyzeResult(score=self.score, ball=ball, goals=goals, frame=frame, info=info, ball_track=track)}) def check_reset_score(self): if self.score_reset.is_set(): diff --git a/foosball/tracking/preprocess.py b/foosball/tracking/preprocess.py index 9a68c0c..77141d3 100644 --- a/foosball/tracking/preprocess.py +++ b/foosball/tracking/preprocess.py @@ -147,7 +147,7 @@ def process(self, msg: Msg) -> Msg: except Exception as e: self.logger.error(f"Error in preprocess {e}") traceback.print_exc() - return Msg(kwargs={"result": PreprocessResult(self.iproc(frame), self.iproc(preprocessed), self.homography_matrix, self.goals, info)}) + return Msg(timestamp=msg.timestamp, kwargs={"result": PreprocessResult(self.iproc(frame), self.iproc(preprocessed), self.homography_matrix, self.goals, info)}) @staticmethod def corners2pt(corners) -> [int, int]: diff --git a/foosball/tracking/tracker.py b/foosball/tracking/tracker.py index d10bdef..b6a8b86 100644 --- a/foosball/tracking/tracker.py +++ b/foosball/tracking/tracker.py @@ -107,6 +107,6 @@ def process(self, msg: Msg) -> Msg: logger.error(f"Error in track {e}") traceback.print_exc() if not self.verbose: - return Msg(kwargs={"result": TrackResult(preprocess_result.original, goals, ball_track, ball, info)}) + return Msg(timestamp=msg.timestamp, kwargs={"result": TrackResult(preprocess_result.original, goals, ball_track, ball, info)}) else: - return Msg(kwargs={"result": TrackResult(preprocess_result.preprocessed, goals, ball_track, ball, info)}) + return Msg(timestamp=msg.timestamp, kwargs={"result": TrackResult(preprocess_result.preprocessed, goals, ball_track, ball, info)})