Cozmo人工智慧機器人SDK使用筆記(5)-時序部分async_sync

zhangrelay發表於2019-01-28

Cozmo首先尋找一個立方體。 找到立方體後,立方體的燈以迴圈方式綠色閃爍,然後等待輕敲立方體。

此時,程式分別為同步和非同步兩種型別,注意區分。


1. 同步

立方體閃爍同步示例

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


def cozmo_program(robot: cozmo.robot.Robot):
    cube = None
    look_around = robot.start_behavior(cozmo.behavior.BehaviorTypes.LookAroundInPlace)

    try:
        cube = 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")
        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)

2. 非同步

立方體閃爍非同步示例

注意註釋(效果相似但實現過程有差異):

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

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)

Fin


 

相關文章