ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

ROS with multiple classes

asked 2020-03-21 10:26:44 -0600

Hyperion gravatar image

updated 2020-03-21 10:35:04 -0600

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.

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted

answered 2020-04-24 07:05:16 -0600

Hyperion gravatar image

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

    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.ros_node = RosController.instance()
edit flag offensive delete link more

Question Tools

1 follower


Asked: 2020-03-21 10:26:44 -0600

Seen: 650 times

Last updated: Apr 24 '20