ros-infrastructure/rospkg

ROS package path order

Closed this issue · 3 comments

While diving into the code to find out how packages were located on the system I found this quite confusing :

This computes the package path :
https://github.com/ros-infrastructure/rospkg/blob/master/src/rospkg/environment.py#L170

It always adds the ROS_ROOT first. in the list. then after you get your defined workspaces, and other (share, stacks).

Documentation says :

:returns: paths to search in reverse order of precedence, ``[str]``

When this list is used from roslaunch : https://github.com/ros/ros_comm/blob/indigo-devel/tools/roslaunch/src/roslaunch/node_args.py#L223 and fills in rospack

rospack is then used like this :

try:
        #TODO:fuerte: pass through rospack and catkin cache
        matches = roslib.packages.find_node(node.package, node.type, rospack=rospack)
    except rospkg.ResourceNotFound as e:
        # multiple nodes, invalid package
        raise NodeParamsException(str(e))
    if not matches:
        raise NodeParamsException("can't locate node [%s] in package [%s]"%(node.type, node.package))
    else:
        # old behavior was to take first, do we want to change this in Fuerte-style?
        cmd = matches[0]

So what happens is that, when doing a roslaunch via the script api, if we have a multiple matches ( package installed in ROS_ROOT and in the workspace configured in ROS_PACKAGE_PATH in first position) the package found and used is the one coming from ROS_ROOT.

This behavior, I think, is inconsistent with the documentation and with user expectation...
From what I can tell this is different than when launching a node from a roslaunch file ( the package in your workspace will be picked up first ).
Or am I missing something ?

I am assuming changing any of this will probably affect other places, but I m wondering where the issue actually comes from (rospkg ? roslaunch?) and what the fix should be.

The ROS_ROOT only exists for backward compatibility. The ros root is set to (<INSTALL_PREFIX>/share/ros) and only used by dry (rosbuild) packages. The ROS_PACKAGE_PATH on the other hand always contains path of the following pattern: <INSTALL_PREFIX>/share. So these paths are always non overlapping. The old API favors old dry packages over new catkin packages. So as far as I can see this is all intentional and should pose any problem.

My question would be what did you do that you end up having multiple matches, one on the ros root and one from the ros package path? Do you use dry and wet packages? Did you changes the ros root?

Thanks for the explanation, I now understand the specific case ( and also why an extra path was always added for packages search, in front of the ROS_PACKAGE_PATH ).

Here is a quick checklist :

  • I use only wet packages ( the ones I know about at least ) and the package that gave me an issue was a wet package.
  • I didn't ( and usually don't ) play with ros_root
  • I use this snippet from python code to navigate packages :
rospack = rospkg.RosPack()
mypackage_path = rospack.get_path('mypackage')
  • I use this snippet from python code to start nodes :
# launcher : one time only
self.launch = roslaunch.scriptapi.ROSLaunch()
self.launch.start()
# for each node we want to start
mypackage_mynode = roslaunch.core.Node('mypackage', 'mynode.py', name='mynode')
self.mynode_process = self.launch.launch(mypackage_mynode)

This will also do a ROS package lookup (after copying the environment variables for the child process). This is how I do roslaunch job, basically, but dynamically from python code.

  • I have different version of the same package installed in different places : ( distro, company distro, underlay workspaces, top workspace )
  • I am using a dynamic way of setting up ROS environment for python (pyros-setup), and there is likely bugs in there...

I now realize that the package should be found in ROS_ROOT <INSTALL_PREFIX>/share/ros only if it comes along with the rosbuild related tools.
So I ll attempt to reproduce the issue and find out why the package I was working on, was found in ros root to begin with...

I will close this ticket for now. If you run into the problem again please feel free to comment with more information and it can be reopened.