【手把手做ROS2机器人系统开发五】使用C++实现编写简单的服务器和客户端

news2024/11/25 22:27:01

使用C++实现编写简单的服务器和客户端

目录

使用C++实现编写简单的服务器和客户端

一、程序编写

1、创建软件包

 2、编译软件包

3、软件配置

4、服务器程序编写

5、客户端程序编写

6、软件包设置

7、设置编译选项

二、程序测试

1、编译程序

2、开启节点测试运行

3、执行效果展示


        上一讲我们讲解了如何编写一个发布者和订阅者程序。本章节继续讲解程序模板,如何编写一个服务器和客户端程序。对于后续的实战开发,前期的理论教学还是少不了,请大家多多阅读。

一、程序编写

1、创建软件包

        继续将软件包创建src目录下,方便统一存放和管理。

ros2 pkg create --build-type ament_cmake cpp_srvcli --dependencies rclcpp example_interfaces

 2、编译软件包

        回到上级目录进行编译工作,注意路径。

colcon build --packages-select cpp_srvcli

3、软件配置

 软件编程环境配置,参考上一章节

【手把手做ROS2机器人系统开发三】搭建vscode编程环境

【手把手做ROS2机器人系统开发四】使用C++实现编写简单的发布者和订阅者

4、服务器程序编写

服务器代码路径:

src/cpp_srvcli/src/add_two_ints_server.cpp

实现两个数相加基本运算服务

/**
 * @file add_two_ints_server.cpp
 * @author gmotion (motion_gui@126.com)
 * @brief 发布服务器节点
 * @version 0.1
 * @date 2022-06-10
 * @copyright Copyright (c) 2022
 */

#include <memory>       //内存管理
#include <string>       //字符串

#include <rclcpp/rclcpp.hpp>
//这里使用示例中的接口,后续章节会重点讲解如何自定义专用接口
#include <example_interfaces/srv/add_two_ints.hpp>

//添加服务信息
void add(const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request>reques,
        std::shared_ptr<example_interfaces::srv::AddTwoInts::Response>response)
{
    response->sum = reques->a + reques->b;
    RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Incoming request\n a:%ld " "b: %ld",
    reques->a,reques->b);
    RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"sending back response: [%ld] ",
    (long int)response->sum);
}

//主运行程序
int main(int argc,char * argv[])
{
    rclcpp::init(argc,argv);
    //创建服务名称节点
    std::shared_ptr<rclcpp::Node>node = rclcpp::Node::make_shared("add_two_ints_server");
    //创建服务函数
    rclcpp::Service<example_interfaces::srv::AddTwoInts>::SharedPtr service=
    node->create_service<example_interfaces::srv::AddTwoInts>("add_two_ints",&add);

    RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Ready to add two ints.");
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

5、客户端程序编写

客户端代码路径:

src/cpp_srvcli/src/add_two_ints_client.cpp

实现请求服务器调用计算,测试服务器是否正确运行

/**
 * @file add_two_ints_client.cpp
 * @author gmotion (motion_gui@126.com)
 * @brief 客户端-请求服务器计算
 * @version 0.1
 * @date 2022-06-10
 * @copyright Copyright (c) 2022
 */

#include <chrono>       //处理时间类
#include <cstdlib>      //标准函数库
#include <memory>       //内存管理

#include <rclcpp/rclcpp.hpp>
#include <example_interfaces/srv/add_two_ints.hpp>

using namespace std::chrono_literals;

//主程序函数
int main(int argc,char * argv[])
{
    rclcpp::init(argc,argv);

    //参数数量发生错误
    //传入两个计算对应的数值-用于请求服务器及计算
    if(argc !=3)
    {
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"usage: add_two_ints_client X Y");
        return 1;
    }

    //建立node节点
    std::shared_ptr<rclcpp::Node>node = rclcpp::Node::make_shared("add_two_ints_client");

    //建立客户端
    rclcpp::Client<example_interfaces::srv::AddTwoInts>::SharedPtr client =
    node->create_client<example_interfaces::srv::AddTwoInts>("add_two_ints");

    //建立请求发送参数
    auto request = std::make_shared<example_interfaces::srv::AddTwoInts::Request>();
    request->a = atoll(argv[1]);
    request->b = atoll(argv[2]);

    //等待服务
    while (!client->wait_for_service(1s))
    {
        if (!rclcpp::ok())
        {
            RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"service no avaiable,wait again...");
        }
    }
    
    //发送运行请求
    auto result = client->async_send_request(request);
    //等待运行结果
    if(rclcpp::spin_until_future_complete(node,result) == rclcpp::FutureReturnCode::SUCCESS)
    {
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Sum: %ld",result.get()->sum);
    }
    else
    {
        RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"Failed to call service add_two_ints");
    }

    rclcpp::shutdown();
    return 0;
}

