问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

ROS怎样实现在两台电脑间进行数据通信

发布网友 发布时间:2022-05-10 21:24

我来回答

2个回答

懂视网 时间:2022-05-11 01:45

需求

有时候我们需要有几个不同的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()

结论

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

热心网友 时间:2022-05-10 22:53

在我看来,ROS最牛*的地方就是它的通信机制了,不仅仅是进程间通信方便,就连不同设备间通信也很方便,只需添加几行代码,你就可以实现多电脑间的 Topi c共享, 远程控制等功能。下面就让我们一起来实现吧!
这里假设我们有两个电脑:电脑 A 为主机端,电脑 B 为控制端。最终要实现在 A 电脑上运行roscore,并且运行 Turtlesim 程序,然后在 B 电脑上运行键盘控制程序,控制 Turtlesim 小乌龟移动。
1. 查看电脑A和电脑B的 IP 和 Hostname
查看IP,在控制台输入:
$ ifconfig
如果电脑连接的时有线网,则显示结果中,etho 部分的 inet addr 后面就是该电脑的 IP 地址;
如果电脑连接的是无线,则 wlp3s0 部分的 inet addr 后就是 IP 地址。
查看 Hostname,在控制台输入:
$ hostname
2. 修改hosts文件内容
使用如下指令,分别在电脑A和电脑B的打开 hosts 文件:
$ sudo gedit /etc/hosts
在电脑A端的 hosts文件 中添加如下加粗指令:
复制代码
127.0.0.1    localhost
127.0.1.1 [ hostname_A ]
[IP_A] [ hostname_A ]
[IP_B] [ hostname_B ]
***
复制代码
同理,在电脑B端的 hosts 文件中,加入如下加粗指令:
复制代码
127.0.0.1    localhost
127.0.1.1 [ hostname_B ]
[IP_B] [ hostname_B ]
[IP_A] [ hostname_A ]
***
复制代码
3. 修改 .bashrc 文件
使用如下指令,分别在电脑A和电脑B的打开 .bashrc 文件
$ sudo gedit ~/.bashrc
在电脑A端和电脑B端打开的 .bashrc 文件的最后一行,加入如下代码:
export ROS_MASTER_URI=http://[hostname_A]:11311
[注意] 此处假设电脑A为主机,如果改成电脑B为主机,则只需要将此步中的 [hostname_A] 改成 [hostname_B] 即可。
4. 运行小乌龟程序
电脑A端:
首先启动 ROS:
$ roscore
然后 Ctrl + T 打开新的控制台,运行:
$ rosrun turtlesim turtlesim_node
电脑B端:
$ rosrun turtlesim turtle_teleop_key
现在,你就可以用电脑 B 控制电脑 A 中的小乌龟尽情遨游啦! ~\(≧▽≦)/~啦啦啦
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
泰勒公式有哪些常见形式? 空调室内风机怎样工作 什么是县级以上医院 关于聚金宝 买白银问题 平安银行个人贵金属交易业务有哪些? 网易云音乐为什么歌这么少? 公路边种的有什么花 高速路上常用的绿化花卉有那些? 公路绿化用什么花 我一键开核后顺利进入WIN7 系统,可是一开网站就重启是怎么回事,我开6... 明年女孩取什么名子,爸,姓郎,妈姓焦 给女孩取名缺木缺金属蛇2013年农历4月14出生姓郎取什么名好 取名 姓郎 远辈男孩叫什么? 一般家里飞的蛾子吃什么 求大师、我想给我儿子起名:郎路什么、辈分是路、姓郎、给想想吧 飞蛾是益虫还是害虫? 男孩取名姓郎,中间要有个一或同音益逸艺毅都行,叫郎一什么好呢? 蝗虫,天牛,蛾子等属于什么害虫 现在稻子上有很多蛾子能产什么害虫? 飞蛾是害虫吗 飞蛾是害虫吗? 飞蛾是害虫还是益虫? 飞蛾是益虫还是害虫 蛾子是害虫还是益虫? 百利金墨水堵笔吗? 钢笔是百乐贵妃,墨水就是百利金4001,不知道是笔的问题还是啥,不盖盖子放一会 百乐贵妃是必须要安装上墨器吗,有了上墨器就能像普通钢笔一样打墨水还是说要用墨胆? 长期上火怎么办? 经常上火应该怎么办? 只要安卓系统就能装微信吗 ? 8号001070净值是多少 我老公姓郎,我姓王,我们俩都属牛,孩子属龙,想起个四个字的名字 姓郎带凯字取名 取名,女孩,姓郎,属猴叫什么好 宝宝起名姓郎,字辈是启 虎年女孩取名,父亲姓郎,母亲姓段,2010年农历七月二十九出生,请高手... 姓郎的孩子起名,看看生晨八字缺什么? 荧幕初吻是指真亲吗? 流变应力是指真应力还是工程应力 英语IF Ihave...i will 和IF I had ...i would中哪个是指真的有,哪个指想法 能率油烟机触摸屏失灵怎么办 蒸箱能代替压力锅吗 蒸箱可以煲汤么? 密码学中的随机数是指真随机数还是伪随机数? 电蒸箱可以做双皮奶吗? 喜欢上自己师父,怎么办? 喜欢上自己师傅怎么办 喜欢上自己师父怎么办 喜欢上了自己拜的师傅,怎么办 我喜欢上我的师父怎么办? 紫砂壶外壁能用酒精擦吗