当前位置:   article > 正文

ROS理论与实践(以移动机器人为例)连载(七) ——机器人语音交互_基于ros的移动机械臂语音机器人设计

基于ros的移动机械臂语音机器人设计


1. 科大讯飞开放平台使用简介

①如何使用科大讯飞开放平台

  1. 登录/注册 科大讯飞开放平台;

在这里插入图片描述

  1. 打开控制台创建新应用;

在这里插入图片描述

  1. 语音听写和语音合成SDK下载;

在这里插入图片描述

  • 包含五个文件夹:
    • bin: 最后生成的可执行文件
    • doc: API的使用文档和说明手册
    • include: 头文件
    • libs: 语音识别相关的链接库文件
    • samples: 例程
      • iat_online_record_sample:语音听写的例程包
      • tts_online_sample:语音输出,将某个字符串通过语音生成
  1. 编译iat_online_record_sample

在这里插入图片描述
如果报错:

linuxrec.c:12:28: fatal error: alsa/asoundlib.h: No such file or directory
  • 1

则执行

sudo apt-get install libasound2-dev
  • 1
  1. 执行bin文件夹目录下的可执行文件; 选择不提供使用者词库,麦克风输入音频;

在这里插入图片描述

  1. 编译tts_online_sample并执行可执行文件; 会生成一个Wav文件,里面是对科大讯飞的介绍;

在这里插入图片描述

②对SDK中提供的源码进行简要分析

我们可以打开iat_online_record_sample文件夹下的iat_online_record_sample.c文件(由于文件300多行这里就不粘贴了),熟悉一下里面核心的API。

大体上main函数里包括这些:

  1. 对appid的配置;
  2. 登录用户名;
  3. 上传用户的words列表;
  4. 选择语音从哪里来;
  5. demo_mic函数具体实现识别功能。

demo_mic:

