除了话题通信,ROS中常用的通信方式还有服务通信,学完这一块知识点后,自己尝试做了一个简单的计算器(只有加法、减法以及乘法),主要是为了巩固一下所学内容。
简易计算器执行方式如下:
1 客户端输入数字与运算规则,例如(5 + 3)<注意,输入时要有空格>, 服务端接收到客户端发送来的数字,将计算结果返回客户端。
2 每次计算完成后,询问是否继续运算,输入数字0即可退出运算,输入其他数字则继续运算
实现简易计算器的步骤如下:
第一步:创建工作空间
mkdir -p dmeo05_ws/src
第二步:进入工作空间,使用catkin_make进行编译,编译成功后进入src文件夹
cd demo05_ws
catkin_make
cd src
第三步:使用catkin_create_pkg创建service_pkg包, 注意添加依赖项rospy roscpp std_msgs message_generation message_runtime。随后使用vscode 打开src文件夹,准备编译
catkin_create_pkg service_pkg rospy roscpp std_msgs message_generation message_runtime
code .
第四步:在service_pkg下创建文件夹srv,在文件夹srv下创建Compute.srv文件
第五步:编辑Compute.srv文件,其中num1和num2是运算数字,symbol是运算规则(加减乘除…),result是结果。
!!!注意:request和responce的数据用"—"隔开
第六步:编辑service_pkg文件夹下的CMakeLists.txt
首先,编辑第10行的find_package()
之后,编辑第59行的add_service_files()
随后,编辑第72行的generate_messages()
最后,编辑106行的catkin_package()
第七步:编辑service_pkg文件夹下的package.xml文件
第八步:至此就完成了srv相关的准备,回到demo05_ws下使用catkin_make编译即可。
第九步:进入service_pkg下的src文件夹,创建server_node.cpp 以及 client_node.cpp
第十步:编写server_node.cpp文件
#include <ros/ros.h>
#include <service_pkg/Compute.h>
#include <std_msgs/String.h>
bool compute_callback(service_pkg::Compute::Request &req, service_pkg::Compute::Response &res)
{
float num1 = req.num1;
float num2 = req.num2;
float result = 0;
std_msgs::String str;
str.data = req.symbol;
if(str.data == "+")
{
result = num1 + num2;
}
if(str.data == "-")
{
result = num1 - num2;
}
if(str.data == "*")
{
result = num1 * num2;
}
res.result = result;
return true;
}
int main(int argc, char *argv[])
{
ros::init(argc,argv,"server_node");
ros::NodeHandle nh;
ros::ServiceServer server = nh.advertiseService("Compute", compute_callback);
while(ros::ok())
{
ros::spinOnce();
}
return 0;
}
第十一步:编写client_node.cpp
#include <ros/ros.h>
#include <service_pkg/Compute.h>
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"client_node");
ros::NodeHandle nh;
ros::ServiceClient client = nh.serviceClient<service_pkg::Compute>("Compute");
client.waitForExistence();
while(true)
{
service_pkg::Compute ai;
ROS_INFO("Input num1 , symbol and num2: ");
std::cin >> ai.request.num1;
std::cin >> ai.request.symbol;
std::cin >> ai.request.num2;
bool flag = client.call(ai);
if(flag)
{
ROS_INFO("--- 计算完成 ---");
ROS_INFO("result = %.2f", ai.response.result);
}
ROS_INFO("--- 是否继续 ---");
int choice;
std::cout << "input your choice : ";
std::cin >> choice;
if(choice == 0)
{
ROS_INFO("--- 结束计算 ---");
break;
}
}
return 0;
}
第十二步:编写service_pkg下的CMakeLists.txt文件(就是上面的那个CMakeLists.txt)
第十三步:回到demo05_ws下,catkin_make进行编译。
第十四步:启动三个终端页面,其中一个启动roscore,第二个启动服务端,第三个启动客户端
第十五步:输入数字和运算规则,进行测试
完成任务。