当前位置: 首页 > news >正文

ROS学习之服务通信

根据b站赵老师的视频进行学习,下面给出代码

服务通信,可以用于两个无人车之间的通信。

(补充:动作通信可用于雷达之间的持续通信。

在客户端给出两个数 在服务端输出两个数之和

在前面的准备工作(如,创建工作空间,创建功能包等不再一一给出,详细请参考这一

ROS中话题通信之C++实现-CSDN博客

关于C++的服务端:

#include "rclcpp/rclcpp.hpp"
#include "base_interfaces/srv/addints.hpp"//using namespace std::chrono_literals;
using base_interfaces::srv::Addints;
using std::placeholders::_1;
using std::placeholders::_2;class AddintsServer: public rclcpp::Node{
public:AddintsServer():Node("add_ints_server_node_cpp"){RCLCPP_INFO(this->get_logger(),"server create!");server_ = this->create_service<Addints>("add_ints",std::bind(&AddintsServer::add,this,_1,_2));//创建服务端// use: ros2 topic echo /chatter 检测接收方 是否接受到//timer_ = this->create_wall_timer(1s,std::bind(&AddintsServer::on_timer,this));}
private:
//创建回调函数void add(const Addints::Request::SharedPtr req, const Addints::Response::SharedPtr res){res->sum = req->num1 + req->num2;RCLCPP_INFO(this->get_logger(),"%d + %d = %d",req->num1,req->num2,res->sum);}rclcpp::Service<Addints>::SharedPtr server_;//rclcpp::TimerBase::SharedPtr timer_;//size_t count;
};
int main(int argc, char ** argv)
{rclcpp::init(argc,argv);rclcpp::spin(std::make_shared<AddintsServer>());rclcpp::shutdown();return 0;
}

关于C++的客户端:

// listen 订阅发布的消息 并且在终端输出
// 1、包含头文件 2、初始化客户端 3、自定义节点类 4、调用spin函数 并且传入节点指针 5、支援释放
// 3.1、创建订约方 3、2 解释并且输出数据
#include "rclcpp/rclcpp.hpp"
#include "base_interfaces/srv/addints.hpp"using base_interfaces::srv::Addints;
using namespace std::chrono_literals;
class AddintsClient: public rclcpp::Node{
public:AddintsClient():Node("add_ints_client_node_cpp"){RCLCPP_INFO(this->get_logger(),"client create!");//subscription_ = this->create_subscription<std_msgs::msg::String>("chatter",10,std::bind(&AddintsClient::do_cb,this,std::placeholders::_1));client_ = this->create_client<Addints>("add_ints");}bool connect_server(){// 在1s内 连接服务器 链接上返回true 否着 False//client_->wait_for_service(1s);while (!client_->wait_for_service(1s)){if (!rclcpp::ok())// 针对crtl+c 的特殊处理{RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Connect false in force...");return false;/* code */}RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Connecting...");/* code */}return true;}rclcpp::Client<Addints>::FutureAndRequestId send_request(int num1,int num2){auto request = std::make_shared<Addints::Request>();request->num1 = num1;request->num2 = num2;return client_->async_send_request(request);}
private:rclcpp::Client<Addints>::SharedPtr client_;//rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};
int main(int argc, char const *argv[])
{if(argc != 3){RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"give:num1 and num2");return 1;}rclcpp::init(argc,argv);//rclcpp::spin(std::make_shared<AddintsClient>());auto client = std::make_shared<AddintsClient>();bool flag = client->connect_server();if (!flag){RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"false connect!");return 0;/* code */}auto future = client->send_request(atoi(argv[1]),atoi(argv[2]));if (rclcpp::spin_until_future_complete(client,future) == rclcpp::FutureReturnCode::SUCCESS){/* code */RCLCPP_INFO(client->get_logger(),"success!sum = %d",future.get()->sum);}else{RCLCPP_INFO(client->get_logger(),"False");}rclcpp::shutdown();/* code */return 0;
}

相关的Cmakelist修改:

cmake_minimum_required(VERSION 3.8)
project(cpp02_service)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(rclcpp REQUIRED)
find_package(base_interfaces REQUIRED)add_executable(demo01_server src/demo01_server.cpp)
add_executable(demo02_client src/demo02_client.cpp)
target_include_directories(demo01_server PUBLIC$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>$<INSTALL_INTERFACE:include>)
target_compile_features(demo01_server PUBLIC c_std_99 cxx_std_17)  # Require C99 and C++17
ament_target_dependencies(demo01_server"rclcpp""base_interfaces"
)ament_target_dependencies(demo02_client"rclcpp""base_interfaces"
)install(TARGETS demo01_serverDESTINATION lib/${PROJECT_NAME})install(TARGETS demo02_clientDESTINATION 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 filesset(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 filesset(ament_cmake_cpplint_FOUND TRUE)ament_lint_auto_find_test_dependencies()
endif()ament_package()

结果如下:

下面给出Python相关代码:

import rclpy
from rclpy.node import Node
from base_interfaces.srv import Addintsclass Addintsserver(Node):def __init__(self):super().__init__("add_ints_server_node_py")self.get_logger().info("server create!(py)")self.server = self.create_service(Addints,"add_ints",self.add)def add(self,request,response):response.sum = request.num1 + request.num2self.get_logger().info("%d + %d = %d" % (request.num1,request.num2,response.sum))return responsedef main():rclpy.init()rclpy.spin(Addintsserver())rclpy.shutdown()if __name__ == '__main__':main()

客户端:

import rclpy
import sys
from rclpy.logging import get_logger
from rclpy.node import Node
from base_interfaces.srv import Addintsclass Addintsclient(Node):def __init__(self):super().__init__("add_ints_client_node_py")self.get_logger().info("client create!(py)")self.client = self.create_client(Addints,"add_ints")while not self.client.wait_for_service(1.0):self.get_logger().info("COnnetcing...")def send_request(self):request = Addints.Request()request.num1 = int(sys.argv[1])request.num2 = int(sys.argv[2])self.future = self.client.call_async(request)def main():if len(sys.argv) != 3:get_logger("rclpy").info("Need two nums")returnrclpy.init()client = Addintsclient()client.send_request()rclpy.spin_until_future_complete(client,client.future)try:response = client.future.result()client.get_logger().info("result: sum = %d" % response.sum)except Exception:client.get_logger().error("client fail")rclpy.shutdown()if __name__ == '__main__':main()

需要对setup.py进行修改:

from setuptools import find_packages, setuppackage_name = 'py02_service'setup(name=package_name,version='0.0.0',packages=find_packages(exclude=['test']),data_files=[('share/ament_index/resource_index/packages',['resource/' + package_name]),('share/' + package_name, ['package.xml']),],install_requires=['setuptools'],zip_safe=True,maintainer='xwh',maintainer_email='xwh@todo.todo',description='TODO: Package description',license='TODO: License declaration',tests_require=['pytest'],entry_points={'console_scripts': ['demo01_server_py = py02_service.demo01_server_py:main','demo02_client_py = py02_service.demo02_client_py:main'],},
)

运行后的结果,与C++的相同。

本篇与ROS学习之动作通信-CSDN博客这一篇是一起学习的,上传的程序代码包含了话题、服务、动作通信。

相关文章:

  • Android11 Settings详解
  • 【统计术语】
  • Dart 类型系统与 GetX 类型写法完整指南
  • yarn create vite报错:文件名、目录名或卷标语法不正确。 error Command failed.
  • 【嵌入式】鲁班猫玩法大全
  • E结构体基础.go
  • 01.线性代数是如何将复杂的数据结构转化为可计算的数学问题,这个过程是如何进行的
  • FPGA基础 -- Verilog 结构建模之端口的不同位宽处理机制
  • flink如何基于Pekko实现RPC调用
  • openKylin适配RISC-V高性能服务器芯片,携手睿思芯科共拓智算新蓝海
  • ROS学习之动作通信
  • LangChain4j入门学习项目
  • 解决Vue再浏览器的控制台中更新属性不生效
  • Zephyr boot
  • 电池自动点焊机:技术革新下的电池制造核心引擎
  • FastMCP框架进行MCP开发:(一)基础环境搭建及测试
  • 新生活的开启:从 Trae AI 离开后的三个月
  • 如何在 Windows 上实时显示键盘操作?
  • C++ 面向对象特性详解:继承机制
  • Oracle EBS R12.1.3无法打开WEBADI界面
  • c网站开发源代码/百度网盘app下载
  • 大型网站开发方案/免费产品推广软件
  • 在线制作网站系统/自媒体135免费版下载
  • 石家庄商城网站搭建多少钱/站长数据
  • 上虞市建设风机厂网站/seo优化排名
  • 做同城信息网站怎么赚钱/互联网推广运营是干什么的