static void demo_mic(const char* session_begin_params)
{
   
	int errcode;
	int i = 0;

	struct speech_rec iat;

	struct speech_rec_notifier recnotifier = {
   
		on_result,
		on_speech_begin,
		on_speech_end
	};

	errcode = sr_init(&iat, session_begin_params, SR_MIC, &recnotifier);
	if (errcode) {
   
		printf("speech recognizer init failed\n");
		return;
	}
	errcode = sr_start_listening(&iat);
	if (errcode) {
   
		printf("start listen failed %d\n", errcode);
	}
	/* demo 15 seconds recording */
	while(i++ < 15)
		sleep(1);
	errcode = sr_stop_listening(&iat);
	if (errcode) {
   
		printf("stop listening failed %d\n", errcode);
	}

	sr_uninit(&iat);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

我们需要关注里面的 on_result 的结果是如何发布的:

void on_result(const char *result, char is_last)
{
   
	if (result) {
   
		size_t left = g_buffersize - 1 - strlen(g_result);
		size_t size = strlen(result);
		if (left < size) {
   
			g_result = (char*)realloc(g_result, g_buffersize + BUFFER_SIZE);
			if (g_result)
				g_buffersize += BUFFER_SIZE;
			else {
   
				printf("mem alloc failed\n");
				return;
			}
		}
		strncat(g_result, result, size);
		show_result(g_result, is_last);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

从代码中我们猜想只要拿到这里的 g_result 这个全局变量就可以拿到最终的识别结果。

再来看一看tts_online_sample.c中的代码,text_to_speech是语音合成关键的函数:

const char* filename = "tts_sample.wav"; //合成的语音文件名称
const char* text = "亲爱的用户,您好,这是一个语音合成示例,感谢您对科大讯飞语音技术的支持!科大讯飞是亚太地区最大的语音上市公司,股票代码:002230"; //合成文本
ret = text_to_speech(text, filename, session_begin_params);
  • 1
  • 2
  • 3

通过这些代码结合用户登录和函数text_to_speech等,将text内的文字转换成了语音保存到了filename的文件中。
当然,我们可以修改代码,将语音直接输出出来。在文件末173行左右:

printf("合成完毕\n");

popen("play tts_sample.wav","r");	
//就是这句话很关键,但是需要提前确认Linux系统可以使用play
  • 1
  • 2
  • 3
  • 4

所以我们安装play相关的工具:(第一句话因SDK包名而异)

$ cd cd Linux_iat1227_tts_online1227_5e9199eb/libs/x64
$ sudo cp libmsc.so /usr/lib/
$ sudo apt install sox
$ sudo apt install libsox-fmt-all
  • 1
  • 2
  • 3
  • 4

科大讯飞的SDK带有ID号,每个人每次下载后的ID都不相同,更换SDK之后需要修改代码中的APPID。APPID可以在SDK包的名字后几位可以看到。

2. ROS语音识别与语音输出

①语音识别

在这里插入图片描述
通过修改上面提供的SDK源码文件,改成可以在ROS环境下使用的功能包,达成语音识别的目的。这个功能框图,描述了我们将通过一个唤醒词,就像“Hi Siri”一样,这里通过一个std_msgs::String的话题消息唤醒语音识别的功能,而不是执行一次./iat_online_record_sample识别一次;随后通过Result将识别后的文字包装成话题发布出去,可供其他操作者调用。

- 具体实现

  • subscriber:接收唤醒信号,将wakeupFlag变量置位;
  • publisher:主循环中调用SDK的语音识别功能,识别成功后置位resultFlag变量,将识别出来的字符串发布。

步骤:

  1. 创建功能包;

在这里插入图片描述

  1. 将SDK内的头文件复制粘贴在新创建的功能包内,包括include文件夹内的和samples/iat_online_record_sample文件夹下的.h文件;

在这里插入图片描述

  1. 将samples/iat_online_record_sample文件夹下的iat_online_record_sample.c,linuxrec.c和speech_recognizer.c文件放入新建功能包的src文件夹目录下,并把iat_online_record_sample.c文件扩展名改为cpp,因为我们将用到C++的语法;并创建launch文件夹;

在这里插入图片描述

  1. 修改iat_online_record_sample.cpp文件,这里我们可以发现ROS可以通过其他不同平台的已经实现功能的代码,经过修改达成ROS机器人使用的目的。

这里我把iat_publish.cpp全部代码都粘贴到了页面上,大家可以对比下载下来的SDK中iat_online_record_sample.c文件。多数代码都是讯飞提供的SDK的内容,我会解读其中修改的重要的部分:(解读的部分都由注释放置到对应的位置)

/*
* 语音听写(iFly Auto Transform)技术能够实时地将语音转换成对应的文字。
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "robot_voice/qisr.h"				//这里我们将头文件都放到了robot_voice/include/robot_voice文件夹内
#include "robot_voice/msp_cmn.h"
#include "robot_voice/msp_errors.h"
#include "robot_voice/speech_recognizer.h"

#include "ros/ros.h"						//调用ROS的头文件和发布消息类型的头文件
#include "std_msgs/String.h"

#define FRAME_LEN	640 
#define	BUFFER_SIZE	4096

int wakeupFlag   = 0 ;						//创建两个全局变量,wakeupFlag用来显示是否被唤醒;resultFlag标志有没有语音识别的结果
int resultFlag   = 0 ;
//跳转到main函数,其他函数大多没有修改都是科大讯飞给出的

/* Upload User words */
static int upload_userwords()
{
   
	char*			userwords	=	NULL;
	size_t			len			=	0;
	size_t			read_len	=	0;
	FILE*			fp			=	NULL;
	int				ret			=	-1;

	fp = fopen("userwords.txt", "rb");
	if (NULL == fp)										
	{
   
		printf("\nopen [userwords.txt] failed! \n");
		goto upload_exit;
	}

	fseek(fp, 0, SEEK_END);
	len = ftell(fp); 
	fseek(fp, 0, SEEK_SET);  					
	
	userwords = (char*)malloc(len + 1);
	if (NULL == userwords)
	{
   
		printf("\nout of memory! \n");
		goto upload_exit;
	}

	read_len = fread((void*)userwords, 1, len, fp); 
	if (read_len != len)
	{
   
		printf("\nread [userwords.txt] failed!\n");
		goto upload_exit;
	}
	userwords[len] = '\0';
	
	MSPUploadData("userwords", userwords, len, "sub = uup, dtt = userword", &ret); //ÉÏ´«Óû§´Ê±í
	if (MSP_SUCCESS != ret)
	{
   
		printf("\nMSPUploadData failed ! errorCode: %d \n", ret)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/465388
推荐阅读
相关标签
  

闽ICP备14008679号