问题:
如果在启动 ROS 服务的客户端之前启动了 ROS 服务,客户端可能会因为缺少服务而发出异常请求。这可能会导致服务端不知道如何处理请求,从而导致通信失败。要解决这个问题,有以下几种方法:
等待服务启动:在启动客户端之前,请确保 ROS 服务已经成功启动并且准备好接受请求。可以使用 rosservice list 命令来检查服务是否已经启动。如果服务还没有启动,请等待它启动,然后再启动客户端。
rosservice list
需求:
如果先启动客户端,不要直接抛出异常,而是挂起,等服务器启动后,再正常请求。
解决:
在ROS中内置了相关函数,这些函数可以让客户端启动后挂起,等待服务器启动。
在处理响应的地方加上两种函数的一种,以之前的服务通信srv为例子,在demo02_client.cpp里面的int main()函数里面加上内置函数。
使用 waitForService 方法:在客户端代码中,可以使用 waitForService 方法等待服务启动。这个方法会一直阻塞直到服务启动或者超时,如果服务启动了,那么它就可以接受请求了。
函数一
//调用判断服务器状态的函数
//函数一
client.waitForExistence();
rosrun plumbing_server_client demo02_client 100 500
[ INFO] [1680764959.960409145]: waitForService: Service [/addints] could not connect to host [ros-virtual-machine:46975], waiting...
服务端未启动,先启动客户端就会抛出
这个时候再去启动客户端,可以成功运行。
rosrun plumbing_server_client demo01_server
然后回车就会出现如下图所示:
函数二
使用服务代理:在客户端代码中,可以使用 ROS 服务代理来处理服务请求。服务代理会在请求服务之前自动检查服务是否已经启动,如果没有启动,那么它会等待服务启动,然后再发送请求。这样可以确保客户端发送的请求一定会被正确处理。
ros::service::waitForService("话题名字");
ros::service::waitForService("addints");
效果一样。