ROS入门21讲(5)
九、服务数据的定义与使用
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)的更多相关文章
- Ros入门21讲
一.ROS是什么? ROS=通信机制+开发工具+应用功能+生态系统 目的:提高机器人研发中的软件复用率. 1.ROS中的通信机制 松耦合分布式通信: 注意:什么是耦合.紧耦合.松耦合? 1.1 耦合 ...
- ros系统21讲—前六讲
课程介绍(第一讲) linux介绍安装(第二讲) linux的基础操作(第三讲) ROS中语言c++与python介绍(第四讲) 安装ROS系统(第五讲) 第一个: sudo sh -c echo d ...
- SLAM+语音机器人DIY系列:(二)ROS入门——5.编写简单的消息发布器和订阅器
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...
- SLAM+语音机器人DIY系列:(二)ROS入门——6.编写简单的service和client
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...
- SLAM+语音机器人DIY系列:(二)ROS入门——10.在实际机器人上运行ROS高级功能预览
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...
- ROS入门学习
ROS学习笔记 ROS入门网站; ROS入门书籍 ROS主要包含包括功能包.节点.话题.消息类型和服务; ROS功能包/软件包(Packages) ROS软件包是一组用于实现特定功能的相关文件的集合, ...
- 《VC++ 6简明教程》即VC++ 6.0入门精讲 学习进度及笔记
VC++6.0入门→精讲 2013.06.09,目前,每一章的“自测题”和“小结”三个板块还没有看(备注:第一章的“实验”已经看完). 2013.06.16 第三章的“实验”.“自测题”.“小结”和“ ...
- c#委托事件入门--第二讲:事件入门
上文 c#委托事件入门--第一讲:委托入门 中和大家介绍了委托,学习委托必不可少的就要说下事件.以下思明仍然从事件是什么.为什么用事件.怎么实现事件和总结介绍一下事件 1.事件是什么:. 1.1 NE ...
- ROS_Kinetic_03 ROS入门向导
ROS_Kinetic_03 ROS入门向导 每个人都有不同的学习习惯和爱好并针对不同的应用进行ROS相关设计与开发, 没有固定不变的学习模式,但以下的内容是通常都会用到的. 1. ROS基础教程 1 ...
- SLAM+语音机器人DIY系列:(二)ROS入门——1.ROS是什么
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...
随机推荐
- Visual Studio 个人配置和插件
主题和字体 一般为黑色深色主题,看起来比较舒服. 字体使用Fira Code,好处就是它把 =>和!=换成更加熟悉的表示.就比如以下.缺点就是习惯之后,看别人的代码就不习惯. 插件 当然是首推R ...
- 使用 createError 创建错误对象的详细指南
title: 使用 createError 创建错误对象的详细指南 date: 2024/8/8 updated: 2024/8/8 author: cmdragon excerpt: 摘要:本文介绍 ...
- 树莓派高级开发——“IO口驱动代码的编写“ 包含总线地址、物理_虚拟地址、BCM2835芯片手册知识
微机总线地址 地址总线: 百度百科解释: 地址总线 (Address Bus:又称:位址总线) 属于一种电脑总线 (一部份),是由CPU 或有DMA 能力的单元,用来沟通这些单元想要存取(读取/写入) ...
- WPF:MVVM的由来与属性绑定的过程
WPF:MVVM的由来与属性绑定的过程 1.MVVM (1)MVVM是什么? MVVM(Model-View-ViewModel)是一种软件架构设计模式MVVM模式.有助于分离应用程序的业务逻辑和 ...
- 2024-08-24:用go语言,给定一个下标从1开始,包含不同整数的数组 nums,数组长度为 n。 你需要按照以下规则进行 n 次操作,将数组 nums 中的所有元素分配到两个新数组 arr1 和
2024-08-24:用go语言,给定一个下标从1开始,包含不同整数的数组 nums,数组长度为 n. 你需要按照以下规则进行 n 次操作,将数组 nums 中的所有元素分配到两个新数组 arr1 和 ...
- TwinCAT3 - 实现自己的Dictionary
目录 1,前言 2,C#的字典 3,TwinCAT3的字典 定义功能块 添加方法 4,用起来 1,前言 C#有字典,TwinCAT没字典,咋办,自己写一个咯 2,C#的字典 C#的字典使用很简单,下面 ...
- 【Mac + Appium + Java1.8(一)】之Android自动化环境安装配置以及IDEA配置(附录扩展Selenium+Java自动化)
配置环境: MacOS:10.13.6 java:1.8 IntelliJ IDEA:2018.3 Android SDK:25 Appium:1.9.1 Appium-desktop:1.7.1 j ...
- 【Python后端开发】Flask之ORM数据库操作
一.前言 ORM 对象映射关系程序. 通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直 ...
- Coursera, Big Data 5, Graph Analytics for Big Data, Week 5
Computing Platforms for Graph Analytics programming models for Graphs Giraph and GraphX 其中讲 GraphX 的 ...
- powershell 常用插件
1. z 「z」这个 zsh 下常用的跳转工具,当频繁需要进入一个比较深的目录的时候,「z」这个插件会帮我们自动记录这个目录,之后我们只需要执行z [Directory]就可以快速跳转了 PowerS ...