【ros学习笔记】-5 服务

服务

首先,创建一个新的功能包:service_pkg

catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim

依旧是在包下的src文件夹下写c++文件,script文件夹下写python文件

在这里插入图片描述

服务的数据类型是:srv
查看系统中的服务数据类型:

rossrv list

在这里插入图片描述

注意:一定要先启动roscore
本次使用的数据类型:turtlesim/Spawn
查看数据类型:

rossrv info turtlesim/Spawn

在这里插入图片描述

1 服务端(service)

1.1 c++

创建cpp文件:server_cpp.cpp
该文件意思:创建一个服务:cpp_server,该服务作用是,每调用一次服务,就打印一次“your are right!!!”

#include <ros/ros.h>
#include <turtlesim/Spawn.h>

int count=0;
bool b = false;
//回调函数(回调函数返回值是bool)       这里规定了“服务”的srv类型:turtlesim::Spawn
bool CallBack(turtlesim::Spawn::Request  &req,
          			turtlesim::Spawn::Response &res)
{
    b = !b;
    count++;
    ROS_INFO("your are right!!!! ---%d", count);

    //调用服务时,response的值会打印到屏幕
    res.name = req.name;

    return true;
}

int main(int argc, char **argv){
    ros::init(argc,argv,"server_cpp");
    ros::NodeHandle n;
    //创建一个 服务:cpp_server  服务的数据类型由回调函数决定
    ros::ServiceServer ser = n.advertiseService("cpp_server", CallBack);

    ROS_INFO("---------1-------");
    //循环查看回调函数
    ros::spin();
    ROS_INFO("---------2-------");

    return 0;
}

c++文件需要生成可执行文件
在CMakeList文件中添加:

add_executable(client_cpp src/client_cpp.cpp)
target_link_libraries(client_cpp ${catkin_LIBRARIES})

运行:
在一个终端中输入:

rosrun service_pkg server_cpp

另一个终端输入:

# 指令意思:向服务(cpp_server)发出请求
rosservice call /cpp_server    双击tab键

在这里插入图片描述
可以修改x、y等里的内容,修改好后并回车
在这里插入图片描述

1.2 python

创建文件:server_py.py
作用:创建一个名为/py_server的服务,该服务每调用一次,就打印一次“your are right!!!”

#!/usr/bin/env python

import rospy
from turtlesim.srv import Spawn, SpawnResponse

count =0

def Callback(req):
    global count    # 定义全局变量
    count += 1

    rospy.loginfo(f"you are right!!! ---{count}")
    # 将 请求的名字 传给 响应
    res_name = req.name
    # Spawn的response中只有一个参数,则SpawnResponse只有一个参数
    return SpawnResponse(res_name)

def server_py():
    rospy.init_node("server_py")
    # 创建一个服务:/py_server  数据类型是Spawn
    s = rospy.Service('/py_server', Spawn, Callback)
    rospy.loginfo("....ready....")
    rospy.spin()

if __name__ == "__main__":
    server_py()

注意:python虽然不需要配置,但需要将文件改为可执行文件

rosrun service_pkg server_py.py 
rosservice call /py_server  双击tab键
# 向/py_server发出请求,双击tab之后出现的内容是request的内容;
# 最后回车

在这里插入图片描述

2 客户端(client)

2.1 c++

创建文件:client_cpp.cpp
作用:创建一个连接服务cpp_server的客户端

#include <ros/ros.h>
#include <turtlesim/Spawn.h>


int main(int agrc,char** agrv){
    ros::init(agrc,agrv,"client_cpp");
    ros::NodeHandle n;
    ROS_INFO("wait");
    //等待名为cpp_server的服务
    ros::service::waitForService("/cpp_server");
    ROS_INFO("finish");
    //创建服务客户端cli,连接服务cpp_server
    ros::ServiceClient cli = n.serviceClient<turtlesim::Spawn>("/cpp_server");

    turtlesim ::Spawn srv;
    srv.request.x = 3;
    srv.request.y = 5;
    srv.request.name = "server";

    ROS_INFO("request: x:%.0f,y:%.0f,name:%s",srv.request.x,srv.request.y,srv.request.name.c_str());
    //向服务发出请求
    cli.call(srv);

    ROS_INFO("name:%s", srv.response.name.c_str());

    return 0;
}

注意:不要忘记配置cpp文件
运行:

rosrun service_pkg client_cpp
rosrun service_pkg server_cpp

在这里插入图片描述

2.2 python

创建文件:client_py.py

#!/usr/bin/env python


import rospy
from turtlesim.srv import Spawn


def func():
	rospy.init_node("client_py")
	rospy.loginfo("....wait....")
	# 查找服务py_server
	rospy.wait_for_service('/py_server')
	rospy.loginfo("....finish....")
	try:
		# 创建客户端,链接服务py_server   服务的数据类型:Spawn
		cli = rospy.ServiceProxy("/py_server",Spawn)
		# 向服务发送请求    请求的数据
		res = cli(2,2,0,'name1')
		rospy.loginfo("....end....")
	except rospy.ServiceException as e:
		print(f"error:{e}")
		
if __name__ == '__main__':
	func()

运行:

rosrun service_pkg client_py.py 
rosrun service_pkg server_py.py 

在这里插入图片描述
包中最后的文件结构:
在这里插入图片描述

3 易错点

1.运行程序时,没有运行roscore
2.c++文件没有进行配置(CMakeList文件)
3.python文件,没有改成可执行文件:在文件上右击——属性——权限

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值