如何在一个python脚本中使用多个运行ros.init_node()?

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

我用 ROS 在 python 中编写了一个程序。它包含一个用于“机器人远程操作”的 GUI,并且在其 MainWindow 中我添加了 3 个小部件(rviz、操纵杆、按钮面板)。当我启动 MainWindow 时,出现以下错误:

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.pyButton.py 包含 ros.init_node() 函数。在 MainWindow 我实例化 JoystickButton class 并将它们添加到 主窗口。我需要多次调用 ros.init_node() 来与各个节点通信。

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)

一个ROS node在你的程序中只能初始化一次。你应该在主脚本的开头集中初始化节点,其余导入的模块不应尝试初始化新节点,因为这是不允许的。

如果你想要的是不同的子模块来处理不同的数据,那么你应该在同一个节点中创建不同的主题。

在导入语句之前将其放在脚本顶部的某个位置。

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