最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

ROS多个master消息互通

来源:懂视网 责编:小采 时间:2020-11-27 14:28:04
文档

ROS多个master消息互通

ROS多个master消息互通:需求有时候我们需要有几个不同的master, 他们之间要交换topic的内容,这时候就不能使用ros自带的设置同一个master的方法.我们的处理方法是,构造一个client和一个server,他们运行在不同的master下面, client在master1下订阅topic1,然后通过t
推荐度:
导读ROS多个master消息互通:需求有时候我们需要有几个不同的master, 他们之间要交换topic的内容,这时候就不能使用ros自带的设置同一个master的方法.我们的处理方法是,构造一个client和一个server,他们运行在不同的master下面, client在master1下订阅topic1,然后通过t

需求

有时候我们需要有几个不同的master, 他们之间要交换topic的内容,这时候就不能使用ros自带的设置同一个master的方法.

我们的处理方法是,构造一个client和一个server,他们运行在不同的master下面, client在master1下订阅topic1,然后通过tcp协议(自己定义一个消息协议格式)发到master2下面的server,进行消息解析,再发布出master2下面的topic1,这样我们不改变ros自带的topic框架,就实现topic1的消息从master1到master2的传播.

下面我们实现的是将一个amcl_pose的topic,消息类型是PoseWithCovarianceStamped从master1传到master2,其他的topic代码类似

client 的代码

#! /usr/bin/env python# -*- coding=utf-8 -*-import socketimport structimport rospyimport timefrom geometry_msgs.msg import PoseWithCovarianceStamped,PoseStamped#message proto# id | length | datadef send_msg(sock, msg ,id):
 # Prefix each message with a 4-byte id and length (network byte order)
 msg = struct.pack('>I',int(id)) + struct.pack('>I', len(msg)) + msg
 sock.sendall(msg)def odomCallback(msg):
 global odom_socket

 data = ""

 id = msg.header.seq print "send id: ",id
 x = msg.pose.pose.position.x
 y = msg.pose.pose.position.y #orientation
 orien_z = msg.pose.pose.orientation.z
 orien_w = msg.pose.pose.orientation.w

 data += str(x) + "," + str(y)+ "," + str(orien_z)+ "," + str(orien_w)

 send_msg(odom_socket,data,id)


odom_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
odom_socket.connect(('127.0.0.1',8000))

rospy.init_node('server_node')

rospy.Subscriber('/amcl_pose',PoseWithCovarianceStamped,odomCallback)

rospy.spin()

server 的代码

#! /usr/bin/env python# -*- coding=utf-8 -*-import socketimport time,os,fcntlimport structimport rospyfrom geometry_msgs.msg import PoseWithCovarianceStamped,PoseStamped#message proto# id | length | datadef recv_msg(sock):
 try: # Read message length and unpack it into an integer
 raw_id = recvall(sock, 4) if not raw_id: return None
 id = struct.unpack('>I', raw_id)[0] print "receive id: ",id
 raw_msglen = recvall(sock, 4) if not raw_msglen: return None
 msglen = struct.unpack('>I', raw_msglen)[0] # Read the message data
 return recvall(sock, msglen) except Exception ,e: return Nonedef recvall(sock, n):
 # Helper function to recv n bytes or return None if EOF is hit
 data = ''
 while len(data) < n:
 packet = sock.recv(n - len(data)) if not packet: return None
 data += packet return data##把接受的数据重新打包成ros topic发出去def msg_construct(data):

 list = data.split(',')

 pose = PoseWithCovarianceStamped()
 pose.header.stamp = rospy.Time.now()
 pose.header.frame_id = "/map"
 pose.pose.pose.position.x = float(list[0])
 pose.pose.pose.position.y = float(list[1])
 pose.pose.pose.position.z = 0
 pose.pose.pose.orientation.x = 0
 pose.pose.pose.orientation.y = 0
 pose.pose.pose.orientation.z = float(list[2])
 pose.pose.pose.orientation.w = float(list[3])
 pose.pose.covariance = [0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.06853891945200942] return pose#初始化socket,监听8000端口odom_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
odom_socket.bind(('',8000))
odom_socket.listen(10)

(client,address) = odom_socket.accept()

rospy.init_node("client_node")
odom_pub = rospy.Publisher("/amcl_pose",PoseWithCovarianceStamped,queue_size=30)
r = rospy.Rate(1000)#设置noblock,否则会阻塞在接听,下面while不会一直循环,只有在有数据才进行下一次循环fcntl.fcntl(client, fcntl.F_SETFL, os.O_NONBLOCK)while not rospy.is_shutdown():
 data = recv_msg(client) if data:
 odom_pub.publish(msg_construct(data))
 r.sleep()

结论

上面的代码在局域网内测试过,发送图像,激光的数据都可以保证不丢数据。

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

ROS多个master消息互通

ROS多个master消息互通:需求有时候我们需要有几个不同的master, 他们之间要交换topic的内容,这时候就不能使用ros自带的设置同一个master的方法.我们的处理方法是,构造一个client和一个server,他们运行在不同的master下面, client在master1下订阅topic1,然后通过t
推荐度:
标签: 信息 互通 多个
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top