ROS的服务通信实现

需求: 服务通信中,客户端提交两个整数至服务端,服务端求和并响应结果到客户端,请创建服务器与客户端通信的数据载体。

流程:

srv 文件内的可用数据类型与 msg 文件一致,且定义 srv 实现流程与自定义 msg 实现流程类似:

  1. 按照固定格式创建 srv 文件
  2. 编辑配置文件
  3. 编译生成可以被 Python C++ 调用的中间文件。

实现:

创建功能包:

右键src文件夹->Create Catin Package,在弹框中输入包名称:server_client,回车,然后在输入依赖:roscpp rospy std_msgs,创建功能包。

自定义msg文件:

进入功能包目录下,新建srv目录,添加文件 addints.srv并添加自定义类型数据,addints.srv中输入内容:

addints.srv中输入内容:
#客户端请求时发送的两个数字
int32 num1
int32 num2
---
#服务器响应发送的数据
int32 age

编辑配置文件:

package.xml中添加编译依赖与执行依赖:

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>
  <!-- 
  exce_depend 以前对应的是 run_depend 现在非法
  -->

CMakeLists.txt编辑 srv 相关配置:

# 需要加入 message_generation,必须有 std_msgs
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
## 配置 msg 源文件
add_message_files(
  FILES
  addints.srv
)
# 生成消息时依赖于 std_msgs
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
)

编译生成文件:

ctrl+shift+B

编译后的中间文件查看:

C++ 需要调用的中间文件(.../工作空间/devel/include/包名/xxx.h)

Python 需要调用的中间文件(.../工作空间/devel/lib/python3/dist-packages/包名/msg)

C++实现服务通信模型源码:

       服务端实现流程:

           1.包含头文件

        2.初始化 ROS 节点

        3.创建 ROS 句柄

        4.创建 服务 对象

        5.回调函数处理请求并产生响应

        6.由于请求有多个,需要调用 ros::spin()

#include “ros/ros.h”
#include “server_client/addints.h”

bool doReq(server_client::addints::Request& req,
server_client::addints::Response& resp)
{
	Int num1 = req.num1;
	Int num2 = req.num2;
	ROS_INFO("服务器接收到的请求数据为:num1 = %d, num2 = %d",num1, num2);
	//逻辑处理
    if (num1 < 0 || num2 < 0)
    {
        ROS_ERROR("提交的数据异常:数据不可以为负数");
        return false;
    }
    //如果没有异常,那么相加并将结果赋值给 resp
    resp.sum = num1 + num2;
    return true;
}
//1 包含头文件
int main(int argc,char *argv[])
{
	setlocale(LC_ALL,“”);
	//2 初始化ros节点
	ros::init(argc,argv,”addints_server”);
	//3 创建ros句柄
	ros::NodeHandle nh;
	//4 创建服务对象
	ros::ServiceServer server = nh.advertiseService(“addints”,doReq);
	ROS_INFO(“服务已经启动…”);
	//5 回调函数处理请求并产生响应
	//6 由于请求有多个,需要调用ros::spin()
	ros::spin();
	return 0;
}

客户端实现流程:

        1.包含头文件

        2.初始化 ROS 节点

        3.创建 ROS 句柄

        4.创建 客户端 对象

        5.请求服务,接收响应

// 1.包含头文件
#include “ros/ros.h”
#include “server_client/addints.h”

int main(int argc, char *argv[])
{
	setlocale(LC_ALL,"");
	if(argc != 3)
{
	ROS_ERROR("请提交两个整数");
	return 1;
}
//2 初始化ros节点
ros::init(argc,argv,”addints_client”);
//3 创建ros句柄
ros::NodeHandle nh;
//4 客户端对象
ros::ServiceClient client = nh.serviceClient<server_client::addInts>("addInts");
//等待服务器启动成功
Ros::service::waitForService(“addints”);
//5 构建数据
server_client::addints ai;
ai.request.num1 = atoi(argv[1]);
ai.request.num2 = atoi(argv[2]);
//6 发送请求,返回bool数值,标记是否成功
Bool flag = client.call(ai);
//7 处理响应
    if (flag)
    {
        ROS_INFO("请求正常处理,响应结果:%d",ai.response.sum);
    }
    else
    {
        ROS_ERROR("请求处理失败....");
        return 1;
    }
return 0;
}

 配置Cmakelists.txt:

add_executable(server src/server.cpp)
add_executable(client src/client.cpp)

add_dependencies(server ${PROJECT_NAME}_gencpp)
add_dependencies(client ${PROJECT_NAME}_gencpp)

target_link_libraries(server
  ${catkin_LIBRARIES}
)
target_link_libraries(client
  ${catkin_LIBRARIES}
)

执行:

需要先启动服务:rosrun 包名 服务

然后再调用客户端 :rosrun 包名 客户端 参数1 参数2

Python实现:

服务端实现流程:

 

  1. 导包
  2. 初始化ROS节点
  3. 创建服务对象
  4. 回调函数处理请求产生响应
  5. Spin函数
#! /usr/bin/env python
import rospy
from server_client.srv import *
#回调函数
Def doReq(req):
	# 解析提交的数据
	num1 = req.num1
	num2 = req.num2
	sum = num1 + num2
	# 创建响应对象,赋值并返回
	resp = addintsResponse(sum)
	return resp
If __name__ == “__main__”:
	# 2.初始化 ROS 节点
	rospy.nodeinit(“server_p”)
	# 3.创建服务对象
	server = rospy.Service(“addints_p”,addints,doReq)
	# 4.回调函数处理请求并产生响应
# 5.spin 函数
rospy.spin()

 

客户端实现

        1.导包

        2.初始化 ROS 节点

        3.创建请求对象

        4.发送请求

        5.接收并处理响应

#! /usr/bin/env python
import rospy
from server_client.srv import *
import sys
if __name__ == "__main__":
	if len(sys.argv) != 3:
		rospy.logerr("请正确提交参数")
		sys.exit(1)
	# 2.初始化 ROS 节点
	rospy.nodeinit(“client_p”)
	# 3.创建请求对象
	client = rospy.ServiceProxy(“addints_p”,addints)
	# 请求前,等待服务已经就绪
	client.wait_for_service()
	# 4.发送请求,接收并处理响应
	req = addintsRequest()
	req.num1 = int(sys.argv[1])
	req.num2 = int(sys.argv[2])
	resp = client.call(req)
	rospy.loginfo("响应结果:%d",resp.sum)

修改文件权限:

chmod +x ./*.py

配置CMakeLists.txt:

catkin_install_python(PROGRAMS
  scripts/server_p.py 
  scripts/client_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

执行:

需要先启动服务:rosrun 包名 服务

然后再调用客户端 :rosrun 包名 客户端 参数1 参数2

 

 

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值