/examples/tutorials/05_async_python/02_cube_blinker.py
https://github.com/anki/cozmo-python-sdk · Python · 104 lines · 75 code · 2 blank · 27 comment · 3 complexity · 4f6d2de7ef54b766511be1e276684f14 MD5 · raw file
- #!/usr/bin/env python3
- # Copyright (c) 2016 Anki, Inc.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License in the file LICENSE.txt or at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- '''Cube Blinker asynchronous example
- Cozmo first looks around for a cube. Once a cube is found,
- the cube's lights blink green in a circular fashion. The
- script then waits for the cube to be tapped.
- '''
- import asyncio
- import sys
- import cozmo
- class BlinkyCube(cozmo.objects.LightCube):
- '''Subclass LightCube and add a light-chaser effect.'''
- def __init__(self, *a, **kw):
- super().__init__(*a, **kw)
- self._chaser = None
- def start_light_chaser(self):
- '''Cycles the lights around the cube with 1 corner lit up green,
- changing to the next corner every 0.1 seconds.
- '''
- if self._chaser:
- raise ValueError("Light chaser already running")
- async def _chaser():
- while True:
- for i in range(4):
- cols = [cozmo.lights.off_light] * 4
- cols[i] = cozmo.lights.green_light
- self.set_light_corners(*cols)
- await asyncio.sleep(0.1, loop=self._loop)
- self._chaser = asyncio.ensure_future(_chaser(), loop=self._loop)
- def stop_light_chaser(self):
- if self._chaser:
- self._chaser.cancel()
- self._chaser = None
- # Make sure World knows how to instantiate the subclass
- cozmo.world.World.light_cube_factory = BlinkyCube
- async def cozmo_program(robot: cozmo.robot.Robot):
- '''The async equivalent of 01_cube_blinker_sync.
- The usage of ``async def`` makes the cozmo_program method a coroutine.
- Within a coroutine, ``await`` can be used. With ``await``, the statement
- blocks until the request being waited for has completed. Meanwhile
- the event loop continues in the background.
- For instance, the statement
- ``await robot.world.wait_for_observed_light_cube(timeout=60)``
- blocks until Cozmo discovers a light cube or the 60 second timeout
- elapses, whichever occurs first.
- Likewise, the statement ``await cube.wait_for_tap(timeout=10)``
- blocks until the tap event is received or the 10 second timeout occurs,
- whichever occurs first.
- For more information, see
- https://docs.python.org/3/library/asyncio-task.html
- '''
- cube = None
- look_around = robot.start_behavior(cozmo.behavior.BehaviorTypes.LookAroundInPlace)
- try:
- cube = await robot.world.wait_for_observed_light_cube(timeout=60)
- except asyncio.TimeoutError:
- print("Didn't find a cube :-(")
- return
- finally:
- look_around.stop()
- cube.start_light_chaser()
- try:
- print("Waiting for cube to be tapped")
- await cube.wait_for_tap(timeout=10)
- print("Cube tapped")
- except asyncio.TimeoutError:
- print("No-one tapped our cube :-(")
- finally:
- cube.stop_light_chaser()
- cube.set_lights_off()
- cozmo.run_program(cozmo_program)