本知识点将用一个实例(服务端处理客户端提交的两个数字求和,然后返回处理结果)来理解 服务通信的基本使用,大致分为三块:

1.自定义消息*.srv的编写()

2.服务端编写

3.客户端编写

一.首先创建一个工作空间和软件包

创建工作空间


mkdir -p ~/catkin_ws_srv_self/srccd catkin_ws_srv_selfcatkin_make

创建软件包

cd srccatkin_create_pkg server_client std_msg rospy roscpp

二.自定义消息*.srv的编写——srv编写其实与前面说的话题通信步骤一样,只不过改成了srv自己的东西。

(PS:这里可以完全参考ros wki上面的教程,消息创建部分,照搬就可以)

2.1编写srv文件

方式一:在终端中创建msg

cd ~/catkin_ws_srv_self/src/server_clientmkdir msggedit sum_ints.srv

在打开的文本,然后输入如下自己定义的信息(像结构体一样编写就行):

int32 num1
int32 num2
---
int32 sum

方式二:在vscode中创建srv

在终端中输入:

cd ~/catkin_ws_srv_selfcode .

这样就打开了vscode编辑器,在~/catkin_ws_srv_self/src/plumbing_server_client/目录下,创建一个srv文件夹,在srv文件下,创建一个sum_ints.srv文件,在输入自己定义的信息:

int32 num1
int32 num2
---
int32 sum

最终效果如下:

以上两种方式实现效果一样,但是显然vscode的交互界面舒服。

2.2编辑配置文件(简记:231——package.xml改动两项,CMakeLists.txt改动三项,放开注释一项)

2.2.1首先在package.xml中添加编译依赖与执行依赖

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

2.2.2然后在CMakeLists.txt编辑srv相关配置

# 不要直接复制这一大段,只需将message_generation加在括号闭合前即可
find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation
)
#执行时依赖
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo02_talker_listenerCATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)
#配置srv的源文件
add_service_files(FILESnum_sum.srv//这里放你自己定义的消息文件名
)
# 生成消息时依赖于 std_msgs
generate_messages(DEPENDENCIESstd_msgs
)

好了,至此已经自定义消息配置完了。但是还没完,编译完了之后,还需要继续配置环境。

2.3编译

编译之后,会产生一些中间文件(后续调用相关 msg 时,是从这些中间文件调用的),但我只关注头文件在创建的工作空间的开发空间下 include的文件夹里 即(~/catkin_ws_example/devel/inlcude下)。

因为这是自己定义的消息,所以现在需要做的是,把这个头文件包含进本工作空间的路径里面(在c_cpp_properties.json 里的 includepath属性引入,这样可以避免的是 在用vscode开发时,引入 自定义消息头文件,不会出现误报错误和代码无法补齐的情况)

PS:如何快速的得到这个头文件的路径呢?——这个路径可以鼠标放在include上,然后右击鼠标打开终端,输入pwd可得

引入的框架大致如下:

