Issue
I am trying to emulated the generation of a sequence of numbers as shown in the code below. I want to execute this at regular intervals without time drift and without keeping track of the number of times serial_sequence() has been called, i.e. without using the variable num. How can this be done?
In the example code, delay2 is always 0.1, but it should be slightly less since the event loop is busy elsewhere between calls to serial_sequence(). Thus the elapsed time is over 2.0 seconds.
import asyncio
import time
rx_data = list()
EOT = 20
async def serial_sequence():
'''async generator function that simulates incoming sequence of serial data'''
num = 0
tprev = time.time()
while True:
dt = time.time() - tprev
delay2 = 0.1 - dt #Want to avoid time drift
print('dt: {}'.format(dt))
print('delay2: {}'.format(delay2))
await asyncio.sleep(delay2) #simulated IO delay
tprev = time.time()
num += 1
yield num
async def read_serial1():
gen = serial_sequence()
while(True):
data = await gen.__anext__()
rx_data.append(data)
print('read_serial1:', data)
if data == EOT:
break
return rx_data
async def main():
start = time.time()
task1 = asyncio.create_task(read_serial1())
await(task1)
stop = time.time()
print('Elapsed: {}'.format(stop-start))
if __name__ == '__main__':
asyncio.run(main())
Solution
The code in the while loop itself needs some time to compute. The timedrift in your example accumulates because you base dt
on the time of the previous timestep tprev
.
You could instead use the absolute starting time of serial_sequence
as point of reference like so:
async def serial_sequence():
'''async generator function that simulates incoming sequence of serial data'''
num = 0
starttime = time.time()
while True:
dt = (time.time() - starttime) % 0.1
delay2 = 0.1 - dt #Want to avoid time drift
print('dt: {}'.format(dt))
print('delay2: {}'.format(delay2))
await asyncio.sleep(delay2) #simulated IO delay
tprev = time.time()
num += 1
yield num
Compare the accumulation by changing EOT
. I.e. Doubling EOT
results in double the time drift for your solution, while it is approximately constant for this one.
My answer is largely based on this answer to a very similar question.
Answered By - pypae
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.