# rosservice via Python

I have a drone which has certain services, say random.srv. I want to use this service via Python. Now I know that there is a page in ROS wiki that tells you how to create a service client in Python. Unfortunately that is not sufficient for me. Here goes my case:

Once I start the drone node, the service is listed as

/main/random_task


Now an important point to note is that the name of the service is as stated above

random.srv


The function that I am writing is:

from random.srv import *
import rospy

def enableRandom():
try:
doSomething(1)  # something seems to be missing

except rospy.ServiceException:
print('Service call failed')

if __name__ == '__main__':

enableRandom()


The thing is it gives an error saying random is undefined. But that is the name of the srv file.

Can someone also explain why it doesn't work the way it should. You can guess by this question that I am new to this.

Edit 1: Now I understand that in the statement

from random.srv import *


the 'random' should be the package name. This is not the case. The package name is, lets call it my-package1. The service random.srv that I want to use is in

src/my-package1/main/srv/


Another thing to clear up is that /main/random_task is the name with which random.srv is shown in rosservice list. The new code now is

from my-package1.srv import random
import rospy

def enableRandom():
try:
doSomething()

except rospy.ServiceException:
print('Service call failed')

if __name__ == '__main__':

enableRandom()


Now I get my-project1 as having invalid syntax (I guess due to having '-'symbol). If I use

from main.srv import random


it says it cannot find 'main'.

First if I have to use 'my-project1.srv' how to I get around the syntax issue with '-'.

Secondly, if I have to use the subfolder name i.e. main.srv, why does it not recognize the package if it can recognize the services inside it (when using rosservice list on the terminal).

I think there is an issue with the syntax.

• Do you still have a question? – Ari Onasafari Aug 1 '18 at 15:06
• @Ari sorry update it... – Zero Aug 1 '18 at 15:08

What is the exact error you're getting? You have random in two locations - your module import (from random.srv import *), and when you setup the service proxy (rospy.ServiceProxy('main/random_task', random).

An import error would probably mean Python can't find random.srv, where the service proxy error would probably mean that Python can't find random.srv.random, which means that it can't find the random service definition inside your random.srv file.

Maybe this is enough to point you in the right direction, but if not, could you edit your question to provide a link to the random.srv file?

:EDIT:

First, you need to get your naming straight. See this question on Stack Overflow, "How to import module when module name has a '-' dash or hyphen in it?" The two top answers are, in short:

you can't. foo-bar is not an identifier. rename the file to foo_bar.py

And

If you can't rename the module to match Python naming conventions, create a new module to act as an intermediary:

 ---- foo_proxy.py ----
tmp = __import__('foo-bar')
globals().update(vars(tmp))

---- main.py ----
from foo_proxy import *


Second, you might have a naming conflict with main/srv. Check out the tutorial on creating messages and services. Specifically, I noticed:

Also you need the same changes to package.xml for services as for messages, so look above for the additional dependencies required.

Remove # to uncomment the following lines:

# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )


It would seem to me that, if you already had a main.srv declared in your package.xml file, then it might be chance that your services are getting read, because your my-package1 folder happens to be in the src folder (so it's on the path) and then main.srv shares a name with something else. Sharing names is bad, especially when you're importing all, because of the same reason import * or using namespace std is bad - you can/might/will overwrite something and then it's not clear which function/service/method you're actually using.

My suggestions would be:

1. Rename your my-package1 to my_package1.
2. Put all of the services for my_package1 in the my_package1\srv folder - don't use \main\ as a subfolder if possible.

Try these, see if it helps. If it does, and you have a related question, please start a new question and link to this one if you feel it provides context for the new question. If this isn't the answer you're looking for, please edit your question to reflect what happened when you tried the steps above.

• I made the changes to make it more info – Zero Aug 1 '18 at 14:59
• @Zero - I'll try my best to update the answer here, but in the future please start a new question if you have a new question. In the future, if a question is solved, please accept the answer to mark it as solved and ask a new one. You can reference earlier questions whenever you make a new question; just click the "share" button under the post to get a link and then put that link in your new question. – Chuck Aug 1 '18 at 15:44

A lot of gratitude for Chuck for investing the time and making me learn a lot. But the issue I had was more for a stupid reason that anything else. Having multiple catkin workspaces, I tend to source the terminal if and when required. While running ROS, I run the code above using a new terminal. I just did not source it and hence I couldn't locate the packages (and consequently services) in that workspace despite the ROS running the nodes and services from those packages.

• Well, glad you solved the problem problem, regardless of the cause. Sometimes even the trivial issues can cause endless headaches. Since you've solved your question, please accept it so future visitors can find the solution easier (accepted answers are always on top). – Chuck Aug 9 '18 at 13:10