{"configurations": [{"browse": {"databaseFilename": "","limitSymbolsToIncludedHeaders": true},"includePath": ["/opt/ros/noetic/include/**","/usr/include/**","/xxx/yyy工作空间/devel/include/**" //配置 head 文件的路径 ],"name": "ROS","intelliSenseMode": "gcc-x64","compilerPath": "/usr/bin/gcc","cStandard": "c11","cppStandard": "c++17"}],"version": 4
}

在本例中,引入图为:

最后面 ~/include/**的意思是,引入inlcude文件夹下的所有头文件。

至此,自定义消息部分,已经配置完成。

总结一下,做了哪些事?编写:

自定义消息

然后配置package.xml,CMakeLists.txt

引入头文件

三.服务端编写

3.1在~/catkin_ws_srv_self/src/server_client/src文件夹下创建一个*.cpp文件(本例为 server.cpp),然后放如下代码:

#include<ros/ros.h>
#include "plumbing_server_client/sum_ints.h"/*
服务端实现:解析客户端提交的数据,并运算在产生结果1.包含头文件2. 初始化ros节点3.创建句柄4.创建句柄对象(服务对象)5.处理请求并产生响应spin()
*///5.处理请求并产生响应
bool add(plumbing_server_client::sum_ints::Request &request,plumbing_server_client::sum_ints::Response &response)
{/*操作主要有两步*///1.处理请求int num1 = request.num1;/*问题:这里为什么用的是.   而不是->呢? ——因为函数形参列表不是以指针方式引用的,拿到的是引用,而不是指针,进一步的描述,这里的request和response不是指针,没有用ConstPtr来接收,而是对象。*/int num2 = request.num2;ROS_INFO("收到的请求数据:num2 = %d,num2 = %d",num1,num2);//ROS_INFO(" 收到的数据: num1= %d,num2=%d",request.num1,request.num2);//以上三条消息,可以融合成一条打印,只是多了中间变量接收一下而已//2.处理响应int  sum = num1+num2;response.sum = sum;//response.sum = request.num1+request.num2;//以上两条信息,也可以融合成一条打印,只是多了一个中间变量接收而已ROS_INFO("求和结果:%d",sum);// ROS_INFO("求和结果:%d",response.sum);//说明返回response.sum和sum中间变量都可以return true;
}int main(int argc, char  *argv[])
{setlocale(LC_ALL,"");//日志输出,如果用中文的话,不要忘了这一句。//  2. 初始化ros节点ros::init(argc,argv,"server");//3.创建句柄ros::NodeHandle nh ;//4.创建句柄对象(服务对象)ros::ServiceServer server = nh.advertiseService("add_two_ints",add) ;/*第二个参数就是回调函数,处理请求的,只要是关于有回调函数的就不用写模板函数,他会自己推导然后填写的
回调函数返回的是 布尔类型的,因为这个处理结果请求,可能性有两个,成功或失败*/ROS_INFO("服务器端启动了!");ros::spin();return 0;
}

3.2配置CMakeLists.txt(需要修改三个地方,都是找到对应的地方,然后复制注释下来,修改需要改的部分即可)

第二句放的位置 有坑的说明,已经在发布的 话题通信之自定义消息 里已经说明了。

OK~发布方已经编写好了,接下来就可以编译测试了(这个模块写好了,先测试没有问题在写其他模块)。

3.3编译测试

3.3.1

方式一(终端编译方式):

cd ~/catkin_ws_srv_selfcatkin_make

方式二(vscode的快捷键编译方式):

在vscode中,shift+ctrl+B

3.3.2运行发布者节点(前提是已经运行了 roscore)

打开一个新的终端:

roscore

另开一个终端:

cd ~/catkin_ws_srv_selfsoure devel/setup.bashrosrun server_client server​

到这一步之后,就运行成功了,服务端已经挂起了,但是在终端看不到什么反应,但是我们可以用内置指令,在终端上提交数字让服务端计算并把结果打印出来到终端来看结果,如:

另开一个终端:输入rosservice list 可以查看当前挂起的服务(发现/two_sum为我们所需的服务),然后输入rosservice  -h可以查看rosservice有什么功能(指令忘记了,可以走这一步),然后输入rosservice call /two_sum "num1:[自己随便输入数字,如1] num2:[自己随便输入数字,如2]"

(这一串指令这么长,怎么记得住?——小技巧:可以输入到rosservice call /two_sum 然后多按几次tab键盘,就能自动补齐后面的东西,PS:后面可以自己输入的数字,其实就是自己写的服务端所做的事情。)

结果如图:

验证成功~

总结一下干了哪些事?

编写*.cpp文件

配置CMakeLists.txt

四.客户端编写

以固定方式(即程序运行前,数字已经固定死)提交:

4.1在~/catkin_ws_srv_self/src/server_client/src文件夹下创建一个*.cpp文件(本例为 client.cpp),然后放如下代码:

#include<ros/ros.h>
#include "server_client/num_sum.h"/*
客户端:提交两个整数,并处理响应的结果。1.包含头文件;2.初始化ros节点3.创建节点句柄4.创建一个客户端对象5.提交请求并处理响应
*/int main(int argc, char  *argv[])
{setlocale(LC_ALL,"");//2.初始化ros节点ros::init(argc,argv,"client");// 3.创建节点句柄ros::NodeHandle nh;//4.创建一个客户端对象ros::ServiceClient client = nh.serviceClient<server_client::num_sum>("two_sum");//serviceClient有三个重载,意思是可以 形参输入有三种样式,这里使用第二个重载,有范型的那一个,范型可以就是自己创建的那个服务消息srv(具体解释可看视频第67个4min10s)//5.提交请求并处理响应(主逻辑实现)server_client::num_sum srv;//5.1 组织请求srv.request.num1 = 1;srv.request.num2 = 2;//5.2 处理响应bool flag = client.call(srv); //返回值是一个布尔类型的,提交完之后,是有返回结果的,所以可以用一个bool值接收一下。如果是true就正常处理,false就是处理失败了。并且响应的结果(比如这里的sum),也封装进了这个srv对象(在这个srv对象中,有request还有response这两个属性)。if(flag){ROS_INFO("响应成功!");//获取结果ROS_INFO("处理结果 = %d" ,srv.response);}else{ROS_INFO("响应失败...");}ros::spin();return 0;
}

4. 2配置CMakeLists.txt(需要修改三个地方,都是找到对应的地方,然后复制注释下来,修改需要改的部分即可,改的方法与发布方一样,因此这里只放了最终效果图即可,用红笔标出改了哪些部分)

shift+ctrl+B编译(或者用终端方式的编译,上面3.3.1写过了)通过,好了。可以联合调试了。

总结一下干了哪些事?

编写*.cpp文件

配置CMakeLists.xtxt

五.联合调试

5.1 编译(不会编译的见3.1)

5.2运行roscore

5.3运行服务端节点

新开一个终端:

cd ~/catkin_ws_srv_selfsoure devel/setup.bashrosrun server_client server

5.4运行客户端节点

新开一个终端:

cd ~/catkin_ws_srv_selfsoure devel/setup.bashrosrun server_client client

最后效果如图所示:

OK~完成,结束~

--------------------------------------------------------分割线--------------------------------------------------------

这里值得一提的是(主要体会思想动态提交的思想,可以从终端输入数据,然后从mian函数入口进到程序里面):上面第四部分,写了一个以固定方式(即程序运行前,数字已经固定死)提交,这里优化客户端的编写,以动态的方式提交(就是灵活的填写两个数字,都可以实现求解)

可以在client.cpp文件中,放如下代码:

//优化客户端,实现参数的动态提交
//1.终端输入格式:rosrun xxxx(包名) xxxx(节点名)  1 2
//2.节点执行时,需要获取命令中的参数,然后数据放入requerst中
#include<ros/ros.h>
#include "server_client/num_sum.h"int main(int argc, char  *argv[])
{setlocale(LC_ALL,"");//优化实现,获取命令中的参数/*此时argc 应该等于3(节点文件名,两个参数,所以是三个),*argv指针数组应该也是3,并且argv[0]为客户端文件名,argv[1]为终端传进来的第一个数,如1,,argv[2]为传进来的第二个数,如2*/if(argc != 3){ROS_INFO("输入个数不对...");return 1;}ros::init(argc,argv,"client");ros::NodeHandle nh;ros::ServiceClient client = nh.serviceClient<server_client::num_sum>("two_sum");server_client::num_sum srv;srv.request.num1 = atoi(argv[1]);srv.request.num2 = atoi(argv[2]);bool flag = client.call(srv);if(flag){ROS_INFO("求和结果为:%d",srv.response.sum);}else{ROS_INFO("响应失败...");return 1;}//return 0;ros::spin();//经过测试,程序运行到这里,会回调(因为终端就停在那了,并没有结束,继续给输入命令,需要按ctrl+c才能结束)。然后就不经过 return 0了。  ( return 0为正常停止,return 1为非正常停止的意思。)return 0;
}

然后就可以开始调试了。

1. 编译(不会编译的见3.1)

2。运行roscore

3运行服务端节点

新开一个终端:

cd ~/catkin_ws_srv_selfsoure devel/setup.bashrosrun server_client server

4。运行客户端节点

新开一个终端:

cd ~/catkin_ws_srv_selfsoure devel/setup.bashrosrun server_client client

最后效果如图所示(如图演示了 两组动态提交数据,分别是 1和2 ,5和10):

OK~完成,结束~

我的ROS学习之路——服务通信相关推荐

  1. ROS学习笔记-多机器人通信(1)-实现两台机器通信

    ROS是一个分布式的计算环境.一个正在运行的ROS可以在多个机器人之间分布成几十甚至上百个节点.取决于系统的配置方式,任何节点可能需要随时与任何其他节点进行通信,为实现使用同一个master控制多台机 ...

  2. ROS学习小笔记(Topic通信 ,service通信,参数服务器)

    (菜鸡整理的学习笔记,原文链接已经挂上,不小心过来的朋友建议去博主那边学习,谢谢) 原文链接:https://blog.csdn.net/LoongEmbedded/article/details/1 ...

  3. ros学习笔记_服务通讯

    学习地址 0.话题通讯理论模型 前言: 话题通信基本操作(C++) 注:启动roscore的时候rosmaster已经启动了,因此ROS master 不需要实现,而连接的建立也已经被封装了(因此连接 ...

  4. ROS学习之路的整理

    ROS是基于linux系统的一个次级操作系统,目前被看做是机器人界的一套标准平台,可以类比手机的安卓操作系统或者是电脑的windows操作系统.ROS最大的优点在于灵活.低耦合.分布式.开源以及功能强 ...

  5. 我的ROS学习之路——动起来的小海龟

    a.让小海龟出现的两个步骤: 1.roscore2.rosrun turtlesim turtlesim_node b.让小海龟动起来的三个方法(当前学习): 1.键盘控制,命令行输入: rosrun ...

  6. 《ROS学习之路(1)》ROS Kinetic版本安装---ubuntu16.04(Xenial Xerus 好客的非洲地松鼠)

    一.ubuntu16.04换国内软件源 https://blog.csdn.net/qq_40584960/article/details/104298468 二.按照官方教程来安装(ros源也用国内 ...

  7. ros和java通讯_ROS学习之路(二)——通信架构(上)

    1. master&&node mater中文名又称为节点管理器,作为管家管理所需要的进程,其作用有两个: 每个node启动时都要向master注册. 管理node之间的通信. nod ...

  8. ROS学习:创建机器人的urdf

    ROS学习之路08:创建机器人的urdf(xacro)模型并通过rviz可视化_Hi, Robotics-CSDN博客_urdf可视化 1 创建工作空间 mkdir -p ~/catkin_ws/sr ...

  9. 周末ROS学习沙龙第三期——launch文件、自定义服务通信、控制机器人移动、传感器数据处理

    非博主原创,出于方便学习的目的,将周末ROS学习沙龙www.corvin.cn的课堂讲义PPT整理在这(老师讲得超棒!),无任何盈利目的,若有侵权则删除. Ros小课堂链接:https://space ...

  10. ROS学习笔记(八): ROS通信架构

    ROS学习笔记(八): ROS通信架构 文章目录 01 Node & Master 1.1 Node 1.2 Master 1.3 启动master和node 1.4 rosrun和rosno ...

最新文章

  1. ## *将以下学生成绩数据,存放在Hdfs上,使用Spark读取完成下面分析**
  2. linux下防DDOS***软件及使用方法详解
  3. androidstudio表格中填充 宽跟长一样_Excel表格的基本操作教程,覆盖表格制作的10大知识!...
  4. 两个学习英语的好软件
  5. Easy Tech:什么是I帧、P帧和B帧?
  6. highcharts 怎么去掉鼠标悬停效果_练瑜伽减肥没效果什么原因?
  7. 摘抄自知乎的redis相关
  8. python学习随笔day3
  9. C/C++ OpenCV五种滤波器综合示例
  10. SQL Server -- 如何书写优雅、漂亮的SQL脚本?
  11. matlab 符号表,MATLAB——matlab特殊符号表【转载】
  12. 今天我们谈一下HTML标签中的map标签的用法和使用场景
  13. 在小公司待了3年后,我废了
  14. java计算机毕业设计论文评审系统源码+系统+mysql数据库+lw文档
  15. Hbase的过滤器分类
  16. 如何开通微信小程序在线客服系统?
  17. ad16 导入dwg_AD16怎样精确导入CAD文件
  18. Web2 大厂「谷歌」是如何进入 Web3 的?
  19. Mastering Selections in Photoshop CC Photoshop CC选区教程 Lynda课程中文字幕
  20. Jmeter导出性能测试报告

热门文章

  1. rostcm6情感分析案例分析_ROSTCM6 情感分析软件 这款软件能分析文章中所表达的情绪内容 从而帮助使用者得出文章的情绪 - 下载 - 搜珍网...
  2. CSDN终于破2万粉了,几百块钱的课程可白嫖,就是宠粉!
  3. 百度文库免积分下载器
  4. adb调试工具下载使用
  5. 一个完整的C语言程序
  6. Linux开发环境——tftp服务器的搭建
  7. ubuntu skill
  8. 用SQL备份数据库表
  9. iis如何连接mysql_iis怎么连接数据库
  10. eggjs 项目实践