本文是关于第14讲的学习内容总结
所以要完成的目标是,用C++代码编程实现服务端
Server的作用就是给海龟发布指令的,Client的作用是来控制Server是否要给海龟发布指令
老师的解释是Client相当于是一个海龟运动的开关。
需要说明的一点,这也是我看了好几遍的讲解才明白的,因为这讲的代码中既有topic又有service所以很容易弄模糊。
所以要知道:客户端Client到服务器Server中的通迅是service(有反馈),而服务器Server给海龟发布的运动指令是topic(无反馈)。
代码实现步骤:
代码理解:
1.服务数据类型std_srvs/Trigger,这个是std中自带的数据类型
2.头文件
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <std_srvs/Trigger.h>
第一个是ros的头文件
第二个是给海龟发topic的头文件
第三个是包含Trigger的头文件
3.建立一个名为/turtle_command的server,设置回调函数commandCallback,Server一旦收到请求就跳到回调函数
ros::ServiceServer command_service = n.advertiseService("/turtle_command", commandCallback);
4.查看回调函数队列
查看是否有消息进回调函数队列来了,如果有就进入回调函数
ros::spinOnce();
这里也容易弄糊,server不是收到指令就会跳到回调函数中吗,为什么这里还要查看消息是否进来
原因:受到请求的回调函数会先排队,当程序执行到spin0one时,队列中的函数才会陆续进行。spin0once会执行队列中的第一个。简单而言就是server接受到请求后会进入回调函数队列,然后spin0once会检查队列中是否真的有数据进来,有就执行回调函数,没有就继续等。
5.判断标志位
为真——发布海龟的运动指令
为假——海龟不动
6.回调函数部分
(一)对标志位取反
pubCommand = !pubCommand;
(二)显示请求的数据
ROS_INFO("Publish turtle velocity command [%s]", pubCommand==true?"Yes":"No");
(三)设置反馈的数据
res.success = true;
res.message = "Change turtle command state!";
设置编译规则:
add_executable(turtle_command_server src/turtle_command_server.cpp)
target_link_libraries(turtle_command_server ${catkin_LIBRARIES})
含义同上一讲,不再赘述
代码跑起来:
四个终端分别输入四个代码。
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_command_server
rosservice call /turtle_command