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