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

How to optimize service calls

asked 2019-07-04 02:47:21 -0500

kump gravatar image

updated 2019-07-04 02:48:14 -0500

I'm trying to optimize my code so I was measuring how long different parts of ROS process take. Specifically

rospy.wait_for_service(rospy.get_param('~service_name'))

always seems to take little over 2 ms

service = rospy.ServiceProxy(rospy.get_param('~service_name'), MySrv)

always seems to take little under 1 ms

resp = service(MySrvRequest())

always seems to take little over 1 ms

This all causes the one service call to result in about 4 ms of delay and I want to get my program to 1 ms precision. What are the variables that effect how long those service calls take? Can I adjust the setting somewhere to make it faster?

edit retag flag offensive close merge delete

Comments

Service calls use the networking functions to communicate with different nodes. So their speed is effected by many factors. If the service server node was on a different computer These numbers could be much higher! If you really need speed and consistency that much then you'll have to try and merge functionality into a single node (binary)

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2019-07-04 08:19:45 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
6

answered 2019-07-09 08:18:20 -0500

gvdhoorn gravatar image

updated 2019-07-09 08:25:56 -0500

A few things to note:

  • you're trying to achieve a 1kHz loop rate with a Python script: not impossible, but certainly not the first combination of runtime environment and performance requirements I'd choose. Have you considered the amount of jitter this is going to experience?
  • using parameters is always good (improves reusability of your code), but in this case for your service variable to be initialised you're incurring the overhead of communicating with the parameter server by using get_param(..) there. That's a full XML-RPC session setup, communication (ie: transmit and receive), (de)serialisation and teardown just to read a single parameter.
  • you don't appear to be using a persistent connection. That causes rospy to always do a full lookup and rebinding of the ServiceProxy upon invoking it. That is a lot of overhead as the network stack and multiple other nodes are involved (ie: service server and the master).

And from this:

This all causes the one service call to result in about 4 ms of delay and I want to get my program to 1 ms precision.

I get two impressions:

  1. you're executing this piece of code in an inner / performance critical loop
  2. you're using services for something they are not really suited for

If my first impression is correct: don't do that. If you must, only invoke the already initialised (ie: bound) service call in your loop. The rest should be done in the initialisation phase of your script.

For the second: I would personally not use services for something like this, but that is of course your choice and would depend on many things we do not know.

Finally: in #q328017 you mention the word "real-time". You're most likely already aware, but a standard Python interpreter is not a deterministic runtime environment. rospy is incapable of deterministic execution, and the TCP/IP based communication system used is also non-deterministic. If "real-time" was meant to say "fast enough", then it's probably possible, but it won't be deterministic.

edit flag offensive delete link more

Comments

1

For completeness: http://wiki.ros.org/rospy/Overview/Se... shows how to enable persistent connections in rospy while your impressive answer links to roscpp

Simon Schmeisser gravatar image Simon Schmeisser  ( 2022-12-16 10:01:11 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2019-07-04 02:47:21 -0500

Seen: 14,306 times

Last updated: Jul 09 '19