栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

四、服务通信原理,代码实现

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

四、服务通信原理,代码实现

文章目录
  • 1、服务通信原理
  • 2、服务通信自定义srv
  • 3、代码实现
    • 1.C++实现
    • 2.Python实现

1、服务通信原理

  1. Server注册
    Server启动后,会通过RPC协议在Master中注册自己的地址和提供的服务(话题)
  2. Client注册
    Client启动后,会在Master中注册自己所需要的服务(话题)
  3. 匹配
    Master根据注册表进行话题匹配,并将Server的TCP地址通过RPC协议发送给Client
  4. Client发送请求
    Client收到TCP地址后,通过TCP协议与Server建立连接,发送请求数据
  5. Server发送相应
    Server根据请求,发送结果
    注意:
    在话题通信中,由于是采用订阅的方式,双方启动前后顺序无要求。但是,在服务通信中,由于采用请求响应的方式,所以要先启动Server,再启动Client
2、服务通信自定义srv
  1. 在服务通信中,srv文件分两部分:客户端和服务端,而在话题通信中,msg文件只有一部分,在功能包下创建srv目录,在其下面添加xxx.srv文件:
    #客户端
    int32 num1
    int32 num2
    ---
    #服务端
    int32 sum
    
    注意: 客户端和服务端之间用—分割
  2. 编辑配置文件
    1. package.xml
      message_generation
      message_runtime
      
      
    2. CmakeLists.txt
      find_package(catkin REQUIRED COMPONENTS
      roscpp
      rospy
      std_msgs
      message_generation
      )
      # 需要加入 message_generation,必须有 std_msgs
      
      add_service_files(
      FILES
      AddInts.srv
      )
      
      generate_messages(
      DEPENDENCIES
      std_msgs
      )
      
    3. 编译
      编译后会生成相应的中间件,包括C++中的.h文件和Python中的.py文件
3、代码实现 1.C++实现
  1. vscode配置,在C++中,需要配置c_cpp_properies.json文件,主要是"includePath"路径的设置,如果不设置的话,将无法找到生成的.h文件,在敲代码的过程中,也没有相应的提示
    {
       "configurations": [
          {
                "browse": {
                   "databaseFilename": "",
                   "limitSymbolsToIncludedHeaders": true
                },
                "includePath": [
                   "/opt/ros/noetic/include
       //方式1
       ros::service::waitForService("add_int");
       //方式2
       // client.waitForExistence();
       //5.组织请求数据
       server_client::add ai;
       ai.request.num1 = atoi(argv[1]);
       ai.request.num2 = atoi(argv[2]);
       //6.发送请求,返回bool值,成功为真
       bool flag = client.call(ai);
       if (flag){
          ROS_INFO("请求正常,结果为:%d, %s, %s, %s",ai.response.sum,argv[0],argv[1],argv[2]);
       }
       else{
          ROS_INFO("请求失败!");
          return 1;
       }
       return 0;
    }
    
  2. 配置CMakeLists.txt
    add_executable(AddInts_Server src/AddInts_Server.cpp)
    add_executable(AddInts_Client src/AddInts_Client.cpp)
    
    
    add_dependencies(AddInts_Server ${PROJECT_NAME}_gencpp)
    add_dependencies(AddInts_Client ${PROJECT_NAME}_gencpp)
    
    
    target_link_libraries(AddInts_Server
    ${catkin_LIBRARIES}
    )
    target_link_libraries(AddInts_Client
    ${catkin_LIBRARIES}
    )
    
  3. 执行
    1. 启动服务
      rosrun 包名 服务名
      
    2. 启动客户
      rosrun 包名 客户名 参数1 参数2
      
2.Python实现
  1. vscode配置,在Python中,需要配置setting.json文件,方面参数补齐
    {
     "python.autoComplete.extraPaths": [
         "/opt/ros/noetic/lib/python3/dist-packages",
     ]
    }
    
  2. 服务端
    #! /usr/bin/env python
    
    #1. 导包
    import rospy
    #从功能包下的srv文件导入相应的数据类型
    from server_client.srv import add, addRequest, addResponse
    
    #req参数可以随便取名,它是一个类,但是其元素必须为srv中的参数
    def doReq(req):
       #num1 num2为srv中定义的数据类型
       sum = req.num1 + req.num2
       rospy.loginfo("结果:%d",sum)
       resp = addResponse(sum)
    
       #回调函数返回响应结果
       return resp
    
    if __name__ == "__main__":
    
       #2.初始化ROS节点    注意节点名唯一
       rospy.init_node("server_p")
    
       #3.创建服务对象     
       # add_int_p为话题名 add为数据类型 
       # doReq为回调函数,其数据类型为srv中的数据类型
       server = rospy.Service("add_int_p",add,doReq)
    
       #4.回调函数处理请求并产生响应
       
       #5.spin函数
       rospy.spin()
    
  3. 客户端
    #! /usr/bin/env python
    #1.导包
    import rospy
    from server_client.srv import *
    import sys 
    
    if __name__ == "__main__":
    
       if len(sys.argv) != 3:
          rospy.logerr("请输入正确参数!")
          sys.exit
    
       #2.初始化ROS节点
       rospy.init_node("client_p")
    
       #3.创建请求对象     
       # add_int_p为话题,与服务端的一样
       # add为数据类型
       client = rospy.ServiceProxy("add_int_p",add)
    
       rospy.wait_for_service("add_int_p")
       # client.wait_for_service()
    
       #4.发送请求,接受并处理相应
       #方式1
       #resp = client(3,4)
    
       #方式2
       #resp = client(addRequest(1,2))
       
       #方式3
       req = addRequest()
       req.num1 = int(sys.argv[1])
       req.num2 = int(sys.argv[2])
    
       resp = client.call(req)
       rospy.loginfo("结果为:%d",resp.sum)
    
  4. 添加可执行权限
    在scripts文件夹下,执行:chmod +x *.py
  5. 配置CMakeLists.txt文件
    catkin_install_python(PROGRAMS
    scripts/AddInts_Server_p.py 
    scripts/AddInts_Client_p.py
    DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    )
    
  6. 执行
    • 服务端:rosrun 包名 服务
    • 客户端:rosrun 包名 客户 参数1 参数2
      注意: 服务和客户都是.py文件
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/947408.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号