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 ...
随机推荐
- Apache SeaTunnel社区首位学生Committer诞生!
采访对象 | 陈炳烨 采访人&编辑 | Debra Chen Apache SeaTunnel社区第一位学生Committer就此诞生!这位来自西安交通大学软件工程专业的同学从较为简单的文档修 ...
- jQuery的基本操作总结
什么是jquery? 就是一个用js的插件库 解决了原生dom的操作的兼容性和代码量 使用前需要引入它的js库 以下例子以 jQuery1.12.4.js 这个版本为例 一:jQuery入口函数 ...
- .NET 高效开发Nuget管理工具(开源)
我们.NET开发会引用很多外部Nuget包,多项目.多个解决方案.甚至多个仓库. 简单的Nuget包管理,通过VS就能比较简单处理好.但复杂的场景呢,比如: 1.一个仓库里,有多个解决方案的Nuget ...
- kali常用配置
用户须知 1.免责声明:本教程作者及相关参与人员对于任何直接或间接使用本教程内容而导致的任何形式的损失或损害,包括但不限于数据丢失.系统损坏.个人隐私泄露或经济损失等,不承担任何责任.所有使用本教程内 ...
- WebShell流量特征检测_冰蝎篇
80后用菜刀,90后用蚁剑,95后用冰蝎和哥斯拉,以phpshell连接为例,本文主要是对这四款经典的webshell管理工具进行流量分析和检测. 什么是一句话木马? 1.定义 顾名思义就是执行恶意指 ...
- 【YashanDB知识库】YMP元数据阶段二报错YAS-04204
[问题分类]YMP迁移 [关键字]YMP迁移,YAS-04204 [问题描述]数据库采用最小规格部署,机器配置2C8G,使用YMP进行数据和对象迁移,在元数据阶段二创建索引时报错:YAS-04204 ...
- 计算QPS-Sentinel限流算法
sentinel 前方参考 计算QPS-Sentinel限流算法 https://www.cnblogs.com/yizhiamumu/p/16819497.html Sentinel 介绍与下载使用 ...
- Google – Reviews
前言 继上一篇 Facebook – Reviews (Graph API) 后, 这篇继续介绍另一个 Reviews 大平台 Google Reviews. 想通过 API 获取 Google Re ...
- JAVAEE——navicat安装
Navicat Premium 15激活步骤 准备 Navicat Premium 15.Navicat Premium 15注册机 用到的都放在这里了: 链接:https://pan.baidu.c ...
- C++ STL set/multiset容器
set/multiset容器 简介 Set的特性是,所有元素都会根据元素的值自动被排序.Set不允许两个元素有相同的值. Set的迭代器iterator是一种const_iterator,不能通过迭代 ...