roslaunch doesn't terminate on pressing Ctrl-C when changing ROS param in a loop

asked 2019-11-07 02:12:07 -0500

cybodroid gravatar image

updated 2019-11-07 02:32:58 -0500

Hello All, I am facing a weird behavior while running a ROS node. In my ROS node, I am continuously setting a ROS parameter that changes at a fixed interval. The overall goal is to set write a node that will tell another node when to publish. This 'when' frequency is set in this node whose code I have written below.

See below:

#include <ros/ros.h>
#include <ctime>
#include <cstdlib>

int main(int argc, char** argv)
{
    ros::init(argc, argv, "timer_companion");

    ros::NodeHandle nodeHandle("~");

    ros::Rate loop_rate(1000);

    /* Desired Publish rate: This will be passed as ROS Param */
    double pub_rate;

    nodeHandle.param("pub_rate", pub_rate, 10.0);

    ros::param::get("pub_rate", pub_rate);

    ROS_INFO_STREAM("Desired publish rate provided by the user is "<< pub_rate);

    ros::param::set("do_publish", false);

    ros::Time lastTime = ros::Time::now();

    ROS_INFO_STREAM("Starting companion Time");
    do
    {
        ros::param::set("do_publish",  false);
        ros::Time newTime = ros::Time::now();
        ros::Duration duration = newTime - lastTime;

        if (duration.toSec() >= 1.0/pub_rate)
        {
            lastTime = newTime;
            ros::param::set("do_publish",  true);
        }
        ros::spinOnce();
        loop_rate.sleep();
    }while(ros::ok());

    ROS_INFO_STREAM("Shutting down...");

    return EXIT_SUCCESS;
}

I run this ROS node using the following launch file:

<?xml version="1.0"?>

<launch>

<arg name = "publish_rate" default="20.0"/>

<node pkg="companion" type="companion_timer" name="timer_companion" output="screen">

    <param name="pub_rate" value="$(arg publish_rate)"/>

</node>


</launch>

In the terminal, I execute:

roslaunch companion companion_timer.launch

However, upon pressing ctrl-C, the roslaunch doesn't terminate and I get the following error message and it stays forever and I am forced to use pkill command or close the terminal:

^C[timer_companion-2] killing on exit
[ERROR] [1573113830.192797427]: [setParam] Failed to contact master at [ubuntu.local:11311].  Retrying...

I investigated to best of my knowledge but I have not been able to understand why this is happening. The only catch is that out of roughly 10 times, once it roslaunch is terminated gracefully. Any help in this regard will be much appreciated.

Thanks.

edit retag flag offensive close merge delete

Comments

1

Just a comment (as I do not know whether this is actually an/the answer): the problem is probably with your use of setParam(..). If you happen to press ctrl+c right when setParam() is trying to communicate with the master, it (ie: setParam(..)) will have to time-out, as the master cannot be reached any more (the master 'runs' the parameter server). That is also why you see the error mentioning setParam.

Regardless I would say that continuously setting parameters like this is an anti-pattern and should be avoided. Setting parameters is a heavy operation (requires multiple messages per parameter) and this is not how parameters should be used. If you want to update parameters at runtime use dynamic_reconfigure.

But even then I doubt a parameter do_publish -- probably to let another node know whether it should publish something? -- is the right way to achieve what you are after.

gvdhoorn gravatar image gvdhoorn  ( 2019-11-07 02:26:53 -0500 )edit
1

And to avoid an xy-problem: could you please describe what it is that you're actually trying to do?

gvdhoorn gravatar image gvdhoorn  ( 2019-11-07 02:27:39 -0500 )edit

Thanks for your comment. Definitely, I lack understanding of the mechanism behind this whole set param thing. However, one thing you definitely got that with this code, I want to tell another node, when to publish. Thanks for the suggestion about dynamic_reconfigure. Let me check on that, and I will report my findings here.

cybodroid gravatar image cybodroid  ( 2019-11-07 02:31:03 -0500 )edit

Sure, I am updating the question description a bit.

cybodroid gravatar image cybodroid  ( 2019-11-07 02:31:53 -0500 )edit
1

The overall goal is to set write a node that will tell another node when to publish.

I believe we already understood this from your code.

My question is: why are you structuring your system like this? And: what is that other node publishing? And why do you make another node responsible for deciding when things should be published or not? Why not include that in the same node?

gvdhoorn gravatar image gvdhoorn  ( 2019-11-07 02:41:24 -0500 )edit

Your question is legit but that needs a big explanation. In short, I can say that some ABC node is doing the computation at rate X, but I want it to publish only at X/Y rate, Y is being decided by the node whose code is given above. However, I cannot control much on ABC as I am using Simulink to generate the ABC ROS node.

cybodroid gravatar image cybodroid  ( 2019-11-07 02:53:18 -0500 )edit

Upon a quick investigation, it doesn't look like that Simulink's ROS Toolbox supports dynamic_reconfigure. I will have to explore further.

cybodroid gravatar image cybodroid  ( 2019-11-07 02:59:01 -0500 )edit
1

And using topic_tools/throttle is not an option?

Controlling timing of other nodes like this is really not very nice.

Operating on the datastream coming out of a node is something that is fairly standard.

Also be aware that you're introducing quite a bit of jitter and possible delay into your system with the approach that you've taken.

gvdhoorn gravatar image gvdhoorn  ( 2019-11-07 02:59:35 -0500 )edit