修复1在WebSocket回调线程内执行stop/start竞争条件,'socket already closed'循环出现,2陈旧结果5秒复用窗口旧识别结果污染新请求,意图混乱

This commit is contained in:
lxy
2026-03-06 17:29:55 +08:00
parent ed861a9fb1
commit a0ceb934ce
2 changed files with 13 additions and 25 deletions

View File

@@ -1,11 +1,5 @@
# ROS 语音包配置文件
asr:
mode: 'cloud' # 'cloud' | 'local' - ASR模式选择
local:
server_url: "ws://127.0.0.1:10095" # 本地FunASR服务地址
# 云端模式配置在dashscope中
dashscope:
api_key: "sk-7215a5ab7a00469db4072e1672a0661e"
asr:
@@ -56,11 +50,11 @@ system:
shutup_keywords: "bi zui" # 闭嘴指令关键词(拼音,逗号分隔)
interrupt_command_queue_depth: 10 # 中断命令订阅的队列深度QoS
sv_enabled: false # 是否启用声纹识别
sv_model_path: "~/hivecore_robot_os1/voice_model" # 声纹模型路径
# sv_model_path: "~/ros_learn/speech_campplus_sv_zh-cn_16k-common" # 声纹模型路径
# sv_model_path: "~/hivecore_robot_os1/voice_model" # 声纹模型路径
sv_model_path: "~/ros_learn/speech_campplus_sv_zh-cn_16k-common" # 声纹模型路径
sv_threshold: 0.65 # 声纹识别阈值0.0-1.0,值越小越宽松,值越大越严格)
sv_speaker_db_path: "~/hivecore_robot_os1/config/speakers.json" # 声纹数据库保存路径JSON格式相对于ROS2包share目录
# sv_speaker_db_path: "~/ros_learn/hivecore_robot_voice/config/speakers.json" # 声纹数据库保存路径JSON格式相对于ROS2包share目录
# sv_speaker_db_path: "~/hivecore_robot_os1/config/speakers.json" # 声纹数据库保存路径JSON格式相对于ROS2包share目录
sv_speaker_db_path: "~/ros_learn/hivecore_robot_voice/config/speakers.json" # 声纹数据库保存路径JSON格式相对于ROS2包share目录
sv_buffer_size: 96000 # 声纹验证录音缓冲区大小样本数48kHz下2秒=96000
continue_without_image: true # 多模态意图skill_sequence/chat_camera未获取到图片时是否继续推理
@@ -69,5 +63,5 @@ camera:
jpeg_quality: 85 # JPEG压缩质量0-10085是质量和大小平衡点
interfaces:
root_path: "~/hivecore_robot_os1/hivecore_robot_interfaces/src" # 接口文件根目录,支持 ~ 展开和相对路径
# root_path: "~/ros_learn/hivecore_robot_interfaces/src" # 接口文件根目录,支持 ~ 展开和相对路径
# root_path: "~/hivecore_robot_os1/hivecore_robot_interfaces/src" # 接口文件根目录,支持 ~ 展开和相对路径
root_path: "~/ros_learn/hivecore_robot_interfaces/src" # 接口文件根目录,支持 ~ 展开和相对路径

View File

@@ -199,7 +199,7 @@ class DashScopeASR:
enable_turn_detection=True,
turn_detection_type='server_vad',
prefix_padding_ms=1000,
turn_detection_threshold=0.2,
turn_detection_threshold=0.3,
turn_detection_silence_duration_ms=800,
)
@@ -395,7 +395,7 @@ class ASRAudioNode(Node):
# ========== 异常识别检测 ==========
self._abnormal_results = ["嗯。", "", "啊。", "哦。"] # 异常识别结果列表
self._consecutive_abnormal_count = 0 # 连续异常识别次数
self.MAX_CONSECUTIVE_ABNORMAL = 2 # 最大连续异常次数
self.MAX_CONSECUTIVE_ABNORMAL = 5 # 最大连续异常次数
self.recording_thread = threading.Thread(
target=self.audio_recorder.record, name="RecordingThread", daemon=True
@@ -450,7 +450,7 @@ class ASRAudioNode(Node):
self.asr_client.on_sentence_end = self._on_asr_result
self.asr_client.on_speech_started = lambda: self._put_vad_event("speech_started")
self.asr_client.on_speech_stopped = lambda: self._put_vad_event("speech_stopped")
self.asr_client.on_speech_stopped = lambda: (self._clear_result(), self._put_vad_event("speech_stopped"))
self.asr_client.start()
def _on_asr_result(self, text: str):
@@ -467,15 +467,9 @@ class ASRAudioNode(Node):
self.get_logger().warn(f"[ASR] 检测到异常识别结果: '{self._last_result}' | 连续异常:{self._consecutive_abnormal_count}")
# 如果连续多次异常,强制重置 ASR 连接
if self._consecutive_abnormal_count >= self.MAX_CONSECUTIVE_ABNORMAL:
self.get_logger().error(f"[ASR] 连续{self._consecutive_abnormal_count}次异常识别,强制重置连接")
try:
self.asr_client.stop()
time.sleep(0.5)
self.asr_client.start()
self._consecutive_abnormal_count = 0
self.get_logger().info("[ASR] 连接已重置")
except Exception as e:
self.get_logger().error(f"[ASR] 重置连接失败: {e}")
self.get_logger().error(f"[ASR] 连续{self._consecutive_abnormal_count}次异常识别,标记需要重连")
self.asr_client._consecutive_send_failures = self.asr_client.MAX_CONSECUTIVE_FAILURES
self._consecutive_abnormal_count = 0
else:
# 正常识别,重置异常计数
self._consecutive_abnormal_count = 0
@@ -601,7 +595,7 @@ class ASRAudioNode(Node):
if self.asr_client.running:
current_time = time.time()
if (self._last_result and self._last_result_time and
(current_time - self._last_result_time) < 5.0) or (self._result_event.is_set() and self._last_result):
(current_time - self._last_result_time) < 0.3) or (self._result_event.is_set() and self._last_result):
return self._return_result(response, self._last_result, "返回最近识别结果")
if self._result_event.wait(timeout=2.0) and self._last_result:
return self._return_result(response, self._last_result, "识别成功(等待中)")