class IceBreaker(WOC): theFace = None def __init__(self): self._isCompleted = False self._face = None self._newRound = True self._questions = Questions() async def run(self, coz_conn: cozmo.conn.CozmoConnection): await Common.wochelper.initFaceHandlers(coz_conn, self.onFaceObserved, self.onFaceAppeared, self.onFaceDisappeared) self._robot = await coz_conn.wait_for_robot() self._initPose = self._robot.pose self._cube = None # start with the "next question button" cube placed in front of cozmo try: self._cube = await self._robot.world.wait_for_observed_light_cube(timeout=30) print("Found cube: %s" % self._cube) except asyncio.TimeoutError: print("Didn't find a cube") while True: if not self._face: # first spin fast, then spin slower to seek human face await self.crazySpin() await self.spin() else: # find a face, do interaction await self.moveCloser() await self.coreInteraction() await self.waitFinishInteraction() await self.afterInteraction() await asyncio.sleep(0.1) # spin to find any human face async def spin(self): # start spin if not self._robot.is_moving: # head up so that Cozmo can see faces spinAction = self._robot.set_head_angle(MAX_HEAD_ANGLE, in_parallel=True) await self._robot.drive_wheels(-TURN_SPEED, TURN_SPEED) await spinAction.wait_for_completed() cozmo.logger.info("spinAction = %s", spinAction) # close up to human whose face is just seen by Cozmo async def moveCloser(self): # turn to human Cozmo saw await self._robot.turn_towards_face(self._face).wait_for_completed() # move closer action1 = self._robot.drive_straight(distance_mm(DISTANCE_HUMAN), speed_mmps(STRAIGHT_SPEED), should_play_anim=False, in_parallel=True) action2 = self._robot.set_lift_height(0.0, accel=1.0, in_parallel=True) await action1.wait_for_completed() cozmo.logger.info("action1 = %s", action1) await action2.wait_for_completed() cozmo.logger.info("action2 = %s", action2) # ask ice breaking question async def coreInteraction(self): self._question = self._questions.getRandomQuestion() (pitch, self._duration) = await self.customizeSpeech(self._question) print(self._question) print("pitch = %s, durationScalar = %s" % (pitch, self._duration)) await self._robot.say_text(self._question, use_cozmo_voice=True, in_parallel=True, voice_pitch=pitch, duration_scalar=self._duration).wait_for_completed() # repeat question if repeating button is pressed async def repeatInteraction(self): pitch = random.uniform(MIN_PITCH, MAX_PITCH) await self._robot.say_text(self._question, use_cozmo_voice=True, in_parallel=True, voice_pitch=pitch, duration_scalar=self._duration).wait_for_completed() # use cubes to finish interaction with human async def waitFinishInteraction(self): finishConfirmed = False while not finishConfirmed: cube = None await self._robot.set_head_angle(degrees(0), in_parallel=True).wait_for_completed() await self._robot.play_anim_trigger(cozmo.anim.Triggers.MeetCozmoGetIn).wait_for_completed() # wait to see a cube try: cube = await self._robot.world.wait_for_observed_light_cube(timeout=30) print("Found cube: %s" % cube) except asyncio.TimeoutError: print("Didn't find a cube") finally: pass # found ANY cube if cube: # set cube flashing light cube.set_lights(CUBE_READY_LIGHT) # Cozmo being curious await self._robot.play_anim_trigger(cozmo.anim.Triggers.BlockReact).wait_for_completed() await asyncio.sleep(1) # finishConfirmed = True tapped = None # wait this cube to be tapped try: tapped = await cube.wait_for_tap(timeout=30) print("Cube tapped: %s" % tapped) except asyncio.TimeoutError: print("Didn't tap the cube") if tapped: # show the cube is tapped cube.set_lights(cozmo.lights.green_light) # the tapped cube is the cube of "next question" if cube == self._cube: finishConfirmed = True await self._robot.play_anim_trigger(cozmo.anim.Triggers.BuildPyramidSuccess).wait_for_completed() # other cube else: await self.repeatInteraction() cube.set_lights_off() else: # didn't find cube await self._robot.play_anim_trigger(cozmo.anim.Triggers.DriveStartAngry).wait_for_completed() # return to spin position to start next round async def afterInteraction(self): await self._robot.go_to_pose(self._initPose).wait_for_completed() ## await self._robot.turn_in_place(TURN_ANGLE_AFTER_INTERACTION).wait_for_completed() self._newRound = True ## await self._robot.drive_straight(distance_mm(-DISTANCE_HUMAN), ## speed_mmps(STRAIGHT_SPEED), ## should_play_anim=False).wait_for_completed() # customize speech voice pitch and length async def customizeSpeech(self, question): pitch = random.uniform(MIN_PITCH, MAX_PITCH) length = len(question) - question.count(' ') duration = log_mapping(10, MIN_DURATION, 100, MAX_DURATION, length, 10) return (pitch, duration) # fast spin, don't care about faces async def crazySpin(self): if self._newRound: t = random.uniform(MIN_CRAZY_SPIN_TIME, MAX_CRAZY_SPIN_TIME) await self._robot.drive_wheels(-TURN_SPEED_FAST, TURN_SPEED_FAST) await asyncio.sleep(t) self._robot.stop_all_motors() await asyncio.sleep(0.5) self._newRound = False async def onFaceObserved(self, evt: cozmo.faces.EvtFaceObserved, obj=None, **kwargs): if self._face and self._face == evt.face: pass async def onFaceAppeared(self, evt: cozmo.faces.EvtFaceAppeared, obj=None, **kwargs): if not self._face: self._face = evt.face self._robot.stop_all_motors() print("Find a face, start tracking") if not self.theFace: self.theFace = evt.face async def onFaceDisappeared(self, evt: cozmo.faces.EvtFaceDisappeared, obj=None, **kwargs): if self._face and self._face == evt.face: self._face = None print("Lose tracking face")
class CozmoQuiz(WOC): cl = None exit_flag = False audioThread = None curEvent = None idleAnimations = [ 'anim_sparking_idle_03', 'anim_sparking_idle_02', 'anim_sparking_idle_01' ] attractAttentionAnimations = [ 'anim_keepaway_pounce_02', 'reacttoblock_triestoreach_01' ] numMap = { 'CustomObjectTypes.CustomType00': '0', 'CustomObjectTypes.CustomType01': '1', 'CustomObjectTypes.CustomType02': '2', 'CustomObjectTypes.CustomType03': '3', 'CustomObjectTypes.CustomType04': '4', 'CustomObjectTypes.CustomType05': '5', 'CustomObjectTypes.CustomType06': '6', 'CustomObjectTypes.CustomType07': '7', 'CustomObjectTypes.CustomType08': '8', 'CustomObjectTypes.CustomType09': '9' } animCtr = 0 face = None lookingForFace = False buzzerWinner = None timeToAnswer = 15 currentPlayer = 0 numPlayers = 2 #get input later from command line turnsCompleted = 0 numList = [] answerGiven = False questions = None currentQuestion = None questionAsked = False playerTries = [] startPose = None totalQuestions = 4 questionsAsked = [] playerScores = [] points = [10, 5] questionNum = 0 def __init__(self, *a, **kw): sys.setrecursionlimit(0x100000) self.questions = Questions() cozmo.setup_basic_logging() # cozmo.connect_with_tkviewer(self.startResponding) cozmo.connect(self.startResponding) def startResponding(self, coz_conn): asyncio.set_event_loop(coz_conn._loop) self.coz = coz_conn.wait_for_robot() self.coz.world.define_custom_cube(CustomObjectTypes.CustomType00, CustomObjectMarkers.Circles2, 100, 90, 90, False) self.coz.world.define_custom_cube(CustomObjectTypes.CustomType01, CustomObjectMarkers.Diamonds2, 100, 90, 90, False) self.coz.world.define_custom_cube(CustomObjectTypes.CustomType02, CustomObjectMarkers.Hexagons2, 100, 90, 90, False) self.coz.world.define_custom_cube(CustomObjectTypes.CustomType03, CustomObjectMarkers.Circles3, 100, 90, 90, False) self.coz.world.define_custom_cube(CustomObjectTypes.CustomType04, CustomObjectMarkers.Diamonds3, 100, 90, 90, False) self.coz.world.define_custom_cube(CustomObjectTypes.CustomType05, CustomObjectMarkers.Hexagons3, 100, 90, 90, False) self.coz.world.define_custom_cube(CustomObjectTypes.CustomType06, CustomObjectMarkers.Circles4, 100, 90, 90, False) self.coz.world.define_custom_cube(CustomObjectTypes.CustomType07, CustomObjectMarkers.Diamonds4, 100, 90, 90, False) self.coz.world.define_custom_cube(CustomObjectTypes.CustomType08, CustomObjectMarkers.Hexagons4, 100, 90, 90, False) self.coz.world.define_custom_cube(CustomObjectTypes.CustomType09, CustomObjectMarkers.Circles5, 100, 90, 90, False) self.startPose = self.coz.pose look_around = self.coz.start_behavior( cozmo.behavior.BehaviorTypes.LookAroundInPlace) try: self.cubes = self.coz.world.wait_until_observe_num_objects( self.numPlayers, object_type=cozmo.objects.LightCube, timeout=60) except asyncio.TimeoutError: print("Didn't find a cube :-(") return finally: look_around.stop() for i in range(0, len(self.cubes)): self.cubes[i].set_lights(Colors.WHITE) self.playerScores.append(0) self.coz.go_to_pose(self.startPose).wait_for_completed() self.coz.say_text("Welcome to Math Buzz", duration_scalar=1.5, voice_pitch=-1, in_parallel=False).wait_for_completed() self.coz.play_anim('anim_greeting_happy_01').wait_for_completed() self.coz.say_text("Let's start!!", duration_scalar=1, voice_pitch=-1, in_parallel=False).wait_for_completed() self.askNextQuestion() while not self.exit_flag: asyncio.sleep(0) self.coz.abort_all_actions() def on_object_tapped(self, event, *, obj, tap_count, tap_duration, tap_intensity, **kw): if self.questionAsked is True: if obj not in self.playerTries: self.playerTries.append(obj) for i in range(0, len(self.cubes)): self.cubes[i].set_lights_off() if obj == self.cubes[i]: self.currentPlayer = i self.coz.go_to_object( obj, cozmo.util.distance_mm(250), in_parallel=False).wait_for_completed() self.startTimerAndWaitForAnswer() obj.set_lights(Colors.BLUE) def startTimerAndWaitForAnswer(self): #Set up event handlerss self.coz.world.add_event_handler(cozmo.objects.EvtObjectAppeared, self.foundMarker) self.coz.world.add_event_handler(cozmo.objects.EvtObjectDisappeared, self.removeMarker) Timer(self.timeToAnswer, self.checkAnswer).start() def checkAnswer(self): self.numList.sort(key=lambda c: c.pose.position.y) num = "" for i in range(0, len(self.numList)): num += self.numMap[str(self.numList[i].object_type)] print("The number is ") if num == '': num = '0' print(num) if int(num) == int(self.currentQuestion['answer']): self.playerScores[self.currentPlayer] += self.points[ len(self.playerTries) - 1] self.coz.say_text("Right Answer! You win " + str(self.points[len(self.playerTries) - 1]) + " points", duration_scalar=1.5, voice_pitch=-1, in_parallel=False).wait_for_completed() self.coz.play_anim( 'anim_rtpkeepaway_playeryes_02').wait_for_completed() self.askNextQuestion() else: self.coz.play_anim( 'anim_keepaway_losegame_01').wait_for_completed() self.playerScores[self.currentPlayer] -= 10 print(self.playerScores) self.goToNextPlayer() def goToNextPlayer(self): self.numList = [] self.coz.say_text("You are wrong.. You lose 10 points", duration_scalar=1.5, voice_pitch=-1, in_parallel=False).wait_for_completed() self.turnsCompleted += 1 if self.turnsCompleted < self.numPlayers - 1: for i in range(0, len(self.cubes)): self.cubes[i].set_lights_off() if i != self.currentPlayer and i not in self.playerTries: self.cubes[i].set_lights(Colors.WHITE.flash()) self.buzzerWinner = None else: self.askNextQuestion() def askNextQuestion(self): self.questionNum += 1 if self.questionNum < self.totalQuestions: self.coz.go_to_pose(self.startPose).wait_for_completed() allPlayerScores = ' '.join( str(score) for score in self.playerScores) if self.questionNum > 1: self.coz.say_text("End of Round " + str(self.questionNum - 1) + ". The scores are " + allPlayerScores, duration_scalar=1.75, voice_pitch=-1, in_parallel=False).wait_for_completed() self.coz.say_text("Round " + str(self.questionNum), duration_scalar=1.75, voice_pitch=-1, in_parallel=False).wait_for_completed() self.playerTries = [] self.currentPlayer = 0 self.buzzerWinner = None self.questionAsked = False for i in range(0, len(self.cubes)): self.cubes[i].set_lights_off() self.coz.world.add_event_handler(cozmo.objects.EvtObjectTapped, self.on_object_tapped) self.turnsCompleted = 0 self.currentPlayer = 0 #go to next question while (True): self.currentQuestion = self.questions.getRandomQuestion() if self.currentQuestion in self.questionsAsked: continue else: self.questionsAsked.append(self.currentQuestion) break self.coz.say_text("What is " + self.currentQuestion['question'], duration_scalar=1.75, voice_pitch=-1, in_parallel=False).wait_for_completed() self.coz.say_text("GO", duration_scalar=1, voice_pitch=-1, in_parallel=False).wait_for_completed() for i in range(0, len(self.cubes)): self.cubes[i].set_lights(Colors.WHITE.flash()) self.questionAsked = True else: self.findWinner() def findWinner(self): for i in range(0, len(self.cubes)): self.cubes[i].set_lights_off() self.coz.go_to_pose(self.startPose).wait_for_completed() self.coz.say_text("Game over", duration_scalar=1.75, voice_pitch=-1, in_parallel=False).wait_for_completed() index, value = max(enumerate(self.playerScores), key=operator.itemgetter(1)) print("The winner is " + str(index)) self.cubes[index].set_lights(Colors.YELLOW.flash()) self.coz.go_to_object( self.cubes[index], cozmo.util.distance_mm(150)).wait_for_completed() self.coz.play_anim( 'anim_memorymatch_successhand_cozmo_04').wait_for_completed() self.coz.say_text("You win! Congratulations!!", duration_scalar=1.75, voice_pitch=-1, in_parallel=False).wait_for_completed() def foundMarker(self, event, *, image_box, obj, pose, updated, **kw): if self.questionAsked == True: if 'Custom' in str(type(obj)): if obj not in self.numList: self.numList.append(obj) print(len(self.numList)) def removeMarker(self, event, *, obj): if self.questionAsked == True: if obj in self.numList: self.numList.remove(obj) def playIdle(self): if self.lookingForFace == False: self.coz.play_anim( self.idleAnimations[self.animCtr]).wait_for_completed() self.playIdle()