解决方案

3 ROS2服务通讯基础

seo靠我 2023-09-24 15:32:06

ROS2服务通讯基础

3.1 服务通讯介绍3.2 ROS2服务通讯的基本流程3.2.1 创建ROS2服务通讯功能包的基本流程3.2.2 创建ROS2服务通讯功能包示例 3.3 使用C/C++实现ROS2SEO靠我服务通讯3.3.1 创建C/C++服务通讯服务端功能包并编写节点文件3.3.2 配置C/C++服务通讯服务端功能包3.3.3 编译并运行C/C++服务通讯服务端3.3.4 创建C/C++服务通讯客户端SEO靠我功能包并编写节点文件3.3.5 编译并运行C/C++服务通讯客户端节点 3.4 使用Python实现ROS2服务通讯3.4.1 创建Python服务通讯服务端功能包并编写节点文件3.4.2 配置PytSEO靠我hon服务通讯服务端功能包3.4.3 编译并运行Python服务通讯服务端功能包3.3.4 创建Python服务通讯客户端功能包并编写节点文件3.4.5 编译并运行Python服务通讯客户端节点 3.SEO靠我5 服务通讯小结 其他ROS2学习笔记: ROS2学习笔记代码仓库:Github连接地址欢迎各位互相学习交流

3.1 服务通讯介绍

参考内容

Understanding servicesSEO靠我

服务通讯是ROS2的一种基于请求响应式的通讯方式,与之前的话题通讯不同的是服务通讯不是连续的数据流式的通讯,而是需要特定的触发才能收到回复的模式。

服务通讯可以是单个服务端和和单个客户端直接的通讯,一对SEO靠我一的模式

服务通讯也可以是单个服务端和多个客户端通讯,一对多的模式

3.2 ROS2服务通讯的基本流程

事实上,服务通讯和自定义的话题通讯的操作过程很类似,即将所需要利用到服务模块利用ament_camkeSEO靠我工具编译成.c和.py的ROS2功能包,然后新建的功能包依赖这个服务功能包完成通讯。

3.2.1 创建ROS2服务通讯功能包的基本流程

创建ROS2功能包,功能包可以只用来作为存放自定义的msg/srv/SEO靠我action,不需要节点node的功能包,且--build-type必须是ament_camke ,因为目前来看,Python的自定义的消息或者服务也需要通过cmake编译出来再调用,功能包必须是下划线SEO靠我的推荐命名方法,而不是大小写的驼峰,否则会报错,如下所示: rosidl_adapter.parser.InvalidResourceName: xxxxx is an invalidSEO靠我package name. It should have the pattern^(?!.*__)(?!.*_$)[a-z][a-z0-9_]*$ 在ROS2功能包内创建srv文件夹SEO靠我,里面存放自定义的.srv消息文件,并且.srv文件必须是大写开头的符合类的命名规则配置packages.xml文件,都需要配置下面的内容(下面的配置项与.srv文件无关,是默认的固定配置) SEO靠我 <!-- 这一项是针对在srv文件中可能用到的其他依赖项,例如geomtry_msgs等等,如过没有用到就不添加 --> <depend>其他的depend</depend><SEO靠我!-- 下面三项是必须的 --> <build_depend>rosidl_default_generators</build_depend> <exec_dependSEO靠我>rosidl_default_runtime</exec_depend> <member_of_group>rosidl_interface_packages</member_of_SEO靠我group> 配置CMakeLists.txt文件,find_package和rosidl_generate_interfaces # 0. 是针对在srv文件中可能SEO靠我用到的其他依赖项,例如geomtry_msgs等等,则需要添加 # find_package(geometry_msgs REQUIRED)# 1. rosidl_default_geSEO靠我nerators是必须添加的内容 find_package(rosidl_default_generators REQUIRED)# 2. rosidl_generate_interfSEO靠我aces必须配置,里面添加srv文件位置 rosidl_generate_interfaces(${PROJECT_NAME} # 2.1 添加自定义的srv位置,例如SEO靠我存放在功能包的srv文件夹下的xxx.srv"srv/xxx.srv" # 2.2 可选,如果xxx.srv依赖了其他的内容,例如依赖了geometry_msgsDEPENDENCIESEO靠我S geometry_msgs ) 编译功能包:colcon build --packages-select <功能包名> 此时激活install目录下的setup.SEO靠我bash如. install/setup.bash,可以通过ros2 interface show <功能包名称>/srv/xxx.srv查看到xxx.srv内容,此时编译好的srv的.c文件存放在iSEO靠我nstall/<功能包名>/include下,.py文件则存放在install/<功能包名>/local/

