html个人网站策划书,温州华侨职业中等专业学校,wordpress实现网站勋章功能,app制作哪里正规一、服务服务可以实现类似你问我答的同步通信效果#xff0c;此时可以在需要某个数据的时候#xff0c;发一个查询的请求#xff0c;然后尽快得到目标的最新位置#xff0c;这样的通信模型和话题单向传输有所不同#xff0c;变成了发送一个请求#xff0c;反馈一个应答的…一、服务服务可以实现类似你问我答的同步通信效果此时可以在需要某个数据的时候发一个查询的请求然后尽快得到目标的最新位置这样的通信模型和话题单向传输有所不同变成了发送一个请求反馈一个应答的形式这种通信机制在ROS中成为服务Service。二、服务模型1、客户端/服务器模型发送请求和反馈应答从服务的实现机制上来看这种你问我答的形式叫做客户端/服务器模型简称为CS模型客户端在需要某些数据的时候针对某个具体的服务发送请求信息服务器端收到请求之后就会进行处理并反馈应答信息。浏览器的应用场景这种通信机制在生活中也很常见比如我们经常浏览的各种网页此时你的电脑浏览器就是客户端通过域名或者各种操作向网站服务器发送请求服务器收到之后返回需要展现的页面数据。图1 服务的发送和应答三、同步通信这个过程一般要求越快越好假设服务器半天没有反应你的浏览器一直转圈圈那有可能是服务器宕机了或者是网络不好所以相比话题通信在服务通信中客户端可以通过接收到的应答信息判断服务器端的状态我们也称之为同步通信。四、一对多通信在服务通信中服务器端是唯一而客户端可以不唯一比如古月居这个网站服务器是唯一存在的并没有多个完全一样的古月居网站但是可以访问古月居网站的客户端是不唯一的大家每一个人都可以看到同样的界面。所以服务通信模型中服务器端唯一但客户端可以不唯一。图2 一个服务器和多个客户端五、服务接口和话题通信类似服务通信的核心还是要传递数据数据变成了两个部分一个请求的数据比如请求苹果位置的命令还有一个反馈的数据比如反馈苹果坐标位置的数据这些数据和话题消息一样在ROS中也是要标准定义的话题使用.msg文件定义服务使用的是.srv文件定义。六、案例图3 功能包内部结构1、创建服务接口的功能包进入工作空间study_ws中src路径下cd ~/study_ws/src创建功能包demo_interfaceros2 pkg create --build-type ament_cmake demo_interface进入功能包路径下创建srv目录①cd ./demo_interface ②mkdir srv创建srv文件AddTwoInts.srvtouch AddTwoInts.srv对AddTwoInts.srv写入内容cat srv/AddTwoInts.srv EOF int64 a int64 b --- int64 sum EOF工作原理cat 文件名 - 开始创建文件 EOF - 表示接下来的内容直到遇到EOF为止都写入文件 中间的内容 - 实际要写入文件的内容 最后的EOF - 结束标记告诉系统内容写完了可以用任何词代替EOF2、功能包demo_interface的文件AddTwoInts.srv:int64 a int64 b --- int64 sumCMakeLists.txtcmake_minimum_required(VERSION 3.8) project(demo_interface) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES Clang) add_compile_options(-Wall -Wextra -Wpedantic) endif() # find dependencies # 查找必要的依赖 find_package(ament_cmake REQUIRED) find_package(rosidl_default_generators REQUIRED) # uncomment the following section in order to fill in # further dependencies manually. # find_package(dependency REQUIRED) # 声明服务文件 set(srv_files srv/AddTwoInts.srv ) # 生成接口代码 rosidl_generate_interfaces(${PROJECT_NAME} ${srv_files} DEPENDENCIES ) # 导出依赖 ament_export_dependencies(rosidl_default_runtime) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) # the following line skips the linter which checks for copyrights # comment the line when a copyright and license is added to all source files set(ament_cmake_copyright_FOUND TRUE) # the following line skips cpplint (only works in a git repo) # comment the line when this package is in a git repo and when # a copyright and license is added to all source files set(ament_cmake_cpplint_FOUND TRUE) ament_lint_auto_find_test_dependencies() endif() ament_package()package.xml?xml version1.0? ?xml-model hrefhttp://download.ros.org/schema/package_format3.xsd schematypenshttp://www.w3.org/2001/XMLSchema? package format3 namedemo_interface/name version0.0.0/version descriptionTODO: Package description/description maintainer emailseantodo.todosean/maintainer licenseTODO: License declaration/license buildtool_dependament_cmake/buildtool_depend !-- 添加必要的依赖 -- build_dependrosidl_default_generators/build_depend exec_dependrosidl_default_runtime/exec_depend !-- 声明这是一个接口包关键 -- member_of_grouprosidl_interface_packages/member_of_group test_dependament_lint_auto/test_depend test_dependament_lint_common/test_depend export build_typeament_cmake/build_type /export /package3、功能包learning_pkg_c的文件add_two_ints_server.cpp/** * file add_two_ints_server.cpp * brief ROS2服务示例-提供两个整数相加的服务器处理功能 * author */ #include memory #include rclcpp/rclcpp.hpp #include demo_interface/srv/add_two_ints.hpp using namespace std::placeholders; class AddServer : public rclcpp::Node { public: AddServer(const std::string node_name) : Node(node_name) { RCLCPP_INFO(this-get_logger(), %s节点启动欢迎使用双数据过滤器, node_name.c_str()); // 创建服务器对象服务接口类型、服务名、服务器回调函数 srv_ this-create_servicedemo_interface::srv::AddTwoInts( add_two_int, std::bind(AddServer::adder_callback, this, _1, _2)); } private: // 服务回调函数 void adder_callback( const std::shared_ptrdemo_interface::srv::AddTwoInts::Request request, std::shared_ptrdemo_interface::srv::AddTwoInts::Response response) { // 完成加法求和计算将结果放到反馈的数据中 response-sum request-a request-b; // 输出日志信息提示已经完成加法求和计算 RCLCPP_INFO(this-get_logger(), Incoming request: %ld b: %ld, request-a, request-b); } rclcpp::Servicedemo_interface::srv::AddTwoInts::SharedPtr srv_; }; int main(int argc, char* argv[]) { // ROS2 C接口初始化 rclcpp::init(argc, argv); // 创建ROS2节点对象并进行初始化 auto node std::make_sharedAddServer(add2Ints_server_node); // 循环等待ROS2退出 rclcpp::spin(node); // 销毁节点对象 rclcpp::shutdown(); return 0; }add_two_ints_client.cpp/** * file add_two_ints_client.cpp * brief ROS2服务示例-发送两个加数请求加法器计算 */ #include chrono #include memory #include iostream #include rclcpp/rclcpp.hpp #include demo_interface/srv/add_two_ints.hpp using namespace std::chrono_literals; class AddClient : public rclcpp::Node { public: AddClient(const std::string name) : Node(name) { // 创建服务客户端对象服务接口类型服务名 client_ this-create_clientdemo_interface::srv::AddTwoInts(add_two_int); // 创建服务请求的数据对象 request_ std::make_shareddemo_interface::srv::AddTwoInts::Request(); } // 发送服务请求 void send_request(int a, int b) { request_-a a; request_-b b; // 循环等待服务器端成功启动 while (!client_-wait_for_service(1s)) { RCLCPP_WARN(this-get_logger(), 服务器不可用等待中...); } // 异步方式发送服务请求并绑定回调函数 auto future_result client_-async_send_request( request_, std::bind(AddClient::request_result_callback, this, std::placeholders::_1)); } private: // 请求结果接收回调函数 void request_result_callback(rclcpp::Clientdemo_interface::srv::AddTwoInts::SharedFuture future) { auto response future.get(); // 将收到的反馈信息打印输出 RCLCPP_INFO(this-get_logger(), Result of add_two_int: %ld %ld %ld, request_-a, request_-b, response-sum); // 销毁节点对象并关闭 rclcpp::shutdown(); } rclcpp::Clientdemo_interface::srv::AddTwoInts::SharedPtr client_; std::shared_ptrdemo_interface::srv::AddTwoInts::Request request_; }; int main(int argc, char* argv[]) { // 检查命令行参数 if (argc ! 3) { std::cerr 使用方法: argv[0] 数字A 数字B std::endl; return 1; } // ROS2 C接口初始化 rclcpp::init(argc, argv); // 创建ROS2节点对象并进行初始化 auto node std::make_sharedAddClient(add2Ints_client_node); // 解析命令行参数并发送服务请求 int a std::atoi(argv[1]); int b std::atoi(argv[2]); node-send_request(a, b); // 循环等待回调完成 rclcpp::spin(node); return 0; }CMakeLists.txtcmake_minimum_required(VERSION 3.8) project(learning_pkg_c) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES Clang) add_compile_options(-Wall -Wextra -Wpedantic) endif() # 查找依赖包 find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(demo_interface REQUIRED) # 编译服务端节点 add_executable(add_server src/add_two_ints_server.cpp) ament_target_dependencies(add_server rclcpp demo_interface) # 编译客户端节点 add_executable(add_client src/add_two_ints_client.cpp) ament_target_dependencies(add_client rclcpp demo_interface) # 安装可执行文件 - 使用 ${PROJECT_NAME} 而不是 ${learning_pkg_c} install(TARGETS add_server add_client DESTINATION lib/${PROJECT_NAME}) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) # the following line skips the linter which checks for copyrights # comment the line when a copyright and license is added to all source files set(ament_cmake_copyright_FOUND TRUE) # the following line skips cpplint (only works in a git repo) # comment the line when this package is in a git repo and when # a copyright and license is added to all source files set(ament_cmake_cpplint_FOUND TRUE) ament_lint_auto_find_test_dependencies() endif() ament_package()package.xml?xml version1.0? ?xml-model hrefhttp://download.ros.org/schema/package_format3.xsd schematypenshttp://www.w3.org/2001/XMLSchema? package format3 namelearning_pkg_c/name version0.0.0/version descriptionTODO: Package description/description maintainer emailseantodo.todosean/maintainer licenseTODO: License declaration/license buildtool_dependament_cmake/buildtool_depend dependrclcpp/depend dependdemo_interface/depend test_dependament_lint_auto/test_depend test_dependament_lint_common/test_depend export build_typeament_cmake/build_type /export /package4、编译所有功能包并运行切换路径到工作空间根目录下cd ~/study_ws可以先编译单个功能包检查接口包是否安装成功单个功能包的编译命令colcon build --packages-select 功能包名colcon build --packages-select demo_interfaceros2 interface package demo_interface编译创建的功能包colcon build设置环境变量source install/local_setup.sh5、运行结果图4 服务端图5 客户端七、服务命令的常用操作查看服务列表ros2 service list查看服务数据类型ros2 service type service_name发送服务请求ros2 service call service_name service_type service_data