前言理论模型自定义srv文件
Package调整CmakeLists调整 服务器实现
C++python 客户端实现
C++python 测试与注意事项
前言本文主要是跟着audolabor学习ROS笔记,多为操作性质,并从另一种角度对实现的顺序进行调整,想要多学习,可以参考autolabor教程
理论模型
与之前话题通讯之间有所区别,服务通讯适用于这样的场景:服务器处有一个公共资源,客户端可以调用这个资源,进行运算或者得到某些数据。而话题通讯更多是指发布方不进行数据处理,订阅方直接得到发布方的数据,而后进行自己的数据处理。
新建一个addint.srv文件,在文件中输入
# 以下为请求数据 int32 num1 int32 num2 --- # 以下为返回数据 int32 sumPackage调整
在package.xml中加入以下代码
CmakeLists调整message_generation message_runtime
找到CmakeLists.txt修改以下四个地方
find_package(catkin REQUIRED COMPonENTS roscpp rospy std_msgs message_generation ) add_message_files( FILES Person.msg ) generate_messages( DEPENDENCIES std_msgs ) catkin_package( # INCLUDE_DIRS include # LIBRARIES demo02_talker_listener CATKIN_DEPENDS roscpp rospy std_msgs message_runtime # DEPENDS system_lib )服务器实现
为了代码补全功能,需要在c_cpp文件和setting文件加入srv中间文件的位置,需要注意的是,不要使用~来代替/home/用户,一定要从根目录下开始写,不然亲测python不会有自动补齐的功能,不知道是bug还是linux的奇怪特性
C++#include "ros/ros.h"
#include "fuwu/addint.h"
bool doNums(fuwu::addint::Request& req,fuwu::addint::Response& rep)//cpp同时传入请求数据和response数据,返回一个bool值,与下面python不同
{
int num1 = req.num1;
int num2 = req.num2;
int sum = num1 + num2;
rep.sum = sum;
return 1;
}
int main(int argc, char *argv[])
{
ros::init(argc,argv,"server");
ros::NodeHandle nh;
ros::ServiceServer server = nh.advertiseService("addint", doNums); //使用回调函数处理请求数据,并将处理结果返回
ros::spin();
return 0;
}
python
#! /usr/bin/env python #非常重要,不要忘了
import rospy
from huati.srv import *
def pydoNum(request): #python传入的只有请求数据,通过函数返回数据传回response
num1 = request.num1
num2 = request.num2
response = addintResponse()# python中不传入返回数据需要自己利用类定义返回数据,这个类在srv的中间文件中
response.sum = num1 + num2
return response# response中可以包括多个对象,本例只有一个对象,不要误解
if __name__ == "__main__":
rospy.init_node("pyserver")
server = rospy.Service("addpy",addint,pydoNum)#addint是srv的文件名,即是用户自定义的数据类型名字
rospy.spin()
客户端实现
C++
argc是指输入参数的个数,最小为1,表示输入的只有程序本身,如果输入参数为n,则argc=n+1,argv是二维数组,argv[0]指向程序的地址,argv[1],…指向输入的参数,注意此时输入参数都为字符串
#include "ros/ros.h"
#include "fuwu/addint.h"
int main(int argc, char* argv[])
{
setlocale(LC_ALL,"");
if(argc != 3)
{
ROS_INFO("输入参数数量不对");
return 1;
}
ros::init(argc,argv,"cppclient");
ros::NodeHandle nh;
ros::ServiceClient client = nh.serviceClient("addints");
fuwu::addint nums;//创建发送数据,nums有三个对象,num1,num2和response
nums.num1 = atoi(argv[1]);
nums.num2 = atoi(argv[2]);
ros::service::waitForService("addint")//等待服务器启动,传入的参数是话题名字。也可以使用clinet.waitForExistence();
bool flag = clint.call(nums);
if(flag)
{
ROS_INFO("请求成功,返回数据为%d",nums.response.sum);
}
return 0;
}
python
#! /usr/bin/env python
import rospy
from fuwu.srv import *
import sys
if __name__ == "__main__":
if len(sys.argv) != 3:
rospy.logerr("参数个数不对")
sys.exit(1)
ros.init_node("pyclient")
client = rospy.ServiceProxy("addints",addint)
num1 = int(sys.argv[1])
num2 = int(sys.argv[2])
client.wait_for_service()# 或者使用rospy.wait_for_service("addint")
response = client.call(num1, num2)
rospy.loginfo("返回的数据是%d",response.sum)
测试与注意事项
rosrun fuwu pyserver.py rosrun fuwu pyclient.py 2 4
注意对配置中间文件的更改,不能使用~代替/home/用户名



