Luka
Luka

Reputation: 55

How multiple run ros.init_node () in one python script?

I have written a program in python with ROS. It contains a GUI for "robot teleoperation", and in its MainWindow I added 3 widgets (rviz, joystick, button panel). When I start MainWindow I get the following error:

raise rospy.exceptions.ROSException("rospy.init_node() has already been called with different arguments: "+str(_init_node_args))

rospy.exceptions.ROSException: rospy.init_node() has already been called with different arguments: ('teleop_twist_keyboard', ['MainWindow.py'], False, None, False, False).

Joystick.py and Button.py contain ros.init_node() function. In MainWindow I instantiate Joystick and Button class and add them to MainWindow. I need to call ros.init_node() several times to communicate with various nodes.

directory structure

main window example

code main window

import sys
import PyQt5
import threading

from Joystick import Joystick
from QWidget_rviz import Rviz
from BaseArmPosition import BaseArmPosition

class MainWindow(PyQt5.QtWidgets.QMainWindow):

    def __init__(self,*args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.title = 'Robot teleoperation'
        self.left = 10
        self.top = 10
        self.width = 1920
        self.height = 1080

        self.joy = Joystick(maxDistance=50,MinimumSize=100,EclipseX=-20,EclipseY=40)
        self.rviz = Rviz()
        #self.arm_position = BaseArmPosition()


        self.initUI()

        
    def initUI(self):
        self.central_widget = PyQt5.QtWidgets.QWidget()
        self.setCentralWidget(self.central_widget)

        grid = PyQt5.QtWidgets.QGridLayout(self.centralWidget())

        grid.addWidget(self.joy, 0, 2)
        grid.addWidget(self.rviz, 0, 0)
        #grid.addWidget(self.arm_position, 0, 1)


        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.show() 

app = PyQt5.QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

code buttons widget, joistick.py has the same

import PyQt5
import rospy
from std_msgs.msg import String


class BaseArmPosition(PyQt5.QtWidgets.QWidget):
    def __init__(self, *args, **kwargs):
        super(BaseArmPosition, self).__init__(*args, **kwargs)            
        self.initUI()

    def initUI(self):
        self.pushButton_moveInit = PyQt5.QtWidgets.QPushButton("moveInit",self)
        self.pushButton_moveLeft = PyQt5.QtWidgets.QPushButton("moveLeft",self)
        self.pushButton_moveRight = PyQt5.QtWidgets.QPushButton("moveRight",self)

        layout = PyQt5.QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.pushButton_moveRight)
        layout.addWidget(self.pushButton_moveLeft)
        layout.addWidget(self.pushButton_moveInit)

        self.pushButton_moveInit.clicked.connect(self.moveInit)
        self.pushButton_moveLeft.clicked.connect(self.moveLeft)
        self.pushButton_moveRight.clicked.connect(self.moveRight)

        rospy.init_node("controller_ur")
        self.pub_arm = rospy.Publisher("/controller_ur/order",String,queue_size=1)

    def moveInit(self):
        moveInit = "moveInit"
        msg = String()
        msg.data = moveInit
        self.pub_arm.publish(moveInit)

    def moveLeft(self):
        moveInit = "moveLeft"
        msg = String()
        msg.data = moveInit
        self.pub_arm.publish(moveInit)

    def moveRight(self):
        moveInit = "moveRight"
        msg = String()
        msg.data = moveInit
        self.pub_arm.publish(moveInit)

Upvotes: 1

Views: 4489

Answers (2)

Evin Weissenberg
Evin Weissenberg

Reputation: 99

Put this somewhere towards the top of your script before import statements.

import os 
os.system("rosrun my_package_name my_node_script.py")

Upvotes: -1

Jalo
Jalo

Reputation: 1129

A ROS node can only be initialized once in your program. You should centralize the initialization of the node at the beginning of the main script, and the rest of imported modules should not try to initialize a new node, as that is not allowed.

If what you want is the different sub-modules to deal with different data, then you should just create separate topics within the same node.

Upvotes: 2

Related Questions