def test_dfa(self): g = load_grammar(os.path.join(PKG, "data"), "udon") gram = make_grammar_from_rules(g.rules) voca = make_voca_from_categories(g.categories, g.vocabularies) result = make_dfa(gram, voca) self.assertIsNotNone(result) self.assertEqual(len(result), 2)
def grammar_cb(self, msg): if msg.name: name = msg.name else: rospy.logwarn("Name of grammar is empty. Use 'unknown'") name = 'unknown' grammar = make_grammar_from_rules(msg.rules) voca = make_voca_from_categories(msg.categories, msg.vocabularies) result = make_dfa(grammar, voca) if result is None: rospy.logerr("Failed to make dfa from grammar message") return dfa, dic = result ok = self.add_gram(name, dfa.split(os.linesep), dic.split(os.linesep)) if ok: self.vocabularies[name] = list(set(e for v in msg.vocabularies for e in v.words)) else: rospy.logerr("Failed to change vocabulary")
def speech_recognition_cb(self, req): res = SpeechRecognitionResponse() # change grammar candidate_words = [] if req.grammar_name: ok = self.activate_gram(req.grammar_name) if not ok: rospy.logerr("failed to activate grammar %s" % req.grammar_name) return res if req.grammar_name in self.vocabularies: candidate_words = self.vocabularies[req.grammar_name] elif req.grammar.rules: g = req.grammar if not g.name: g.name = 'unknown' grammar = make_grammar_from_rules(g.rules) voca = make_voca_from_categories(g.categories, g.vocabularies) result = make_dfa(grammar, voca) if result is None: rospy.logerr("Failed to make dfa from grammar message") return res dfa, dic = result ok = self.change_gram(g.name, dfa.split(os.linesep), dic.split(os.linesep)) if not ok: rospy.logerr("Failed to change grammar") return res self.vocabularies[g.name] = list(set(e for v in msg.vocabularies for e in v.words)) candidate_words = self.vocabularies[g.name] elif req.vocabulary.words: v = req.vocabulary if not v.name: v.name = 'unknown' if len(v.phonemes) == 0 or not v.phonemes[0]: v.phonemes = make_phonemes_from_words(v.words) dic = [" %s\t%s" % (w, p) for w, p in zip(v.words, v.phonemes)] ok = self.change_gram(v.name, None, dic) if not ok: rospy.logerr("Failed to change vocabulary") return res self.vocabularies[v.name] = list(set(v.words)) candidate_words = self.vocabularies[v.name] else: rospy.logerr("Invalid request: 'grammar_name', 'grammar' or 'vocabulary' must be filled") return res duration = req.duration if duration <= 0.0: duration = self.default_duration threshold = req.threshold if threshold <= 0.0 or threshold > 1.0: threshold = self.default_threshold if not req.quiet: self.play_sound(self.start_signal, self.start_signal_action_timeout) start_time = rospy.Time.now() self.last_speech = SpeechRecognitionCandidates() while (rospy.Time.now() - start_time).to_sec() < duration: rospy.sleep(0.1) speech = self.last_speech if not self.last_speech.transcript: continue if candidate_words: ok = speech.transcript[0] in candidate_words and speech.confidence[0] >= threshold else: ok = speech.confidence[0] >= threshold if ok: t0 = speech.transcript[0] c0 = speech.confidence[0] rospy.loginfo("Recognized %s (%f)..." % (t0, c0)) if not req.quiet: self.play_sound(self.success_signal, 0.1) res.result = speech return res # timeout rospy.logerr("Timed out") if not req.quiet: self.play_sound(self.timeout_signal, 0.1) return res