ROS入门21讲(4)
八、客户端Client的编程实现
1、话题模型
服务模型(客户端/服务器)

2、创建功能包
命令:
$ cd ~/catkin_ws/src
$ catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim
图示:

3、创建客户端代码
如何实现一个客户端?
①初始化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())
4、配置客户端代码编译规则
如何配置CMakeLists.txt中的编译规则?
①设置需要配置的代码和生成的可执行文件
②设置链接库
CMakeLists.txt中需要添加:
add_executable(turtle_spawn src/turtle_spawn.cpp)
target_link_libraries(turtle_spawn ${catkin_LIBRARIES})
5、编辑并且运行客户端
命令:
$ cd ~/catkin_ws
$ catkin_make
$ source devel/setup.bash
$ roscore
$ rosrun turtlesim turtlesim_node
$ rosrun learning_service turtle_spawn
图示:

九、服务端Server的编程实现
1、服务模型
服务模型(客户端/服务器)

2、创建服务器代码
如何实现一个服务器?
①初始化ROS节点
②创建Server实例
③循环等待服务请求
④在回调函数中完成服务功能的处理,并反馈应答数据
C++代码:

1 /**
2 * 该例程将执行/turtle_command服务,服务数据类型std_srvs/Trigger
3 */
4
5 #include <ros/ros.h>
6 #include <geometry_msgs/Twist.h>
7 #include <std_srvs/Trigger.h>
8
9 ros::Publisher turtle_vel_pub;
10 bool pubCommand = false;
11
12 // service回调函数,输入参数req,输出参数res
13 bool commandCallback(std_srvs::Trigger::Request &req,
14 std_srvs::Trigger::Response &res)
15 {
16 pubCommand = !pubCommand;
17
18 // 显示请求数据
19 ROS_INFO("Publish turtle velocity command [%s]", pubCommand==true?"Yes":"No");
20
21 // 设置反馈数据
22 res.success = true;
23 res.message = "Change turtle command state!"
24
25 return true;
26 }
27
28 int main(int argc, char **argv)
29 {
30 // ROS节点初始化
31 ros::init(argc, argv, "turtle_command_server");
32
33 // 创建节点句柄
34 ros::NodeHandle n;
35
36 // 创建一个名为/turtle_command的server,注册回调函数commandCallback
37 ros::ServiceServer command_service = n.advertiseService("/turtle_command", commandCallback);
38
39 // 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
40 turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);
41
42 // 循环等待回调函数
43 ROS_INFO("Ready to receive turtle command.");
44
45 // 设置循环的频率
46 ros::Rate loop_rate(10);
47
48 while(ros::ok())
49 {
50 // 查看一次回调函数队列
51 ros::spinOnce();
52
53 // 如果标志为true,则发布速度指令
54 if(pubCommand)
55 {
56 geometry_msgs::Twist vel_msg;
57 vel_msg.linear.x = 0.5;
58 vel_msg.angular.z = 0.2;
59 turtle_vel_pub.publish(vel_msg);
60 }
61
62 //按照循环频率延时
63 loop_rate.sleep();
64 }
65
66 return 0;
67 }
图示:

python代码:

1 # 该例程将执行/turtle_command服务,服务数据类型std_srvs/Trigger
2
3 import rospy
4 import thread,time
5 from geometry_msgs.msg import Twist
6 from std_srvs.srv import Trigger, TriggerResponse
7
8 pubCommand = False;
9 turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)
10
11 def command_thread():
12 while True:
13 if pubCommand:
14 vel_msg = Twist()
15 vel_msg.linear.x = 0.5
16 vel_msg.angular.z = 0.2
17 turtle_vel_pub.publish(vel_msg)
18
19 time.sleep(0.1)
20
21 def commandCallback(req):
22 global pubCommand
23 pubCommand = bool(1-pubCommand)
24
25 # 显示请求数据
26 rospy.loginfo("Publish turtle velocity command![%d]", pubCommand)
27
28 # 反馈数据
29 return TriggerResponse(1, "Change turtle command state!")
30
31 def turtle_command_server():
32 # ROS节点初始化
33 rospy.init_node('turtle_command_server')
34
35 # 创建一个名为/turtle_command的server,注册回调函数commandCallback
36 s = rospy.Service('/turtle_command', Trigger, commandCallback)
37
38 # 循环等待回调函数
39 print "Ready to receive turtle command."
40
41 thread.start_new_thread(command_thread, ())
42 rospy.spin()
43
44 if __name__ == "__main__":
45 turtle_command_server()
3、配置服务器代码编译规则
如何配置CMakeLists.txt中的编译规则?
①设置需要配置的代码和生成的可执行文件
②设置链接库
CMakeLists.txt中需要添加:
add_executable(turtle_command_server src/turtle_command_server.cpp)
target_link_libraries(turtle_command_server ${catkin_LIBRARIES})
4、编译并运行服务器
命令:
$ cd ~/catkin_ws
$ catkin_make
$ source devel/setup.bash
$ roscore
$ rosrun turtlesim turtlesim_node
$ rosrun learning_service turtle_command_server
$ rosservice call /turtle_command "{}"
注意:最后一行代码按Tab键补全
图示:

ROS入门21讲(4)的更多相关文章
- 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 ...
随机推荐
- 【转载】 实时调度论文中经常出现的术语 ties broken arbitrary的意思 —— 看伪代码时出现 ties broken arbitrary
看伪代码时突然看到这样的一个Ps标注, ties broken arbitrary, 不明白是啥意思,后来看到下文:https://blog.csdn.net/kangkanglhb88008/ar ...
- Linux的命令合集
Linux常用的命令 这里分享一个博客,里面有很丰富的Linux的常用指令. https://blog.csdn.net/qq_23329167/article/details/83856430. 然 ...
- CF506D题解
Mr. Kitayuta's Colorful Graph 算法:根号分治. 题目大意先说一下:给一个 \(n\) 点 \(m\) 边的无向图,边有颜色.\(q\) 组询问,每次给出 \(u,v\), ...
- NuminaMath 是如何荣膺首届 AIMO 进步奖的?
今年,Numina 和 Hugging Face 合作角逐 AI 数学奥林匹克 (AI Math Olympiad,AIMO) 的首届进步奖.此次比赛旨在对开放 LLM 进行微调,以使其能解决高中难度 ...
- 同一块石头搬到了两次的List<Map> 转List<dto>的问题
不多比比 it is shame to talking about this List<Map<String, Object>> maps = reader.readAll() ...
- Maven经验分享(三)编译引入本地jar
如果编译时需要引入本地jar,则可以增加如下配置: <plugin> <artifactId>maven-compiler-plugin</artifactId> ...
- C语言的指定初始化
----------------版权声明:本文为CSDN博主「Supan-Yang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog ...
- CF Pinely Round 4
https://codeforces.com/contest/1991 \(-122=2019\) D \(1,3,4,6\) 构成团,所以答案下界为 \(4\) 按模 \(4\) 染色.同色的二进制 ...
- OpenTelemetry 实战:从零实现应用指标监控
前言 在上一篇文章:OpenTelemetry 实战:从零实现分布式链路追踪讲解了链路相关的实战,本次我们继续跟进如何使用 OpenTelemetry 集成 metrics 监控. 建议对指标监控不太 ...
- 【Docker学习系列】Docker学习1-docker安装
从本篇开始,凯哥将和大家一起学学docker.本篇是docker学习系列第一篇:安装docker. docker安装前提条件:目前,centos发行版中的内核支持Docker.Docker运行在Cen ...