6 from threading
import Lock
9 from sound_play.msg
import SoundRequest, SoundRequestAction, SoundRequestGoal
16 from speech_recognition_msgs.msg
import Grammar
17 from speech_recognition_msgs.msg
import SpeechRecognitionCandidates
18 from speech_recognition_msgs.msg
import Vocabulary
19 from speech_recognition_msgs.srv
import SpeechRecognition
20 from speech_recognition_msgs.srv
import SpeechRecognitionResponse
21 from std_srvs.srv
import Empty, EmptyResponse
26 start_signal =
"/usr/share/sounds/ubuntu/stereo/bell.ogg" 27 success_signal =
"/usr/share/sounds/ubuntu/stereo/message-new-instant.ogg" 28 timeout_signal =
"/usr/share/sounds/ubuntu/stereo/window-slide.ogg" 32 self.
encoding = rospy.get_param(
"~encoding",
"utf-8")
39 SpeechRecognitionCandidates,
44 if not self.act_sound.wait_for_server(rospy.Duration(5.0)):
45 rospy.logwarn(
"Failed to find sound_play action. Disabled audio alert")
49 host = rospy.get_param(
"~host",
"localhost")
50 module_port = rospy.get_param(
"~module_port", 10500)
51 audio_port = rospy.get_param(
"~audio_port", 10501)
52 max_retry = rospy.get_param(
"~max_connection_retry", 0)
58 self.module.on_received_data(self.
julius_cb)
86 self.module.send_command([
"INPUTONCHANGE",
"PAUSE"])
89 self.module.send_command([
"VERSION"])
90 self.module.send_command([
"STATUS"])
91 self.module.send_command([
"GRAMINFO"])
92 return EmptyResponse()
98 req.sound = SoundRequest.PLAY_FILE
99 req.command = SoundRequest.PLAY_ONCE
101 goal = SoundRequestGoal(sound_request=req)
102 self.act_sound.send_goal_and_wait(goal, rospy.Duration(timeout))
106 self.module.send_command(cmd)
113 cmd = [
"ACTIVATEGRAM", name]
114 self.module.send_command(cmd)
117 rospy.loginfo(
"Successfully activated grammar")
119 rospy.logerr(
"Failed to activate grammar")
124 cmd = [
"DEACTIVATEGRAM", name]
125 rospy.loginfo(
"Deactivating %s" % name)
126 self.module.send_command(cmd)
129 rospy.loginfo(
"Successfully deactivated grammar")
131 rospy.logerr(
"Failed to deactivate grammar")
139 cmd = [
"%s %s" % (cmd_name, name)]
141 cmd += [
' ' + l.strip()
for l
in dfa
if l.strip()]
143 cmd += [
' ' + l.strip()
for l
in dic
if l.strip()]
147 rospy.loginfo(
"%s Success" % cmd_name)
149 rospy.logerr(
"%s Failed" % cmd_name)
153 ok = self.
do_gram(
"ADDGRAM", name, dfa, dic)
158 return self.
do_gram(
"CHANGEGRAM", name, dfa, dic)
164 rospy.logwarn(
"Name of grammar is empty. Use 'unknown'")
170 rospy.logerr(
"Failed to make dfa from grammar message")
173 ok = self.
add_gram(name, dfa.split(os.linesep), dic.split(os.linesep))
175 self.
vocabularies[name] = list(set(e
for v
in msg.vocabularies
for e
in v.words))
177 rospy.logerr(
"Failed to change vocabulary")
183 rospy.logwarn(
"Name of grammar is empty. Use 'unknown'")
185 if len(msg.phonemes) == 0
or not msg.phonemes[0]:
188 phonemes = msg.phonemes
189 dic = [
" %s\t%s" % (w, p)
for w, p
in zip(msg.words, phonemes)]
194 rospy.logerr(
"Failed to change vocabulary")
197 res = SpeechRecognitionResponse()
204 rospy.logerr(
"failed to activate grammar %s" % req.grammar_name)
208 elif req.grammar.rules:
216 rospy.logerr(
"Failed to make dfa from grammar message")
219 ok = self.
change_gram(g.name, dfa.split(os.linesep), dic.split(os.linesep))
221 rospy.logerr(
"Failed to change grammar")
223 self.
vocabularies[g.name] = list(set(e
for v
in msg.vocabularies
for e
in v.words))
225 elif req.vocabulary.words:
229 if len(v.phonemes) == 0
or not v.phonemes[0]:
231 dic = [
" %s\t%s" % (w, p)
for w, p
in zip(v.words, v.phonemes)]
234 rospy.logerr(
"Failed to change vocabulary")
239 rospy.logerr(
"Invalid request: 'grammar_name', 'grammar' or 'vocabulary' must be filled")
242 duration = req.duration
246 threshold = req.threshold
247 if threshold <= 0.0
or threshold > 1.0:
252 start_time = rospy.Time.now()
254 while (rospy.Time.now() - start_time).to_sec() < duration:
257 if not self.last_speech.transcript:
260 ok = speech.transcript[0]
in candidate_words
and speech.confidence[0] >= threshold
262 ok = speech.confidence[0] >= threshold
264 t0 = speech.transcript[0]
265 c0 = speech.confidence[0]
266 rospy.loginfo(
"Recognized %s (%f)..." % (t0, c0))
273 rospy.logerr(
"Timed out")
280 for shypo
in data.xpath(
"//SHYPO"):
283 for whypo
in shypo.xpath(
"./WHYPO"):
284 word = whypo.attrib[
"WORD"].encode(self.
encoding)
285 if word.startswith(
"<"):
287 transcript.append(word)
288 confidence += float(whypo.attrib[
"CM"])
289 confidence /= len(transcript)
290 transcript =
" ".join(transcript)
291 results[confidence] = transcript
293 msg = SpeechRecognitionCandidates()
294 debug_str = [
"Recognized:"]
295 for i, result
in enumerate(sorted(results.items(), reverse=
True)):
297 debug_str += [
"%d: %s (%.2f)" % (i+1, t, c)]
298 msg.transcript.append(t)
299 msg.confidence.append(c)
300 self.pub_speech_recognition.publish(msg)
302 rospy.logdebug(os.linesep.join(debug_str))
309 status, detail = data
310 rospy.logdebug(
"status: %s" % status)
311 rospy.logdebug(
"detail: %s" % lxml.etree.tostring(detail))
312 if status ==
'ENGINEINFO':
313 version = detail.attrib[
"VERSION"]
314 conf = detail.attrib[
"CONF"]
315 rospy.loginfo(
"Version: %s (%s)" % (version, conf))
316 elif status ==
'SYSINFO':
317 rospy.loginfo(
"Status: %s" % detail.attrib[
"PROCESS"])
318 elif status ==
'GRAMINFO':
319 rospy.loginfo(
"Grammar Information:\n%s" % detail.text.strip())
320 elif status ==
'STARTPROC':
321 rospy.loginfo(
"Julius Engine initialized")
322 elif status ==
'ENDPROC':
323 rospy.loginfo(
"Julius Engine stopped")
324 elif status ==
'STARTRECOG':
325 rospy.logdebug(
"Start Recognize")
326 elif status ==
'ENDRECOG':
327 rospy.logdebug(
"End Recognize")
328 elif status ==
'RECOGFAIL':
329 rospy.logerr(
"Recognition Failed")
330 elif status ==
'RECOGOUT':
332 elif status ==
'INPUT':
333 substat = detail.attrib[
"STATUS"]
334 if substat ==
'STARTREC':
335 rospy.logdebug(
"Detect speak start")
336 elif substat ==
'ENDREC':
337 rospy.logdebug(
"Detect speak end")
338 elif status ==
'INPUTPARAM':
339 input_frame = int(detail.attrib[
"FRAMES"])
340 if input_frame >= 2000:
341 rospy.logwarn(
"Audio segment is too long!! Please volume down your microphone.")
342 elif status ==
'GRAMMAR':
343 substat = detail.attrib[
"STATUS"]
344 if substat ==
'RECEIVED':
346 elif substat ==
"ERROR":
347 reason = detail.attrib[
"REASON"]
348 rospy.logerr(
"Failed to change grammar: %s" % reason)
351 rospy.logwarn(
"Received %s" % status)
352 rospy.logwarn(
"%s", lxml.etree.tostring(detail))
354 if __name__ ==
'__main__':
355 rospy.init_node(
"julius_client")
def grammar_cb(self, msg)
def change_gram(self, name, dfa, dic)
def make_phonemes_from_words(words)
def deactivate_gram(self, name)
def speech_recognition_cb(self, req)
def do_gram(self, cmd_name, name, dfa, dic)
def add_gram(self, name, dfa, dic)
def make_dfa(grammar, voca)
def process_result(self, data)
def make_grammar_from_rules(rules)
def send_grammar_cmd(self, cmd)
start_signal_action_timeout
def vocabulary_cb(self, msg)
def status(self, args=None)
def julius_cb(self, data)
def activate_gram(self, name)
def play_sound(self, path, timeout=5.0)
def make_voca_from_categories(cats, vocas)