This commit is contained in:
gcw_4spBpAfv
2026-02-10 17:52:55 +08:00
parent 573c0a3385
commit 592dc6ceb1
9 changed files with 626 additions and 136 deletions

View File

@@ -29,6 +29,7 @@ class LaserManager:
return
# 私有状态
self._serial = None # 激光串口,由 laser_manager 自己持有
self._calibration_active = False
self._calibration_result = None
self._calibration_lock = threading.Lock()
@@ -65,6 +66,38 @@ class LaserManager:
"""
return self._last_frame_with_ellipse
# ==================== 初始化方法 ====================
def init(self, serial_device=None, baudrate=None):
"""
初始化激光模块(包括串口)
初始化完成后主动发送关闭命令,防止 UART 初始化噪声误触发激光
Args:
serial_device: 串口设备路径,默认使用 config.DISTANCE_SERIAL_DEVICE
baudrate: 波特率,默认使用 config.DISTANCE_SERIAL_BAUDRATE
"""
from maix import uart
device = serial_device or config.DISTANCE_SERIAL_DEVICE
baud = baudrate or config.DISTANCE_SERIAL_BAUDRATE
self._serial = uart.UART(device, baud)
print(f"[LASER] 激光串口初始化完成: device={device}, baudrate={baud}")
# 等待串口稳定后主动关闭激光,防止初始化噪声误触发
time.sleep_ms(100)
try:
self._serial.read(-1) # 清空接收缓冲区
except Exception:
pass
self._serial.write(config.LASER_OFF_CMD)
time.sleep_ms(60)
try:
self._serial.read(-1) # 清空回包
except Exception:
pass
print("[LASER] 已发送关闭命令(防止开机误触发)")
# ==================== 业务方法 ====================
def load_laser_point(self):
@@ -117,10 +150,8 @@ class LaserManager:
def turn_on_laser(self):
"""发送指令开启激光,并读取回包(部分模块支持)"""
from hardware import hardware_manager
if hardware_manager.distance_serial is None:
self.logger.error("[LASER] distance_serial 未初始化")
if self._serial is None:
self.logger.error("[LASER] 激光串口未初始化,请先调用 init()")
return None
# 打印调试信息
@@ -128,32 +159,31 @@ class LaserManager:
# 清空接收缓冲区
try:
hardware_manager.distance_serial.read(-1) # 清空缓冲区
self._serial.read(-1) # 清空缓冲区
except:
pass
# 发送命令
written = hardware_manager.distance_serial.write(config.LASER_ON_CMD)
written = self._serial.write(config.LASER_ON_CMD)
self.logger.info(f"[LASER] 写入字节数: {written}")
time.sleep_ms(60)
# 读取回包
resp = hardware_manager.distance_serial.read(len=20,timeout=10)
resp = self._serial.read(len=20, timeout=10)
if resp:
self.logger.info(f"[LASER] 收到回包 ({len(resp)}字节): {resp.hex()}")
if resp == config.LASER_ON_CMD:
self.logger.info("✅ 激光开启指令已确认")
else:
self.logger.warning("🔇 无回包(可能正常或模块不支持回包)")
self._laser_turned_on = True
return resp
def turn_off_laser(self):
"""发送指令关闭激光"""
from hardware import hardware_manager
if hardware_manager.distance_serial is None:
self.logger.error("[LASER] distance_serial 未初始化")
if self._serial is None:
self.logger.error("[LASER] 激光串口未初始化,请先调用 init()")
return None
# 打印调试信息
@@ -161,32 +191,35 @@ class LaserManager:
# 清空接收缓冲区
try:
hardware_manager.distance_serial.read(-1)
self._serial.read(-1)
except:
pass
# 发送命令
written = hardware_manager.distance_serial.write(config.LASER_OFF_CMD)
written = self._serial.write(config.LASER_OFF_CMD)
self.logger.info(f"[LASER] 写入字节数: {written}")
time.sleep_ms(60)
# 读取回包
resp = hardware_manager.distance_serial.read(20)
resp = self._serial.read(20)
if resp:
self.logger.info(f"[LASER] 收到回包 ({len(resp)}字节): {resp.hex()}")
else:
self.logger.warning("🔇 无回包")
self._laser_turned_on = False
return resp
# 不用读回包
# return None
def flash_laser(self, duration_ms=1000):
"""闪一下激光(用于射箭反馈)"""
"""闪一下激光(用于射箭反馈),如果射箭前激光已亮则保持亮"""
try:
was_on = self._laser_turned_on # 记住射箭前的激光状态
self.turn_on_laser()
time.sleep_ms(duration_ms)
self.turn_off_laser()
if not was_on:
self.turn_off_laser() # 射箭前是灭的,才关闭
else:
self.logger.info("[LASER] 射箭前激光已亮(调瞄中),保持激光开启")
except Exception as e:
self.logger.error(f"闪激光失败: {e}")
@@ -956,15 +989,14 @@ class LaserManager:
"""发送测距指令并返回距离(米)和信号质量
返回: (distance_m, signal_quality) 元组,失败返回 (0.0, 0)
"""
from hardware import hardware_manager
if hardware_manager.distance_serial is None:
self.logger.error("[LASER] distance_serial 未初始化")
if self._serial is None:
self.logger.error("[LASER] 激光串口未初始化,请先调用 init()")
return (0.0, 0)
try:
# 清空缓冲区
try:
hardware_manager.distance_serial.read(-1)
self._serial.read(-1)
except:
pass
# 打开激光
@@ -973,7 +1005,7 @@ class LaserManager:
self._laser_turned_on = True
# time.sleep_ms(500) # 需要一定时间让激光稳定
# 发送测距查询命令
hardware_manager.distance_serial.write(config.DISTANCE_QUERY_CMD)
self._serial.write(config.DISTANCE_QUERY_CMD)
# time.sleep_ms(500) # 测试结果:这里的等待没有用!
self.turn_off_laser()
self._laser_turned_on = False
@@ -993,7 +1025,7 @@ class LaserManager:
return (0.0, 0)
# 尝试读取数据
response = hardware_manager.distance_serial.read(config.DISTANCE_RESPONSE_LEN)
response = self._serial.read(config.DISTANCE_RESPONSE_LEN)
# 如果读到完整数据,立即返回
if response and len(response) == config.DISTANCE_RESPONSE_LEN: