如何在一个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.py 和 Button.py 包含 ros.init_node()
函数。在 MainWindow 我实例化 Joystick 和 Button 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")
我用 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.py 和 Button.py 包含 ros.init_node()
函数。在 MainWindow 我实例化 Joystick 和 Button 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")