人生这条路很长,未来如星辰大海般璀璨,不必踟躇于过去的半亩方塘。
真正的优秀不是别人逼出来的,而是自己和自己死磕。 ------ Gaowaly
`

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 }
View Code

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()
View Code

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 };
View Code

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())
View Code

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 }
View Code

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()
View Code

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

 图示:

 

posted @ 2022-09-13 21:37  Gaowaly  阅读(41)  评论(0编辑  收藏  举报
``