九、服务数据的定义与使用

1、服务模型

2、自定义服务数据

Person.srv

string name
uint8 sex
uint8 age uint8 unknown = 0
uint8 male = 1
uint8 female = 2
---
string result

如何自定义服务数据?

①定义srv文件

②在package.xml中添加功能包依赖

<build_depend>message_generation</build_depend>

<exec_depend>message_runtime</exec_depend>

③在CMakeLists.txt添加编译选项

find_package(...... message_generation)

add_service_files(DILES
Person.srv)

generate_messages(DEPENDENCIES
std_msgs)

catkin_package(......
message_runtime)

④编译生成语言相关文件

3、创建服务器代码

如何实现一个服务器?

①初始化ROS节点

②创建Server实例

③循环等待服务请求,进入回调函数

④在回调函数中完成服务功能的处理,并反馈应答数据。

C++代码如下:

 1 /**
2 * 该例程将执行/show_person服务,服务数据类型learning_service::Person
3 */
4
5 #include <ros/ros.h>
6 #include "learning_service/Person.h"
7
8 // service回调函数,输入参数req,输出参数res
9 bool personCallback(learning_service::Person::Request &req,
10 learning_service::Person::Response &res)
11 {
12 // 显示请求数据
13 ROS_INFO("Person: name:%s age:%d sex:%d", req.name.c_str(), req.age, req.sex);
14
15 // 设置反馈数据
16 res.result = "OK";
17
18 return true;
19 }
20
21 int main(int argc, char **argv)
22 {
23 // ROS节点初始化
24 ros::init(argc, argv, "person_server");
25
26 // 创建节点句柄
27 ros::NodeHandle n;
28
29 // 创建一个名为/show_person的server,注册回调函数personCallback
30 ros::ServiceServer person_service = n.advertiseService("/show_person", personCallback);
31
32 // 循环等待回调函数
33 ROS_INFO("Ready to show person informtion.");
34 ros::spin();
35
36 return 0;
37 }

python代码如下:

 1 # 该例程将执行/show_person服务,服务数据类型learning_service::Person
2
3 import rospy
4 from learning_service.srv import Person, PersonResponse
5
6 def personCallback(req):
7 # 显示请求数据
8 rospy.loginfo("Person: name:%s age:%d sex:%d", req.name, req.age, req.sex)
9
10 # 反馈数据
11 return PersonResponse("OK")
12
13 def person_server():
14 # ROS节点初始化
15 rospy.init_node('person_server')
16
17 # 创建一个名为/show_person的server,注册回调函数personCallback
18 s = rospy.Service('/show_person', Person, personCallback)
19
20 # 循环等待回调函数
21 print "Ready to show person informtion."
22 rospy.spin()
23
24 if __name__ == "__main__":
25 person_server()

4、创建客户端代码

①初始化ROS节点

②创建一个Client实例

③发布服务请求数据

④等待Server处理之后的应答结果

C++代码如下:

 1 /**
2 * 该例程将请求/show_person服务,服务数据类型learning_service::Person
3 */
4
5 #include <ros/ros.h>
6 #include "learning_service/Person.h"
7
8 int main(int argc, char** argv)
9 {
10 // 初始化ROS节点
11 ros::init(argc, argv, "person_client");
12
13 // 创建节点句柄
14 ros::NodeHandle node;
15
16 // 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
17 ros::service::waitForService("/show_person");
18 ros::ServiceClient person_client = node.serviceClient<learning_service::Person>("/show_person");
19
20 // 初始化learning_service::Person的请求数据
21 learning_service::Person srv;
22 srv.request.name = "Tom";
23 srv.request.age = 20;
24 srv.request.sex = learning_service::Person::Request::male;
25
26 // 请求服务调用
27 ROS_INFO("Call service to show person[name:%s, age:%d, sex:%d]",
28 srv.request.name.c_str(), srv.request.age, srv.request.sex);
29
30 person_client.call(srv);
31
32 // 显示服务调用结果
33 ROS_INFO("Show person result : %s", srv.response.result.c_str());
34
35 return 0;
36 };

python代码如下:

 1 # 该例程将请求/show_person服务,服务数据类型learning_service::Person
2
3 import sys
4 import rospy
5 from learning_service.srv import Person, PersonRequest
6
7 def person_client():
8 # ROS节点初始化
9 rospy.init_node('person_client')
10
11 # 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
12 rospy.wait_for_service('/show_person')
13 try:
14 person_client = rospy.ServiceProxy('/show_person', Person)
15
16 # 请求服务调用,输入请求数据
17 response = person_client("Tom", 20, PersonRequest.male)
18 return response.result
19 except rospy.ServiceException, e:
20 print "Service call failed: %s"%e
21
22 if __name__ == "__main__":
23 #服务调用并显示调用结果
24 print "Show person result : %s" %(person_client())

5、配置服务器/客户端代码编译规则

如何配置CMakeLists.txt中的编译规则?

①设置需要配置的代码和生成的可执行文件

②设置链接库

③添加依赖项

CMakeLists.txt中需要添加:

