received a tcpros connection for nonexistent service
I created a custom global planner that copies a plan (calculated in a different node) through a service. I have the service server set inside the node calculating the global plan.
When I run the application I get the following error on the server's side:
[ERROR] [1625582846.614443975]: received a tcpros connection for a nonexistent service [/copier]
A thing to note is that, the callback function is not consistently called. My robot enters in recovery behavior as most of the time it takes too long for the service to be advertised. I believe this might be affecting it.
The service is advertising inside a ticking function that ticks each time the global plan is available as follows:
void RosService::tick()
{
//
//Unrelated codelines
//
node_handle_ = std::make_unique<ros::NodeHandle>();
ros::ServiceServer service = node_handle_->advertiseService("copier", copy);
ros::spinOnce();
}
My client is written as follows in the global planner:
#include <pluginlib/class_list_macros.h>
#include "copy_planner.h"
//register this planner as a BaseGlobalPlanner plugin
PLUGINLIB_EXPORT_CLASS(copy_planner::CopyPlanner, nav_core::BaseGlobalPlanner)
using namespace std;
//Default Constructor
namespace copy_planner
{
CopyPlanner::CopyPlanner()
{
}
CopyPlanner::CopyPlanner(std::string name, costmap_2d::Costmap2DROS *costmap_ros)
{
initialize(name, costmap_ros);
}
void CopyPlanner::initialize(std::string name, costmap_2d::Costmap2DROS *costmap_ros)
{
if (!initialized_)
{
costmap_ros_ = costmap_ros; //initialize the costmap_ros_ attribute to the parameter.
costmap_ = costmap_ros_->getCostmap(); //get the costmap_ from costmap_ros_
// // initialize other planner parameters
n.param("step_size", step_size_, costmap_->getResolution());
world_model_ = new base_local_planner::CostmapModel(*costmap_);
// create a client for the path planning service
service_ = n.serviceClient<copy_service::copier>("copier");
// wait for the service to be advertised and available
service_.waitForExistence();
initialized_ = true;
}
else
ROS_WARN("This planner has already been initialized... doing nothing");
}
bool CopyPlanner::makePlan(const geometry_msgs::PoseStamped &start, const geometry_msgs::PoseStamped &goal, std::vector<geometry_msgs::PoseStamped> &plan)
{
copy_service::copier srv;
geometry_msgs::PoseStamped pose_stamped;
// copy_service::copier path;
srv.request.isaac_plan.header.stamp = ros::Time::now();
srv.request.isaac_plan.poses.push_back(goal);
// sub = n.subscribe("isaac_plan", 1000, &CopyPlanner::callback, this);
service_.call(srv);
if (srv.response.copied_plan.poses.size())
{
for (int i = 0; i < srv.response.copied_plan.poses.size(); ++i)
{
pose_stamped.header.stamp = ros::Time::now();
pose_stamped.header.frame_id = "map";
pose_stamped.pose = srv.response.copied_plan.poses[i].pose;
plan.push_back(pose_stamped);
}
return true;
}
else
{
return false;
}
}
};
I have the similar problem in python, have you got a solution?
@waltergun I believe I had to lower the frequency on the client's side for which it requested the service, I had to reduce it quite drastically (order of 100). This is a bit counter intuitive but it worked well.
Isn't the problem here
ros::ServiceServer
's ctor is called inside a callback / very limited scope?Similar to pub-sub, setting up server-client connections takes time. Recreating a service server every
N
milliseconds will not work reliably.The fact you "had to reduce it quite drastically (order of 100)" seems to support this: there just wasn't enough time for your client(s) to connect to your server. Hence the error message: "received a tcpros connection for a nonexistent service": the server didn't exist any more by the time the client(s) were trying to reach it.
@gvdhoorn Thanks a lot for the info! I dont have my hands on the project anymore but I believe this makes sense, and I wish I knew that back then