1

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?

Luka Jozić
  • 162
  • 2
  • 12
  • Hello, what would you like to achieve with asyncio in your case? If your `find box ops` are CPU bound, it is not right to keep asyncio in the same process with heavy CPU bound ops. – Artiom Kozyrev Apr 02 '21 at 07:07
  • Well what I want is the while loop to run uninterruptedly, and which asyncio I want to call a separate function that the while loop does not have to wait for. So the while loop just runs and the inference function just updates whenever it is ready. Hope that make sense. – Luka Jozić Apr 02 '21 at 14:41

1 Answers1

2

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
user4815162342
  • 141,790
  • 18
  • 296
  • 355