6、软件包设置

src/cpp_srvcli/package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>cpp_srvcli</name>
  <version>0.0.0</version>
  <description>C++ client server tutorial</description>
  <maintainer email="motion_gui@126.com">gmotion</maintainer>
  <license>Apache License 2.0</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <depend>rclcpp</depend>
  <depend>example_interfaces</depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

7、设置编译选项

src/cpp_srvcli/CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(cpp_pubsub)

# Default to C99
if(NOT CMAKE_C_STANDARD)
  set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 14)
endif()


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)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)


add_executable(talker src/publisher_member_function.cpp)
ament_target_dependencies(talker rclcpp std_msgs)

add_executable(listener src/subscriber_member_function.cpp)
ament_target_dependencies(listener rclcpp std_msgs)

install(TARGETS
  talker
  listener
  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()

二、程序测试

1、编译程序

单一软件包指定编译

colcon build --packages-select cpp_srvcli

2、开启节点测试运行

服务器终端:

. install/setup.bash
ros2 run cpp_srvcli server

客户端终端:

. install/setup.bash
ros2 run cpp_srvcli client 12 10

3、执行效果展示

         程序准确执行,达到预期结果。本节实现一个简单的服务器节点和一个客户端节点。更多精彩内容,欢迎订阅,敬请阅读下一章内容。谢谢大家的阅读。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/459197.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

verilog语言中的门级描述、行为描述及测试验证

描述D型主从触发器模块的门级结构建模&#xff1a; module flop(data, clock, clear, q, qb);input data, clock, clear; output q, qb;// 批量定义门电路 nand #10 nd1(a, data, clock, clear)&#xff0c;nd2(b, ndata, clock)&#xff0c;nd4(d, c, b, clear)&#xf…

算法刷题|1049.最后一个块石头的重量||、494.目标和、474.一和零

最后一个块石头的重量|| 题目&#xff1a;有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉…

HBase的表设计笔记

HBase的RowKey设计 HBase是三维有序存储的&#xff0c;通过rowkey&#xff08;行键&#xff09;&#xff0c;column key&#xff08;column family和qualifier&#xff09;和TimeStamp&#xff08;时间戳&#xff09;这个三个维度可以对HBase中的数据进行快速定位。 HBase中row…

中国能源网络安全大会举办,腾讯安全曹文炎分享助力能源企业安全建设的实践经验

2023年4月20日-21日&#xff0c;由中国能源研究会主办的“2023年中国能源网络安全大会”&#xff08;以下简称“大会”&#xff09;在南京召开。大会以“新形势新安全”为主题&#xff0c;围绕提升我国能源行业网络安全水平&#xff0c;增强和维护我国能源网络安全能力&#xf…

Pytorch的CNN,RNNLSTM

CNN 拿二维卷积举例&#xff0c;我们先来看参数 卷积的基本原理&#xff0c;默认你已经知道了&#xff0c;然后我们来解释pytorch的各个参数&#xff0c;以及其背后的计算过程。 首先我们先来看卷积过后图片的形状的计算&#xff1a; 参数&#xff1a; kernel_size &#xff…

【AI炼丹术】写深度学习代码的一些心得体会

写深度学习代码的一些心得体会 体会1体会2体会3总结内容来源 一般情况下&#xff0c;拿到一批数据之后&#xff0c;首先会根据任务先用领域内经典的Model作为baseline跑通&#xff0c;然后再在这个框架内加入自己设计的Model&#xff0c;微调代码以及修改一些超参数即可。总体流…

Matlab进阶绘图第18期—相关性气泡热图

相关性气泡热图是一种特殊的气泡热图。 与一般的气泡热图相比&#xff0c;其数值位于[-1 1]区间&#xff0c;其颜色用于表示正负&#xff0c;而其气泡的大小用于表示数值绝对值的大小&#xff0c;可以十分直观地对两个变量的相关性进行分析。 由于Matlab中未收录相关性气泡热…

In-Context Learning中的示例选择及效果

一. ICL的背景 大型语言模型&#xff08;LLM&#xff09;如GPT-3是在大规模的互联网文本数据上训练&#xff0c;以给定的前缀来预测生成下一个token&#xff08;Next token prediction&#xff09;。这样简单的训练目标&#xff0c;大规模数据集以及高参数量模型相结合&#x…

国内可直接使用的OpenAI DALL*E 图片AI体验站,可通过自然语言生成图片

体验站最终演示效果 国内可直接使用的图片AI体验站&#xff1a;https://zizhu888.cn/text2img/index.html ChatGPT3.5 Turbo国内体验站: https://zizhu888.cn/chatgpt/index.html OpenAI DALL*E可以通过自然语言生成图片&#xff0c;内容创作者的福音&#xff0c;大大降低了创…

基于飞桨 PaddleVideo 的骨骼行为识别模型 CTR-GCN

main.pysame_seedsparse_argsmain ensemble.pyconfigs 文件夹Joint&#xff08;J&#xff09;的配置文件ctrgcn_fsd_J_fold0.yamlctrgcn_fsd_J_fold1.yaml Joint Angle&#xff08;JA&#xff09;的配置文件ctrgcn_fsd_JA_fold0.yaml paddlevideo 文件夹utils 文件夹__init__.p…

【Python 协程详解】

0.前言 前面讲了线程和进程&#xff0c;其实python还有一个特殊的线程就是协程。 协程不是计算机提供的&#xff0c;计算机只提供&#xff1a;进程、线程。协程是人工创造的一种用户态切换的微进程&#xff0c;使用一个线程去来回切换多个进程。 为什么需要协程&#xff1f; …

中国制造再击败一家海外企业,彻底取得垄断地位

中国制造已在13个行业取得领先优势&#xff0c;凸显出中国制造的快速崛起&#xff0c;日前中国制造又在一个行业彻底击败海外同行&#xff0c;再次证明了中国制造的实力。 一、海外企业承认失败 提前LGD宣布它位于广州的8.5代液晶面板生产线停产&#xff0c;预计该项目将出售给…

crm day03 创建市场活动

页面切割 div切割&#xff0c;ifram显示 如何分割的呢&#xff0c;在主页面上打开iframe $(function(){ //页面加载时window.open("workbench/main/index.do","workareaFrame"); })注意所有在WEB-INF的页面都会收到保护&#xff0c;因此到达此目录下的页…

不得不的创建型模式-建造者模式

目录 建造者模式是什么 下面是一个简单的示例代码&#xff0c;演示了如何使用建造者模式来构建一个复杂对象&#xff1a; 面试中可能遇到的问题及回答&#xff1a; 建造者模式是什么 建造者模式是一种创建型模式&#xff0c;它的目的是将复杂对象的构造过程分离成多个简单的…

你知道项目进度控制和跟踪的目的是什么吗?

项目进度控制和跟踪的目的是&#xff1a; 增强项目进度的透明度&#xff0c;当项目进展与项目计划出现偏差时&#xff0c;可以及时采取适当的措施。 1、计划是项目监控的有效手段 项目控制的手段是根据计划对项目的各项活动进行监控&#xff0c;项目经理可以使用甘特图来制…

界面控件DevExtreme使用指南 - 折叠组件快速入门(二)

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序&#xff0c;该套件附带功能齐…

微信小程序nodejs+python+php+springboot+vue 微型整容医美挂号预约app系统

(a) 管理员&#xff1b;管理员使用本系统涉到的功能主要有首页、个人中心、用户管理、体检预约管理、项目预约、系统管理等功能 (b) 用户&#xff1b;用户进入app可以实现首页、美容产品、我的等&#xff0c;在我的页面可以对在线预约、体检预约、项目预约等功能进行操作 本基于…

Unity之OpenXR+XR Interaction Toolkit实现 UI交互

一.前言 在VR中我们经常会和一些3D的UI进行交互&#xff0c;今天我们就来说一下如何实现OpenXRXRInteraction Toolkit和UI的交互。 二.准备工作 有了前两篇的配置介绍,我们就不在详细说明这些了&#xff0c;大家自行复习 Unity之OpenXRXR Interaction Toolkit接入Pico VR一体…

钉钉用一条斜杠,金山系用一张表格,做了华为一直想做的事

阿里的“新钉钉”又一次站在风口上 一场疫情导致数万企业停工的同时&#xff0c;却让阿里的钉钉、腾讯会议&#xff0c;还有字节跳动的飞书等在线协同办公产品火得一塌糊涂。 今天&#xff0c;OpenAI公司的一个chatGPT,让阿里、百度等各大互联网巨头扎堆发布大模型产品。 回顾…

如何在Web上实现激光点云数据在线浏览和展示?

无人机激光雷达测量是一项综合性较强的应用系统&#xff0c;具有数据精度高、层次细节丰富、全天候作业等优势&#xff0c;能够精确测量三维现实世界&#xff0c;为各个行业提供了丰富有效的数据信息。但无人机激光雷达测量产生的点云数据需要占用大量的存储空间&#xff0c;甚…