ROS服务通信机制实操Python

ROS通信机制包括话题通信、服务通信和参数服务器三种通信方式,各原理及代码实现如下表

在这里插入图片描述

功能博客链接说明
VScode配置 ROS 环境VScode创建ROS项目 ROS集成开发环境使用VScode使用配置了ROS开发环境,实现ROS开发的第一步
话题通信理论ROS话题通信流程理论介绍了话题通信机制的原理
ROS话题通信机制实操C++ROS话题通信机制实操C++手把手的用C++实现了话题通信机制
ROS话题通信机制实操PythonROS话题通信机制实操Python手把手的用Python实现了话题通信机制
ROS话题通信流程自定义msg格式ROS话题通信流程自定义msg格式介绍了如何准备话题通信机制自定义msg数据格式,及相关配置
ROS话题通信机制自定义msg实战C++ROS话题通信机制自定义msg实战C++手把手的用C++实现了话题通信机制自定义msg数据通信
ROS话题通信机制自定义msg实战PythonROS话题通信机制自定义msg实战Python手把手的用Python实现了话题通信机制自定义msg数据通信
服务通信理论ROS服务通信流程理论介绍了服务通信机制的原理
ROS服务通信自定义srvROS服务通信自定义srv介绍了如何准备服务通信机制自定义srv数据格式,及相关配置
ROS服务通信机制实操C++ROS服务通信机制实操C++手把手的用C++实现了服务通信机制
ROS服务通信机制实操PythonROS服务通信机制实操Python手把手的用Python实现了话题通信机制
参数服务器理论ROS参数服务器理论模型介绍了参数服务器的原理
ROS参数服务器增删改查实操C++ROS参数服务器增删改查实操C++用 C++ 实现了参数服务器的的增删改查操作
ROS参数服务器增删改查实操PythonROS参数服务器增删改查实操Python用 Python 实现了参数服务器的的增删改查操作

ROS服务通信的理论查阅:ROS服务通信流程理论

ROS服务通信的自定义srv数据的准备可以查阅:ROS服务通信自定义srv

在模型实现中,ROS master不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:

  • 服务端
  • 客户端
  • 数据

步骤流程

实现ROS服务通信的步骤分为以下5步:

  • 1.vscode配置;
  • 2.编写服务端;
  • 3.编写客户端;
  • 4.编辑配置文件;
  • 5.编译并执行。

vscode配置

为了方便代码提示以及误抛异常,需要先配置 vscode,将前面自定义数据格式生成的 python 文件路径配置进 settings.json

在这里插入图片描述

服务端

  • 基本流程
    服务端:解析客户端请求,产生响应。

    • 1.导包;
    • 2.初始化 ROS 节点;
    • 3.创建服务端对象;
    • 4.处理逻辑(回调函数);
    • 5.spin()
  • 代码实现

      ```python
      #! /usr/bin/env python3
      
      
      import rospy
      from plumbing_server_client.srv import AddInts, AddIntsRequest, AddIntsResponse
      
      """
      服务端:解析客户端请求,产生响应。
          1.导包;
          2.初始化 ROS 节点;
          3.创建服务端对象;
          4.处理逻辑(回调函数);
          5.spin()
      
      """
      
      def doAdd(request):
          num1 = request.num1
          num2 = request.num2
      
          sum = num1 + num2
      
          response = AddIntsResponse()
          response.sum = sum
          rospy.loginfo("服务器解析的数据: num1 = %d num2 = %d 响应的结果sum = %d",num1, num2, sum)
          return response
      
      
      if __name__ == "__main__":
          # 2.初始化 ROS 节点;
          rospy.init_node("heiShui")  # 保洁公司
          # 3.创建服务端对象;
          server = rospy.Service("addInts", AddInts, doAdd)  # 参数1:话题名称 参数2:消息对应的类型  参数3:回调函数
          rospy.loginfo("服务器已启动!!!")
          # 4.处理逻辑(回调函数);
          # 5.spin()
          rospy.spin()
      ```
    
  • 添加可执行权限

    进入到 scripts 文件下,打开Terminal,执行 chmod +x *.py 对demo_server_p.py文件添加可执行的权限

    在这里插入图片描述

  • 验证是否有问题

    • 编辑配置文件
      修改 plumbing_server_client 功能包下的CMakeLists.txt,找到catkin_install_python,修改成如图所示:

      在这里插入图片描述

    • 按快捷键 ctrl + shift + B 编译

      在这里插入图片描述

    • 开启一个Terminal,运行 roscore 命令;再开启一个新的Terminal,运行 source ./devel/setup.bash rosrun plumbing_server_client demo_server_p.py ;再开启一个Terminal,运行 rosservice call addInts “num1: 1 num2: 2” (num1 num2是按Tab键自动补齐,然后修改数字),查看服务请求数据并响应

      在这里插入图片描述

