语言识别

pocketsphinx

语言识别教程:http://wiki.ros.org/pocketsphinx .该包更新之后, 可以用catkin了

 

1.        运行安装命令:sudo apt-get install ros-indigo-pocketsphinx

查看语音库

$ roscd pocketsphinx/demo

$ls

$roslaunch roscup.launch

E: Unable to fetch some archives, maybe run apt-getupdate or try with --fix-missing?

去该网页上找了,发现只有20140304这一新的版本, 看来得需要先更新源,但运行sudo apt-get update 时报错:

W: GPG error: http://security.ubuntu.comprecise-security Release: The followingsignatures wereinvalid:BADSIG 40976EAF437D05B5 Ubuntu Archive Automatic SigningKey 。。。Hash Sum mismatch

解决办法是:

sudo apt-get clean
cd /var/lib/apt
sudo mv lists lists.old //把lists文件夹改名为list.old
sudo mkdir -p lists/partial //新建文件夹
sudo apt-get clean
sudo apt-get update

再运行安装命令,sudo apt-get install ros-indigo-pocketsphinx.成功则提示:ldconfig deferred processing now taking place

2.        运行命令$ roslaunch pocketsphinx robocup.launch  //不识别 还得手动敲进去

3.        需要在系统设置中设置麦克风的音量,要设置得大一些,

4.        查看发布的结果消息$ rostopic echo /recognizer/output

 

查看语音库                       

roscd pocketsphinx/demo

进入了文件夹; /opt/ros/indigo/share/pocketsphinx/demo$ 



如今语音识别在PC机和智能手机上炒的火热,ROS走在技术的最前沿当然也不会错过这么帅的技术。ROS中使用了CMU Sphinx和Festival开源项目中的代码,发布了独立的语音识别包,而且可以将识别出来的语音转换成文字,然后让机器人智能处理后说话。


一、语音识别包


1、安装

        安装很简单,直接使用ubuntu命令即可,首先安装依赖库:
[plain]   view plain  copy
  1. $ sudo apt-get install gstreamer0.10-pocketsphinx  
  2. $ sudo apt-get install ros-indigo-audio-common  
  3. $ sudo apt-get install libasound2  

        然后来安装ROS包:
[plain]   view plain  copy
  1. $ svn checkout http://albany-ros-pkg.googlecode.com/svn/trunk/rharmony  
  2. $ rosmake pocketsphinx  

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

2、测试

        安装完成后我们就可以运行测试了。
        首先,插入你的麦克风设备,然后在系统设置里测试麦克风是否有语音输入。
        然后,运行包中的测试程序:        
[plain]   view plain  copy
  1. $ roslaunch pocketsphinx robocup.launch  

        此时,在终端中会看到一大段的信息。尝试说一些简单的语句,当然,必须是英语,例如:bring me the glass,come with me,看看能不能识别出来。
       《ros by example》这本书中写得测试还是很准确的,但是我在测试中感觉识别相当不准确,可能是我的英语太差了吧。
        
        我们也可以直接看ROS最后发布的结果消息:
[plain]   view plain  copy
  1. $ rostopic echo /recognizer/output  

        


二、语音库


1、查看语音库

        这个语音识别时一种离线识别的方法,将一些常用的词汇放到一个文件中,作为识别的文本库,然后分段识别语音信号,最后在库中搜索对应的文本信息。如果想看语音识别库中有哪些文本信息,可以通过下面的指令进行查询:
[plain]   view plain  copy
  1. $ roscd pocketsphinx/demo  
  2. $ more robocup.corpus  

2、添加语音库

        我们可以自己向语音库中添加其他的文本识别信息,《ros by example》自带的例程中是带有语音识别的例程的,而且有添加语音库的例子。
        首先看看例子中要添加的文本信息:
[plain]   view plain  copy
  1. $ roscd rbx1_speech/config  
  2. $ more nav_commands.txt  

        
        这就是需要添加的文本,我们也可以修改其中的某些文本,改成自己需要的。
        然后我们要把这个文件在线生成语音信息和库文件,这一步需要登陆网站http://www.speech.cs.cmu.edu/tools/lmtool-new.html,根据网站的提示上传文件,然后在线编译生成库文件。

        把下载的文件都解压放在rbx1_speech包的config文件夹下。我们可以给这些文件改个名字:
[plain]   view plain  copy
  1. $ roscd rbx1_speech/config  
  2. $ rename -f 's/3026/nav_commands/' *  

        在rbx1_speech/launch文件夹下看看voice_nav_commands.launch这个文件:
