Ask Your Question
0

can i execute a launch file or run a node through RosWebTool

asked 2017-08-04 00:42:31 -0600

marine0131 gravatar image

updated 2017-08-04 00:43:46 -0600

i am now using roswebtool(roslibjs) to communicate with rosbridge

so i can publish topic and subscribe topic in website

now i want to remote execute a launch file or run a node in website, is that possible?

or is there any other method to run the node when i want to ?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2017-08-04 03:22:05 -0600

updated 2017-11-23 03:53:56 -0600

Hello,

When you use roslibjs with rosbridge, your website is not a node, but it can be seen as a node (it just don't register with the rosmaster, so you can't see him with "rosnode list"). Rosbridge act as a proxy to use ROS functionnalities.

The easiest way to launch a remote process from your website is to use a process management library like std::system, boost::process or POCO , there are all available in ROS (POCO need this)

For an example with std::system (will quit the callback only when the process finish):

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>

    void callback(std_msgs::String msg){
        std::stringstream ss;
        ss << "roslaunch " << msg.data;
        std::system(ss.str().c_str());//std::system only accept c_str() a.k.a char*
    }

    int main(int argc, char** argv){
        ros::init(argc,argv,"roslaunch_launcher");
        ros::NodeHandle n;
        ros::Subscriber sub = n.subscribe("/launch", 1, callback);
        ros::spin();
        return 0;
    }

Just publish a string in the form "< package name > < launch file name >" and the launch file should be called

You also should be sure to source the correct environment BEFORE launch this node, if you try to launch a file from an another workspace (not sourced) or you create a package after launching this node, the loaded environmnent will not find the launch file.

And an example with POCO (with a run/kill procedure):

#include <ros/ros.h>
#include <std_msgs/String.h>
#include <std_msgs/Empty.h>
#include "Poco/Process.h"
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>


Poco::ProcessHandle* ph;
bool running = false;

void callback_run(std_msgs::String msg){
    if(!running){
        std::vector<std::string> args;
        boost::split(args, msg.data, boost::is_any_of(" ") ); //Split the msg.data on space and save it to a vector
        Poco::ProcessHandle ph_running = Poco::Process::launch("roslaunch", args,0,0,0); //launch a new node
        ph = new Poco::ProcessHandle(ph_running); // Copy the processhandler to our global variable
        running = true; //Refuse new launch
        ROS_INFO_STREAM("launched : roslaunch" << msg.data);
    }
    else{
        ROS_ERROR("A process is already running.");
    }
}

void callback_kill(std_msgs::Empty msg){
    if(running){
        Poco::Process::requestTermination(ph->id()); //send SIGINT
            Poco::Process::wait(*ph); //Wait for roslaunch to kill every node
        free(ph);  
        running = false;  //accept a new launch
        ROS_INFO("Killed process");
    }
    else{
        ROS_ERROR("No Process are running.");
    }
}


int main(int argc, char** argv){
    ros::init(argc, argv, "node_runner");
    ros::NodeHandle n;
    ros::Subscriber sub_run = n.subscribe("/run",100,callback_run);
    ros::Subscriber sub_kill = n.subscribe("/kill",100,callback_kill);
    ros::spin();
    return 0;
}

This example subscribe 2 topics : /run and /kill. Run will accept a node package a name (example : 'rqt_gui rqt_gui') and kill accept a std_msgs/Empty.

This need a little work, as the std::system example will block the subscriber (the function return only when the process die).

edit flag offensive delete link more

Comments

thank you so so much, that works!!! there is anthoer question: how to stop this launch remote?

marine0131 gravatar imagemarine0131 ( 2017-08-06 22:26:08 -0600 )edit

I added an example with POCO to run and kill a process, it work with rosrun but not with roslaunch... I think roslaunch spawn multiple process and detach them, but I don't know how to kill them. If you find a solution I will be happy to see it :)

lmathieu gravatar imagelmathieu ( 2017-08-07 12:19:05 -0600 )edit

i use std::system start launch files and nodes. and kill the nodes the same way using "rosnode kill node" command. if i start a launch, i have to know or record which nodes are started, and kill them using nodekill,"rosnode kill node1 node2 node3"

marine0131 gravatar imagemarine0131 ( 2017-08-08 01:57:20 -0600 )edit

Nice, that work too. I found a way to do it with Poco, with the use of Poco::Process::requestTermination() instead of kill(), it send a SIGINT to the roslaunch and close all nodes launched.

lmathieu gravatar imagelmathieu ( 2017-08-08 03:30:19 -0600 )edit

great, so thanks

marine0131 gravatar imagemarine0131 ( 2017-08-08 04:05:01 -0600 )edit

Hello i just found this article. I would like to do the same as you, from a webpage. Do you mind sharing your final solution of this code for me? Did you manage to start/stop all kind of nodes? Thank you for your answer :)

molnardk gravatar imagemolnardk ( 2017-11-15 04:36:00 -0600 )edit

Hi, yes I made some buttons to start/stop all kind of nodes, I write a service in robot to process the request of start/stop nodes, and use std:system to start node and use nodekill to stop node. you can also use @Imathieu 's method

marine0131 gravatar imagemarine0131 ( 2017-11-15 21:22:38 -0600 )edit

I will give a look, thank you :)

molnardk gravatar imagemolnardk ( 2017-11-16 03:43:13 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2017-08-04 00:42:31 -0600

Seen: 780 times

Last updated: Nov 23 '17