|
|
@@ -98,7 +98,9 @@ class DualCameraSystem:
|
|
|
self.calibration_manager = None
|
|
|
|
|
|
# 定时校准
|
|
|
- self.calibration_interval = CALIBRATION_CONFIG.get('interval', 5 * 60) # 默认5分钟
|
|
|
+ self.calibration_interval = CALIBRATION_CONFIG.get('interval', 24 * 60 * 60) # 默认24小时
|
|
|
+ self.daily_calibration_time = CALIBRATION_CONFIG.get('daily_calibration_time', '08:00') # 每日校准时间
|
|
|
+ self.force_daily_recalibration = CALIBRATION_CONFIG.get('force_daily_recalibration', True) # 强制重新校准
|
|
|
self.calibration_thread = None
|
|
|
self.calibration_running = False
|
|
|
self.last_calibration_time = 0
|
|
|
@@ -194,9 +196,13 @@ class DualCameraSystem:
|
|
|
|
|
|
return True
|
|
|
|
|
|
- def _auto_calibrate(self) -> bool:
|
|
|
+ def _auto_calibrate(self, force: bool = False) -> bool:
|
|
|
"""
|
|
|
执行自动校准
|
|
|
+
|
|
|
+ Args:
|
|
|
+ force: 是否强制重新校准(不使用已有数据)
|
|
|
+
|
|
|
Returns:
|
|
|
是否成功
|
|
|
"""
|
|
|
@@ -292,8 +298,11 @@ class DualCameraSystem:
|
|
|
# 创建校准管理器
|
|
|
self.calibration_manager = CalibrationManager(self.calibrator)
|
|
|
|
|
|
- # 执行视觉校准(根据配置决定是否强制重新校准)
|
|
|
- result = self.calibration_manager.auto_calibrate(force=False)
|
|
|
+ # 执行视觉校准(根据参数决定是否强制重新校准)
|
|
|
+ result = self.calibration_manager.auto_calibrate(
|
|
|
+ force=force,
|
|
|
+ fallback_on_failure=True # 校准失败时回退使用已有数据
|
|
|
+ )
|
|
|
|
|
|
if not result.success:
|
|
|
logger.error("=" * 50)
|
|
|
@@ -411,26 +420,18 @@ class DualCameraSystem:
|
|
|
if not SYSTEM_CONFIG.get('enable_calibration', True):
|
|
|
logger.info("定时校准已禁用 (enable_calibration=False)")
|
|
|
return
|
|
|
-
|
|
|
+
|
|
|
if self.calibration_running:
|
|
|
return
|
|
|
-
|
|
|
+
|
|
|
self.calibration_running = True
|
|
|
self.calibration_thread = threading.Thread(
|
|
|
target=self._periodic_calibration_worker,
|
|
|
daemon=True
|
|
|
)
|
|
|
self.calibration_thread.start()
|
|
|
- # 格式化显示间隔
|
|
|
- interval_hours = self.calibration_interval // 3600
|
|
|
- if interval_hours >= 24:
|
|
|
- interval_str = f"{interval_hours // 24}天"
|
|
|
- elif interval_hours >= 1:
|
|
|
- interval_str = f"{interval_hours}小时"
|
|
|
- else:
|
|
|
- interval_str = f"{self.calibration_interval // 60}分钟"
|
|
|
- logger.info(f"定时校准已启动 (间隔: {interval_str})")
|
|
|
-
|
|
|
+ logger.info(f"定时校准已启动 (每日 {self.daily_calibration_time} 自动校准)")
|
|
|
+
|
|
|
def _stop_periodic_calibration(self):
|
|
|
"""停止定时校准"""
|
|
|
self.calibration_running = False
|
|
|
@@ -439,36 +440,71 @@ class DualCameraSystem:
|
|
|
self.calibration_thread = None
|
|
|
logger.info("定时校准已停止")
|
|
|
|
|
|
+ def _get_seconds_until_target_time(self, target_time_str: str) -> int:
|
|
|
+ """
|
|
|
+ 计算到目标时间的秒数
|
|
|
+
|
|
|
+ Args:
|
|
|
+ target_time_str: 目标时间字符串 (HH:MM格式)
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ 到目标时间的秒数,如果已过今天的目标时间则返回到明天目标时间的秒数
|
|
|
+ """
|
|
|
+ from datetime import datetime, timedelta
|
|
|
+
|
|
|
+ now = datetime.now()
|
|
|
+ target_hour, target_minute = map(int, target_time_str.split(':'))
|
|
|
+ target_time = now.replace(hour=target_hour, minute=target_minute, second=0, microsecond=0)
|
|
|
+
|
|
|
+ # 如果已过今天的目标时间,则计算到明天的目标时间
|
|
|
+ if now >= target_time:
|
|
|
+ target_time += timedelta(days=1)
|
|
|
+
|
|
|
+ return int((target_time - now).total_seconds())
|
|
|
+
|
|
|
def _periodic_calibration_worker(self):
|
|
|
- """定时校准工作线程"""
|
|
|
- import time
|
|
|
-
|
|
|
+ """定时校准工作线程 - 每日指定时间执行校准"""
|
|
|
+ from datetime import datetime
|
|
|
+
|
|
|
while self.calibration_running:
|
|
|
try:
|
|
|
- # 等待校准间隔
|
|
|
- for _ in range(self.calibration_interval):
|
|
|
+ # 计算到下一个校准时间的等待秒数
|
|
|
+ wait_seconds = self._get_seconds_until_target_time(self.daily_calibration_time)
|
|
|
+ next_time = datetime.now().replace(
|
|
|
+ hour=int(self.daily_calibration_time.split(':')[0]),
|
|
|
+ minute=int(self.daily_calibration_time.split(':')[1])
|
|
|
+ )
|
|
|
+ if datetime.now() >= next_time:
|
|
|
+ from datetime import timedelta
|
|
|
+ next_time += timedelta(days=1)
|
|
|
+
|
|
|
+ logger.info(f"下次校准时间: {next_time.strftime('%Y-%m-%d %H:%M:%S')} (等待 {wait_seconds // 3600}小时{(wait_seconds % 3600) // 60}分钟)")
|
|
|
+
|
|
|
+ # 等待到校准时间,每分钟检查一次是否需要停止
|
|
|
+ for i in range(wait_seconds):
|
|
|
if not self.calibration_running:
|
|
|
return
|
|
|
time.sleep(1)
|
|
|
-
|
|
|
+
|
|
|
if not self.calibration_running:
|
|
|
return
|
|
|
-
|
|
|
+
|
|
|
# 执行校准
|
|
|
logger.info("=" * 50)
|
|
|
- logger.info("执行定时校准...")
|
|
|
+ logger.info(f"执行每日定时校准 (时间: {self.daily_calibration_time})...")
|
|
|
logger.info("=" * 50)
|
|
|
-
|
|
|
- result = self._auto_calibrate()
|
|
|
-
|
|
|
+
|
|
|
+ # 每日校准强制重新校准(不使用已有数据),失败时可回退
|
|
|
+ result = self._auto_calibrate(force=self.force_daily_recalibration)
|
|
|
+
|
|
|
if result:
|
|
|
- logger.info("定时校准成功!")
|
|
|
+ logger.info("每日定时校准成功!")
|
|
|
else:
|
|
|
- logger.warning("定时校准失败, 将在下次间隔重试")
|
|
|
-
|
|
|
+ logger.warning("每日定时校准失败!")
|
|
|
+
|
|
|
except Exception as e:
|
|
|
logger.error(f"定时校准错误: {e}")
|
|
|
- time.sleep(10)
|
|
|
+ time.sleep(60) # 出错后等待1分钟再重试
|
|
|
|
|
|
def manual_calibrate(self) -> bool:
|
|
|
"""
|