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

ROS2 equivalent of ros::package::getPath

asked 2018-04-12 15:10:24 -0500

GregB gravatar image

updated 2018-04-12 18:09:59 -0500

ahendrix gravatar image

Is there a ROS2 API with similar functionality to ros::package::getPath

edit retag flag offensive close merge delete


@GregB can you accept and answer or ask for more clarification? Thanks!

William gravatar image William  ( 2018-06-01 16:01:18 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted

answered 2018-04-12 19:38:50 -0500

William gravatar image

updated 2022-07-21 15:37:00 -0500

AndyZe gravatar image

The closest equivalent to what ros::package::getPath() returns in ROS 1 is what we call the package's "share directory", which is essentially the package's "install prefix" plus a standard (FHS based) relative path of share/<package name>. This is where we put the package.xml and where you should install architecture independent resources like images, launch files, config files, etc...

So, as an example, if your package is called foo and you installed to /home/user/my_ros2_ws/install, then the package share directory would be /home/user/my_ros2_ws/install/share/foo. But to get to that path you need to know (at runtime) where the package was installed to.

In ROS 2 this information is provided by the resource index:

This index is populated at compile time (rather then by crawling the filesystem at runtime as in ROS 1).

This index can be queried in various ways, but it can be used to get the installation prefix of a package (i.e. something like /opt/ros/ardent/ or ~/my_ros2_ws/install/), if it is installed on the system. Once you know that you can easily add the relative share directory path to the install prefix yourself. However, there are convenience API's in both C++ and Python to get the "share directory" of a package directly:




from ament_index_python.packages import get_package_share_directory
# may raise PackageNotFoundError
package_share_directory = get_package_share_directory('my_package_name')




#include <ament_index_cpp/get_package_share_directory.hpp>
// may throw ament_index_cpp::PackageNotFoundError exception
std::string package_share_directory = ament_index_cpp::get_package_share_directory("my_package_name");


With the command line you can only get the package install prefix right now, but it would be simple to add the share directory as well.

Docs (only in -h for now):

% ros2 pkg prefix -h
usage: ros2 pkg prefix [-h] package_name

Output the prefix path of a package

positional arguments:
  package_name  The package name

optional arguments:
  -h, --help    show this help message and exit


% ros2 pkg prefix rclcpp

I made an issue to add the share directory to the command line tool, help welcome :)

edit flag offensive delete link more



Is there a way to get the src directory? This method makes it so that you have to rebuild every time you update a config which kind of defeats the purpose of a config sometimes.

lexi gravatar image lexi  ( 2021-03-04 13:56:53 -0500 )edit

I agree. I need the source directory of the package rather than installed package. Any ideas?

kyubot gravatar image kyubot  ( 2022-07-07 01:36:02 -0500 )edit

You should never reference the src directory of another package. It is fragile and will never work on the buildfarm. Instead you should install resources from that package and reference that package's install folder.

William gravatar image William  ( 2022-07-27 17:43:47 -0500 )edit

answered 2018-04-12 15:25:29 -0500

Dirk Thomas gravatar image

updated 2018-04-12 15:26:03 -0500

In ROS 2 this information is provided by the resource index which is populated at compile time (rather then by crawling the filesystem as in ROS 1). This index can be queried in various ways:

  • Command line: ros2 pkg prefix rclcpp
  • Python API:

    import ament_index_python ament_index_python.get_resource('package', 'rclcpp')

  • C++ API (no example code out of my head...)

In either of the cases the result is the prefix path where the specific package is being installed. Depending on that information you are looking for you can construct derived paths manually. E.g. the manifest is in the location <prefix>/share/<pkgname>, the include directory is in <prefix>/include etc.

edit flag offensive delete link more


The exact equivalent in Python is this function:

William gravatar image William  ( 2018-04-12 15:46:10 -0500 )edit

Sorry, that was the wrong one for Python, I'll edit the comment. The C++ one is here:

William gravatar image William  ( 2018-04-12 15:47:13 -0500 )edit

Both of those are to the share directory of the package (which is the closest thing in my opinion to ros::package::getPath), both also have the "installation prefix for a package" and the ability to list packages and their prefixes.

William gravatar image William  ( 2018-04-12 15:49:20 -0500 )edit

I'm using ament_index_cpp::get_package_prefix("packagename"), which returns the same as 'ros2 pkg prefix <packagename>'. Is there any reason why that isn't the recommended answer to this question?

mkhansen gravatar image mkhansen  ( 2018-06-01 15:42:37 -0500 )edit

@mkhansen, do you mean why is this not the example in this answer or why is it not the answer to the original question? I would say ament_index_cpp::get_package_prefix() isn't the closest replacement for ros::package::getPath, but I explain that in my answer above.

William gravatar image William  ( 2018-06-01 16:00:53 -0500 )edit

@William - OK, I see the difference now. I was thinking getPath() was for the prefix, not the share location.

mkhansen gravatar image mkhansen  ( 2018-06-04 12:25:46 -0500 )edit

Question Tools



Asked: 2018-04-12 15:10:24 -0500

Seen: 15,961 times

Last updated: Jul 21 '22