RAPP Platform  v0.6.0
RAPP Platform is a collection of ROS nodes and back-end processes that aim to deliver ready-to-use generic services to robots
 All Classes Namespaces Files Functions Variables Macros
speech_recognition_sphinx4.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # -*- encode: utf-8 -*-
3 
4 #Copyright 2015 RAPP
5 
6 #Licensed under the Apache License, Version 2.0 (the "License");
7 #you may not use this file except in compliance with the License.
8 #You may obtain a copy of the License at
9 
10  #http://www.apache.org/licenses/LICENSE-2.0
11 
12 #Unless required by applicable law or agreed to in writing, software
13 #distributed under the License is distributed on an "AS IS" BASIS,
14 #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 #See the License for the specific language governing permissions and
16 #limitations under the License.
17 
18 # Authors: Athanassios Kintsakis, Aris Thallas, Manos Tsardoulias
19 # contact: akintsakis@issel.ee.auth.gr, aris.thallas@{iti.gr, gmail.com}, etsardou@iti.gr
20 
21 import rospy
22 import sys
23 import subprocess
24 import time
25 
26 from rapp_utilities import RappUtilities
27 from rapp_exceptions import RappError
28 
29 from greek_support import *
30 from english_support import *
31 from greek_english_support import *
32 from sphinx4_wrapper import *
33 from sphinx4_configuration_params import *
34 from global_parameters import GlobalParams
35 
36 from rapp_platform_ros_communications.srv import (
37  SpeechRecognitionSphinx4Srv,
38  SpeechRecognitionSphinx4SrvResponse,
39  SpeechRecognitionSphinx4SrvRequest,
40  SpeechRecognitionSphinx4ConfigureSrv,
41  SpeechRecognitionSphinx4ConfigureSrvResponse,
42  SpeechRecognitionSphinx4ConfigureSrvRequest,
43  SpeechRecognitionSphinx4TotalSrv,
44  SpeechRecognitionSphinx4TotalSrvResponse
45  )
46 
47 from rapp_platform_ros_communications.msg import (
48  StringArrayMsg
49  )
50 
51 from std_msgs.msg import (
52  String
53  )
54 
55 ## @class SpeechRecognitionSphinx4
56 # @brief Provides a complete Rapp Sphinx Entity.
57 #
58 # Maintains a complete Rapp Sphinx Entity for the
59 # speech_recognition_sphinx4_handler_node.SpeechRecognitionSphinx4HandlerNode
60 # to perform the speech recognition.
62 
63  ## Constructor performing initializations
64  def __init__(self, configurationName=None):
65 
66  ## Contains global Sphinx parameters
67  #
68  # (see global_parameters.GlobalParams)
69  self._globalParams = GlobalParams()
70 
71  ## The sphinx wrapper communicates with the actual Sphinx.java process
72  #
73  # (see sphinx4_wrapper.Sphinx4Wrapper)
75  ## Greek_support creates necessary files for Greek speech recognition
76  #
77  # (see greek_support.GreekSupport)
79  ## English creates necessary files for english speech recognition
80  #
81  # (see english_support.EnglishSupport)
83  ## The Sphinx configuration parameters
84  #
85  # (see sphinx4_configuration_params.SphinxConfigurationParams)
87 
88  ## A dictionary to transform the englified greek words to actual greek words
89  self._word_mapping = {}
90 
91  if configurationName != None:
92  self._createPreconfiguration( configurationName )
93 
94 
95  ## @brief Requests the configuration's sha1 hash
96  #
97  # Hash is used to identify common request configurations for proper
98  # subprocess selection.
99  # (Requests with common requests do not require reconfiguration reducing
100  # computation time)
101  #
102  # @return hexdigest [string] The hash digest containing only hexadecimal digits
104  return self._configuration_params.getHash()
105 
106  ## @brief Create the requested preconfiguration
107  #
108  # Creates the configuration via the name requested from
109  # rapp_speech_detection_sphinx4::cfg::sphinx4_wrapper_params.yaml
110  #
111  # @param configurationName [string] The preconfiguration name
112  def _createPreconfiguration(self, configurationName):
113  RappUtilities.rapp_print( "Creating preconfiguration: " + configurationName )
114  tempConf = SphinxConfigurationParams( configurationName )
115 
116  req = SpeechRecognitionSphinx4ConfigureSrvRequest()
117  req.language = tempConf._language
118  req.words = tempConf._words
119  req.grammar = tempConf._grammar
120  req.sentences = tempConf._sentences
121 
122  self._configureSpeechRecognition( req )
123 
124  ## Performs Sphinx4 configuration and speech recognition
125  #
126  # @param req [rapp_platform_ros_communications::SpeechDetectionSphinx4Wrapper::SpeechRecognitionSphinx4TotalSrvRequest] The speech recognition request
127  # @return res [rapp_platform_ros_communications::SpeechDetectionSphinx4Wrapper::SpeechRecognitionSphinx4TotalSrvResponse] The speech recognition response
128  def speechRecognitionBatch(self, req):
129 
130  total_res = SpeechRecognitionSphinx4TotalSrvResponse()
131 
132  RappUtilities.rapp_print('Configuring Sphinx')
133  conf_res = SpeechRecognitionSphinx4ConfigureSrvResponse()
134  conf_res = self._configureSpeechRecognition(req)
135  total_res.error = conf_res.error
136  if conf_res.error != '':
137  total_res.error = total_res.error + '\n' + conf_res.error
138  RappUtilities.rapp_print(total_res.error, 'ERROR')
139  return total_res
140 
141  RappUtilities.rapp_print('Performing recognition')
142  spee_res = self._speechRecognition(req)
143  total_res.words = spee_res.words
144  total_res.error = spee_res.error
145  RappUtilities.rapp_print(total_res.words)
146  return total_res
147 
148  ## Performs Sphinx4 speech recognition
149  #
150  # @param req [rapp_platform_ros_communications::SpeechDetectionSphinx4Wrapper::SpeechRecognitionSphinx4SrvRequest] The speech recognition request
151  # @return res [rapp_platform_ros_communications::SpeechDetectionSphinx4Wrapper::SpeechRecognitionSphinx4SrvResponse] The speech recognition response
152  def _speechRecognition(self, req):
153  res = SpeechRecognitionSphinx4SrvResponse()
154  words = self._sphinx4.performSpeechRecognition(req.path, req.audio_source, req.user)
155  RappUtilities.rapp_print (words)
156  # Error handling - Must be implemented with exceptions
157  if len(words) == 1 and "Error:" in words[0]:
158  res.error = words[0]
159  res.words = []
160  return res
161 
162  for word in words:
163  RappUtilities.rapp_print ("Word: #" + word + "#")
164  if word == "" or word == '<unk>':
165  continue
166  res.words.append(self._word_mapping[word].replace("'", " "))
167 
168  return res;
169 
170  ## Choose the language support based on the request language
171  #
172  # @param req [rapp_platform_ros_communications::SpeechDetectionSphinx4Wrapper::SpeechRecognitionSphinx4ConfigureSrvRequest] The sphinx configuration request
173  #
174  # @return support [language_support::LanguageSupport] A child class of the LanguageSupport depending on the requested language
175  def _selectLanguageSupport(self, req):
176  if self._configuration_params._language == 'en':
177  RappUtilities.rapp_print ("Language set to English")
178  return self._english_support
179  elif self._configuration_params._language == 'el':
180  RappUtilities.rapp_print ("Language set to Greek")
181  return self._greek_support
182  else:
183  raise RappError("Wrong Language")
184 
185  ## Performs Sphinx4 configuration
186  #
187  # @param req [rapp_platform_ros_communications::SpeechDetectionSphinx4Wrapper::SpeechRecognitionSphinx4ConfigureSrvRequest] The sphinx configuration request
188  # @return res [rapp_platform_ros_communications::SpeechDetectionSphinx4Wrapper::SpeechRecognitionSphinx4ConfigureSrvRequest] The sphinx configuration response
190  res = SpeechRecognitionSphinx4ConfigureSrvResponse()
191  res.error = ''
192  conf = {} # Dummy initialization
193  reconfigure = True
194 
195  if self._configuration_params.equalsRequest(req):
196  reconfigure = False
197  self._configuration_params.makeEqualToRequest(req)
198 
199  if reconfigure == False:
200  RappUtilities.rapp_print('Skipping Configuration')
201  return res
202  RappUtilities.rapp_print('Recognition Configuration')
203 
204  try:
205  support = self._selectLanguageSupport(req)
206  except RappError as e:
207  res.error = e.value
208  return res
209 
210  try:
211  conf = self._createSupportConfiguration(support, res)
212  except RappError as e:
213  res.error = e.value
214  return res
215 
216  # Actual sphinx4 configuration
217  RappUtilities.rapp_print("Configuration: \n")
218  RappUtilities.rapp_print(conf)
219  self._sphinx4.configureSphinx(conf)
220  return res
221 
222 
223  ## Get Sphinx configuration paths from Language Support
224  #
225  # @param support [language_support::LanguageSupport] A child class of the LanguageSupport depending on the requested language
226  # @param req [rapp_platform_ros_communications::SpeechDetectionSphinx4Wrapper::SpeechRecognitionSphinx4ConfigureSrvRequest] The sphinx configuration request
227  #
228  # @return conf [dictionary] The Sphinx configuration files' paths
229  def _createSupportConfiguration(self, support, res):
230  # Whole dictionary utilization
231  if len(self._configuration_params._words) == 0:
232  RappUtilities.rapp_print ("Generic model used")
233  # success is either True (bool) or error (string)
234  try:
235  conf = support.getGenericConfiguration()
236  except RappError as e:
237  raise RappError( e.value )
238  # Limited dictionary utilization
239  else:
240  RappUtilities.rapp_print ("Limited model used")
241  # success is either True (bool) or error (string)
242  try:
243  [conf, mapping] = support.getLimitedVocebularyConfiguration(\
244  self._configuration_params._words, \
245  self._configuration_params._grammar, \
246  self._configuration_params._sentences)
247  except RappError as e:
248  raise RappError( e.value )
249 
250  self._word_mapping = {}
251  for ew in mapping:
252  self._word_mapping[ew] = mapping[ew]
253  RappUtilities.rapp_print (self._word_mapping)
254 
255  return conf
256 
257 
258 # Main function
259 if __name__ == "__main__":
260  rospy.init_node('SpeechRecognitionSphinx4')
261  SpeechRecognitionSphinx4Node = SpeechRecognitionSphinx4()
262  rospy.spin()
_english_support
English creates necessary files for english speech recognition.
def _createSupportConfiguration
Get Sphinx configuration paths from Language Support.
def _selectLanguageSupport
Choose the language support based on the request language.
_sphinx4
The sphinx wrapper communicates with the actual Sphinx.java process.
def speechRecognitionBatch
Performs Sphinx4 configuration and speech recognition.
Contains the Sphinx subprocess and is responsible for configuring Sphinx and performing the recogniti...
_word_mapping
A dictionary to transform the englified greek words to actual greek words.
_greek_support
Greek_support creates necessary files for Greek speech recognition.
Allows the creation of configuration files for English Sphinx speech recognition. ...