语音控制
初步达成通过usb麦克风进行语音控制小狗运动的效果。
- iat_publish.cpp修改
由于我们想要达成的效果是向麦克风说话来控制机器狗,所以不再需要多余的选择文件等输入。我之前的代码全部默认wakeupFlag等于1,即时刻处于唤醒状态,然后通过键盘输入来选择识别哪个音频文件。本次代码修改了wakeupFlag,使其需要被唤醒,唤醒之后就立即去识别刚刚录入的音频文件。
int main(int argc, char* argv[])
{
// 初始化ROS
ros::init(argc, argv, "voiceRecognition");
ros::NodeHandle n;
ros::Rate loop_rate(10);
// 声明Publisher和Subscriber
// 订阅唤醒语音识别的信号
ros::Subscriber wakeUpSub = n.subscribe("voiceWakeup", 1000, WakeUp);
// 订阅唤醒语音识别的信号
ros::Publisher voiceWordsPub = n.advertise<std_msgs::String>("voiceWords", 1000);
ROS_INFO("Sleeping...");
int count=0;
int aud_src=0;
while(ros::ok())
{
// 语音识别唤醒
if (wakeupFlag){
ROS_INFO("Wakeup...");
int ret = MSP_SUCCESS;
const char* login_params = "appid = 5fa8bc98, work_dir = .";
const char* session_begin_params =
"sub = iat, domain = iat, language = zh_cn, "
"accent = mandarin, sample_rate = 16000, "
"result_type = plain, result_encoding = utf8";
ret = MSPLogin(NULL, NULL, login_params);
if(MSP_SUCCESS != ret){
MSPLogout();
printf("MSPLogin failed , Error code %d.\n",ret);
}
printf("Demo recgonizing the speech from the usb microphone\n");
demo_file("/home/liuda/spotmicro/src/spotMicro/robot_voice/bin/wav/test.wav", session_begin_params);
printf("please wait for 1 seconds\n");
delay(1);
wakeupFlag=0;
MSPLogout();
}
// 语音识别完成
std_msgs::String msg;
if(resultFlag){
resultFlag=0;
msg.data = g_result;
voiceWordsPub.publish(msg);
printf("pub\n");
}
else{
std::stringstream ss;
ss << "nothing";
msg.data = ss.str();
voiceWordsPub.publish(msg);
}
ros::spinOnce();
loop_rate.sleep();
count++;
}
exit:
MSPLogout(); // Logout...
return 0;
}
- 编写启动脚本
编写sh脚本来进行录制文件和发布语音唤醒消息,从而达到录制好音频文件后自动识别的功能。
#!/bin/bash
cd /home/liuda/spotmicro/src/spotMicro/robot_voice/bin/wav
sudo arecord -D "plughw:1,0" -d 5 -r 16000 -c 1 -t wav -f S16_LE test.wav #录制音频文件
rostopic pub /voiceWakeup std_msgs/String "data: 'start'" #发布语音唤醒消息
问题
- 实时性
目前机器狗的语音控制实时性具有比较明显的延迟,除去录音时间3s钟,自己写定的延时之外还有延时,可能是因为先录制文件再识别的原因,如果使用实时语音流的话应该会快一点,另外我观察在语音识别到消息并发布后机器狗也有停顿才开始
执行动作,这部分可能是控制部分代码结构不够优化导致存在消息阻塞之类的原因。两个部分都可以进行改进。 - 录入音频
我编写了一个脚本进行音频录制和消息发布。目前存在的一个问题是这个脚本默认执行一遍,我要发布下一条指令的话需要CTRL+C停止这个终端再重新执行,不过脚本代码编写我也还没了解太多,再多学习一下应该可以解决这个问题。