add_executable(person_server src/person_server.cpp)
target_link_libraries(person_server ${catkin_LIBRARIES})
add_dependencies(person_server ${PROJECT_NAME}_gencpp) add_executable(person_client src/person_client.cpp)
target_link_libraries(person_client ${catkin_LIBRARIES})
add_dependencies(person_client ${PROJECT_NAME}_gencpp)

6、编译并且运行客户端和服务器

命令:

  $ cd ~/catkin_ws

  $ catkin_make

  $ source devel/setup.bash

  $ roscore

  $ rosrun learning_topic person_server

  $ rosrun learning_topic person_client

图示:

十、参数的使用与编程方法

1、参数模型

参数模型(全局字典):

2、创建功能包

命令:

$ cd ~/catkin_ws/src

$ catkin_create_pkg learning_parameter roscpp rospy std_srvs

3、参数命令行使用

YAML参数文件

rosparam

命令:

①rosparam list 作用:列出当前所有参数

②rosparam get param_key 作用:显示某个参数值

③rosparam set param_key param_value 作用:设置某个参数值

④rosparam dump file_name 作用:保存参数到文件

⑤rosparam load file_name 作用:从文件读取参数

⑥rosparam delete param_key 作用:删除参数

图示:

4、编程方法

如何获取/设置参数?

①初始化ROS节点

②get函数获取参数

③set函数设置参数

C++代码:

 1 /**
2 * 该例程设置/读取海龟例程中的参数
3 */
4 #include <string>
5 #include <ros/ros.h>
6 #include <std_srvs/Empty.h>
7
8 int main(int argc, char **argv)
9 {
10 int red, green, blue;
11
12 // ROS节点初始化
13 ros::init(argc, argv, "parameter_config");
14
15 // 创建节点句柄
16 ros::NodeHandle node;
17
18 // 读取背景颜色参数
19 ros::param::get("/background_r", red);
20 ros::param::get("/background_g", green);
21 ros::param::get("/background_b", blue);
22
23 ROS_INFO("Get Backgroud Color[%d, %d, %d]", red, green, blue);
24
25 // 设置背景颜色参数
26 ros::param::set("/background_r", 255);
27 ros::param::set("/background_g", 255);
28 ros::param::set("/background_b", 255);
29
30 ROS_INFO("Set Backgroud Color[255, 255, 255]");
31
32 // 读取背景颜色参数
33 ros::param::get("/background_r", red);
34 ros::param::get("/background_g", green);
35 ros::param::get("/background_b", blue);
36
37 ROS_INFO("Re-get Backgroud Color[%d, %d, %d]", red, green, blue);
38
39 // 调用服务,刷新背景颜色
40 ros::service::waitForService("/clear");
41 ros::ServiceClient clear_background = node.serviceClient<std_srvs::Empty>("/clear");
42 std_srvs::Empty srv;
43 clear_background.call(srv);
44
45 sleep(1);
46
47 return 0;
48 }

python代码:

 1 # 该例程设置/读取海龟例程中的参数
2
3 import sys
4 import rospy
5 from std_srvs.srv import Empty
6
7 def parameter_config():
8 # ROS节点初始化
9 rospy.init_node('parameter_config', anonymous=True)
10
11 # 读取背景颜色参数
12 red = rospy.get_param('/background_r')
13 green = rospy.get_param('/background_g')
14 blue = rospy.get_param('/background_b')
15
16 rospy.loginfo("Get Backgroud Color[%d, %d, %d]", red, green, blue)
17
18 # 设置背景颜色参数
19 rospy.set_param("/background_r", 255);
20 rospy.set_param("/background_g", 255);
21 rospy.set_param("/background_b", 255);
22
23 rospy.loginfo("Set Backgroud Color[255, 255, 255]");
24
25 # 读取背景颜色参数
26 red = rospy.get_param('/background_r')
27 green = rospy.get_param('/background_g')
28 blue = rospy.get_param('/background_b')
29
30 rospy.loginfo("Get Backgroud Color[%d, %d, %d]", red, green, blue)
31
32 # 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
33 rospy.wait_for_service('/clear')
34 try:
35 clear_background = rospy.ServiceProxy('/clear', Empty)
36
37 # 请求服务调用,输入请求数据
38 response = clear_background()
39 return response
40 except rospy.ServiceException, e:
41 print "Service call failed: %s"%e
42
43 if __name__ == "__main__":
44 parameter_config()

5、配置代码编译规则

如何配置CMakeLists.txt中的编译规则?

①设置需要配置的代码和生成的可执行文件

②设置链接库

CMakeLists.txt中需要添加:

add_executable(parameter_config src/parameter_config.cpp)
target_link_libraries(parameter_config ${catkin_LIBRARIES})

6、编译并且运行发布者

命令:

  $ cd ~/catkin_ws

  $ catkin_make

  $ source devel/setup.bash

  $ roscore

  $ rosrun turtlesim turtlesim_node

  $ rosrun learning_parameter parameter_config

图示:

