ROS with multiple classes
Hi people!
I built a system integrating ROS with EtherLAB to communicate with a machine. To perform the control, I also built a HMI using PyQt5. So I have a piece of code written in C ++ (EtherLAB) and a portion made in Python. Both programs has publishers and subscribers and I use ROS to interconnect them.
The process works normally, but when I add several classes, the system loses a lot of performance. In this case I have several classes (in Python):
class db_connect(object):
# Some stuff to connect with DB
class ROSController(db_connect):
# Some code to create the node, publishers and subscribers and also the logic behind the system
# Has an __init__ method that allows the beginning that creates the publishers and subscribers
class MainController(ROSController):
# Class that creates the interconnection between graphical intreface and logic. In addition to integrating the functionallity between all windows.
# this is the CLASS that is instantiated by the function def main() of python in order to execute the program.
# this class have methods to call another windows, such as Window_1, Window_2, Window_3 and so on.
class Window_1(ROSController):
# Main window containing buttons and other things.
# ALL WINDOWS ARE MADE USING QTDESIGNER and exported using pyuic command.
class Window_2(ROSController):
# Another window, this responsible for checking the read data of sensors.
class Window_3(ROSController):
# Another window, this responsible to trigger some actuators.
And so on...
The problem is that every time a class that inherits from ROSController seems to restart all nodes, publishers and subscribers. Creating new instances that should not exist and thus generating threads that apparently slow the program. The curious thing is that the activation of the actuators occur in near real time (about 10 ms). But reading a sensor, for example, takes 4 to 5 seconds to be recognized.
Over time, the system memory consumption increases and freezing the server. I have seen that is not the EtherLAB or the PyQt5, but can be the ROS itself. But I do not know how to fix.
This machine needs to work 24/7 without interruption of anykind.
In short (TL: DR): What is the best way to call a class that contains the methods of publish and subscribe in order to be used for several other classes without losing or reset the previous values (keep the consistency of information) and so that it is thread safe?
Thank you and excuse me for my English.
Asked by Hyperion on 2020-03-21 10:26:44 UTC
Answers
I solved this problem thanks for a tip of Edouard Renard (Udemy: ROS for Beginners Course). I implemented a singleton in each class and I did not use inheritance, but composition. This helped me to solve the problem. The code was something like this:
class db_connect(object):
# Some stuff to connect with DB
class ROSController(objetc):
# singleton flag
_instance = None
@classmethod
def instance(cls):
if cls._instance is None:
cls._instance = cls()
return cls._instance
def __init__(self, parent=None):
super(ROSController, self).__init__(parent)
...
class MainController(db_connect):
def __init__(self):
super(MainController, self).__init__()
self.ros_node = RosController.instance()
class Window_1(object):
# Main window containing buttons and other things.
def __init__(self):
super(Window_1, self).__init__()
self.setupUi(self)
self.ros_node = RosController.instance()
Asked by Hyperion on 2020-04-24 07:05:16 UTC
Comments