< >
Home » ROS探索总结 » ROS探索总结-28.机器听觉

ROS探索总结-28.机器听觉

ROS探索总结-28.机器听觉

说明:

  • 介绍如何接入语音识别,采用CMU Sphinx和Festival的语音识别包
  • 介绍如何与机器人对话,采用人工智能标记语言AIML

前言:

机器人通过机器视觉看到色彩斑斓的世界,但是人类最美好的不只是看到的,还有听到的,让机器人听懂人类的语音,同样是一样非常美妙的事情。

机器听觉,简单来说就是让机器人能听懂人说的话,以便更好的服务于人类。将语音——人类最自然的沟通和交换信息的媒介应用到智能机器人控制中,在机器人系统上增加语音接口,用语音代替键盘输入,并进行人机对话,不仅是将语音识别从理论转化为实用的有效证明,同时也是机器人智能化的重要标志之一。

语音识别原理

  • 语音识别分为两步:

第一步是根据识别系统的类型选择能够满足要求的一种识别方法,采用语音分析方法分析出这种识别方法所要求额度语音特征参数,这些参数作为标准模式存储起来,这一过程称为“学习”或“训练”。

第二步就是“识别”或“检测”阶段。根据实际需要选择语音特征参数,这些特征参数的时间序列构成了测试模版,将其与已存在的参考模版逐一进行比较,进行测度估计,最后经由专家知识库判决,最佳匹配的参考模版即为识别结果。

  • 原理图如下:

请输入图片描述

让机器人听懂你说的话:

ROS中集成了CMU Sphinx和Festival开源项目中的代码,发布了独立的语音识别功能包。

  • 安装pocketsphinx功能包

首先,我们需要安装pocketsphinx功能包和其依赖的其他声音功能库。

sudo apt-get install gstreamer0.10-pocketsphinx
sudo apt-get install gstreamer0.10-gconf
sudo apt-get install ros-indigo-pocketsphinx
sudo apt-get install ros-indigo-audio-common
sudo apt-get install libasound2

该功能包中的核心节点是recognizer.py文件。这个文件通过麦克风收集语音信息,然后调用语音识别库进行识别生成文本信息,通过/recognizer/output消息发布,其他节点就可以订阅该消息然后进行相应的处理了。

  • 安装完成后我们就可以运行测试了。

首先,插入你的麦克风设备,然后在系统设置里测试麦克风是否有语音输入。
然后,运行包中的测试程序:

roslaunch pocketsphinx robocup.launch

此时,在终端中会看到一些加载功能包的信息。尝试说一些指定的语句,当然,必须是英语,例如:bring me the glass,come with me。在运行的终端中,你应该可以看到识别后的文本信息:

请输入图片描述

该识别后的消息也会通过/recognizer/output话题发布,我们也可以直接看ROS最后发布的结果消息:

rostopic echo /recognizer/output

效果图:

请输入图片描述

从之前的原理介绍上,我们语音识别是将输入的语音与模版进行对比。pocketsphinx
功能包是一种离线的语音识别功能,默认支持的模版有限,我们可以通过下面的命令来查看暂时支持的所有语音指令:

roscd pocketsphinx/demo
more robocup.corpus
  • 创建语音库

语音库中的可识别信息使用txt文档存储,使用如下命令查看功能包中设计的语音指令:

roscd rbx1_speech/config
more nav_commands.txt

你应该可以看到如下可识别的指令:

请输入图片描述

你可以根据需求,对以上文件进行修改和添加。
然后我们要把这个文件在线生成语音信息和库文件,这一步需要登陆网站http://www.speech.cs.cmu.edu/tools/lmtool-new.html,根据网站的提示上传文件,然后在线编译生成库文件。

请输入图片描述

点击“选择文件”,然后选择nav_commands.txt文件,再点击“Compile Knowledge Base”按键进行编译。编译完成后,下载“COMPRESSED TARBALL”压缩文件,解压至config文件夹下,这些解压出来的”.dic”和“.lm”文件就是根据我们设计的语音识别指令生成的语音模版库。我们可以给这些文件改个名字:

roscd rbx1_speech/config
rename -f 's/3026/nav_commands/' *

在rbx1_speech/launch文件夹下看看voice_nav_commands.launch这个文件:

<launch> 
  <node name="recognizer" pkg="pocketsphinx" type="recognizer.py" output="screen"> 
    <param name="lm" value="$(find rbx1_speech)/config/nav_commands.lm"/> 
    <param name="dict" value="$(find rbx1_speech)/config/nav_commands.dic"/> 
  </node> 
</launch>

可以看到,这个launch文件在运行recognizer.py节点的时候使用了我们生成的语音识别库和文件参数,这样就可以实用我们自己的语音库来进行语音识别了。

通过之前的命令来测试一下效果如何吧:

roslaunch rbx1_speech voice_nav_commands.launch 
rostopic echo /recognizer/output

让机器人说话

现在机器人已经可以按照我们说的话行动了,要是机器人可以和我们对话就更好了。再之前的安装过程中,ros-indigo-audio-common元功能包已经包含了文本转语音的(Text-to-speech,TTS)的功能包sound_play。如果你还没有安装,可以使用下边的命令进行安装:

sudo apt-get install ros-indigo-audio-common
sudo apt-get install libasound2

然后我们来测试一下。在一个终端中运行sound_play的主节点:

rosrun sound_play soundplay_node.py

在另外一个终端中输入需要转化成语音的文本信息:

rosrun sound_play say.py "Greetings Humans. Take me to your leader."

有没有听见声音!ROS通过识别我们输入的文本,让机器人读了出来。发出这个声音的人叫做kal_diphone,如果不喜欢,我们也可以换一个人来读:

sudo apt-get install festvox-don  
 rosrun sound_play say.py "Welcome to the future" voice_don_diphone

与机器人对话

接下来我们再玩点更高级的,综合使用前边学习的pocketsphinx和sound_play功能包,再加入一点简单的人工智能,让机器人具备简单的自然语言理解能力,能够和我们进行简单的交流,就像苹果手机上的Siri助手一样。

  • 人工智能标记语言——AIML

AIML(Artificial Intelligence Markup Language,人工智能标记语言)是一种创建自然语言软件代理的XML语言,由Richard Wallace和世界各地的自由软件社区在1995年至2002年发明。AIML主要用于实现机器人的语言交流功能,用户可以与机器人说话,而机器人通过一个自然语言的软件代理,也可以给出一个聪明的回答。目前AIML已经有了Java,Ruby,Python, C ,C#,Pascal等语言的版本。
AIML文件包含一系列已定义的标签。我们通过一个简单的实例学习一下AIML的语法规则。

<aiml version="1.0.1" encoding="UTF-8">
  <category>
    <pattern> HOW ARE YOU </pattern>
    <template> I AM FINE </template>
  </category>
</aiml>

1.<aiml>标签:所有的aiml代码都需要介于<aiml></aiml>标签之间,该标签包含文件的版本号和编码格式。
2.<category>标签:表示一个基本的知识块,包含一条输入语句和一条输出语句,用来匹配机器人和人交流过程中的一问一答和一问多种应答,但不允许多种提问匹配。
3.<pattern>标签:表示用户的输入语句的匹配,在上边的例子中,用户一旦输入 “How are you” ,机器人就会找到这个匹配。注意,<pattern>标签内的语句必须大写。
4.<template>标签:表示机器人应答语句,机器人找到相应的匹配语句之后,会输出匹配语句对应的应答语句。

有了这几个简单的元素理论上就可以写出任意匹配模式,达到一定智能,但实际应用当中只有这些元素是不够的,我们在通过另一个示例略微深入的理解一下AIML。

<aiml version="1.0.1" encoding="UTF-8">
  <category>
    <pattern> WHAT IS A ROBOT? </pattern>
    <template>
    A ROBOT IS A MACHINE MAINLY DESIGNED FOR EXECUTING REPEATED TASK WITH SPEED AND PRECISION.
    </template>
  </category>
  <category>
    <pattern> DO YOU KNOW WHAT A * IS ? </pattern>
    <template>
      <srai> WHAT IS A <star/> </srai>
    </template>
  </category>
</aiml>

<star/>标签:表示,这里pattern元素里的匹配模式是用号表示任意匹配的,但在其他元素里面不能用号,而用<star/>这个元素来表示。在该示例中,当用户输入“Do you know what a robot is?”后,机器人会使用匹配输入的“robot”,然后将<star/>替换为“robot”。

<srai>标签:表示<srai>里面的话会被当作是用户输入,从新查找匹配模式,直到找到非<srai>定义的回复。用户输入 “Do you know what a robot is?”后,机器人会把“what is a robot”作为用户输入,然后查找到匹配的输出是“A ROBOT IS A MACHINE MAINLY DESIGNED FOR EXECUTING REPEATED TASK WITH SPEED AND PRECISION.”

当然,AIML支持的标签和用法远远不止这些,这里只作为背景知识进行了简单的介绍,如果你想深入的了解、学习AIML,可以访问网站http://www.alicebot.org/aiml.html。

  • Python中的AIML解析器

Python有针对AIML的开源解析模块—— PyAIML,该模块可以通过扫描AIML文件,建立一个定向模式树,然后通过深度搜索来匹配用户的输入。我们会使用该模块解析AIML文件,构建我们的机器人AI平台,所以先对该模块进行简单的介绍。

在ubuntu14.04上安装PyAIML的方法很简单,一句话搞定:

sudo apt-get install python-aiml

想要确定PyAIML是否安装成功,在python终端中输入“import aiml”,如果没有初相任何错误,则安装成功。

>>> import aiml

aiml模块中最重要的类是Kernel(),我们必须创建一个aiml.Kernel()对象,来进行对AIML文件的操作。

>>> mybot = aiml.Kernel()

下一步我们来加载一个AIML文件:

>>> mybot.learn('sample.aiml')

如果是加载多个AIML文件,可以在使用下边的命令:

>>> mybot.learn('startup.xml')

内容如下:

<aiml version="1.0">
    <category>
        <pattern>LOAD AIML B</pattern>
        <template>
        <!-- Load standard AIML set -->
            <learn>*.aiml</learn>
        </template>
    </category>
</aiml>

我们需要出发一条指令,这个命令会把当前路径下的所有aiml文件加载,并且生成模式匹配树。

>>> mybot.respond("load aiml b")

现在系统已经记住了所有的匹配语句,我们尝试出发一条定义的输入语句:

>>> while True: print k.respond(raw_input("> "))

OK,现在你应该可以看到机器人匹配到了我们输入的语句,并且输出了对应的回复:

请输入图片描述

  • 来和机器人对话吧

OK,如果有兴趣的话,可以把上边两部分的内容连接到一起,就可以完成与机器人的简单对话了!

请输入图片描述

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ros探索总结