3.2.2 创建ROS2服务通讯功能包示例

创建自定义消息功能包srv_demo,采用amentSEO靠我_cmake方式:ros2 pkg create srv_demo --build-type ament_cmake

在功能包内创建srv文件夹,其中存放AddInt.srv文件,需要利用到---符号作SEO靠我为分割,文件在---上面的内容作为请求体的参数,在---下面的内容作为响应体的参数,文件内容如下:

int32 num1 int32 num2 --- iSEO靠我nt32 sum 此时的功能包内部的目录结构如下:tree -a pldz@pldz-pc:~/share/ROS2_DEMO/3_Chapter/code/srv_SEO靠我demo$ tree -a . ├── CMakeLists.txt ├── include │ └── srv_demo SEO靠我 ├── package.xml ├── src └── srv└── AddInt.srv 配置packages.xml添加依赖项,由于AddInSEO靠我t.srv没有依赖任何的东西因此不需要添加其他的depend: <?xml version="1.0"?> <?xml-model href="http://downlSEO靠我oad.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <pSEO靠我ackage format="3"><name>msg_demo</name><version>0.0.0</version><description>TODO: Package descriptioSEO靠我n</description><maintainer email="pldz@R7000.com">pldz</maintainer><license>TODO: License declaratioSEO靠我n</license><buildtool_depend>ament_cmake</buildtool_depend><!-- 构建自定义功能包的的必须依赖项 --><buildtool_dependSEO靠我>rosidl_default_generators</buildtool_depend><exec_depend>rosidl_default_runtime</exec_depend><membeSEO靠我r_of_group>rosidl_interface_packages</member_of_group><test_depend>ament_lint_auto</test_depend><tesSEO靠我t_depend>ament_lint_common</test_depend><export><build_type>ament_cmake</build_type></export> SEO靠我 </package> 配置CMakeLists.txt文件,添加构建自定义AddInt.srv的依赖: cmake_minimum_required(VERSIONSEO靠我 3.8) project(srv_demo)if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")SEO靠我add_compile_options(-Wall -Wextra -Wpedantic) endif()# find dependencies find_packagSEO靠我e(ament_cmake REQUIRED) # uncomment the following section in order to fill in # furtSEO靠我her dependencies manually. # find_package(<dependency> REQUIRED)# 1. 构建自定义功能包必须的依赖 fSEO靠我ind_package(rosidl_default_generators REQUIRED)# 2. 配置自定义的srv的位置 rosidl_generate_interfaces(SEO靠我${PROJECT_NAME}"srv/AddInt.srv" )if(BUILD_TESTING)find_package(ament_lint_auto REQUIRED)# thSEO靠我e following line skips the linter which checks for copyrights# comment the line when a copyright andSEO靠我 license is added to all source filesset(ament_cmake_copyright_FOUND TRUE)# the following line skipsSEO靠我 cpplint (only works in a git repo)# comment the line when this package is in a git repo and when# aSEO靠我 copyright and license is added to all source filesset(ament_cmake_cpplint_FOUND TRUE)ament_lint_autSEO靠我o_find_test_dependencies() endif()ament_package()

