异步模式¶
我们前面一直在使用同步模式控制 Cozmars,其实还有两种异步的控制模式。这里只能做个非常简略的介绍
concurrent 异步模式¶
如果要让机器人的头部和手臂在 2 秒内 同时 抬起,我们大概会这样做:
from rcute_cozmars import Robot
with Robot('xxxx') as robot:
robot.lift.set_height(1, duration=2)
robot.head.set_angle(20, duration=2)
但实际效果是,机器人先举手,再抬头,一共用了 4 秒
试试把上面代码中的 Robot 改成 AsyncRobot ,对比一下效果:
from rcute_cozmars import AsyncRobot
with AsyncRobot('xxxx') as robot:
robot.lift.set_height(1, duration=2) # 不等指令执行完毕就立刻执行下一条指令
robot.head.set_angle(20, duration=2)
input()
看出来区别了吗?这回举手和抬头是 同时 动作的,一共只用 2 秒。
AsyncRobot 的用法和 Robot 一样,只是在向机器人发送指令时,不等指令执行结束就立刻返回,接着执行下一条指令。
实际上,以上两条指令都分别返回了一个 concurrent.futures.Future 对象,如果要等待一条指令执行完毕再开始下一条指令,则要调用该对象的 result() 方法
from rcute_cozmars import AsyncRobot
with AsyncRobot('xxxx') as robot:
robot.lift.set_height(1, duration=2).result() # 等待指令执行完毕再接着执行下一条指令
robot.head.set_angle(20, duration=2).result() # 这样就和原来效果一样的,用时 4 秒
async 异步模式¶
另一种异步模式是使用 协程,对应的类是 AioRobot,这是 Cozmars 程序内部的运行方式,也是我们在 自定义 animation 时要使用协程的原因。上面的代码改成 async 模式大概是这样的:
from rcute_cozmars import AioRobot
import asyncio
async def main():
async with AioRobot('xxxx') as robot:
await robot.lift.set_height(1, duration=2)
await robot.head.set_angle(20, duration=2)
asyncio.run(main())
除了开发 animation,你应该不需要用到这个模式 :)
警告
需要注意的是,不能 同时 有两条指令控制机器人的同一个元件!
比如一条抬头的指令还未执行完,就立刻执行另一条低头的指令,这可能会损坏舵机