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

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. Vue Vine:带给你全新的 Vue 书写体验!

    你好,我是 Kagol,个人公众号:前端开源星球. 上个月和 TinyVue 的小伙伴们一起参加了 VueConf 24 大会,有幸认识沈青川大佬,并了解了他的 Vue Vine 项目,Vue Vin ...

  2. 模拟实现FutureTask

    1.背景 面试官问,,假设让你编写一个FutureTask,你的思路是..... 2.代码 2.1.GuardedObject对象 package com.common; /** * @author ...

  3. 3.2.0 终极预告!云原生支持新增 Spark on k8S 支持

    视频贡献者 | 王维饶 视频制作者 | 聂同学 编辑整理 | Debra Chen Apache DolphinScheduler 3.2.0 版本将发布,为了让大家提前了解到此版本更新的主要内容,我 ...

  4. Sentry For Vue 完整接入详解(2021 Sentry v21.8.x)前方高能预警!三万字,慎入!

    内容源于:https://docs.sentry.io/platforms/javascript/guides/vue/ 系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创 ...

  5. SMCA:港中文提出注意力图校准的DETR加速方案 | ICCV 2021

    为了加速DETR收敛,论文提出了简单而有效的Spatially Modulated Co-Attention(SMCA)机制,通过在初始边界框位置给予较高的协同注意力响应值的约束来构建DETR的回归感 ...

  6. Mybatis Log 插件

    目前的idea插件已经开始收费---找了一个免费的插件安装到idea中重启一下就可以了 百度网盘提取码:sjc8

  7. mysql 5.7密码修改

    官网下载安装包:https://dev.mysql.com/downloads/mysql/ 一.停止mysqld服务 二.编辑配置文件 有的Linux版本是/etc/my.cnf 有的Linux版本 ...

  8. 阿里云图床(PicGo+阿里云OSS)搭建

    阿里云图床搭建方法: 1.登录阿里云,搜索对象存储oss,新用户免费使用3个月20G,到期后,一年也就9元左右,还是很划算的. 2.在左侧列表里,点击Bucket列表,创建Bucket 3.Bucke ...

  9. JVM笔记六-堆区知识之对象生命周期和GC的关系

    通过上一篇文章的学习,我们对JVM堆区有了初步的认识,接下来,我们继续展开讲解堆区. 对象生命周期和GC的关系. 我们已经知道了,堆区的新生区分成了三个部分:伊甸园区.幸存者0区.幸存者1区. 其中0 ...

  10. Spark - Pandas UDF

    spark 本身对 dataframe 的操作支持没有像pandas 那样强大,所有我们可以把spark dataframe 转化成 pandas dataframe 来利用pandas datafr ...