[plain]   view plain  copy
  1. <launch>  
  2. <node name="recognizer" pkg="pocketsphinx" type="recognizer.py"  
  3. output="screen">  
  4. <param name="lm" value="$(find rbx1_speech)/config/nav_commands.lm"/>  
  5. <param name="dict" value="$(find rbx1_speech)/config/nav_commands.dic"/>  
  6. </node>  
  7. </launch>  

        可以看到,这个launch文件在运行recognizer.py节点的时候使用了我们生成的语音识别库和文件参数,这样就可以实用我们自己的语音库来进行语音识别了。
        通过之前的命令来测试一下效果如何吧:
[plain]   view plain  copy
  1. $ roslaunch rbx1_speech voice_nav_commands.launch  
  2. $ rostopic echo /recognizer/output  

三、语音控制

        有了语音识别,我们就可以来做很多犀利的应用了,首先先来尝试一下用语音来控制机器人动作。

1、机器人控制节点

        前面说到的recognizer.py会将最后识别的文本信息通过消息发布,那么我们来编写一个机器人控制节点接收这个消息,进行相应的控制即可。
        在pocketsphinx包中本身有一个语音控制发布Twist消息的例程voice_cmd_vel.py,rbx1_speech包对其进行了一些简化修改,在nodes文件夹里可以查看voice_nav.py文件:
