[NRP] ROS services and transfer function


#1

Is it possible to call a custom ROS service from the transfer function’s body?


#2

Hi,

yes, it is possible. You basically have two different options: You can either use persistent service proxies and map them to a variable or use non-persistent service proxies and create them in the body of a TF.

import rospy
from whatever_you_need.srv import YourService

@nrp.MapVariable("service", initial_value=rospy.ServiceProxy("/a/service", YourService, persistent=True))
@nrp.Neuron2Robot()
def call_a_service(t, service):
    service(0, 8, 15)

or non-persistent:

import rospy
from whatever_you_need.srv import YourService

@nrp.Neuron2Robot()
def call_a_service(t):
    service = rospy.ServiceProxy("/a/service", YourService, persistent=True)
    service(0, 8, 15)

Which option is better for your use case mainly depends (i guess) on how often you need to run that service. The downside of this is that unlike topic communication, the service spec really depends on that you use ROS.


#3

Hi,

As Georg has said, it’s indeed possible.

You can find an example in the iCub Visual Tracking experiment:
The move_target Transfer Function uses the set_model_state service proxy.
It’s implemented using the first approach described by Georg.
You can also see how to call the service and check for errors.


#4

I was having problems making this work in the current NRP version. For anyone else with the same problem, here is the solution.

To make the persistent solution work, instead of

service(0, 8, 15)

you have to use

service.value(0, 8, 15)