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

Call Time Stamped Services From Node

asked 2020-10-26 10:33:37 -0600

JackB gravatar image

How can I call a time stamped service from a ROS node?

For example, RVZ launches 3 services (regarding logging etc.) but they are all time stamped (or have some other PID) that makes the service name unique to that instance of RVIZ.

This means that I can't use that service in another node (a cpp node in this case) because its name changes every time. Is there a way to work around this using maybe regex of some other dynamic name matching technique? Or is preventing this behavior done on purpose to keep you from using time stamped services in nodes?

I shopped around on ROS Answers but couldn't find and obvious answer, but if there is already one, a link would be much appreciated.

Thanks!

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2020-10-26 21:10:01 -0600

JackB gravatar image

So really the say that I solved the problem of the randomly named services was to assign the RVIZ node a name like rosrun rviz rviz __name:=rviz. For some reason RVIZ assigns an anonymous name by default. If you assign the node a name then its services etc. will not have the anonymous unique identifier and will be readily callable with a repeatable name structure.

edit flag offensive delete link more
1

answered 2020-10-26 13:16:31 -0600

I don't know how about C++/roscpp, but in node.js (using rosnodejs) this is relative straightforward:

const rosnodejs = require('rosnodejs');

rosnodejs.initNode('/testing').then((rosNode) => {

  rosNode._node._masterApi.getSystemState().then(state => {

    const s = Object.keys(state.services).find(
      serviceName => serviceName.match(/^\/rviz.*save/));

    const client = rosNode.serviceClient(s, 'rviz/SendFilePath');

    console.log(`calling service ${s}`);
    client.call({path: { data: '/tmp/rviz.rviz' }}).then( response => {
      console.log('service response:', response);
      rosnodejs.shutdown();
    });
  });
});

Output:

> node test.js 
[INFO] [1603735888.341] (ros): Connected to master at http://localhost:11311!
calling service /rviz_1603735127814459630/save_config
service response: SendFilePathResponse { success: true }

In C++ you would presumably need to follow a similar approach, i.e., make a xmlrpc call to the ROS master API to lookup all services and then match your regex against that list. But I'm not familiar with how to do that in C++.

Hope this helps.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2020-10-26 10:33:37 -0600

Seen: 395 times

Last updated: Oct 26 '20