I am writing an inference system for a underwater vehicle and I've been told to look into async to improve the object tracking. The idea is to have a tflite object detection model that detects object and returns a box/coordinates for each object it detects, which then meanshift (or some other tracking algo then uses to track the objects). However, the tflite model takes roughly 1 second to do its detection which is too slow. So I want to be running that in a separate thread while meanshift is tracking, whenever the tflite model is done, it updates the box to track. That way I would assume we would have smooth detection and tracking.
I find async kinda tricky and cannot quite get it right. For testing purposes I created a inference function with a 5 second delay just to clearly emulate the time inference takes and a tracking function that just runs continuously to emulate meanshift. This is what I have so far:
async def inference(x):
await asyncio.sleep(x)
return "===========Inference Done================= "
def tracking():
print("tracking...")
def start_loop(loop):
asyncio.set_event_loop(loop)
loop.run_forever()
new_loop = asyncio.new_event_loop()
t = Thread(target=start_loop, args=(new_loop,))
t.start()
# start the object detection model before
box = asyncio.run_coroutine_threadsafe(inference(5), new_loop)
while True:
if box: # if the object detection has detected an object and return a bounding box, track it
tracking()
if box.done(): # if the tflite has completed its detection, start the next detection
box = asyncio.run_coroutine_threadsafe(inference(5), new_loop)
print(box.result())
The expected output here is for tracking...
to print continuously and ===========Inference Done=================
to print once every 5 seconds. However, what happens is that tracking...
runs continuously for 5 seconds, then it start doing this:
tracking...
tracking...
tracking...
tracking...
tracking...
tracking...
tracking...
tracking...
===========Inference Done=================
tracking...
===========Inference Done=================
tracking...
How can I fix this?
Your weird output is because the order of print
and assignment to box
is opposite of what it should be. The way you've written it:
box = asyncio.run_coroutine_threadsafe(inference(5), new_loop)
print(box.result())
...the first time an inference is done, you schedule a new inference and wait for it to finish. At the next loop iteration, you will print one "tracking" and then box.done()
will immediately be true because you have already waited for it to finish.
To fix it, either reverse the order:
print(box.result())
box = asyncio.run_coroutine_threadsafe(inference(5), new_loop)
or re-phrase it as follows:
new_box = asyncio.run_coroutine_threadsafe(inference(5), new_loop)
print(box.result())
box = new_box