[python]   view plain  copy
  1. #!/usr/bin/env python  
  2.   
  3. """ 
  4.   voice_nav.py 
  5.    
  6.   Allows controlling a mobile base using simple speech commands. 
  7.    
  8.   Based on the voice_cmd_vel.py script by Michael Ferguson in 
  9.   the pocketsphinx ROS package. 
  10.    
  11.   See http://www.ros.org/wiki/pocketsphinx 
  12. """  
  13.   
  14. import roslib; roslib.load_manifest('rbx1_speech')  
  15. import rospy  
  16. from geometry_msgs.msg import Twist  
  17. from std_msgs.msg import String  
  18. from math import copysign  
  19.   
  20. class VoiceNav:  
  21.     def __init__(self):  
  22.         rospy.init_node('voice_nav')  
  23.           
  24.         rospy.on_shutdown(self.cleanup)  
  25.           
  26.         # Set a number of parameters affecting the robot's speed  
  27.         self.max_speed = rospy.get_param("~max_speed"0.4)  
  28.         self.max_angular_speed = rospy.get_param("~max_angular_speed"1.5)  
  29.         self.speed = rospy.get_param("~start_speed"0.1)  
  30.         self.angular_speed = rospy.get_param("~start_angular_speed"0.5)  
  31.         self.linear_increment = rospy.get_param("~linear_increment"0.05)  
  32.         self.angular_increment = rospy.get_param("~angular_increment"0.4)  
  33.           
  34.         # We don't have to run the script very fast  
  35.         self.rate = rospy.get_param("~rate"5)  
  36.         r = rospy.Rate(self.rate)  
  37.           
  38.         # A flag to determine whether or not voice control is paused  
  39.         self.paused = False  
  40.           
  41.         # Initialize the Twist message we will publish.  
  42.         self.cmd_vel = Twist()  
  43.   
  44.         # Publish the Twist message to the cmd_vel topic  
  45.         self.cmd_vel_pub = rospy.Publisher('cmd_vel', Twist)  
  46.           
  47.         # Subscribe to the /recognizer/output topic to receive voice commands.  
  48.         rospy.Subscriber('/recognizer/output', String, self.speech_callback)  
  49.           
  50.         # A mapping from keywords or phrases to commands  
  51.         self.keywords_to_command = {'stop': ['stop''halt''abort''kill''panic''off''freeze''shut down''turn off''help''help me'],  
  52.                                     'slower': ['slow down''slower'],  
  53.                                     'faster': ['speed up''faster'],  
  54.                                     'forward': ['forward''ahead''straight'],  
  55.                                     'backward': ['back''backward''back up'],  
  56.                                     'rotate left': ['rotate left'],  
  57.                                     'rotate right': ['rotate right'],  
  58.                                     'turn left': ['turn left'],  
  59.                                     'turn right': ['turn right'],  
  60.                                     'quarter': ['quarter speed'],  
  61.                                     'half': ['half speed'],  
  62.                                     'full': ['full speed'],  
  63.                                     'pause': ['pause speech'],  
  64.                                     'continue': ['continue speech']}  
  65.           
  66.         rospy.loginfo("Ready to receive voice commands")  
  67.           
  68.         # We have to keep publishing the cmd_vel message if we want the robot to keep moving.  
  69.         while not rospy.is_shutdown():  
  70.             self.cmd_vel_pub.publish(self.cmd_vel)  
  71.             r.sleep()                         
  72.               
  73.     def get_command(self, data):  
  74.         # Attempt to match the recognized word or phrase to the   
  75.         # keywords_to_command dictionary and return the appropriate  
  76.         # command  
  77.         for (command, keywords) in self.keywords_to_command.iteritems():  
  78.             for word in keywords:  
  79.                 if data.find(word) > -1:  
  80.                     return command  
  81.           
  82.     def speech_callback(self, msg):  
  83.         # Get the motion command from the recognized phrase  
  84.         command = self.get_command(msg.data)  
  85.           
  86.         # Log the command to the screen  
  87.         rospy.loginfo("Command: " + str(command))  
  88.           
  89.         # If the user has asked to pause/continue voice control,  
  90.         # set the flag accordingly   
  91.         if command == 'pause':  
  92.             self.paused = True  
  93.         elif command == 'continue':  
  94.             self.paused = False  
  95.           
  96.         # If voice control is paused, simply return without  
  97.         # performing any action  
  98.         if self.paused:  
  99.             return         
  100.           
  101.         # The list of if-then statements should be fairly  
  102.         # self-explanatory  
  103.         if command == 'forward':      
  104.             self.cmd_vel.linear.x = self.speed  
  105.             self.cmd_vel.angular.z = 0  
  106.               
  107.         elif command == 'rotate left':  
  108.             self.cmd_vel.linear.x = 0  
  109.             self.cmd_vel.angular.z = self.angular_speed  
  110.                   
  111.         elif command == 'rotate right':    
  112.             self.cmd_vel.linear.x = 0        
  113.             self.cmd_vel.angular.z = -self.angular_speed  
  114.               
  115.         elif command == 'turn left':  
  116.             if self.cmd_vel.linear.x != 0:  
  117.                 self.cmd_vel.angular.z += self.angular_increment  
  118.             else:          
  119.                 self.cmd_vel.angular.z = self.angular_speed  
  120.                   
  121.         elif command == 'turn right':      
  122.             if self.cmd_vel.linear.x != 0:  
  123.                 self.cmd_vel.angular.z -= self.angular_increment  
  124.             else:          
  125.                 self.cmd_vel.angular.z = -self.angular_speed  
  126.                   
  127.         elif command == 'backward':  
  128.             self.cmd_vel.linear.x = -self.speed  
  129.             self.cmd_vel.angular.z = 0  
  130.               
  131.         elif command == 'stop':   
  132.             # Stop the robot!  Publish a Twist message consisting of all zeros.           
  133.             self.cmd_vel = Twist()  
  134.           
  135.         elif command == 'faster':  
  136.             self.speed += self.linear_increment  
  137.             self.angular_speed += self.angular_increment  
  138.             if self.cmd_vel.linear.x != 0:  
  139.                 self.cmd_vel.linear.x += copysign(self.linear_increment, self.cmd_vel.linear.x)  
  140.             if self.cmd_vel.angular.z != 0:  
  141.                 self.cmd_vel.angular.z += copysign(self.angular_increment, self.cmd_vel.angular.z)  
  142.               
  143.         elif command == 'slower':  
  144.             self.speed -= self.linear_increment  
  145.             self.angular_speed -= self.angular_increment  
  146.             if self.cmd_vel.linear.x != 0:  
  147.                 self.cmd_vel.linear.x -= copysign(self.linear_increment, self.cmd_vel.linear.x)  
  148.             if self.cmd_vel.angular.z != 0:  
  149.                 self.cmd_vel.angular.z -= copysign(self.angular_increment, self.cmd_vel.angular.z)  
  150.                   
  151.         elif command in ['quarter''half''full']:  
  152.             if command == 'quarter':  
  153.                 self.speed = copysign(self.max_speed / 4self.speed)  
  154.           
  155.             elif command == 'half':  
  156.                 self.speed = copysign(self.max_speed / 2self.speed)  
  157.               
  158.             elif command == 'full':  
  159.                 self.speed = copysign(self.max_speed, self.speed)  
  160.               
  161.             if self.cmd_vel.linear.x != 0:  
  162.                 self.cmd_vel.linear.x = copysign(self.speed, self.cmd_vel.linear.x)  
  163.   
  164.             if self.cmd_vel.angular.z != 0:  
  165.                 self.cmd_vel.angular.z = copysign(self.angular_speed, self.cmd_vel.angular.z)  
  166.                   
  167.         else:  
  168.             return  
  169.   
  170.         self.cmd_vel.linear.x = min(self.max_speed, max(-self.max_speed, self.cmd_vel.linear.x))  
  171.         self.cmd_vel.angular.z = min(self.max_angular_speed, max(-self.max_angular_speed, self.cmd_vel.angular.z))  
  172.   
  173.     def cleanup(self):  
  174.         # When shutting down be sure to stop the robot!  
  175.         twist = Twist()  
  176.         self.cmd_vel_pub.publish(twist)  
  177.         rospy.sleep(1)  
  178.   
  179. if __name__=="__main__":  
  180.     try:  
  181.         VoiceNav()  
  182.         rospy.spin()  
  183.     except rospy.ROSInterruptException:  
  184.         rospy.loginfo("Voice navigation terminated.")  

        可以看到,代码中定义了接收到各种命令时的控制策略。

