ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

No response from service, node won't close either

asked 2018-02-25 10:15:17 -0500

Pigskin gravatar image

I am running into an issue with calling a service in the callback function of a listener. I couldn't find a way to call the service as the initialization of the client stood in the main, but moving that to the function as well gave a whole different series of errors, so i tried to implement a work-around

#include "ros/ros.h"
#include "std_msgs/String.h"
#include "final/add_duplicates.h"
#include <string>
int message = 0;
std::string text;

void preparefortrouble(const std_msgs::String::ConstPtr& msg)
{
text = msg->data.c_str();
message = 1;
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "add_duplicates_client");
    ros::init(argc, argv, "print_twice");
    ros::NodeHandle n;  
    ros::Subscriber sub = n.subscribe("print_twice", 1, preparefortrouble);
    ros::ServiceClient client = n.serviceClient<final::add_duplicates>("add_duplicates");

    while (1){
        while (message == 1)
        {
            final::add_duplicates srv;
            srv.request.text = text.c_str();
            srv.request.nrOfDuplicates = 2;
            if (client.call(srv) == false)
            {
                ROS_ERROR("Orga het is stuk");
            }
            message = 0;
        }
    }
  ros::spin();

  return 0;
}

The server has been tested and works fine, the topic is called in the terminal. However, when i use this node, it cannot be close by crtl-c and sending a message to the topic results in nothing.

i try to call it with

$ rostopic pub /print_twice std_msgs/string “hello"

and my srv file is as following:

string text
int32 nrOfDuplicates
---
string multitext

thanks for the support.

edit retag flag offensive close merge delete

Comments

1

I couldn't find a way to call the service as the initialization of the client stood in the main

I don't really understand what you write here, so I've ignored that for now.

What are you trying to do really?

gvdhoorn gravatar image gvdhoorn  ( 2018-02-25 10:50:06 -0500 )edit

2 Answers

Sort by » oldest newest most voted
0

answered 2018-02-25 10:46:05 -0500

gvdhoorn gravatar image

updated 2018-02-25 11:08:18 -0500

and sending a message to the topic results in nothing

This is most likely caused by the fact that your node does not handle any incoming events (ie: msgs on topics).

To remedy that you'd need to either call ros::spin() or periodically call ros::spinOnce().

Your node does the former, but only after it has progressed through the while-loops. And this is the problem, as in order to get through the loops, your node needs to handle incoming events (otherwise message will never be set to 1). This seems to be a deadlock situation.

I would suggest to avoid the two nested while-loops, as I believe they are not needed and only complicate things.

What are you actually trying to do and what are the two while-loops supposed to achieve?

Some other things I noticed:

  • there is no ros::Rate::sleep() in the body of either of your while-loops (busy-wait, 100% cpu usage)
  • you have two calls to ros::init(..) in there, I'm not sure that is going to work (or at the very least: it's not needed)
  • avoid using final for anything (unless you want to declare something as final). It is a C++11 keyword: final specifier (since C++11)

However, when i use this node, it cannot be close by crtl-c

if you need to run a while-loop, make sure to use something like while (ros::ok()) { .. }. This makes your node check whether it has been requested to exit.

See also wiki/roscpp/Overview/Callbacks and Spinning.


Edit: (nested) while-loops are not necessarily a good idea with an event-based, asynchronous framework such as ROS. You may want to re-evaluate your approach and possibly restructure your node.

edit flag offensive delete link more
0

answered 2021-07-20 02:45:15 -0500

bach gravatar image

As noticed by gvdhoorn, the problem is caused by the lack of a spinner before service call. I can think 2 possible solutions:

  • Call ros::spin() on the server side, just after you register the service.
  • Use ros::AsyncSpinner that basically is a non-blocking spin request (see docs for details).

Hope this is helpful!

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2018-02-25 10:15:17 -0500

Seen: 1,694 times

Last updated: Jul 20 '21