1. 前言
在使用ros pulisher时, 我们在建立话题 pub = rospy.Publisher('chatter', String, queue_size=10)
我们的目的时将我们的message (string)通过话题发布出去,如:pub.publish(hello_str)。 如果是为了处理单个话题的问题, 我们只用一个pub.publish()去发布就好。 我们也能够记住这个话题是干什么的。 但是当我们在一个节点中, 我们需要处理多个的publisher 和 subscriber 时, 无法记住某个话题的功能以及话题。那么如何便于操作???
python
#!/usr/bin/env python
2 # license removed for brevity
3 import rospy
4 from std_msgs.msg import String
5
6 def talker():
7 pub = rospy.Publisher('chatter', String, queue_size=10)
8 rospy.init_node('talker', anonymous=True)
9 rate = rospy.Rate(10) # 10hz
10 while not rospy.is_shutdown():
11 hello_str = "hello world %s" % rospy.get_time()
12 rospy.loginfo(hello_str)
13 pub.publish(hello_str)
14 rate.sleep()
15
16 if __name__ == '__main__':
17 try:
18 talker()
19 except rospy.ROSInterruptException:
20 pass
2. 字典话题publisher
python
##建立一个publisher.py 文件
import rospy
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
def send_gripper_command(gripper_pub, gripper_side, positions, time_from_start):
"""
发送手抓命令。
:param gripper_pub: 包含两个手抓发布者的字典。
:param gripper_side: 字符串,'left' 或 'right',指定要控制哪个手抓。
:param positions: 关节的目标位置列表。
:param time_from_start: 达到目标位置的时间,单位为秒。
"""
# 创建一个JointTrajectory消息
trajectory = JointTrajectory()
# 这里假设你的机器人手抓关节有特定的名称,根据你的机器人实际情况修改
trajectory.joint_names = ['gripper_joint']
# 创建一个轨迹点
point = JointTrajectoryPoint()
point.positions = positions # 设置目标位置
point.time_from_start = rospy.Duration(time_from_start) # 设置时间
# 将轨迹点添加到轨迹消息中
trajectory.points.append(point)
# 发布轨迹命令
gripper_pub[gripper_side].publish(trajectory)
# 初始化ROS节点
rospy.init_node('gripper_command_example')
gripper_pub = {
'left': rospy.Publisher("left_gripper/command", JointTrajectory, queue_size=1),
'right': rospy.Publisher("right_gripper/command", JointTrajectory, queue_size=1)
}
# 控制左手抓闭合
send_gripper_command(self.gripper_pub, 'left', [0.5], 1.0) # 0.5是目标位置(示例值),1.0秒内达到
# 控制右手抓打开
send_gripper_command(self.gripper_pub, 'right', [0.0], 1.0) # 0.0是目标位置(示例值),1.0秒内达到
在上述的代码中, JointTrajectory 是一个trajectory_msg的消息类型, 根据这个消息类型,
我们可以查到消息类型.msg的内容是:header,joint_names,points
self.joint_names = []
self.points = []
那么, 可以通过字典建立,gripper_pub['left']就可以获得rospy.Publisher("left_gripper/command", JointTrajectory, queue_size=1)。 使用gripper_pub["left"].publish(trajectory) 可以直接发布。
3. 字典话题订阅
为了接收发布到"left_gripper/command"
和"right_gripper/command"
话题的消息,我们需要创建两个订阅者(Subscriber
)实例。下面是如何使用Python在ROS中创建这样的订阅者字典的示例。
python
import rospy
from trajectory_msgs.msg import JointTrajectory
def left_gripper_callback(msg):
print("Received left gripper command:")
print(msg)
def right_gripper_callback(msg):
print("Received right gripper command:")
print(msg)
def setup_gripper_subscribers():
gripper_sub = {
'left': rospy.Subscriber("left_gripper/command", JointTrajectory,
left_gripper_callback),
'right': rospy.Subscriber("right_gripper/command", JointTrajectory,
right_gripper_callback)
}
return gripper_sub
if __name__ == '__main__':
rospy.init_node('gripper_command_listener', anonymous=True)
gripper_subscribers = setup_gripper_subscribers()
rospy.spin() # Keep the program alive
4.注意事项
- 确保你的ROS环境发布的话题 名称与你试图订阅的话题匹配。
rospy.spin()
调用是必要的,它让你的节点保持运行状态并持续监听话题上的消息。- 在实际应用中,你可能需要根据接收到的消息内容执行更复杂的操作,而不仅仅是打印消息。