☰
挑战一周学会ROS(第五天)
2026/9/30 2:22:23 网站建设 项目流程

接下来登场的是服务通讯

基于请求响应模式,是一种应答机制,也即:一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A

比如:机器人巡逻过程中,控制系统分析传感器数据发现可疑物体或人,此时需要拍摄照片并保存

(一个节点需要向相机节点发送拍照请求,相机节点处理请求,并返回处理结果)

服务通讯更适用于对实时性有要求,具有一定逻辑处理的应用场景

概念:以请求响应的方式实现不同节点之间数据交互的通讯模式

作用:用于偶然的、对实时性有要求、有一定逻辑处理需求的数据传输场景

角色

1、master---->管理者(114平台)

2、server----->服务端(服务公司)

3、client------>客户端(我)

流程

master会根据话题实现server和client的连接

注意:

1、不同于话题通讯,服务通讯中服务端必须先启动

2、客户端和服务端都可以存在多个

服务通讯自定义srv:文件内的可用数据类型与msg文件一致,且自定义srv实现流程与自定义msg实现流程类似,都是基于标准数据类型

srv

流程:

1、按照固定格式创建srv文件

2、编辑配置文件

3、编译生成中间文件

在我的不懈努力下

代码如下:

成功!

下面为你拆析argc argv的底层原理

int main(int argc, char *argv[])

这两个参数不是你程序内部生成的,是操作系统shell启动程序时,自动解析命令行字符串传给main函数的

argc:argument count参数计数器

类型:int

含义:整个命令行总参数的个数

规则:永远大于1(包含自身文件名)

argv:argument vector参数字符串数组

类型:char*argv[],等价于char**argv字符串指针数组

含义:存放每一段命令行分割后的字符串

argv[0]:固定是程序本身的路径/名称

argv[1],argcv[2]:手动输入的外部参数

没话说,简直牛逼

#include "ros/ros.h" #include "plumbing_server_client/AddInts.h" /* 客户端:提交两个整数,并处理响应的结果 1,包含头文件 2,初始化ROS节点 3,创建节点句柄 4,创建一个客户端对象 5,提交请求并处理响应 实现参数的动态提交 1,格式:rosrun xxxxx xxxxx 12 34 2,节点执行时需要获取命令中的参数,并组织进行 request */ int main(int argc, char *argv[]) { //优化实现,获取命令中的参数 setlocale(LC_ALL,""); if(argc != 3) { ROS_INFO("提交时的参数个数不对"); return 1; } // 2,初始化ROS节点 ros::init(argc,argv,"daBao"); // 3,创建节点句柄 ros::NodeHandle nh; // 4,创建一个客户端对象 ros::ServiceClient client = nh.serviceClient<plumbing_server_client::AddInts>("addInts"); // 5,提交请求并处理响应 plumbing_server_client::AddInts ai; //5.1 组织请求 ai.request.num1=atoi(argv[1]); ai.request.num2=atoi(argv[2]); //5.2 处理响应 bool flag = client.call(ai); if(flag){ ROS_INFO("响应成功"); //获取结果 ROS_INFO("响应结果 = %d",ai.response.sum); } else{ ROS_INFO("处理失败"); } return 0; }
#include "ros/ros.h" #include "plumbing_server_client/AddInts.h" /* 服务端实现:解析客户端提交的数据并运算再产生响应 1,包含头文件 2,初始化ROS节点 3,创建节点句柄 4,创建服务对象 5,处理请求并产生响应 6,spin() */ bool doNums(plumbing_server_client::AddInts::Request & request, plumbing_server_client::AddInts::Response &response){ //1,处理请求 int num1 = request.num1; int num2 = request.num2; ROS_INFO("收到的数据是:num1=%d,num2=%d",num1,num2); int sum=num1+num2; response.sum=sum; ROS_INFO("求和结果 sum = %d",sum); return true; } int main(int argc, char *argv[]) { setlocale(LC_ALL,""); //2,初始化ROS节点 ros::init(argc,argv,"heiShui"); //节点名称保证唯一 //3,创建节点句柄 ros::NodeHandle nh; //4,创建服务对象 ros::ServiceServer server = nh.advertiseService("addInts",doNums); ROS_INFO("服务器端启动"); //5,处理请求并产生响应 //6,spin() ros::spin(); return 0; }

等待执行

python版本的应该如何操作:

1、编写服务端实现

2、编写客户端实现

3、为python文件添加可执行权限

4、编辑配置文件

5、编译并执行

拿下拿下:

终于出来了:

接下来登场的是参数服务器

参数服务器在ROS中主要用于不同节点之间的数据共享,参数服务器相当于是独立于所有节点的一个公共容器,被不同的节点调用,当然不同的节点也可往其中存储数据

比如:导航实现时,会进行路径规划,全局路径规划,设计一个从出发点到目标的大致路径。本地路径规划会根据路况生成时时的行进路径

路径规划时,需要参考小车的尺寸,我们可以把这些尺寸信息存储到参数服务器,全局路径规划节点与本地路径规划节点可以从参数服务器中调用这些参数

参数服务器适用于存放数据共享的一些应用场景

理论模型:

ROS Master(管理者)

Talker(参数设置者)

Listener(参数调用者)

ROS Master作为一个公共容器保存参数,Talker可以向容器中设置参数,Listener可以获取参数

参数服务器不是为了高性能而设计的,最好用于存储静态的非二进制的简单数据

参数服务器,原来如此简单

修改

获取:

遍历:

现在进入常用命令的学习

这些命令和之前的文件操作相比较,文件操作命令是静态的,操作的是磁盘上的文件,而上述命令是动态的,在ROS程序启动之后,可以动态的获取运行中的节点或参数的相关信息

rosnode 用于获取节点的信息

rosnode ping 测试到节点的连接状态
rosnode list 列出活动节点
rosnode info 打印节点信息
rosnode machine 列出指定设备上节点
rosnode kill 杀死某个节点
rosnode cleanup 清除不可连接的节点

rostopic用于显示有关ROS主题的调试信息包括发布者、订阅者、发布频率和ROS消息

rostopic bw 显示主题使用的带宽
rostopic delay 显示带有 header 的主题延迟
rostopic echo 打印消息到屏幕
rostopic find 根据类型查找主题
rostopic hz 显示主题的发布频率
rostopic info 显示主题相关信息
rostopic list 显示所有活动状态下的主题
rostopic pub 将数据发布到主题
rostopic type 打印主题类型

rosservice

........

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询