ROS python 使用参数服务器传输数据

ROS 参数服务器一般用于整个运行环境中的全局变量, 但是我们也可以使用参数服务器传输一些频率比较低的数据.

优点:

  • 使用参数服务器, 可以避免在接收数据时使用回调函数.
  • 对于这种更新频率不高的数据, 当我们需要使用该数据时, 使用 rospy.get_param(Name) 即可获取数据, 避免的一直使用topic订阅数据

缺点:

  • 由于参数服务器由roscore 进行管理, 过大的数据, 频繁的请求, 都会占用网络带宽, 减低ROS系统的性能.
  • 参数服务器的容量有限.

通过参数服务器发送二维数组示例

  • 发送端
import os, sys
import numpy as np
import rospy

rospy.init_node(name="pub_img_param")
rospy.set_param(param_name='/test_img', param_value=' ')
while not rospy.is_shutdown():
    img_np = np.random.rand(40, 40)
    rospy.set_param(param_name='/test_img', param_value=img_np.tolist()) # 参数服务器不能直接发送numpy格式的数据
    rospy.sleep(duration=3)                                              # 过于频繁的 发送 和 接收 都会减低ROS系统性能
  • 接收端
import os, sys
import numpy as np
import rospy
rospy.init_node(name='read_param')
read_img = ' '

while not rospy.is_shutdown():
    if rospy.has_param(param_name='/test_img'):
    	# 该程序会频繁的请求参数服务器, 并不合适
    	# 在实际场景下, 程序需要执行一段时间才会去执行 has_param 和 get_param
        img_list = rospy.get_param(param_name='/test_img')
        # 只有参数发生更新,才会更新本地变量数据
        if not img_list == read_img:
            read_img = img_list
            img_np = np.asarray(read_img)
            print(img_np.shape)
  • 注意:
    • 只要roscore节点没有关闭, 我们添加的参数始终都存在, 因此我们需要手动清空哪些可能影响下次程序运动的参数, rospy.delete_param(param_name)
### ROS1 节点间数据输方法 #### 发布/订阅模式 在ROS1中,节点之间的通信可以通过发布(Publish)/订阅(Subscribe)机制来实现。这是一种异步的通信方式,在该模型下,发送者(Publisher)并不知道接收者的存在;同样地,接收者(Subscriber)也不知道是谁发布的消息。这种方式非常适合于广播型的数据分发场景。 ```python import rospy from std_msgs.msg import String def talker(): pub = rospy.Publisher('chatter', String, queue_size=10) rospy.init_node('talker', anonymous=True) rate = rospy.Rate(10) # 10hz while not rospy.is_shutdown(): hello_str = "hello world %s" % rospy.get_time() rospy.loginfo(hello_str) pub.publish(hello_str) rate.sleep() if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass ``` 此代码展示了如何创建一个简单的发布者节点[^3]。 对于订阅方,则需编写相应的回调函数处理收到的消息: ```python def listener(): rospy.init_node('listener', anonymous=True) rospy.Subscriber("chatter", String, callback) rospy.spin() def callback(data): rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data) if __name__ == '__main__': listener() ``` 这段脚本实现了监听指定主题并打印接收到的内容的功能。 #### 请求/应答模式 (服务调用) 除了上述提到的主题通信外,另一种常见的交互形式是基于请求-响应的服务调用(Service Call),即客户端向服务器发起请求,并等待其返回的结果。这适用于一对一的关系,其中一方提供某种功能或操作给另一方使用。 ```python # Service server side code snippet from beginner_tutorials.srv import * import rospy def handle_add_two_ints(req): print "Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b)) return AddTwoIntsResponse(req.a + req.b) def add_two_ints_server(): rospy.init_node('add_two_ints_server') s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints) print "Ready to add two ints." rospy.spin() if __name__ == "__main__": add_two_ints_server() ``` 这是设置服务端的例子,用于接受来自其他节点的操作请求[^2]。 相对应地,客户端会这样构建: ```python # Client-side service call example from beginner_tutorials.srv import * import sys import rospy def add_two_ints_client(x, y): rospy.wait_for_service('add_two_ints') try: add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts) resp1 = add_two_ints(x, y) return resp1.sum except rospy.ServiceException as e: print ("Service call failed: %s"%e) def usage(): return "%s [x y]"%sys.argv[0] if __name__ == "__main__": if len(sys.argv) == 3: x = int(sys.argv[1]) y = int(sys.argv[2]) else: print (usage()) sys.exit(1) print ("Requesting %s+%s"%(x, y)) print ("%s + %s = %s"%(x, y, add_two_ints_client(x, y))) ``` 这里给出了发起一次远程过程调用的具体做法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值