0
$\begingroup$

Rosanswers logo

Final update: The solution so far is modified from here with help from ufr3c_tjc. (Thank you loudly in my heart) So the original codes from the link above is erroneous and won't work. The main part is remained:

class open_launch_file(): 
    def __init__(self):
        rospy.init_node('tester', anonymous=True)
        rospy.on_shutdown(self.shutdown)

        uuid = roslaunch.rlutil.get_or_generate_uuid(None, False)
        roslaunch.configure_logging(uuid)
        launch = roslaunch.parent.ROSLaunchParent(uuid,["/path/to/your/launch/file"])
        launch.start()

    def shutdown(self):
        rospy.loginfo("Stopping the robot...")
        destroy() #my own cleaning stuff function, you dont have to have it. but if there is anything you need to do before close the ros node, do it here.
        rospy.sleep(1)

===============================================================================

I have a .launch file that basically just open the webcam. And I would like to call it from my python code when needed. I searched online and found something like this: I have test other normal commands like "ls -l", "echo Hello world". And they are working fine. However, it would not work with the launch file

import subprocess
p = subprocess.Popen(["roslaunch ~/path/to/cam.launch "],stdout=subprocess.PIPE,stderr = subprocess.PIPE,shell=True)
print p.communicate()

the error message is:

'/bin/sh: 1: roslaunch: not found\n

I am using python 2.7

update:

the output of printenv | grep PY is:

INSIDE_CAJA_PYTHON=
PYTHONPATH=/opt/ros/kinetic/lib/python2.7/dist-packages

When using the API example provide by ROS, there were errors that confuse me. I have set the environment correctly I believe. When I rosrun tester_pkg tester.py , it gives error NameError: name 'rospy' is not defined

So I tried sudo python tester.py directly, it gives ImportError: No module named roslaunch

Thank you all for the replying. I am new to ROS and really need some helps.

update codes: tester.py

#!/usr/bin/env python
import roslaunch
import rospy

rospy.init_node('tester', anonymous=True)
rospy.on_shutdown(self.shutdown)

uuid = roslaunch.rlutil.get_or_generate_uuid(None, False)
roslaunch.configure_logging(uuid)
launch = roslaunch.parent.ROSLaunchParent(uuid,["/home/yue/catkin_ws/src/webcam_car/launch/cam.launch"])

launch.start()

launch.shutdown()

Originally posted by yue.z on ROS Answers with karma: 1 on 2017-06-14

Post score: 0


Original comments

Comment by ufr3c_tjc on 2017-06-14:
Don't use sudo. That will run it as root, which will never work unless ROS is installed as root. line 3: syntax error near unexpected token is telling you the issue. Look at line 3 of the file and see what could be wrong (or post the file for us to see).

Comment by ufr3c_tjc on 2017-06-14:
NameError: name 'rospy' is not defined

Add import rospy

Comment by yue.z on 2017-06-14:
Thank you! But now the error become

rospy.on_shutdown(self.shutdown)
NameError: name 'self' is not defined

Comment by yue.z on 2017-06-14:
the line 3 error is fixed by adding #!/usr/bin/env python. stupid missing.

Comment by ufr3c_tjc on 2017-06-14:
Can you edit the question with the file's code you are trying to run? That will make it much easier to help you.

Comment by yue.z on 2017-06-14:
sure. It's basically the sample II from the roslaunch API page.

Comment by ufr3c_tjc on 2017-06-14:
The self.shutdown part is weird. The self keyword is only used in a class context. Just remove that line completely. Also, this script will immediately start then shutdown the launch file, so maybe just remove the launch.shutdown() part until you decide how/when you want to shut it down.

Comment by yue.z on 2017-06-14:
I found comment about the self.shutdown # Set rospy to exectute a shutdown function when terminating the script Remove this line and the launch.shutdown() works as I can see the process being created! But still the launch file shutdown itself. I guess I can take over from here now! Thank you so muc

Comment by yue.z on 2017-06-14:
thank you for you patient! :)

Comment by ufr3c_tjc on 2017-06-14:
Yes, the rospy.on_shutdown(self.shutdown) will run the shutdown function if your have one defined, when running inside a class. It's just weird that their example doesn't have a class, so it errors. Remove the launch.shutdown(), this is what's causing it to stop.

