Reputation: 331
I'm building a DJ lighting system with events that are triggered at certain beat intervals (i.e. flash strobe halfway between the next beat). The bpm (beats per minute) changes based on an external application and can never be assumed as fixed.
I would like to schedule a bunch of IO operations (flash strobe, trigger laser) to happen in the next beat by running a scheduling_function
a few ms before the start of the next beat.
I know the time, in event_loop
time units, when I would like the function to run (returned by get_next_time_to_run()
).
I tried using the event_loop.call_at()
function, with a recursive call, to continuously schedule the scheduling_function
to be run right before the next beat. However, i get a RecursionError.
What might be a better way of setting this up. Here is my current code:
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()
Upvotes: 0
Views: 44
Reputation: 154846
You want to tell asyncio to run schedule_next_frame(frame)
at the specified time. The following code doesn't do that:
loop.call_at(time_to_run, schedule_next_frame(frame))
Instead, it first calls schedule_next_frame
recursively, and then passes the result of that call to call_at
. Since the recursion is infinite, there never is any result, and you get an exception instead.
The correct way to tell call_at
to run schedule_next_frame(frame)
is:
loop.call_at(time_to_run, lambda: schedule_next_frame(frame))
The lambda
expression will produce a function that, when called without arguments, invokes schedule_next_frame(frame)
.
Upvotes: 1