class Example: """Example that shows how to use the BasicSICConnector. For more information go to https://socialrobotics.atlassian.net/wiki/spaces/CBSR/pages/616398873/Python+Examples#Basic-SIC-Connector""" def __init__(self, server_ip, robot): self.sic = BasicSICConnector(server_ip, robot) self.awake_lock = threading.Event() def run(self): # active Social Interaction Cloud connection self.sic.start() # set language to English self.sic.set_language('en-US') # stand up and wait until this action is done (whenever the callback function self.awake is called) self.sic.wake_up(self.awake) self.awake_lock.wait( ) # see https://docs.python.org/3/library/threading.html#event-objects self.sic.say_animated('You can tickle me by touching my head.') # Execute that_tickles call each time the middle tactile is touched self.sic.subscribe_touch_listener('MiddleTactilTouched', self.that_tickles) # You have 10 seconds to tickle the robot sleep(10) # Unsubscribe the listener if you don't need it anymore. self.sic.unsubscribe_touch_listener('MiddleTactilTouched') # Go to rest mode self.sic.rest() # close the Social Interaction Cloud connection self.sic.stop() def awake(self): """Callback function for wake_up action. Called only once. It lifts the lock, making the program continue from self.awake_lock.wait()""" self.awake_lock.set() def that_tickles(self): """Callback function for touch listener. Every time the MiddleTactilTouched event is generated, this callback function is called, making the robot say 'That tickles!'""" self.sic.say_animated('That tickles!')
class Storyteller: """ Represents the logic guiding conversations between a robot and a human. """ def __init__(self, server_ip, dialogflow_key_file, dialogflow_agent_id): """ :param server_ip: IP address of Social Interaction Cloud server :param dialogflow_key_file: path to Google's Dialogflow key file (JSON) :param dialogflow_agent_id: ID number of Dialogflow agent to be used (project ID) """ self.sic = BasicSICConnector(server_ip, 'en-US', dialogflow_key_file, dialogflow_agent_id) self.conversation = Conversation(self.sic, robot_present=True, animation=False) self.story = Story(interactive=False) def run(self) -> None: """ Start the social interaction cloud and a conversation. :return: """ self.sic.start() self.conversation.introduce(interaction=False) self.sic.subscribe_touch_listener('MiddleTactilTouched', self.conversation.detect_stop) # START STORY part = None branch_option = None while True: if self.conversation.stop: break part = self.story.getFollowUp(part, branch_option) if (part is None): break storypart = part.content self.conversation.tell_story_part(Storypart.format( storypart, self.conversation.user_model, part.id), movement=part.movement, movement_type=part.movement_type, eye_color=part.eye_color, soundfile=part.soundfile) self.conversation.end_conversation() self.sic.stop()
class Storyteller: """ Represents the logic guiding conversations between a robot and a human. """ def __init__(self, server_ip, dialogflow_key_file, dialogflow_agent_id): """ :param server_ip: IP address of Social Interaction Cloud server :param dialogflow_key_file: path to Google's Dialogflow key file (JSON) :param dialogflow_agent_id: ID number of Dialogflow agent to be used (project ID) """ self.sic = BasicSICConnector( server_ip, 'en-US', dialogflow_key_file, dialogflow_agent_id) self.conversation = Conversation(self.sic, robot_present=True, animation=True) self.story = Story(interactive=True) def run(self) -> None: """ Start the social interaction cloud and a conversation. :return: """ self.sic.start() self.conversation.introduce(interaction=True) self.sic.subscribe_touch_listener( 'MiddleTactilTouched', self.conversation.detect_stop) path = self.conversation.ask_question( "Do you want to hear a story or a joke?", intent="joke_path") while path == ReturnType.SUCCESS and self.conversation.current_choice == "joke": # tell joke joke = self.conversation.get_joke() for joke_part in joke: self.conversation.tell_story_part(text=joke_part) path = self.conversation.ask_question( "Do you want to hear a story or another joke?", intent="joke_path") pass # START STORY part = None branch_option = None while True: if self.conversation.stop: break part = self.story.getFollowUp(part, branch_option) if (part is None): break if part.type == "question": question, intent, expected_answer = part.content res = self.conversation.ask_question(question=Storypart.format(question, user_model=self.conversation.user_model, story_part_id=part.id), intent=Storypart.format( intent, user_model=self.conversation.user_model, story_part_id="intent_" + part.id), expected_answer=Storypart.format(expected_answer, user_model=self.conversation.user_model, story_part_id="answer_" + part.id)) if res == ReturnType.STOP: break elif res == ReturnType.MAX_ATTEMPTS: self.conversation.tell_story_part( "Sorry, I did not understand your answer.") # TODO ask for repetetion or ending through fist bump # res = self.conversation.ask_question(question, intent) # last_choice = self.conversation.current_choice # self.sic.subscribe_touch_listener( # 'HandRightBackTouched', lambda: self.conversation.set_current_choice(0)) # self.sic.subscribe_touch_listener( # 'HandLeftBackTouched', lambda: self.conversation.set_current_choice(1)) # self.conversation.request_choice( # "To repeat the last part fistbump my right fist. To stop fistbump my left fist.") # while (last_choice == self.conversation.current_choice): # pass # if last_choice == 0: # # TODO implement repetition # pass # elif last_choice == 1: # break elif res == ReturnType.WRONG_ANSWER: branch_option = 0 elif res == ReturnType.SUCCESS: if expected_answer is not None: branch_option = 1 else: branch_option = None elif part.type == "storypart": storypart = part.content self.conversation.tell_story_part(Storypart.format( storypart, self.conversation.user_model, part.id), movement=part.movement, movement_type=part.movement_type, eye_color=part.eye_color, soundfile=part.soundfile) elif part.type == "choice": self.conversation.current_choice = None storypart = part.content if self.conversation.robot_present: self.sic.subscribe_touch_listener( 'HandRightBackTouched', lambda: self.conversation.set_current_choice(0)) self.sic.subscribe_touch_listener( 'HandLeftBackTouched', lambda: self.conversation.set_current_choice(1)) else: self.conversation.current_choice = 1 self.conversation.request_choice(question=Storypart.format( storypart, self.conversation.user_model, part.id)) while (self.conversation.current_choice is None): pass branch_option = self.conversation.current_choice elif part.type == "highfive": self.sic.subscribe_touch_listener( 'HandLeftLeftTouched', self.conversation.detect_highfive) self.sic.subscribe_touch_listener( 'HandLeftRightTouched', self.conversation.detect_highfive) self.conversation.request_highfive(part.content) while (self.conversation.current_choice != 1): pass if not self.conversation.stop: path = self.conversation.ask_question( "Do you want to hear another joke or stop?", intent="joke_path") while path == ReturnType.SUCCESS and self.conversation.current_choice == "joke": # tell joke joke = self.conversation.get_joke() for joke_part in joke: self.conversation.tell_story_part(text=joke_part) path = self.conversation.ask_question( "Do you want to hear another joke or stop?", intent="joke_path") pass self.conversation.end_conversation() self.sic.stop()