I noticed that the stretch_body SDK heavily relies on Python threads.
For example, take the following snippet:
robot.base.translate_by(0.1) robot.push_command() time.sleep(0.05) robot.base.translate_by(0.1) robot.push_command()
time.sleep is necessary here to have the main thread yield to the controller thread correctly.
sleep, whether the first
translate_by actually executes or not is left to chance.
Additionally, the amount of time to sleep also seems to matter in executing some command correctly (maybe the controller thread is yielding back too quickly to the main thread before it’s logic is finished running).
This is a known issue when one relies on Python threads, because they don’t actually run parallely with each other, because of the GIL.
I wonder if you have considered using Python multiprocessing, which alleviates these issues.
droidlet for example, we built up a small utility called BackgroundTask, which uses the Python-inbuilt
multiprocessing package to truly run parallel work. This process runs as a
daemon process, so that when the parent process exits, this process is automatically collected. Additionally, things such as exception-propagation are also handled similar to threads. Lastly, you can register an
__atexit__ handler to do process cleanup as well, i.e. if someone presses
ctrl+c or does a
kill -9, the
__atexit__ handler can close connections to the hardware interfaces and such.
If you have considered or are considering using Python
multiprocessing instead of multithreading, I am happy to send some patches to help with this direction.