def speech_recognition_srv_cb(self, req): res = SpeechRecognitionResponse() duration = req.duration if duration <= 0.0: duration = self.default_duration with self.audio as src: if self.dynamic_energy_threshold: self.recognizer.adjust_for_ambient_noise(src) rospy.loginfo("Set minimum energy threshold to %f" % self.recognizer.energy_threshold) if not req.quiet: self.play_sound("start", 0.1) start_time = rospy.Time.now() while (rospy.Time.now() - start_time).to_sec() < duration: rospy.loginfo("Waiting for speech...") try: audio = self.recognizer.listen( src, timeout=self.listen_timeout, phrase_time_limit=self.phrase_time_limit) except SR.WaitTimeoutError as e: rospy.logwarn(e) break if not req.quiet: self.play_sound("recognized", 0.05) rospy.loginfo("Waiting for result... (Sent %d bytes)" % len(audio.get_raw_data())) try: result = self.recognize(audio) rospy.loginfo("Result: %s" % result.encode('utf-8')) if not req.quiet: self.play_sound("success", 0.1) res.result = SpeechRecognitionCandidates( transcript=[result]) return res except SR.UnknownValueError: if self.dynamic_energy_threshold: self.recognizer.adjust_for_ambient_noise(src) rospy.loginfo("Set minimum energy threshold to %f" % self.recognizer.energy_threshold) except SR.RequestError as e: rospy.logerr("Failed to recognize: %s" % str(e)) rospy.sleep(0.1) if rospy.is_shutdown(): break # Timeout if not req.quiet: self.play_sound("timeout", 0.1) return res
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