我正在构建一个DJ照明系统,其中包含以特定节拍间隔触发的事件(即在下一拍之间的闪光频闪中途)。 bpm(每分钟节拍)根据外部应用程序而变化,永远不会被认为是固定的。
我想通过在下一个节拍开始前几毫秒运行scheduling_function
来安排一系列IO操作(闪光灯频闪,触发激光)在下一拍中发生。
我知道时间,以event_loop
时间单位,我想要运行该函数(由get_next_time_to_run()
返回)。
我尝试使用带有递归调用的event_loop.call_at()
函数来连续安排scheduling_function
在下一个节拍之前运行。但是,我得到一个RecursionError。
有什么可能是更好的设置方法。这是我目前的代码:
def schedule_next_frame():
"""This function is schedules the next frame (light, motor, lasers). It is trigged to run just before the next beat to give it time to prepare"""
set_up_frame() #actual scheduling of IO
frame += 1
time_to_run = get_next_time_to_run(frame-0.1)
loop.call_at(time_to_run, schedule_next_frame(frame))
print("Beginning YettiCubes2.0")
frame = get_current_beat()+1 #FIXME if this is really close to a beat boundary, we might tick over a beat before we can setup the next frame
loop.call_soon(schedule_next_frame())
loop.run_forever()
答案 0 :(得分:1)
您想告诉asyncio在指定时间运行schedule_next_frame(frame)
。以下代码不会这样做:
loop.call_at(time_to_run, schedule_next_frame(frame))
相反,它首先递归调用schedule_next_frame
,然后将该调用的结果传递给call_at
。由于递归是无限的,所以从来没有任何结果,而是你得到一个例外。
告诉call_at
运行schedule_next_frame(frame)
的正确方法是:
loop.call_at(time_to_run, lambda: schedule_next_frame(frame))
lambda
表达式将生成一个函数,当不带参数调用时,调用schedule_next_frame(frame)
。