ROS入门21讲(5)的更多相关文章

  1. Ros入门21讲

    一.ROS是什么? ROS=通信机制+开发工具+应用功能+生态系统 目的:提高机器人研发中的软件复用率. 1.ROS中的通信机制 松耦合分布式通信: 注意:什么是耦合.紧耦合.松耦合? 1.1 耦合 ...

  2. ros系统21讲—前六讲

    课程介绍(第一讲) linux介绍安装(第二讲) linux的基础操作(第三讲) ROS中语言c++与python介绍(第四讲) 安装ROS系统(第五讲) 第一个: sudo sh -c echo d ...

  3. SLAM+语音机器人DIY系列:(二)ROS入门——5.编写简单的消息发布器和订阅器

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  4. SLAM+语音机器人DIY系列:(二)ROS入门——6.编写简单的service和client

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  5. SLAM+语音机器人DIY系列:(二)ROS入门——10.在实际机器人上运行ROS高级功能预览

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  6. ROS入门学习

    ROS学习笔记 ROS入门网站; ROS入门书籍 ROS主要包含包括功能包.节点.话题.消息类型和服务; ROS功能包/软件包(Packages) ROS软件包是一组用于实现特定功能的相关文件的集合, ...

  7. 《VC++ 6简明教程》即VC++ 6.0入门精讲 学习进度及笔记

    VC++6.0入门→精讲 2013.06.09,目前,每一章的“自测题”和“小结”三个板块还没有看(备注:第一章的“实验”已经看完). 2013.06.16 第三章的“实验”.“自测题”.“小结”和“ ...

  8. c#委托事件入门--第二讲:事件入门

    上文 c#委托事件入门--第一讲:委托入门 中和大家介绍了委托,学习委托必不可少的就要说下事件.以下思明仍然从事件是什么.为什么用事件.怎么实现事件和总结介绍一下事件 1.事件是什么:. 1.1 NE ...

  9. ROS_Kinetic_03 ROS入门向导

    ROS_Kinetic_03 ROS入门向导 每个人都有不同的学习习惯和爱好并针对不同的应用进行ROS相关设计与开发, 没有固定不变的学习模式,但以下的内容是通常都会用到的. 1. ROS基础教程 1 ...

  10. SLAM+语音机器人DIY系列:(二)ROS入门——1.ROS是什么

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

随机推荐

  1. H5页面\PC端实现QQ客服功能

    1.背景 很多应用都有在线客服,最简单是实现就是利用人们常用的QQ 2.实现 步骤一:授权QQ通讯组件(普通QQ都是可以的) 授权链接:https://shang.qq.com/v3/widget.h ...

  2. 这篇 DolphinScheduler on k8s 云原生部署实践,值得所有大数据人看!

    在当前快速发展的技术格局中,企业寻求创新解决方案来简化运营并提高效率成为一种趋势. Apache DolphinScheduler作为一个强大的工具,允许跨分布式系统进行复杂的工作流任务调度.本文将深 ...

  3. 在Debian上安装freeswitch

    在Debian上安装freeswitch 说明: 首次发表日期:2024-08-12 参考文档: https://medium.com/@jogikrunal9477/ultimate-guide-t ...

  4. java如何保证一个方法只能执行一次

    我们经常会遇到一些情况需要某一个方法或者操作只执行一次,比如说配置信息加载,如果配置信息需要动态刷新,这个不在适用范围.下面列举几种方式 第一种 如果是web容器,可以使用servlet或者Liste ...

  5. centos7.3离线安装和配置NFS

    概述 # NFS为 Network FileSystem 的简称,它的目的就是想让不同的机器.不同的操作系统可以彼此分享个别的档案啦! 目前在 Unix Like 当中用来做为文件服务器是相当不错的一 ...

  6. P10884 [COCI 2017-2018#2] San

    题目传送门:P10884 [COCI 2017-2018#2] San 看下标签 COCI(克罗地亚) 2017 啊 比我小4年的题 --------------------------------- ...

  7. 【YashanDB知识库】statement级别的触发器在jdbc接口调用executeBatch时被多次触发

    问题现象 某客户使用jdbc接口向yashandb的表A插入数据. 表A上有一个语句级触发器,其内容为在触发时执行alter sequence操作:另外还有一个insert时的行级触发器,其内容为将每 ...

  8. Kubernetes 环境中切换代理ipvs模式

    Kubernetes 环境中切换代理ipvs模式 service代理默认使用iptables规则通过内核模块netfilter实现流量转发,内核转发效率高,但是iptables不具备更为灵活的负载均衡 ...

  9. Ollama + JuiceFS:一次拉取,到处运行

    今天这篇博客转载自我们的全栈工程师朱唯唯.在使用 Ollma 进行大模型加载时,她尝试使用了 JuiceFS 进行模型共享,JuiceFS 的数据预热和分布式缓存功能显著提升了加载效率,优化了性能瓶颈 ...

  10. Failed to convert value of type 'java.lang.String' to required type

    DEBUG 微信小程序Java后台 Failed to convert value of type 'java.lang.String' to required type 产生这种条件的原因一般是使用 ...