I’ve looked through the Dexter Industries Forums and spent some time on Stack Overflow, but I’m not sure I’ve found “best practices” to have the Raspberry Pi based robots complete different actions relatively simultaneously.
Threading seems to be the most obvious approach, but there are other options such as queueing or asyncio.
For my intended application, I’m using BrickPi and want to:
- Monitor sensors
- Run Motors
- work with sensor values - probably lots of math
- write files
- connect with other wi-fi enabled devices
Sorry if I’ve missed the question in other parts of the forum - pointers welcome.
of course there will not be 1 answer which solves all existing problems. And above all, the question is not, which millions of things you want to do, but if there are threads which are time-sensitive and will get stuck when being processed in a queue or not.
And that eventually is already the ultimate answer to qeueing, multithreading, and anything - in other words:
as much queueing as possible and as little multithreading as possible, and all depending on the features of your programming language,
As to me, I am using MT already since about 15 years. Currently I use the BrickPi3 with C++ and (when required) POSIX pthread by different thread priorities plus mutexes, and also Arduinos with Patel’s and Maglie’s Scheduler libs, and it (mostly) works like a charme.
(Additionally, sometimes also pinchange Interrupts might be a possible option , but I don’t use them generally.)
Take a look at this forum thread.
@rolly – Thanks Rolly - I will take a look through the code you posted. The discussion also deserves some study. Thanks for the pointers!
@HaWe - Thanks. I appreciate the feedback. I figured the answer would be the always true, and almost always useless “it depends,” – but your comments about queueing vs multithreading are very helpful. Thanks for sharing your experience.
Personally, I think I would go with some sort of topic/direct-based queuing to do the following:
Send data from the sensors down to a processing service - which does the number crunching.
Send processed data to a manager service that aggregates the data coming from the sensor and from the user into a final command which then gets relayed to a motor service.
Or I may go with separating the number crunching operations and the processing of data and actuation into 2 separate processes. In this case, the process which deals with processing the data and actuating the robot would implemented some sort of MT or asyncio.
All in all, I would push for segregating different components of the project into as many services as possible. The idea is to reduce them to the level of irreducibility.
I generally agree with idea of separating the program flow paths, but I’ve got to explore it more to ensure against some of the issues like “race conditions” that I’ve read about, but never yet experienced. Yes, this text-based parallel programming is somewhat new to me.
I don’t want to be spoon-fed, but pointers to solid examples always welcome.
Thanks! I’ll keep working the problems.
All my best,
you don’t have to worry about race conditions as long as your functions won’t write to any shared variable from 2 or more different threads simultaneously.
I case that might happen, you either put your write-functions into 1 single thread and queue them up, or, alternatively, wrap mutexes around them to prevent your variables from simultaneous write actions.
Which is your programming language?
I appreciate the insight on race conditions.
I’m using python 3 with BrickPi and PiZeroW… and hopefully another BrickPi and a GoPiGo or two.
… but one thing at a time.
I’m just picking up the project after a year hiatus for other priorities and getting my head back into the process.
I too am interested in this topic, though only for a single RPi 3B or 3B+ processor.
My last bot architecture had a single main that instantiated separate threaded classes for bumpers, ultrasonic distance sensor, IR distance sensor, motor management, and power management, along with a few imported plain function modules that used “with lock”, and I used some globals in a few places - in other words: a bit of a mess.
Robot Egret uses threaded classes in …/rwpilib
as to Python, unfortunately I can’t give you any advice at all.
As stated, I am using only C/C++ with the POSIX pthread libs, providing also mutexes and thread priorities, which all work extremely quick, safe, and efficiently.