From 59dcecdbc2f1c63f37af6fdc07cceb022dcf4086 Mon Sep 17 00:00:00 2001 From: bugobliterator Date: Tue, 1 Aug 2023 12:45:08 +1000 Subject: [PATCH] file: add support for stream read progress and end of stream --- dronecan/driver/common.py | 8 ++++++++ dronecan/driver/file.py | 26 ++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/dronecan/driver/common.py b/dronecan/driver/common.py index 45f5c13..171f019 100644 --- a/dronecan/driver/common.py +++ b/dronecan/driver/common.py @@ -158,5 +158,13 @@ def set_signing_passphrase(self, passphrase): '''set MAVLink2 signing passphrase''' pass + def stream_progress(self): + '''stream progress of the current stream''' + pass + + def end_of_stream(self): + '''end of stream''' + pass + def send(self, message_id, message, extended=False, canfd=False): self.send_frame(CANFrame(message_id, message, extended, canfd=canfd)) diff --git a/dronecan/driver/file.py b/dronecan/driver/file.py index 9c3271d..8dd377b 100644 --- a/dronecan/driver/file.py +++ b/dronecan/driver/file.py @@ -40,13 +40,16 @@ def __init__(self, filename, **kwargs): super(file, self).__init__() self.filename = filename self.start_file_monotonic_ts = 0 + self.speedup = kwargs.get('speedup', 1) # check if read only option selected if kwargs.get('readonly', False): self.readonly = True self.file = open(filename, 'rb') self.curr_frame = None self.start_monotonic_ts = time.monotonic() + self.file_size = os.path.getsize(filename) self.set_first_and_last_timestamp() + self.eof = False else: self.readonly = False self.file = open(filename, 'wb') @@ -62,6 +65,9 @@ def __del__(self): self.close() def _read_frame(self): + if (self.file.tell() >= self.file_size): + self.eof = True + return None, None # read header header = self.file.read(20) if len(header) < 20: @@ -102,6 +108,7 @@ def set_first_and_last_timestamp(self): if frame is None: break # seek to start of file + self.eof = False self.file.seek(0, os.SEEK_SET) def get_start_timestamp(self): @@ -113,8 +120,20 @@ def get_last_timestamp(self): def set_start_timestamp(self, timestamp): self.start_monotonic_ts = timestamp - def receive(self, timeout=None): + def end_of_stream(self): if not self.readonly: + return False + return self.eof + + def stream_progress(self): + '''stream progress of the current stream''' + if not self.readonly or self.eof: + return 100 + # return file seek position vs file size + return (self.file.tell()/self.file_size)*100 + + def receive(self, timeout=None): + if not self.readonly or self.eof: if timeout is not None: time.sleep(timeout) return None @@ -125,7 +144,10 @@ def receive(self, timeout=None): self.curr_frame, _ = self._read_frame() if self.curr_frame is None: return None - time_to_next_frame = self.curr_frame.ts_monotonic - curr_time + if self.speedup == -1: + time_to_next_frame = 0 + else: + time_to_next_frame = (self.curr_frame.ts_monotonic - curr_time)/self.speedup if time_to_next_frame > 0: if timeout is not None and time_to_next_frame <= timeout: # sleep until next frame