def say(self, text, lang): # SSML tags for english TTS only. if lang in ['en-US']: text = self._add_ssml(text) text = self.replace_variables_text(text) self.runner.topics['tts'].publish(TTS(text, lang))
def _request_callback(self, chat_message): if not self.enable: logger.info("Chatbot is disabled") return if self.speech: logger.info("In speech, ignore the question") return if 'shut up' in chat_message.utterance.lower(): logger.info("Robot's talking wants to be interruptted") self.tts_ctrl_pub.publish("shutup") rospy.sleep(0.5) self._affect_publisher.publish(String('sad')) if not self.mute: self._response_publisher.publish( TTS(text='Okay', lang=chat_message.lang)) return # Handle chatbot command cmd, arg, line = self.client.parseline(chat_message.utterance) func = None try: if cmd is not None: func = getattr(self.client, 'do_' + cmd) except AttributeError as ex: pass if func: try: func(arg) except Exception as ex: logger.error("Executing command {} error {}".format(func, ex)) return chat_message.utterance = self.handle_control(chat_message.utterance) # blink that we heard something, request, probability defined in # callback self._blink_publisher.publish('chat_heard') if self.delay_response: logger.info("Add input: {}".format(chat_message.utterance)) self.input_stack.append((time.clock(), chat_message)) self._gesture_publisher.publish(SetGesture('nod-2', 0, 1, 1)) self._gesture_publisher.publish( SetGesture('blink-relaxed', 0, 1, 1)) self.reset_timer() else: self.ask([chat_message])
def _response_callback(self, msg): logger.info("Get response msg %s", msg) text = msg.text text = re.sub(r"""\[callback.*\]""", '', text) logger.warn('Send to TTS "%s"', text) self._response_publisher.publish(TTS(text=text, lang=msg.lang)) if self.client.last_response and self.client.last_response_time: request_id = self.client.last_response.get('RequestId') elapse = dt.datetime.utcnow() - self.client.last_response_time if elapse.total_seconds( ) > 10: # don't record request id for late coming msg request_id = '' try: self.write_response(request_id, msg) except Exception as ex: logger.exception(ex) else: logger.warn("No last response") # send the response back to chat server so it's aware of what's been # actually said self.client.feedback(msg.text, msg.label, msg.lang)
def on_response(self, sid, response): if response is None: logger.error("No response") return if sid != self.client.session: logger.error("Session id doesn't match") return logger.info("Get response {}".format(response)) for k, v in response.iteritems(): rospy.set_param('{}/response/{}'.format(self.node_name, k), v) text = response.get('text') emotion = response.get('emotion') lang = response.get('lang', 'en-US') orig_text = response.get('orig_text') if orig_text: try: self.handle_control(orig_text) except Exception as ex: logger.error(ex) #elif self.recover: # param = { # 'delay_response': False # } # update_parameter('chatbot', param, timeout=2) # self.recover = False # logger.info("Recovered delay response") # Add space after punctuation for multi-sentence responses text = text.replace('?', '? ') text = text.replace('_', ' ') if self.insert_behavior: # no pattern = r"(\bnot\s|\bno\s|\bdon't\s|\bwon't\s|\bdidn't\s)" text = re.sub(pattern, '\g<1>|shake3| ', text, flags=re.IGNORECASE) # yes pattern = r'(\byes\b|\byeah\b|\byep\b)' text = re.sub(pattern, '\g<1>|nod|', text, flags=re.IGNORECASE) # question # pattern=r'(\?)' # thinks = ['thinkl', 'thinkr', 'thinklu', 'thinkld', 'thinkru', 'thinkrd'] # random.shuffle(thinks) # text = re.sub(pattern, '|{}|\g<1>'.format(thinks[0]), text, flags=re.IGNORECASE) # if sentiment active save state and wait for affect_express to publish response # otherwise publish and let tts handle it if self._sentiment_active: emo = String() if emotion: emo.data = emotion self._affect_publisher.publish(emo) rospy.loginfo('[#][PERCEIVE ACTION][EMOTION] {}'.format( emo.data)) logger.info('Chatbot perceived emo: {}'.format(emo.data)) else: p = self.polarity.get_polarity(text) logger.debug('Polarity for "{}" is {}'.format( text.encode('utf-8'), p)) # change emotion if polarity magnitude exceeds threshold defined in constructor # otherwise let top level behaviors control if p > self._polarity_threshold: emo.data = 'happy' self._affect_publisher.publish(emo) rospy.loginfo('[#][PERCEIVE ACTION][EMOTION] {}'.format( emo.data)) logger.info('Chatbot perceived emo: {}'.format(emo.data)) # Currently response is independant of message received so no need to wait # Leave it for Opencog to handle responses later on. elif p < 0 and abs(p) > self._polarity_threshold: emo.data = 'frustrated' self._affect_publisher.publish(emo) rospy.loginfo('[#][PERCEIVE ACTION][EMOTION] {}'.format( emo.data)) logger.info('Chatbot perceived emo: {}'.format(emo.data)) # Currently response is independant of message received so no need to wait # Leave it for Opencog to handle responses later on. if not self.mute: self._blink_publisher.publish('chat_saying') self._response_publisher.publish(TTS(text=text, lang=lang)) if rospy.has_param('{}/context'.format(self.node_name)): rospy.delete_param('{}/context'.format(self.node_name)) context = self.client.get_context() logger.warn("Get context %s" % context) context['sid'] = self.client.session for k, v in context.iteritems(): rospy.set_param('{}/context/{}'.format(self.node_name, k), v) logger.info("Set param {}={}".format(k, v)) # Assign known name to the percepted faces face_id = self.client.user if face_id in self.perception_users: uid = self.perception_users[face_id].uid context_firstname = context.get('firstname') context_lastname = context.get('lastname') firstname = self.perception_users[face_id].first_name if not uid: self.assign_name(face_id, context_firstname, context_lastname) elif uid and firstname != context_firstname: logger.warn("Update the name of face id %s from %s to %s" % (face_id, firstname, context_firstname)) self.forget_name(uid) self.assign_name(face_id, context_firstname, context_lastname) else: logger.warn( "Failed to update name of face id %s from %s to %s" % (face_id, firstname, context_firstname)) else: logger.warn("Face %s is out of scene" % face_id) logger.warn("Perception face %s" % str(self.perception_users.keys()))
def Say(self, text): # publish TTS message msg = TTS() msg.text = text msg.lang = 'en-US' self.tts_pub.publish(msg)
def publish_tts(self, text): msg = TTS() msg.text = text msg.lang = 'en-US' self.tts_pub.publish(msg) rospy.logdebug("published tts: '{}', '{}'".format(msg.text, msg.lang))
def respond(self, response): self.runner.topics['events'].publish(Event('chat_end', 0)) self.talking = True self.runner.topics['tts'].publish(TTS(response, 'en-US'))