客户端

  • 基本流程
    客户端:组织并提交请求,处理服务端响应。

    • 1.导包;
    • 2.初始化 ROS 节点;
    • 3.创建客户端对象;
    • 4.组织请求数据,并发送请求;
    • 5.处理响应。
  • 代码实现

    #! /usr/bin/env python
    
    import rospy
    from plumbing_server_client.srv import AddInts, AddIntsRequest, AddIntsResponse
    
    
    
    """
    客户端:组织并提交请求,处理服务端响应。
        1.导包;
        2.初始化 ROS 节点;
        3.创建客户端对象;
        4.组织请求数据,并发送请求;
        5.处理响应。
    """
    
    
    if __name__ == "__main__":
    
        # 2.初始化 ROS 节点;
        rospy.init_node("daZhuang")
        # 3.创建客户端对象;
        client = rospy.ServiceProxy("addInts", AddInts)  # 参数1:话题名称 参数2:消息对应的类型
        # 4.组织请求数据,并发送请求;
        reponse = client.call(30, 50)
        # 5.处理响应。
        rospy.loginfo("响应的数据: %d",reponse.sum)
    
  • 添加可执行权限

    进入到 scripts 文件下,打开Terminal,执行 chmod +x *.py 对demo_client_p.py文件添加可执行的权限

    在这里插入图片描述

编辑配置文件

修改 plumbing_server_client 功能包下的CMakeLists.txt,找到catkin_install_python,修改成如图所示:

在这里插入图片描述

编译并执行

  • 按快捷键 ctrl + shift + B 编译
    在这里插入图片描述

  • 执行代码

    • 1.启动 roscore;
      开启一个Terminal,启动 roscore
      在这里插入图片描述

    • 2.启动服务端;
      开启一个新的Terminal

      在这里插入图片描述

    • 3.启动客户端;
      开启一个新的Terminal
      在这里插入图片描述

优化

实现参数的动态提交

前面响应的数据都是写死的,将数据实现动态的输入,主要是修改客户端代码,服务端不用修改。
格式:rosrun xxxxx xxxxxx num1 num2
代码实现

#! /usr/bin/env python3

import rospy
from plumbing_server_client.srv import AddInts, AddIntsRequest, AddIntsResponse
import sys


"""
客户端:组织并提交请求,处理服务端响应。
    1.导包;
    2.初始化 ROS 节点;
    3.创建客户端对象;
    4.组织请求数据,并发送请求;
    5.处理响应。
"""


if __name__ == "__main__":

    # 判断传入的参数个数
    if len(sys.argv) != 3:
        rospy.loginfo("传入参数的个数不对!!!")
        sys.exit(1)

    # 2.初始化 ROS 节点;
    rospy.init_node("daZhuang")
    # 3.创建客户端对象;
    client = rospy.ServiceProxy("addInts", AddInts)  # 参数1:话题名称 参数2:消息对应的类型
    # 4.组织请求数据,并发送请求;
    # 解析传入的参数
    num1 = int(sys.argv[1])
    num2 = int(sys.argv[2])
    reponse = client.call(num1, num2)
    # 5.处理响应。
    rospy.loginfo("响应的数据: %d",reponse.sum)

编译后,启动 roscore 和服务端,然后启动客户端,同时输入请求的参数 num1 和 num2,如图所示:
在这里插入图片描述

优化先启动客户端后启动服务端

客户端先于服务端启动,会抛出异常
如果有先启动客户端,挂起等待服务端启动后再请求的需求。就需要调用ROS的内置等待函数 client.wait_for_service()和 rospy.wait_for_service(“服务话题”) 。

代码实现

#! /usr/bin/env python3

import rospy
from plumbing_server_client.srv import AddInts, AddIntsRequest, AddIntsResponse
import sys


"""
客户端:组织并提交请求,处理服务端响应。
    1.导包;
    2.初始化 ROS 节点;
    3.创建客户端对象;
    4.组织请求数据,并发送请求;
    5.处理响应。
"""


if __name__ == "__main__":

    # 判断传入的参数个数
    if len(sys.argv) != 3:
        rospy.loginfo("传入参数的个数不对!!!")
        sys.exit(1)

    # 2.初始化 ROS 节点;
    rospy.init_node("daZhuang")
    # 3.创建客户端对象;
    client = rospy.ServiceProxy("addInts", AddInts)  # 参数1:话题名称 参数2:消息对应的类型
    rospy.loginfo("客户端启动")
    # 4.组织请求数据,并发送请求;
    # 解析传入的参数
    num1 = int(sys.argv[1])
    num2 = int(sys.argv[2])

    # 等待服务端启动
    # client.wait_for_service()
    rospy.wait_for_service("addInts")  # 参数:话题名称
    reponse = client.call(num1, num2)
    # 5.处理响应。
    rospy.loginfo("响应的数据: %d",reponse.sum)

启动客户端后,没有启动服务端,在等待服务端启动,没有抛出异常,结果如图所示:
在这里插入图片描述

再启动服务端后,请求进行响应,结果如图所示:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值