5.2.1 语音控制
语音控制接口提供了完整的语音交互能力,包括语音合成、语音识别、音频降噪、音频播放和音量控制等功能。
核心特性
语音合成 (TTS)
文本转语音:将文本转换为自然语音
多语言支持:支持中文、英文等多种语言
情感语音:支持不同情感风格的语音合成
优先级管理:支持多级优先级控制
语音识别 (ASR)
实时识别:支持实时语音识别
多语言识别:支持中文、英文等多种语言
音频流处理:支持音频流实时处理
音频处理
实时降噪:支持实时音频降噪处理
语音活动检测:支持VAD(Voice Activity Detection)
流式传输:支持降噪后音频流式传输
音频播放
音频流播放:支持音频数据流播放
优先级控制:支持播放优先级管理
格式支持:支持多种音频格式
音量控制
音量调节:支持系统音量调节
静音控制:支持静音/取消静音
音量查询:支持当前音量查询
音量控制服务
服务名称 |
数据类型 |
描述 |
|---|---|---|
|
查询音量 |
|
|
设置音量 |
|
|
查询静音 |
|
|
设置静音 |
GetVolumeros2-srv @ hal/audio/srv/GetVolume.srv# 获取音量 # 服务名称: /aimdk_5Fmsgs/srv/GetVolume # 请求 CommonRequest request # 请求头 --- # 响应 CommonResponse reponse # 响应头 uint32 audio_volume # 当前音量(范围:0-100)
SetVolumeros2-srv @ hal/audio/srv/SetVolume.srv# 设置音量 # 服务名称: /aimdk_5Fmsgs/srv/SetVolume # 请求 CommonRequest request # 请求头 uint32 audio_volume # 音量值(范围:0-100) --- # 响应 CommonResponse reponse # 响应头 uint32 audio_volume # 当前音量(范围:0-100)
GetMuteros2-srv @ hal/audio/srv/GetMute.srv# 获取静音状态 # 服务名称: /aimdk_5Fmsgs/srv/GetMute # 请求 CommonRequest request # 请求头 --- # 响应 CommonResponse reponse # 响应头 bool is_mute # 当前静音状态
SetMuteros2-srv @ hal/audio/srv/SetMute.srv# 设置静音 # 服务名称: /aimdk_5Fmsgs/srv/SetMute # 请求 CommonRequest request # 请求头 bool is_mute # 静音状态 --- # 响应 CommonResponse reponse # 响应头 bool is_mute # 当前静音状态
备注
SetVolume 与 SetMute 联动:SetVolume(0) 自动静音,SetVolume(>0) 自动取消静音。SetMute 不改变音量。
语音合成服务
服务名称 |
数据类型 |
描述 |
|---|---|---|
|
|
语音合成(文字转语音)播放 |
PlayTtsros2-srv @ interaction/srv/PlayTts.srv# 语音合成播放 # 服务名称: /aimdk_5Fmsgs/srv/PlayTts # 请求 CommonRequest header PlayTtsRequest tts_req #内嵌Request msg --- # 响应 CommonResponse header PlayTtsResponse tts_resp #内嵌Response msg
其中
PlayTtsRequestros2-msg @ interaction/msg/PlayTtsRequest.msg# 内嵌Request msg string text # 文本内容 TtsPriorityLevel priority_level # 优先级级别 (见下方TtsPriorityLevel说明) uint32 priority_weight # 优先级权重 (0-99) string domain # 调用方来源 string trace_id # 请求追踪ID bool is_interrupted # 是否打断同等优先级播报(不打断时进播放队列)
TtsPriorityLevelros2-msg @ interaction/msg/TtsPriorityLevel.msg# TTS优先级级别 uint8 value # 优先级值
TtsPriorityLevel可用级别:级别
数值
说明
使用场景
紧急安全层(SAFETY_L10)
10
最高优先级
安全警告、紧急通知
危险预警层(WARNING_L8)
8
高优先级
危险提醒、警告信息
系统提示层(SYSTEM_L7)
7
中高优先级
系统语音播报
交互响应层(INTERACTION_L6)
6
中优先级
用户交互、对话响应
任务执行层(MISSION_L4)
4
中低优先级
任务执行、状态播报
主动服务层(SERVICE_L2)
2
低优先级
主动服务、提醒
后台服务层(BACKGROUND_L1)
1
最低优先级
后台服务、日志
声音播放优先级机制说明:
本优先级体系适用于语音合成播放(PlayTts)
优先级比较:单纯的数字比大小,数值越高优先级越高
相等优先级行为:由
is_interrupted参数控制is_interrupted=true:打断当前播报is_interrupted=false:进入队列排队播报
打断时当前播放队列将被清空
紧急安全层优先级最高,不被任何其他优先级打断
注意
避免语音播报冲突:
系统运行时,以下模块会自动调用 PlayTts,可能打断用户的语音播报:
task_manager(运控计算单元 PC1,10.0.1.40):在故障诊断场景下以SAFETY_L10(如摔倒/阻尼倒/过温)或WARNING_L8(如导航中断/过温提示)自动播报。其中SAFETY_L10是最高优先级,无法被抢占;用户使用SYSTEM_L7可挡住WARNING_L8及以下,但会覆盖故障语音提示(如摔倒保护、过温告警等),导致用户无法通过语音感知这些故障。interaction_slave(交互计算单元 PC3,10.0.1.42):在充电状态变化等场景下以INTERACTION_L6(priority_level=6, is_interrupted=true)自动调用 PlayTts。使用高于 6 的priority_level(如SYSTEM_L7及以上)可避免被打断。
如需彻底停止
task_manager的自动播报,可在运控计算单元(PC1,10.0.1.40)上执行:aima em stop-app task_manager
如需彻底停止
interaction_slave的自动播报,可在交互计算单元(PC3,10.0.1.42)上执行:aima em stop-app interaction_slave
备注
使用高优先级或关闭系统模块后,故障语音提示(如摔倒保护、过温告警等)可能被覆盖或不再播报。建议同时订阅 HDS 诊断话题(
/aima/hds/diag_code_list、/aima/hds/post_proc/signal)以程序化方式监测系统安全警报,确保不遗漏关键故障信息。详见 故障处理。备注
音频文件播放(PlayAudioFile)使用与 PlayTts 不同的优先级体系,通过音频焦点机制管理,详见音频流播放功能集。
PlayTtsResponseros2-msg @ interaction/msg/PlayTtsResponse.msg# 内嵌Response msg string text # 响应文本 TtsPriorityLevel priority_level # 优先级级别 uint32 priority_weight # 优先级权重 string domain # 调用方来源 string trace_id # 请求追踪ID bool is_success # 是否成功 string error_message # 错误信息 uint32 estimated_duration # 预计耗时(单位:ms,当前固件版本始终返回 0;如需预估时长,请调用 GetTtsDuration 服务) uint8 error_code # 错误码(0 (ERROR_NONE 无错误), 1 (ERROR_HIGHER_PRIORITY_BUSY 更高优先级播报占用), 2 (ERROR_NETWORK_DISCONNECTED 预留), 3 (ERROR_UNKNOWN 未知错误))
音频文件播放服务
调用 PlayAudioFile 服务,指定音频文件路径(file_path 填父目录绝对路径,file_name 填文件名)和优先级,即可触发播放。响应中 reponse.status.value 为状态码:1(SUCCESS)=成功,2(FAILURE)=焦点申请失败,5(INVALID)=参数无效(文件名/格式不支持/文件不可访问/数据长度为 0 等)。
服务名称 |
数据类型 |
描述 |
|---|---|---|
|
|
音频文件播放 |
PlayAudioFileros2-srv @ hal/audio/srv/PlayAudioFile.srv# 播放音频文件 # 服务名称: /aimdk_5Fmsgs/srv/PlayAudioFile # 请求 CommonRequest request # 请求头 AudioFile file # 音频文件信息(必要项) builtin_interfaces/Time play_stamps # 可选,指定播放时刻(UTC),默认立即播放 --- # 响应 CommonResponse reponse # 响应头
备注
reponse.status.value恒为SUCCESS(1),无论是否获得焦点。判断是否获得焦点须看focus_response.focus_gain(true= 已获得,false= 未获得)。AudioFileros2-msg @ hal/audio/msg/AudioFile.msgstring pkg_name # 必要项,标识调用方来源 string file_name # 必要项,文件名 string file_path # 必要项,文件路径(不设置时使用系统默认路径,不以文件名结尾) AudioInfo info # PCM文件必填,WAV文件不使用(从文件头自动解析采样率和声道数) uint32 priority # 必要项,优先级(1~10, 默认6) uint32 priority_weight # 可选项,优先级权重(范围:0~99),priority + priority_weight% 为最终优先级
注意事项:
音频文件需要是PCM编码的原始文件(要求后缀.pcm)或WAV文件(要求后缀.wav,编码须为 PCM 或配套 PCM SubFormat 的 WAVE_FORMAT_EXTENSIBLE),不支持MP3等其他格式
音频数据须为16bit有符号整型PCM(S16LE)格式,数据长度不得为0。采样率和声道数不限,系统会自动重采样至16kHz/单声道;建议使用16kHz/单声道以获得最佳效果
PCM文件须通过
info字段指定sample_rate和channels;WAV文件不使用info字段,从文件头自动解析采样率和声道数file_path填父目录绝对路径(如/var/tmp/my_audio),file_name填文件名(如test.wav)音频文件须放置于交互计算单元(PC3,10.0.1.42)上,不在开发计算单元(PC2)上
音频文件夹及该文件夹所有父目录应当为所有用户可访问读取(建议在/var/tmp/下创建子目录存放)
音频流播放功能集
提供原始音频流播放支持
警告
焦点管理说明
通过 /aima/hal/audio/playback 话题推送音频数据时,hal_audio 订阅端不会自动请求焦点。用户需在播放前自行调用 RequestAudioFocus 服务申请焦点,否则可能与其他播放源冲突。
仅 PlayAudioFile 服务内部会自动管理焦点。
服务名称 |
数据类型 |
描述 |
|---|---|---|
|
音频播放焦点申请 |
|
|
音频播放焦点释放 |
|
|
停止音频播放 |
话题名称 |
数据类型 |
描述 |
QoS |
频率 |
|---|---|---|---|---|
|
音频流播放 |
|
用户发送(按需) |
|
|
音频焦点切换监听 |
|
触发式(事件驱动) |
|
|
音频播放状态监听 |
|
触发式(事件驱动) |
RequestAudioFocus ros2-srv @ hal/audio/srv/RequestAudioFocus.srv
# 音频播放焦点申请 # 服务名称: /aimdk_5Fmsgs/srv/RequestAudioFocus # 请求 CommonRequest request # 请求头 FocusRequester focus_requester # 请求焦点信息 --- # 响应 CommonResponse reponse # 响应头 FocusResponse focus_response # 请求结果
备注
reponse.status.value恒为SUCCESS(1),仅表示请求已被处理。判断是否获得焦点须看focus_response.focus_gain(true= 已获得,false= 未获得)。FocusRequester ros2-msg @ hal/audio/msg/FocusRequester.msg
string pkg_name # 播放源标识 uint32 priority # 优先级(范围:1~10,默认6) uint32 priority_weight # 权重(可选,范围:0~99),细分同优先级时的优先性
FocusResponse ros2-msg @ hal/audio/msg/FocusResponse.msg
string pkg_name # 播放源标识 bool focus_gain # 焦点结果
AbandonAudioFocus ros2-srv @ hal/audio/srv/AbandonAudioFocus.srv
# 音频播放焦点释放 # 服务名称: /aimdk_5Fmsgs/srv/AbandonAudioFocus # 请求 CommonRequest request # 请求头 FocusRequester focus_requester # 请求焦点信息 --- # 响应 CommonResponse reponse # 响应头 FocusResponse focus_response # 请求结果
备注
reponse.status.value恒为SUCCESS(1),仅表示请求已被处理。判断焦点是否释放须看focus_response.focus_gain。FocusRequester, FocusResponse 定义如前所示>>
警告
AbandonAudioFocus 注意事项
调用
AbandonAudioFocus时,focus_requester中的pkg_name、priority、priority_weight三个字段必须与对应RequestAudioFocus调用时所传入的值完全一致,否则焦点无法匹配和释放。焦点抢占规则:高优先级或同等优先级的挑战者会抢占当前焦点持有者,并通过
/aima/hal/audio/focus_response话题发布焦点丢失通知。同一pkg_name重复请求焦点时静默更新,不发布焦点丢失通知。
StopAudioPlay ros2-srv @ hal/audio/srv/StopAudioPlay.srv
# 停止音频播放 # 服务名称: /aimdk_5Fmsgs/srv/StopAudioPlay # 请求 CommonRequest request # 请求头 --- # 响应 CommonResponse reponse # 响应头
调用此服务会立即清空播放队列和音频缓冲区,停止当前正在播放的音频。
警告
此服务会停止所有正在播放的音频, 需考虑告警播报等安全提示被阻断的风险
AudioPlayback ros2-msg @ hal/audio/msg/AudioPlayback.msg
# 音频流播放 # 话题名称: /aima/hal/audio/playback builtin_interfaces/Time stamps # 时间戳 AudioInfo info # 音频格式 AudioData data # 音频数据 string pkg_name # 播放源标识(变化时清空播放缓存,打断当前播放) string token_id # 预留
说明:当不同
pkg_name的消息到达时,hal_audio 会 flush 所有旧数据(清空队列和 ring buffer),发布PLAYER_STATE_STOPED,然后开始播放新数据。不同pkg_name的消息不会共存。AudioInfo ros2-msg @ hal/audio/msg/AudioInfo.msg
uint8 channels # 通道数(播放PCM文件和音频流时必填) uint32 sample_rate # 采样率(单位:Hz,播放PCM文件和音频流时必填) uint32 size # 预留 string sample_format # 预留 string coding_format # 预留
说明:
size、sample_format和coding_format为预留字段,系统始终按 S16LE PCM 处理数据。WAV 文件播放时info字段整体不被读取(采样率和声道数从 WAV 文件头自动解析)。AudioData ros2-msg @ hal/audio/msg/AudioData.msg
uint8[] data
FocusResponse ros2-msg @ hal/audio/msg/FocusResponse.msg
# 音频焦点切换监听 # 话题名称: /aima/hal/audio/focus_response string pkg_name # 播放源标识 bool focus_gain # 焦点结果(仅在焦点被抢占时发布,focus_gain 始终为 false;申请/释放动作本身不在此话题通知)
PlayStateChange ros2-msg @ hal/audio/msg/PlayStateChange.msg
# 音频播放状态监听 # 话题名称: /aima/hal/audio/play_state string pkg_name # 播放源标识 PlayStateType state # 播放状态(state.value:0 (PLAYER_STATE_CLOSED 关闭), 1 (PLAYER_STATE_PLAYING 播放中), 2 (PLAYER_STATE_STOPED 停止))
备注
PlayStateType 状态转换:
CLOSED(0):仅在模块初始化时发布一次,之后不再出现PLAYING(1)↔STOPPED(2):开始播放时推送PLAYING,播放结束/中断/缓冲区耗尽时推送STOPPED,两者交替出现
MIC音频流采集话题
支持获取实时降噪后的语音活动检测(VAD, Voice Activity Detection)事件及相应音频流、也支持获取原始音频流
话题名称 |
数据类型 |
描述 |
QoS |
频率 |
|---|---|---|---|---|
|
VAD音频采集 |
|
触发式, 识别到语言后先将识别阶段堆积的数据极速发出, 后续约25Hz |
|
|
原始音频采集 |
|
33.3Hz |
ProcessedAudioOutputros2-msg @ interaction/msg/ProcessedAudioOutput.msgMessageHeader header # 消息头(未启用) uint32 stream_id # 音频流id(0:本体mic, 1:外置mic,与 SetMicSource 服务编号一致。当前切换为哪个麦克风,音频数据就通过对应的 stream_id 发布) AudioVadStateType audio_vad_state # VAD状态(audio_vad_state.value:1 (AUDIO_VAD_STATE_BEGIN 语言开始), 2 (AUDIO_VAD_STATE_PROCESSING 语言处理中), 3 (AUDIO_VAD_STATE_END 语言结束)) uint8[] audio_data # 语音数据(PCM编码,16kHz/16bit/1ch)
注意音频流格式:
采样率: 16kHz
位深: 16bit (S16LE)
声道: 单声道
编码: PCM
上述格式为系统输出的固定格式。通过
/aima/hal/audio/playback播放音频流时,系统会自动将输入数据重采样至上述格式,因此输入数据的采样率和声道数不限,但位深须为16bit。
注意
VAD 需要配合唤醒词使用(v0.9+), 用法如下:
原生的智元交互保持开启时, 唤醒词仅短时激活VAD检测, 该时段的语言触发VAD音频流
智元交互切换到
only_voice模式时, 首次唤醒词已长期激活VAD检测,后续只需有语言即可触发VAD音频流
AudioCaptureros2-msg @ hal/audio/msg/AudioCapture.msg# 原始音频采集 # 话题名称: /aima/hal/audio/capture builtin_interfaces/Time stamps uint8 mic_channels # 麦克风通道数 uint8 ref_channels # 回采信号通道数 AudioInfo info # 音频格式(info.channels = mic_channels + ref_channels,即总通道数) AudioData data # 音频数据 string pkg_name # 音频源(当前固件中始终为空字符串)
备注
AudioCapture 数据布局:data 中多通道音频按采样点(int16_t)交错存储,同一时刻各通道采样依次排列。例如 2 通道序列:(通道0采样, 通道1采样), (通道0采样, 通道1采样), ...(每对括号内为同一时刻的所有通道采样)。通道组成:
内置麦:6 通道(4 麦克风 + 2 回采)
外置麦:2 通道(1 麦克风 + 1 回采)
麦克风控制服务
服务名称 |
数据类型 |
描述 |
|---|---|---|
|
|
查询当前MIC设备 |
|
|
切换MIC设备 |
GetMicSourceRequestros2-srv @ interaction/srv/GetMicSourceRequest.srv# 查询当前MIC设备 # 服务名称: /aimdk_5Fmsgs/srv/GetMicSourceRequest # 请求 CommonRequest header --- # 响应 CommonResponse header uint32 mic_source # 麦克风源(0: 内置麦, 非零值: 外置麦)
SetMicSourceRequestros2-srv @ interaction/srv/SetMicSourceRequest.srv# 切换MIC设备 # 服务名称: /aimdk_5Fmsgs/srv/SetMicSourceRequest # 请求 CommonRequest header uint32 mic_source # 麦克风源(0: 内置麦, 非零值: 外置麦) --- # 响应 CommonResponse header
编程示例
详细的编程示例和代码说明请参考:
C++ 示例:
Python 示例:
安全注意事项
警告
语音播放限制
语音合成服务有优先级限制,避免同时播放多个语音
高优先级语音会打断低优先级语音,请合理设置优先级
建议在语音播放前检查当前播放状态
小心
ROS的服务(service)机制在跨板通信时存在一些待优化问题, 二次开发时请参考例程添加异常处理、快速重试等保护机制
机器人处于稳定站立 / 走跑模式时, 请勿批量快速启动 ROS 节点(建议不超过 2 个/秒), 短时间内大量节点参与 DDS 发现会造成通信拥塞、影响运控实时性, 存在机器人失稳摔倒风险
备注
最佳实践
使用合适的优先级级别,避免影响重要信息播报
实现语音播放状态监控和异常处理
建议实现语音播放队列管理
注意音频格式和采样率要求
VAD 接收队列深度应充分预留
VAD 不要忘记使用唤醒词