You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.7 KiB
73 lines
2.7 KiB
import queue
|
|
import threading
|
|
import time
|
|
|
|
import models.msg
|
|
from upload.RateLimiter import RateLimiter
|
|
|
|
|
|
class DataReporter(threading.Thread):
|
|
call_back=None
|
|
def __init__(self,data_fps:int,video_fps:int):
|
|
super().__init__()
|
|
self.image_queue = queue.Queue(maxsize=video_fps) # 图片队列
|
|
self.data_queue = queue.Queue(maxsize=data_fps) # 数据队列
|
|
self.image_limiter = RateLimiter(max_rate=video_fps, time_window=1) # 图片限速: 5张/秒
|
|
self.data_limiter = RateLimiter(max_rate=data_fps, time_window=1) # 数据限速: 20条/秒
|
|
self.running = True
|
|
self.image_dropped = 0 # 统计丢弃的图片数量
|
|
self.data_dropped = 0 # 统计丢弃的数据数量
|
|
|
|
def register_handler(self,handler_fun):
|
|
self.call_back = handler_fun
|
|
|
|
def run(self):
|
|
while self.running:
|
|
# 优先处理图片上报
|
|
if not self.image_queue.empty() and self.image_limiter.allow_request():
|
|
try:
|
|
image_data = self.image_queue.get_nowait()
|
|
self._report_image(image_data)
|
|
except queue.Empty:
|
|
pass
|
|
|
|
# 然后处理数据上报
|
|
if not self.data_queue.empty() and self.data_limiter.allow_request():
|
|
try:
|
|
data = self.data_queue.get_nowait()
|
|
self._report_data(data)
|
|
except queue.Empty:
|
|
pass
|
|
|
|
time.sleep(0.02) # 避免CPU占用过高
|
|
|
|
def _report_image(self, data):
|
|
# 实现图片上报逻辑
|
|
print(f"Reporting image, timestamp: {data[0]}")
|
|
# 这里替换为实际的上报代码
|
|
msg = models.msg.Msg(_from="dev", cmd="image", values=data[1])
|
|
msg_json = msg.to_json()
|
|
self.call_back(msg_json)
|
|
|
|
def _report_data(self, data):
|
|
# 实现数据上报逻辑
|
|
print(f"Reporting data: {data}")
|
|
# 实际的上报代码,数据结构转换
|
|
msg=models.msg.Msg(_from="dev",cmd="data",values=data[1])
|
|
msg_json=msg.to_json()
|
|
self.call_back(msg_json)
|
|
|
|
def stop(self):
|
|
self.running = False
|
|
self.join()
|
|
print(f"Stats: {self.image_dropped} images dropped, {self.data_dropped} data dropped")
|
|
|
|
def adjust_rate(self, new_rate, data_type='image'):
|
|
if data_type == 'image':
|
|
with self.image_limiter.lock:
|
|
self.image_limiter.max_rate = new_rate
|
|
self.image_queue= queue.Queue(maxsize=new_rate)
|
|
else:
|
|
with self.data_limiter.lock:
|
|
self.data_limiter.max_rate = new_rate
|
|
self.data_queue = queue.Queue(maxsize=new_rate)
|