Comment by yue.z on 2017-06-15:
It happened after I removed launch.shutdown statement. Actually the terminal looks the same with or without it. That's weird. I'm looking into the documents.

Comment by ufr3c_tjc on 2017-06-15:
It because the script ends. Put in a rospy.spin() line at the end, and it will wait and not exit until told to do so by the ros master.

Comment by yue.z on 2017-06-16:
Turns out the rospy.on_shutdown(self.shutdown) is quiet important. otherwise, the node wont stop by ctrl -c any more. So I modify the code into one with class. The attribute 'shutdown' also must be writen. I would update my detailed solution so far for future newbies like me.

Comment by yue.z on 2017-06-16:
thank you for your kindness help

Comment by gvdhoorn on 2017-06-17:
Please post your final update as an answer and then accept your own answer. That way there is a clear answer to this question, and it's also visible from the main question listing. Thanks.

$\endgroup$

2 Answers 2

1
$\begingroup$

Rosanswers logo

Please use the search first in the future, this has been asked multiple times already. That sounds harsh, and we do want to help you, but with almost 35000 questions on this site it gets increasingly important to avoid duplicates.

As to your question: yes, this is possible, you'll just have to make sure that the environment in which you run your Python script has already been setup with the appropriate environment variables. In other words: run it from a terminal in which you have sourced the correct setup.bash, and make sure your Popen call inherits the environment from its caller.

As an alternative: do not start roslaunch .. directly in your Popen call, but use a small wrapper script that first sources the setup.bash and then executes roslaunch.


Originally posted by gvdhoorn with karma: 86574 on 2017-06-14

This answer was NOT ACCEPTED on the original site

Post score: 2

$\endgroup$
0
$\begingroup$

Rosanswers logo

The correct way to do this is to use the actual roslaunch Python API. Do not use calls to subprocess etc. It gets way too messy to control environment variables and makes stopping the processes much harder. Using the proper API allows you to start, but also to stop, the launch file nodes easily. See here for examples.

Again though, that API page is the second Google result for 'roslaunch python'. Please do some searching before posting next time :)


Originally posted by ufr3c_tjc with karma: 885 on 2017-06-14

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by yue.z on 2017-06-14:
actually this was the first thing I tried. It gave error of cannot find module roslaunch.

Comment by ufr3c_tjc on 2017-06-14:
Then your path must be set up incorrectly. Can you edit the question to show the output of printenv | grep PY. It should include something like /opt/ros/kinetic/lib/python2.7/dist-packages

Comment by ufr3c_tjc on 2017-06-14:
Also make sure that you're running the python script from a shell that has the correct environment variables set (ROS_PACKAGE_PATH etc.), otherwise it won't work.

Comment by yue.z on 2017-06-14:
the output is:

    INSIDE_CAJA_PYTHON=
    PYTHONPATH=/opt/ros/kinetic/lib/python2.7/dist-packages

Comment by ufr3c_tjc on 2017-06-14:
That part is at least correct, but it doesn't have your own workspace in the path. I assume that you always source devel/setup.bash before running your code from within your own workspace? Also, what is the output of printenv | grep ROS?

Comment by yue.z on 2017-06-14:
ROS_ROOT=/opt/ros/kinetic/share/ros ROS_PACKAGE_PATH=/home/yue/catkin_ws/src:/opt/ros/kinetic/share ROS_MASTER_URI=http://localhost:11311 ROSLISP_PACKAGE_DIRECTORIES=/home/yue/catkin_ws/devel/share/common-lisp ROS_DISTRO=kinetic ROS_ETC_DIR=/opt/ros/kinetic/etc/ros

Comment by gvdhoorn on 2017-06-15:
@ufr3c_tjc: using the roslaunch Python API is indeed a better approach, but I did not want to complicate things too much for @yue.z, seeing as he already states that he is a beginner.

Comment by yue.z on 2017-06-15:
"she". I will try both ways to see which one fit my need if I could make them work.

Comment by lucasw on 2018-06-19:
The first search result for 'roslaunch python' for me is about launching python nodes from roslaunch, and about half the following results are also for that opposite case. Also, using the proper api is very messy if you want to do something like pass in parameters, unless using lunar or later.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.