2、仿真测试

        和前面一样,我们在rviz中进行仿真测试。
        首先是运行一个机器人模型:
[plain]   view plain  copy
  1. $ roslaunch rbx1_bringup fake_turtlebot.launch  

        
        然后打开rviz:
[plain]   view plain  copy
  1. $ rosrun rviz rviz -d `rospack find rbx1_nav`/sim_fuerte.vcg  

        如果不喜欢在终端里看输出,可以打开gui界面:
[plain]   view plain  copy
  1. $ rxconsole  

        再打开语音识别的节点:
[plain]   view plain  copy
  1. $ roslaunch rbx1_speech voice_nav_commands.launch  

        最后就是机器人的控制节点了:
[plain]   view plain  copy
  1. $ roslaunch rbx1_speech turtlebot_voice_nav.launch  

       OK,打开上面这一堆的节点之后,就可以开始了。可以使用的命令如下:

        下图是我的测试结果,不过感觉准确度还是欠佳:

四、播放语音

        现在机器人已经可以按照我们说的话行动了,要是机器人可以和我们对话就更好了。ROS中已经集成了这样的包,下面就来尝试一下。
        运行下面的命令:
[plain]   view plain  copy
  1. $ rosrun sound_play soundplay_node.py  
  2. $ rosrun sound_play say.py "Greetings Humans. Take me to your leader."  

        有没有听见声音!ROS通过识别我们输入的文本,让机器人读了出来。发出这个声音的人叫做kal_diphone,如果不喜欢,我们也可以换一个人来读:
[plain]   view plain  copy
  1. $ sudo apt-get install festvox-don  
  2. $ rosrun sound_play say.py "Welcome to the future" voice_don_diphone  

       哈哈,这回换了一个人吧,好吧,这不也是我们的重点。
       在rbx1_speech/nodes文件夹中有一个让机器人说话的节点talkback.py:
[python]   view plain  copy
  1. #!/usr/bin/env python  
  2.   
  3. """ 
  4.     talkback.py - Version 0.1 2012-01-10 
  5.      
  6.     Use the sound_play client to say back what is heard by the pocketsphinx recognizer. 
  7.      
  8.     Created for the Pi Robot Project: http://www.pirobot.org 
  9.     Copyright (c) 2012 Patrick Goebel.  All rights reserved. 
  10.  
  11.     This program is free software; you can redistribute it and/or modify 
  12.     it under the terms of the GNU General Public License as published by 
  13.     the Free Software Foundation; either version 2 of the License, or 
  14.     (at your option) any later version.5 
  15.      
  16.     This program is distributed in the hope that it will be useful, 
  17.     but WITHOUT ANY WARRANTY; without even the implied warranty of 
  18.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  19.     GNU General Public License for more details at: 
  20.      
  21.     http://www.gnu.org/licenses/gpl.htmlPoint 
  22. """  
  23.   
  24. import roslib; roslib.load_manifest('rbx1_speech')  
  25. import rospy  
  26. from std_msgs.msg import String  
  27. from sound_play.libsoundplay import SoundClient  
  28. import sys  
  29.   
  30. class TalkBack:  
  31.     def __init__(self, script_path):  
  32.         rospy.init_node('talkback')  
  33.   
  34.         rospy.on_shutdown(self.cleanup)  
  35.           
  36.         # Set the default TTS voice to use  
  37.         self.voice = rospy.get_param("~voice""voice_don_diphone")  
  38.           
  39.         # Set the wave file path if used  
  40.         self.wavepath = rospy.get_param("~wavepath", script_path + "/../sounds")  
  41.           
  42.         # Create the sound client object  
  43.         self.soundhandle = SoundClient()  
  44.           
  45.         # Wait a moment to let the client connect to the  
  46.         # sound_play server  
  47.         rospy.sleep(1)  
  48.           
  49.         # Make sure any lingering sound_play processes are stopped.  
  50.         self.soundhandle.stopAll()  
  51.           
  52.         # Announce that we are ready for input  
  53.         self.soundhandle.playWave(self.wavepath + "/R2D2a.wav")  
  54.         rospy.sleep(1)  
  55.         self.soundhandle.say("Ready"self.voice)  
  56.           
  57.         rospy.loginfo("Say one of the navigation commands...")  
  58.   
  59.         # Subscribe to the recognizer output and set the callback function  
  60.         rospy.Subscriber('/recognizer/output', String, self.talkback)  
  61.           
  62.     def talkback(self, msg):  
  63.         # Print the recognized words on the screen  
  64.         rospy.loginfo(msg.data)  
  65.           
  66.         # Speak the recognized words in the selected voice  
  67.         self.soundhandle.say(msg.data, self.voice)  
  68.           
  69.         # Uncomment to play one of the built-in sounds  
  70.         #rospy.sleep(2)  
  71.         #self.soundhandle.play(5)  
  72.           
  73.         # Uncomment to play a wave file  
  74.         #rospy.sleep(2)  
  75.         #self.soundhandle.playWave(self.wavepath + "/R2D2a.wav")  
  76.   
  77.     def cleanup(self):  
  78.         self.soundhandle.stopAll()  
  79.         rospy.loginfo("Shutting down talkback node...")  
  80.   
  81. if __name__=="__main__":  
  82.     try:  
  83.         TalkBack(sys.path[0])  
  84.         rospy.spin()  
  85.     except rospy.ROSInterruptException:  
  86.         rospy.loginfo("Talkback node terminated.")  

         我们来运行看一下效果:
