🆕 8.9 语音(lyre 语音包)
8.9.1 程序包及安装位置
lyre 语音包包括 lyre_ros2、lyre_msgs 和 lyre_examples 三个程序包。
- lyre_ros2 是语音包的功能程序包,安装在orin主控中。
- lyre_msgs 是语音包的接口定义。该接口定义同时安装在x86的ros2ws目录以 及 lyre_ros2 目录。
- lyre_examples 是语音包接口的调用示例程序。该示例程序安装在x86的 ros2ws 目录。
lyre 语音包程序的目录结构如下:
├── ros2ws/ # x86
│ ├── install
│ │ ├── lyre_msgs # 接口定义
│ │ │ ├──README.md # SDK 开发文档
│ │ ├── lyre_examples # 接口调用示例程序
|
├── lyre_ros2/ # orin
│ ├── install
│ │ ├── lyre_msgs # 接口定义
│ │ │ ├──README.md # SDK 开发文档
│ │ ├── lyre # 功能包
│ ├── scripts
│ │ ├── setup_network.sh # 网络配置脚本
│ │ ├── setup_systemd.sh # 自启动服务部署脚本
│ │ ├── reset_systemd.sh # 自启动服务卸载脚本
│ ├── README.md # 用户手册
│ ├── QAs.md # 常见问题
总结下来是:
分为 lyre 包,lyre_msgs 包和 lyre_examples 包,其中 orin 上的 lyre_ros2 目录安装了 lyre 包和 lyre_msgs 包,x86 上的 ros2ws 目录安装了 lyre_msgs 包和 lyre_examples 包。
8.9.2 语音交互功能
机器人提供有语音交互功能。设备开机以后,语音交互功能为关闭状态。通过遥控器 按键可以开启语音交互功能。
8.9.2.1 遥控器开关
E、G、H键在中间;F键向上。 长按A键,可以打开/关闭语音交互功能。
8.9.2.2 语音对话方式
站立在机器人正前方1.5米左右的位置,正视机器人胸前麦克风上方的摄像头,与机器人进行对话。
8.9.3 启动语音包
语音包的 ROS 包名为 lyre,在 systemd 中的服务名称也是 lyre。
8.9.3.1 手动启动语音对话的ROS节点
在 lyre_ros2 程序包中使用下面的命令启动语音对话的ROS节点。
cd lyre_ros2
source install/setup.bash
ros2 launch lyre chat.launch.py
注意:机器人默认会在开始时自行启动lyre节点。同一时间只允许一个lyre进程运行。通过下面的命令检查系统中是否有其它lyre进程正在运行。
ps -ef | grep "ros2 launch lyre" | grep -v grep
如果有打印内容,则说明 lyre 进程正在运行。通过下面的命令可以关闭系统中正在运行的 lyre 进程。
pkill -INT -f "ros2 launch lyre"
注意:如果通过 systemd 配置了开机自启动服务,则需要在关闭自启动服务以后再结束进程。否则,手动结束的进程会被重新启动。具体操作参考后面的章节。
8.9.3.2 开机自启动服务
出厂时,语音包的 systemd 服务 lyre 会在开机时自行启动。 检查 lyre 服务是否会在开机时自启动
systemctl is-enabled lyre
如果显示 enabled,则说明 lyre 服务会在开机时自启动。 打开 lyre 服务开机自启动设置
sudo systemctl enable lyre
关闭 lyre 服务开机自启动设置
sudo systemctl disable lyre
8.9.4 启动模式
lyre 语音包提供了四种运行模式,分别是 play、asr、audio、chat。接入者可以根据实际情况选用其中的一种。
注意:启动模式是互斥的。同一时间,只可以允许4种启动模式中的一种。
- play: 在此启动模式下,仅『音频播放』相关的功能可以使用。
- asr: 在此启动模式下,仅『语音识别』相关的功能可以使用。
- audio: 在此启动模式下,可以同时使用『语音识别』和『音频播放』功能,包括『文本播放』功能。
- chat: 在此启动模式下,可以同时使用『语音识别』、『音频播放』和『语音对话』功能。
不同模式的节点的启动命令统一为:
ros2 launch lyre <mode>.launch.py
例如,启动audio模式的命令为:
ros2 launch lyre audio.launch.py
部署某个启动模式的开机自启动服务
lyre_ros2 程序包给出了自启动服务的部署脚本 setup_systemd.sh,该脚本位于 lyre_ros2/scripts 目录下。使用方法如下:
bash setup_systemd.sh <mode>[default:chat]
例如:将play启动模式部署为自启动服务的命令如下:
bash setup_systemd.sh play
8.9.5 接口示例程序
lyre_examples 程序包提供了部分 CPP 版本的接口调用示例。程序包的目录结构如下:
lyre_examples/
├──bin/ # 接口调用示例的可执行程序
│ ├──lyre_example_play_file_srv
├──cli/ # 接口调用示例的终端执行脚本
│ ├──call_play_file_srv.sh
│ ├──sub_play_progress_msg.sh
├──src/ # 接口调用示例的CPP代码
│ ├──play_file_srv.cpp
├──res/ # 静态资料
│ ├──test.mp3
├──CMakeLists.txt # 项目CMakeLists.txt示例
├──package.xml # 项目ROSpackage.xml示例
对于每个开放的语音接口,lyre_examples 包都提供有接口调用的示例代码、编译后的可执行程序、终端调用脚本,分别放置在 src、bin、cli 目录。
为了避免混淆,每个演示所用的可执行程序的文件名前面都加了 lyre_example_ 作为前缀。每个用于订阅Topic的脚本的文件名都加了sub_作为前缀;每个用于发布 Topic 的脚本的文件名都加了 pub_ 作为前缀。每个用于调用 Service 的脚本的文件名则都加了 call_ 作为前缀。
对于二次开发的 CPP ROS2 项目,可以参考 lyre_examples 包中的方式导入 lyre_msgs 接口,再参考示例代码完成功能开发。
8.9.5.1 ROSpackage配置
<packageformat="3">
<depend>lyre_msgs</depend>
</package>
8.9.5.2 项目CMake配置
find_package(lyre_msgsREQUIRED)
ament_target_dependencies(
<your_target>
lyre_msgs
)
8.9.5.3 编译时、运行时依赖配置
x86 的 ros2ws 和 orin 的 lyre_ros2 提供了 lyre_msgs 包。在构建或者运行自己的 ROS 程序之前,需要先从这两个工作空间导入 lyre_msgs 依赖。
# x86
source ros2ws/install/setup.bash
# orin
source lyre_ros2/install/setup.bash
8.9.6 音频播放接口
8.9.6.1 播放本地文件(Service)
如果你已经明确知道lyre_ros2程序包所在的主控板中有一个音频文件,你可以使用下面的ROS服务播放这个文件。
# lyre_msgs/srv/PlayFile.srv
# 以本地文件的形式播放一段语音。
string SERVICE_NAME = /audio_play/play_file
string sid #Stream identifier(unique per audio stream).
uint32 seq #Sequence number(incremental per packet).
bool last #Last flag(true if this is the final packet).
bool force #Force playback(stop all running tasks and play immediately).
string path #Absolute path to the audio file in the local file system.
---
int8 CODE_OK = 0
int8 CODE_INVALID_PARAMS = 1
int8 CODE_FAILED = -1
string sid # Playback stream ID (generated internally if absent).
int8 code # Status code.
string message # Human-readable status message.
接口调用的CPP示例代码请参考 lyre_examples 程序包中的 play_text_srv。
8.9.6.2 播放远程文件(Service)
你还可以使用下面的 ROS 服务来播放一个来自网络的音频文件。
# lyre_msgs/srv/PlayUrl.srv
# 以文件URL的形式播放一段语音。
string SERVICE_NAME = /audio_play/play_url
string sid #Stream identifier(unique per audio stream).
uint32 seq #Sequence number(incremental per packet).
bool last #Last flag(true if this is the final packet).
bool force #Force playback(stop all running tasks and play immediately).
string url #URL to the audio file in the network.
---
int8 CODE_OK = 0
int8 CODE_INVALID_PARAMS = 1
int8 CODE_FAILED = -1
string sid # Playback stream ID (generated internally if absent).
int8 code # Status code.
string message # Human-readable status message.
接口调用的CPP示例代码请参考 lyre_examples 程序包中的 play_url_srv。
8.9.6.3 播放文本(Service)
如果你需要从别的主控板访问音频播放服务,可以使用下面的ROS服务来播放一个字符串。
#lyre_msgs/srv/PlayText.srv
#以文本的形式播放一段语音。
string SERVICE_NAME = /audio_play/play_text
string sid # Stream identifier(unique per audio stream).
uint32 seq # Sequence number(incremental per packet).
bool last # Last flag(true if this is the final packet).
bool force # Force playback(stop all running tasks and play immediately).
string text # Text to be synthesized into speech.
string token # System api(unavailable for applications).
string output # System api(unavailable for applications).
---
int8 CODE_OK = 0
int8 CODE_INVALID_PARAMS = 1
int8 CODE_FAILED = -1
string sid # Playback stream ID(generated internally if absent).
int8 code # Status code.
string message # Human-readable status message.
接口调用的CPP示例代码请参考 lyre_examples 程序包中的 play_text_srv。
注意:此功能仅在 audio 和 chat 启动模式下才可用。
8.9.6.4 监听播放事件(Topic)
播放音频的过程中会通过下面的 Topic 来发布播放事件:
# lyre_msgs/msg/PlayEvent.msg
# Play音频播放的事件。
string TOPIC_NAME = /audio_play/event
int8 EVENT_STARTED = 0
int8 EVENT_COMPLETED = 1
int8 EVENT_STOPPED = 2
int8 EVENT_CANCELLED = 3
int8 EVENT_FAILED = 4
string sid
uint32 seq
int8 event
string message
接口调用的CPP示例代码请参考 lyre_examples 程序包中的 play_event_msg。
8.9.6.5 监听播放进度(Topic)
播放音频的过程中会通过下面的 Topic 来发布播放的进度及总时长(单位:秒):
# lyre_msgs/msg/PlayProgress.msg
# Play音频播放的进度。
string TOPIC_NAME = /audio_play/progress
string sid
uint32 seq
float64 position
float64 duration
接口调用的 CPP 示例代码请参考 lyre_examples 程序包中的 play_progress_msg。
8.9.6.6 停止音频播放(Service)
通过下面的 ROS 服务来停止音频播放(停止以后无法恢复):
# lyre_msgs/srv/PlayStop.srv
# 停止当前的音频播放任务(不可恢复)。
string SERVICE_NAME = /audio_play/stop
---
接口调用的 CPP 示例代码请参考 lyre_examples 程序包中的 play_stop_srv。
8.9.6.7 暂停音频播放(Service)
通过下面的 ROS 服务来停止音频播放(暂停以后可以调用 Resume 服务恢复播放):
# lyre_msgs/srv/PlayPause.srv
# 暂停当前的音频播放任务。
string SERVICE_NAME = /audio_play/pause
---
接口调用的 CPP 示例代码请参考 lyre_examples 程序包中的 play_pause_srv。
8.9.6.8 恢复音频播放(Service)
通过下面的 ROS 服务来恢复播放暂停中的音频:
# lyre_msgs/srv/PlayResume.srv
# 恢复已暂停的音频播放任务。
string SERVICE_NAME = /audio_play/resume
---
接口调用的 CPP 示例代码请参考 lyre_examples 程序包中的 play_resume_srv。
8.9.7 语音识别接口
设备集成有语音识别模块,可以提供 ASR 语音识别功能。
8.9.7.1 监听唤醒事件(Topic)
在设备周围喊出关键词,可以触发唤醒事件。不同设备的唤醒关键词请参考用户手册。
在代码中可以通过以下 ROS 话题来监听唤醒消息:
# lyre_msgs/msg/AsrKeyword.msg
# ASR唤醒时识别到的关键字。
string TOPIC_NAME = /audio_asr/keyword
string keyword
int32 angle
接口调用的 CPP 示例代码请参考 lyre_examples 程序包中的 asr_keyword_msg。
8.9.7.2 监听语音识别结果(Topic)
设备可以将周围的声音转化为文本。可以通过以下 ROS 话题获取识别到的文本:
# lyre_msgs/msg/AsrIat.msg
# ASR语音识别到的内容。
string TOPIC_NAME = /audio_asr/iat
string id
string text
接口调用的 CPP 示例代码请参考 lyre_examples 程序包中的 asr_iat_msg。
8.9.7.3 监听其它事件(Topic)
设备还会发布其它 ASR 相关的事件,事件类型定义在下面的 ROS 话题中:
# lyre_msgs/msg/AsrEvent.msg
# ASR设备报出的事件。
string TOPIC_NAME = /audio_asr/event
int8 EVENT_ERROR = 2 #出错事件。arg1是错误码。
int8 EVENT_STATE = 3 #服务状态事件。
int8 EVENT_WAKEUP = 4 #唤醒事件。
int8 EVENT_SLEEP = 5 #休眠事件。
int8 EVENT_PRE_SLEEP = 10 #准备休眠事件。
int8 EVENT_CONNECTED_TO_SERVER = 13 #与服务端建立连接。
int8 EVENT_SERVER_DISCONNECTED = 14 #与服务端断开连接。
int8 event
int8 arg1
接口调用的 CPP 示例代码请参考 lyre_examples 程序包中的 asr_event_msg。
8.9.7.4 aiui_msg 事件
SDK 兼容旧版本的 /xunfei/aiui_msg 话题,这个话题已经被标记为 Deprecated,未来很可能会被移除。
string TOPIC_NAME = /xunfei/aiui_msg
该话题的类型是 std_msgs::msg::String,可以通过下面的示例脚本获取到:
ros2 topic echo -f /xunfei/aiui_msg
8.9.8 语音对话接口
8.9.8.1 语音交互开关
lyre节点接收一个ROS话题来控制语音交互的可用状态。
string TOPIC_NAME = /audio_chat/enable
话题的类型是std_msgs/msg/Bool。
对话开启的示例脚本:
ros2 topic pub -1 /audio_chat/enable std_msgs/msg/Bool 'data: true'
对话关闭的示例脚本:
ros2 topic pub -1 /audio_chat/enable std_msgs/msg/Bool 'data: false'