构建功能包:colcon build --packages-select srv_deSEO靠我mo

查看自定义的消息:激活环境:. install/setup.bash ,查看自定义消息ros2 interface show srv_demo/srv/AddInt

pldz@pldz-pc:~/sSEO靠我hare/ROS2_DEMO/3_Chapter/code$ colcon build --packages-select srv_demo Starting >>> srv_demoSEO靠我 Finished <<< srv_demo [12.2s] Summary: 1 package finished [12.5s] pldz@pldz-pc:~/shSEO靠我are/ROS2_DEMO/3_Chapter/code$ . install/setup.bash pldz@pldz-pc:~/share/ROS2_DEMO/3_Chapter/SEO靠我code$ ros2 interface show srv_demo/srv/AddInt int32 num1 int32 num2 --- SEO靠我 int32 sum 查看instll下面的文件:其中.c的class文件在install/<功能包名>/include/<功能包名>/<功能包名>/msg/**,.py在inSEO靠我stall/<功能包名>/local/lib/python3.10/dist-packages/<功能包名>/msg/**,后续Vscode可以通过配置settings.json添加提示

3.3 使用CSEO靠我/C++实现ROS2服务通讯

这里直接使用3.2.2创建的srv_demo服务功能包进行ROS2 C/C++的服务通讯的实现

参考内容:

Writing a simple service and clienSEO靠我t (C++)

2.3.3_服务通信_C++实现_01框架搭建

ROS2探索(三)service

3.3.1 创建C/C++服务通讯服务端功能包并编写节点文件

创建功能包,其中功能包名称为cpp_srv_seSEO靠我rver,节点名为cppSrvServerNode:ros2 pkg create cpp_srv_server --build-type ament_cmake --node-name cppSrvSEO靠我ServerNode

配置Vscode环境,在工作空间创建.vscode文件夹,并加入settings.json文件,添加ROS2的include环境和当前工作空间的install文件夹下的srv_deSEO靠我mo功能包的include路径:

{"C_Cpp.default.includePath": ["/opt/ros/humble/include/**","./install/srv_demo/inclSEO靠我ude/**"], } 编写服务端节点文件,主要包括导入包,创建服务节点,实现回调函数: // 1. 调用自定义的服务文件 // 1SEO靠我.1 rclcpp和srv_demo两个功能包的头文件 // 如果有vscode的下划线提示,说明是settings.json没有配置好 #include "rclcpSEO靠我p/rclcpp.hpp" #include "srv_demo/srv/add_int.hpp"// 1.2. 调用功能包下的自定义的服务,其中自定义的服务名已经变成了一个类名 SEO靠我 using srv_demo::srv::AddInt;// std_bind的占位符 using std::placeholders::_1; usingSEO靠我 std::placeholders::_2;// 2.定义节点类; class CppSrvServer: public rclcpp::Node{public:// 2.1 构造函SEO靠我数,其中节点名直接赋予cppSrvServerNodeCppSrvServer():Node("cppSrvServerNode"){// 2.2 创建服务端server_ = this->creatSEO靠我e_service<AddInt>("mySrvName",std::bind(&CppSrvServer::addIntFunc, this, _1, _2));RCLCPP_INFO(this->SEO靠我get_logger(),"Server is starting ...");}private:// 3. 服务端的回调函数实现,其中参数的写法区分主要在于类型,参数数量包括请求体req和响应体rspSEO靠我void addIntFunc(const AddInt::Request::SharedPtr req, const AddInt::Response::SharedPtr rsp){rsp->suSEO靠我m = req->num1 + req->num2;RCLCPP_INFO(this->get_logger(),"request body :(%d,%d), response is :%d", rSEO靠我eq->num1, req->num2, rsp->sum);}// 4 服务的声明rclcpp::Service<AddInt>::SharedPtr server_; };int SEO靠我main(int argc, char const *argv[]) {rclcpp::init(argc,argv);auto server_ = std::make_shared<SEO靠我CppSrvServer>();rclcpp::spin(server_);rclcpp::shutdown();return 0; }

3.3.2 配置C/C++服务通讯服务端功能包

SEO靠我置packages.xml文件,添加依赖项有rclcpp用于构建节点,和srv_demo用于构建AddInt: <?xml version="1.0"?> <?xml-SEO靠我model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001SEO靠我/XMLSchema"?> <package format="3"><name>cpp_srv_server</name><version>0.0.0</version><descriSEO靠我ption>TODO: Package description</description><maintainer email="pldz@R7000.com">pldz</maintainer><liSEO靠我cense>TODO: License declaration</license><buildtool_depend>ament_cmake</buildtool_depend><test_depenSEO靠我d>ament_lint_auto</test_depend><test_depend>ament_lint_common</test_depend><!-- 依赖rclcpp创建节点和自定义的服务功SEO靠我能包 --><depend>rclcpp</depend><depend>srv_demo</depend><export><build_type>ament_cmake</build_type></SEO靠我export> </package> 配置CMakeLists.txt: cmake_minimum_required(VERSION 3.8) SEO靠我 project(cpp_srv_server)if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")addSEO靠我_compile_options(-Wall -Wextra -Wpedantic) endif()# find dependencies find_package(aSEO靠我ment_cmake REQUIRED) # uncomment the following section in order to fill in # furtherSEO靠我 dependencies manually. # find_package(<dependency> REQUIRED)# 1. 列出依赖项的包 find_packaSEO靠我ge(rclcpp REQUIRED) find_package(srv_demo REQUIRED)# 2. 默认是已经创建了构建节点的文件配置 add_executSEO靠我able(cppSrvServerNode src/cppSrvServerNode.cpp)# 3. 默认已经包括<INSTALL_INTERFACE>的路径也不用更改 targetSEO靠我_include_directories(cppSrvServerNode PUBLIC$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>$<SEO靠我INSTALL_INTERFACE:include>) target_compile_features(cppSrvServerNode PUBLIC c_std_99 cxx_stdSEO靠我_17) # Require C99 and C++17# 4. ament工具构建节点的依赖配置 ament_target_dependencies(cppSrvServerNodeSEO靠我rclcppsrv_demo )# 5. Install配置,默认ros2 run <包名>的配置 install(TARGETS cppSrvServerNodeDESEO靠我STINATION lib/${PROJECT_NAME})if(BUILD_TESTING)find_package(ament_lint_auto REQUIRED)# the followingSEO靠我 line skips the linter which checks for copyrights# comment the line when a copyright and license isSEO靠我 added to all source filesset(ament_cmake_copyright_FOUND TRUE)# the following line skips cpplint (oSEO靠我nly works in a git repo)# comment the line when this package is in a git repo and when# a copyright SEO靠我and license is added to all source filesset(ament_cmake_cpplint_FOUND TRUE)ament_lint_auto_find_testSEO靠我_dependencies() endif()# 6. 生成包的环境 ament_package()

3.3.3 编译并运行C/C++服务通讯服务端

编译: colcon SEO靠我build --packages-select cpp_srv_server

激活环境:. install/setup.bash

运行:ros2 run cpp_srv_server cppSrvServSEO靠我erNode

pldz@pldz-pc:~/share/ROS2_DEMO/3_Chapter/code$ colcon build --packages-select cpp_srv_server SEO靠我 Starting >>> cpp_srv_server Finished <<< cpp_srv_server [20.6s] Summary: 1 package fiSEO靠我nished [21.0s] pldz@pldz-pc:~/share/ROS2_DEMO/3_Chapter/code$ . install/setup.bash pSEO靠我ldz@pldz-pc:~/share/ROS2_DEMO/3_Chapter/code$ ros2 run cpp_srv_server cppSrvServerNode [INFOSEO靠我] [1683125184.734934447] [cppSrvServerNode]: Server is starting ... ^C[INFO] [1683125186.240SEO靠我946812] [rclcpp]: signal_handler(signum=2)

3.3.4 创建C/C++服务通讯客户端功能包并编写节点文件

创建功能包,功能包名为cpp_srv_client,节点SEO靠我名称为cppSrvClientNode,依赖rclcpp和srv_demo:ros2 pkg create cpp_srv_client --build-type ament_cmake --nodeSEO靠我-name cppSrvClientNode --dependencies rclcpp srv_demo

编写客户端节点,注意在此过程中需要和 服务端的连接进行判断,以及发送的请求是否能够收到返回值的用SEO靠我法的操作

// 1. 调用自定义的服务文件 // 1.1 rclcpp和srv_demo两个功能包的头文件 #include "rclcpp/rclcpp.hpp" SEO靠我 #include "srv_demo/srv/add_int.hpp"// 1.2. 调用功能包下的自定义的服务,其中自定义的服务名已经变成了一个类名 using srvSEO靠我_demo::srv::AddInt;// 时间函数用于持续访问服务端 using namespace std::chrono_literals;// 2.定义节点类; SEO靠我 class CppSrvClient: public rclcpp::Node{public:CppSrvClient():Node("cppSrvClientNode"){// 2.1 创建客户端SEO靠我,并绑定服务通讯名称为mySrvNameclient_ = this->create_client<AddInt>("mySrvName");RCLCPP_INFO(this->get_logger(SEO靠我),"Client is starting ...");}// 2.2 等待与服务的连接bool connect_server(){while (!client_->wait_for_service(SEO靠我1s)){if (!rclcpp::ok()){RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Interrupted while waiting for the SEO靠我service. Exiting.");return false;}RCLCPP_INFO(this->get_logger(),"service not available, waiting agaSEO靠我in...");}return true;}// 2.3 客户端发送请求;rclcpp::Client<srv_demo::srv::AddInt>::FutureAndRequestId send_SEO靠我request(int32_t num1, int32_t num2){auto request = std::make_shared<AddInt::Request>();request->num1SEO靠我 = num1;request->num2 = num2;// 2.3.1 发送请求auto response = client_->async_send_request(request);returSEO靠我n response;}private:// 2.4 服务通讯客户端的声明rclcpp::Client<AddInt>::SharedPtr client_; };int main(iSEO靠我nt argc, char ** argv) {// 3. 初始化ROS2客户端rclcpp::init(argc,argv);// 3.1 创建对象指针并调用其功能;auto cppSEO靠我SrvClientNode = std::make_shared<CppSrvClient>();// 3.2 连接客户端bool flag = cppSrvClientNode->connect_sSEO靠我erver();if (!flag){RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Connect failed! ");return 0;}// 3.3 发送请SEO靠我求并等待响应auto response = cppSrvClientNode->send_request(100,200);// 3.4 节点处理响应if (rclcpp::spin_until_fuSEO靠我ture_complete(cppSrvClientNode,response) == rclcpp::FutureReturnCode::SUCCESS){RCLCPP_INFO(cppSrvCliSEO靠我entNode->get_logger(),"The response is :%d!", response.get()->sum);} else {RCLCPP_INFO(cppSrvClientNSEO靠我ode->get_logger(),"Request error");}rclcpp::shutdown();return 0; }

3.3.5 编译并运行C/C++服务通讯客户端节点

SEO靠我于在创建包的过程中已经指明了所有依赖项,不需要进行额外的配置,直接编译运行即可:colcon build --packages-select cpp_srv_client

激活环境并运行节点

3.4 使用SEO靠我Python实现ROS2服务通讯

参考内容

Writing a simple service and client (Python)

2.3.4_服务通信_Python实现_01框架搭建

3.4.1 创建PySEO靠我thon服务通讯服务端功能包并编写节点文件

创建功能包,包名为python_srv_server,节点名为pythonSrvServerNode:ros2 pkg create python_srv_sSEO靠我erver --build-type ament_python --node-name pythonSrvServerNode

配置Vscode,主要添加功能包的提示环境,编辑settings.jsonSEO靠我

{"C_Cpp.default.includePath": ["/opt/ros/humble/include/**","./install/srv_demo/include/**"],"pythoSEO靠我n.analysis.include": ["/opt/ros/humble/local/lib/python3.10/dist-packages/**","./install/srv_demo/loSEO靠我cal/lib/python3.10/dist-packages/**"] } 编写Python服务端节点文件: import rclpy SEO靠我 from rclpy.node import Node# 1. 导入包,其中的类名等于服务文件名称 from srv_demo.srv import AddInt# 2. 定义SEO靠我服务端节点 class PythonSrvServer(Node):def __init__(self):super().__init__(pythonSrvServerNode)# SEO靠我2.1 创建服务端self.srver_ = self.create_service(AddInt, mySrvName, self.addIntFunc)self.get_logger().infoSEO靠我("Server is starting ...")# 2.2 服务端的处理回调函数def addIntFunc(self, request:AddInt, response:AddInt):respSEO靠我onse.sum = request.num1 + request.num2self.get_logger().info(The request is :{} {},Response is :{}.fSEO靠我ormat(request.num1, request.num2, response.sum))return responsedef main():rclpy.init()pythonSrvServeSEO靠我rNode = PythonSrvServer()rclpy.spin(pythonSrvServerNode)rclpy.shutdown()if __name__ == __main__:mainSEO靠我()

3.4.2 配置Python服务通讯服务端功能包

配置packages.xml增加rclpy和srv_demo两个依赖项,注意Python本身是可执行文件,因此它的为<exec_depend>与C/SEO靠我C++的<depend>关键字不同: <?xml version="1.0"?> <?xml-model href="http://download.ros.org/sSEO靠我chema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <package formatSEO靠我="3"><name>python_srv_server</name><version>0.0.0</version><description>TODO: Package description</dSEO靠我escription><maintainer email="pldz@R7000.com">pldz</maintainer><license>TODO: License declaration</lSEO靠我icense><!-- 添加依赖项的包,注意是exec_depend --><exec_depend>rclpy</exec_depend><exec_depend>srv_demo</exec_deSEO靠我pend><test_depend>ament_copyright</test_depend><test_depend>ament_flake8</test_depend><test_depend>aSEO靠我ment_pep257</test_depend><test_depend>python3-pytest</test_depend><export><build_type>ament_python</SEO靠我build_type></export> </package> 配置setup.py文件,事实上,我们已经创建包的时候已经指定了节点名,其实应该是不用配置生成节点的maSEO靠我in入口的: from setuptools import setuppackage_name = python_srv_serversetup(name=package_name,vSEO靠我ersion=0.0.0,packages=[package_name],data_files=[(share/ament_index/resource_index/packages,[resourcSEO靠我e/ + package_name]),(share/ + package_name, [package.xml]),],install_requires=[setuptools],zip_safe=SEO靠我True,maintainer=pldz,maintainer_email=pldz@R7000.com,description=TODO: Package description,license=TSEO靠我ODO: License declaration,tests_require=[pytest],# 配置节点main函数入口entry_points={console_scripts: [pythonSEO靠我SrvServerNode = python_srv_server.pythonSrvServerNode:main],}, )

3.4.3 编译并运行Python服务通讯服务端功能包

SEO靠我译:colcon build --packages-select python_srv_server

激活环境:. install/setup.bash

运行节点:ros2 run python_srv_SEO靠我server pythonSrvServerNode

pldz@pldz-pc:~/share/ROS2_DEMO/3_Chapter/code$ colcon build --packages-selSEO靠我ect python_srv_server Starting >>> python_srv_server --- stderr: python_srv_server SEO靠我 /usr/lib/python3/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarningSEO靠我: setup.py install is deprecated. Use build and pip and other standards-based tools.warnings.warn( SEO靠我 --- Finished <<< python_srv_server [2.18s]Summary: 1 package finished [2.71s]1 packagSEO靠我e had stderr output: python_srv_server pldz@pldz-pc:~/share/ROS2_DEMO/3_Chapter/code$ . instSEO靠我all/setup.bash pldz@pldz-pc:~/share/ROS2_DEMO/3_Chapter/code$ ros2 run python_srv_server pytSEO靠我honSrvServerNode [INFO] [1683157866.794236460] [pythonSrvServerNode]: Server is starting ...SEO靠我

3.3.4 创建Python服务通讯客户端功能包并编写节点文件

创建Python功能包时,包名为python_srv_client,节点名为pythonSrvClientNode,直接指定依赖项rclpSEO靠我y和srv_demo:ros2 pkg create python_srv_client --build-type ament_python --node-name pythonSrvClientNoSEO靠我de --dependencies rclpy srv_demo

编写节点:主要是统一节点的订阅话题,异步接收返回的结果

import sys import rclpy fSEO靠我rom rclpy.node import Node # 1. 导入包 from srv_demo.srv import AddInt# 2.定义客户端节点 SEO靠我 class pythonSrvClient(Node):def __init__(self):# 2.1 继承node节点,节点名为pythonSrvClientNodesuper().__inSEO靠我it__(pythonSrvClientNode)# 2.2 创建客户端self.client_ = self.create_client(AddInt, mySrvName)# 2.3 等待连接seSEO靠我lf.wait_for_connect()# 3. 实现等待函数def wait_for_connect(self):while not self.client_.wait_for_service(tSEO靠我imeout_sec=1.0):self.get_logger().info(Waiting for connect ...)# 4. 实现发送请求函数def send_request(self, nSEO靠我um1, num2):request = AddInt.Request()request.num1 = num1request.num2 = num2self.future = self.clientSEO靠我_.call_async(request)def main():rclpy.init()# 5.创建客户端节点pythonSrvClientNode = pythonSrvClient()pythonSEO靠我SrvClientNode.send_request(200,300)# 6. 等待响应rclpy.spin_until_future_complete(pythonSrvClientNode,pytSEO靠我honSrvClientNode.future)try:response = pythonSrvClientNode.future.result()except Exception as e:pythSEO靠我onSrvClientNode.get_logger().info(Request error {}.format(e))else:pythonSrvClientNode.get_logger().iSEO靠我nfo(Response is {}.format(response.sum))rclpy.shutdown()if __name__ == __main__:main()

3.4.5 编译并运行PytSEO靠我hon服务通讯客户端节点

由于指定了依赖项,直接编译即可: colcon build --packages-select python_srv_client

激活环境: . install/setup.bSEO靠我ash

运行所有节点:

3.5 服务通讯小结

创建功能包时,如果能够直接指定节点名和依赖项,可以省去很大部分的配置工作 C/C++手动配置功能包时,packages.xml配置依赖项,CMakeLists.SEO靠我txt配置编译的内容,包括find_package;add_executable;target_include_directories;ament_target_dependencies;instalSEO靠我l;ament_package这六个部分 Python手动配置功能包时,packages.xml配置可执行的依赖项exec_depend而不是depend,并且在setup.py中主要配置节点的maiSEO靠我n函数入口 服务通讯的导入本质是创建一个C/C++的功能包,将里面的自定义消息编译成可以使用的.c和.py文件,值得注意的是,生成好的中间文件是存放在工作空间的install文件夹下,如果这个这个工作SEO靠我空间的install找不到或者不是一个,那是需要再进一步的手动配置的 服务通讯的请求响应是这里是异步实现的,即客户端需要等待服务端返回的结果,才能判断是否完成接收
“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2