[plain]   view plain  copy
  1. $ roslaunch rbx1_speech talkback.launch  

         然后再说话,ROS不仅将文本信息识别出来了,而且还读了出来,厉害吧。当然了,现在还没有加入什么人工智能的算法,不能让机器人和我们聪明的说话,不过这算是基础了,以后有时间再研究一下人工智能就更犀利了。

-------------------------------------------------------------


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【资源说明】 基于ros的语音识别源码(采用python与科大讯飞语音听写api)+项目使用说明.zip 基于ros的语音识别,使用python与科大讯飞语音听写api实现实时的语音识别,并利用节点发布话题控制进程。 环境要求: * ros1,python3.x * 声卡:```sudo apt install libasound2-dev``` * requirement: * pass 项目结构: ``` XF_PYROS_IAT │ .gitattributes │ CMakeLists.txt │ package.xml │ README.md │ ├─launch │ main_node.launch │ ├─others │ node.png │ node_main.png │ ├─scripts │ close_switch_node.py │ main_node.py │ open_switch_node.py │ reset_node.py │ └─src func_open_node.cpp func_pause_node.cpp func_reset_node.cpp ``` 节点说明: ![节点图](others/node.png "节点图") * `main_node.py`是主程序,承担语音识别模块,对应节点为:/main_node,只运行该节点不会直接开始语音识别 * `open_switch_node.py`用于开启主程序语音识别,对应节点为:/open_node * `close_switch_node.py`用于关闭主程序语音识别,对应节点为:/pause_node * `reset_node.py`用于重置整个进程,使其恢复到休眠状态,对应节点为:/reset_node,运行一次该节点后就可以通过open_switch_node.py或/open_node再次开启语音识别 * src中的cpp生成的节点实际上就是用于控制以上节点,可有可无,根据自己需求使用,对应关系如下:(主要由于本人不会c++,故才加了src中的三个节点,如果你会C++可以自己把以上其他节点改写为C++) * _`func_open_node.cpp` --> `open_switch_node.py` 、`func_pause_node.cpp` --> `close_switch_node.py` 、`func_reset_node.cpp` --> `reset_node.py`_ 使用步骤: ***注意:请提前修改 main_node.py 中的科大讯飞APPID,APIKey,APISecret!*** 终端一: ``` roslaunch xf_pyros_iat main_node.launch ``` 终端二: * 发布话题:/func_switch_op启动语音识别,data: ' '里可以是任何字符串,没有也行 ``` rostopic pub /func_switch_op std_msgs/String "data: ''" ``` * 发布话题:/func_switch_cl关闭语音识别,data: ' '里可以是任何字符串,没有也行 ``` rostopic pub /func_switch_cl std_msgs/String "data: ''" ``` * 发布话题:/func_switch_re重置语音识别,data: ' '里可以是任何字符串,没有也行 ``` rostopic pub /func_switch_re std_msgs/String "data: ''" ``` * 此外通过:/func_op_node、/func_cl_node、/func_re_node三个节点也可以控制开、关、重置语音识别,命令如下: ``` rosrun xf_pyros_iat func_op_node ``` ``` rosrun xf_pyros_iat 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值