ROS节点就是一个进程,节点间通信的发布话题——订阅话题、服务——客户端都是进程节点间通信,一个进程节点可以发布多个话题、订阅多个话题(订阅多个话题只用一个rospy.spin()反算频率-周期休眠)、既发布也订阅话题。
先写个既发布也订阅话题的例子,发布话题行为放在订阅话题的回调函数中实现"依赖"关系:
节点nodeA,发布topicA:
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
import rospy
# from beginner_tutorials.msg import String
from std_msgs.msg import String
if __name__ == '__main__':
try: #嘿嘿
rospy.init_node('nodeA',anonymous=False)
pub = rospy.Publisher('~topicA',String,queue_size=10)
rate = rospy.Rate(0.5)
pubstr = rospy.get_caller_id()+" pub 'topicA'"
while not rospy.is_shutdown():
rospy.loginfo(pubstr)
pub.publish(pubstr)
rate.sleep()
except rospy.ROSInterruptException:
exceptstr = rospy.get_caller_id()+" exception!"
rospy.loginfo(excepstr)
节点nodeB,订阅topicA后发布topicB:
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
import rospy
# from beginner_tutorials.msg import String #自定义消息类型
from std_msgs.msg import String
def callback(Strobj):
try:
pub = rospy.Publisher('~topicB',String) #定义发布者
strmsg = rospy.get_caller_id()+" sub topicA then pub topicB"
rospy.loginfo(strmsg) #往rospy节点记录信息
#rospy.get_caller_id()返回当前节点的完整解析的节点名
pub.publish(strmsg) #发布话题,已经在rospy.spin()订阅循环中了
#,不用再加循环rospy.Rate().sleep()了
except rospy.ROSInterruptException:
pass
if __name__=="__main__":
'''yamlpath、launchpath存储在参数服务器中由roscore或其他先启节点
以话题的方式发布到当前节点?
'''
rospy.init_node('nodeB',anonymous=False)
rospy.Subscriber('/nodeA/topicA',String,callback) #定义订阅者
rospy.spin()
节点nodeC订阅topicB:
#!/usr/bin/env python2
#-*- coding:UTF-8 -*-
import rospy
# from beginner_tutorials.msg import String
from std_msgs.msg import String
def callback(Strobj):
logstr = rospy.get_caller_id()+" sub topicB"
rospy.loginfo(logstr)
if __name__ == '__main__':
rospy.init_node('nodeC',anonymous=False)
rospy.Subscriber('/nodeB/topicB',String,callback)
rospy.spin()
运行结果:
haypin@ubt:~/catkin_ws/src/beginner_tutorials/scripts$ rosrun beginner_tutorials _PubCheck2.py
[INFO] [1617717494.525536]: /nodeA pub 'topicA'
[INFO] [1617717496.527545]: /nodeA pub 'topicA'
[INFO] [1617717498.527747]: /nodeA pub 'topicA'
[INFO] [1617717500.525839]: /nodeA pub 'topicA'
[INFO] [1617717502.527739]: /nodeA pub 'topicA'
[INFO] [1617717504.527792]: /nodeA pub 'topicA'
[INFO] [1617717506.527812]: /nodeA pub 'topicA'
[INFO] [1617717508.527791]: /nodeA pub 'topicA'
^Chaypin@ubt:~/catkin_ws/src/beginner_tutorials/scripts$
haypin@ubt:~/catkin_ws/src/beginner_tutorials/scripts$ rosrun beginner_tutorials _SubCheckPubUpdate2.py
/home/haypin/catkin_ws/src/beginner_tutorials/scripts/_SubCheckPubUpdate2.py:9: SyntaxWarning: The publisher should be created with an explicit keyword argument 'queue_size'. Please see http://wiki.ros.org/rospy/Overview/Publishers%20and%20Subscribers for more information.
pub = rospy.Publisher('~topicB',String) #定义发布者
[INFO] [1617717498.533295]: /nodeB sub topicA then pub topicB
[INFO] [1617717500.526424]: /nodeB sub topicA then pub topicB
[INFO] [1617717502.529730]: /nodeB sub topicA then pub topicB
[INFO] [1617717504.529405]: /nodeB sub topicA then pub topicB
[INFO] [1617717506.529490]: /nodeB sub topicA then pub topicB
[WARN] [1617717508.051299]: Inbound TCP/IP connection failed: connection from sender terminated before handshake header received. 0 bytes were received. Please check sender for additional details.
[INFO] [1617717508.529696]: /nodeB sub topicA then pub topicB
^Chaypin@ubt:~/catkin_ws/src/beginner_tutorials/scripts$
haypin@ubt:~/catkin_ws/src/beginner_tutorials/scripts$ rosrun beginner_tutorials _SubUpdate2.py
[INFO] [1617717504.530522]: /nodeC sub topicB
[INFO] [1617717506.530790]: /nodeC sub topicB
^Chaypin@ubt:~/catkin_ws/src/beginner_tutorials/scripts$